다른 사용자로 Linux 서비스를 실행하는 모범 사례


141

서비스는 기본적으로 rootRHEL 상자에서 부팅 할 때 시작됩니다 . 올바르게 기억한다면 init 스크립트를 사용하는 다른 Linux 배포판에서도 마찬가지입니다 /etc/init.d.

프로세스를 내가 선택한 (정적) 사용자로 실행하는 가장 좋은 방법은 무엇이라고 생각하십니까?

내가 도착한 유일한 방법은 다음과 같은 것을 사용하는 것입니다.

 su my_user -c 'daemon my_cmd &>/dev/null &'

그러나 이것은 조금 어수선한 것 같습니다 ...

루트가 아닌 다른 사용자로서 서비스를 자동으로 시작하는 쉬운 메커니즘을 제공하는 약간의 마술이 있습니까?

편집 : 이 인스턴스에서 시작하는 프로세스가 Python 스크립트 또는 Java 프로그램이라고 말해야합니다. 오히려 주변에 네이티브 래퍼를 작성하지 않기 때문에 불행히도 Black이 제안한 대로 setuid () 를 호출 할 수 없습니다 .


파이썬은 setuid () 시스템 호출 패밀리에 대한 액세스를 제공하지 않습니까? 그것은 Perl과 비교할 때 심각한 결함처럼 보입니다.
Jonathan Leffler

12
그렇습니다. os.setuid (uid). 매일은 학교 수업입니다!
제임스 브래디

답변:


67

데비안 start-stop-daemon에서는 pid 파일을 처리하고, 사용자를 변경하고, 데몬을 백그라운드로 만드는 유틸리티를 사용합니다 .

나는 RedHat에 익숙하지 않지만, daemon이미 사용중인 유틸리티 ( /etc/init.d/functionsbtw에 정의되어 있음 )는 어디에서나 동등한 것으로 언급 start-stop-daemon되므로 프로그램의 UID를 변경하거나 수행 방식을 변경할 수 있습니다 이미 올바른 것입니다.

그물을 둘러 보면 사용할 수있는 기성품 래퍼가 몇 가지 있습니다. 일부는 이미 RedHat에 패키지되어있을 수도 있습니다. 한 번 봐 가지고 daemonize예를 들어,.


x-ref는 흥미 롭습니다. 나는 비슷한 데몬 즈 프로그램을 가지고있다. pidfile 또는 lockfile을 수행하지 않고 umask를 설정합니다. UID, GID, EUID, EGID 및 보조 그룹 (asroot라고 함)을 설정하기위한 별도의 SUID 루트 프로그램이 있습니다. 나는 'asroot [opts]-env -i [env] daemonize [opts]-command [opts]'를 사용합니다.
Jonathan Leffler

(계속) : POSIX 표준 env 프로그램은 환경 설정과 실행 된 명령 사이에 '-'를 허용하지 않습니다 (irksome이지만 그렇게).
Jonathan Leffler

4
upstart 스크립트에서 /etc/init.d/functions의 데몬 기능을 어떻게 사용할 수 있습니까? 예를 보여 주시겠습니까?
Meglio

10
데비안에서는를 참조하십시오 /etc/init.d/skeleton. UID, GID 변수와에 추가 do_start(): 사용start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --chuid $UID:$GID -- $DAEMON_ARGS
조나단 벤 - 아브라함

I의 통지 daemon()에 정의되어 /etc/rc.d/init.d/function내 두 RHEL 및 CentOS는 박스에.
quickshiftin

53

여기에있는 모든 제안을 살펴본 후, 제 위치에있는 다른 사람들에게 유용 할 수있는 몇 가지 사항을 발견했습니다.

  1. 은 나를 다시 지적하는 것이 옳습니다 /etc/init.d/functions:이 daemon기능을 통해 이미 다른 사용자를 설정할 수 있습니다.

    daemon --user=my_user my_cmd &>/dev/null &
    

    이것은 프로세스 호출을 래핑하여 구현합니다 runuser.

  2. Jonathan Leffler 가 옳습니다 : Python에는 setuid가 있습니다.

    import os
    os.setuid(501) # UID of my_user is 501
    

    그러나 여전히 JVM 내부에서 setuid를 설정할 수 있다고 생각하지 않습니다.

  3. 어느 쪽 surunuser 정상적으로 당신은 당신이 이미있는 사용자로 명령을 실행하도록 요청 경우를 처리하지 않습니다. 예 :

    [my_user@my_host]$ id
    uid=500(my_user) gid=500(my_user) groups=500(my_user)
    [my_user@my_host]$ su my_user -c "id"
    Password: # don't want to be prompted!
    uid=500(my_user) gid=500(my_user) groups=500(my_user)
    

suand의 해당 동작을 해결하기 위해 runuserinit 스크립트를 다음과 같이 변경했습니다.

if [[ "$USER" == "my_user" ]]
then
    daemon my_cmd &>/dev/null &
else
    daemon --user=my_user my_cmd &>/dev/null &
fi

도와 주셔서 감사합니다!


5
  • 일부 데몬 (예 : 아파치)은 setuid () 를 호출하여 스스로이를 수행합니다.
  • setuid-file 플래그 를 사용하여 다른 사용자로 프로세스를 실행할 수 있습니다 .
  • 물론 언급 한 솔루션도 효과가 있습니다.

자신의 데몬을 작성하려면 setuid ()를 호출하는 것이 좋습니다. 이렇게하면 프로세스가

  1. 루트 권한을 사용하십시오 (예 : 열린 로그 파일, pid 파일 작성).
  2. 시작하는 동안 특정 지점에서 루트 권한을 삭제하십시오.

3

주의해야 할 다른 사항을 추가하기 만하면됩니다.

  • init.d 스크립트의 Sudo는 tty가 필요하기 때문에 좋지 않습니다 ( "sudo : 죄송합니다. sudo를 실행하려면 tty가 있어야합니다").
  • Java 응용 프로그램을 디먼중인 경우 Java 서비스 랩퍼 (사용자 ID 설정을위한 메커니즘 제공)를 고려할 수 있습니다.
  • 또 다른 대안은 su --session-command = [cmd] [user]입니다.

3

svn 서버용 CENTOS (Red Hat) 가상 머신에서 : /etc/init.d/svnserver pid를 svn이 쓸 수있는 것으로 변경하도록 편집 되었습니다.

pidfile=${PIDFILE-/home/svn/run/svnserve.pid}

옵션 추가 --user=svn:

daemon --pidfile=${pidfile} --user=svn $exec $args

원래 pidfile은 /var/run/svnserve.pid입니다. 데몬은 루트 만 작성할 수있는 becaseu를 시작하지 않았습니다.

 These all work:
/etc/init.d/svnserve start
/etc/init.d/svnserve stop
/etc/init.d/svnserve restart

3
이로 인해 권한 상승 취약점이 발생합니다. svn 사용자는 이제 svn 서비스가 중지되거나 재시작 될 때마다 svn 프로세스 대신 종료되는 /home/svn/run/svnserve.pid 파일에 임의의 PID를 넣을 수 있습니다.
rbu

2

주의해야 할 사항 :

  • 언급했듯이 su는 이미 대상 사용자 인 경우 암호를 묻습니다.
  • 마찬가지로, 이미 일부 사용자의 경우 대상 사용자 인 경우 setuid (2)가 실패합니다.
  • setuid (2)는 /etc/limits.conf(Linux) 또는 / etc / user_attr (Solaris)에 정의 된 권한 또는 자원 제어를 설치하지 않습니다.
  • setgid (2) / setuid (2) 경로를 사용하는 경우 initgroups (3)를 호출하는 것을 잊지 마십시오 .

일반적으로 데몬을 시작하기 전에 / sbin / su를 사용하여 적절한 사용자로 전환합니다.


2

init 스크립트에서 다음을 시도해보십시오.

setuid $USER application_name

그것은 나를 위해 일했다.


3
모든 배포판에서 사용할 수있는 것은 아닙니다. RHEL 7을 시도했습니다 :setuid: command not found
Cocowalla

0

Spring .jar 애플리케이션을 서비스로 실행해야했고이를 특정 사용자로 실행하는 간단한 방법을 찾았습니다.

jar 파일의 소유자와 그룹을 내가 실행하려는 사용자로 변경했습니다. 그런 다음 init.d 에서이 jar을 심볼 링크하고 서비스를 시작했습니다.

그래서:

#chown myuser:myuser /var/lib/jenkins/workspace/springApp/target/springApp-1.0.jar

#ln -s /var/lib/jenkins/workspace/springApp/target/springApp-1.0.jar /etc/init.d/springApp

#service springApp start

#ps aux | grep java
myuser    9970  5.0  9.9 4071348 386132 ?      Sl   09:38   0:21 /bin/java -Dsun.misc.URLClassPath.disableJarChecking=true -jar /var/lib/jenkins/workspace/springApp/target/springApp-1.0.jar
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.