Рекомендуется запускать службу Linux от имени другого пользователя

службы по умолчанию запускаются как root во время загрузки на моем RHEL box. Если я правильно помню, то же самое верно для других дистрибутивов Linux, которые используют сценарии init в /etc/init.d.

как вы думаете, лучший способ вместо этого запустить процессы как (статический) пользователь по моему выбору?

единственный метод, к которому я пришел, - это использовать что-то вроде:

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

но это кажется немного неопрятным...

есть ли немного магии, спрятанной это обеспечивает простой механизм автоматического запуска служб как других, не корневых пользователей?

EDIT: я должен был сказать, что процессы, которые я запускаю в этом экземпляре, являются скриптами Python или Java-программами. Я бы предпочел не писать родную обертку вокруг них, поэтому, к сожалению, я не могу позвонить setuid () as черный предполагает.

8 ответов


в Debian мы используем start-stop-daemon утилита, которая обрабатывает pid-файлы, изменяя пользователя, помещая демона в фоновый режим и многое другое.

Я не знаком с RedHat, но daemon утилита, которую вы уже используете (которая определена в /etc/init.d/functions, кстати.) упоминается везде как эквивалент start-stop-daemon, поэтому либо он также может изменить uid вашей программы, либо способ, которым вы это делаете, уже правильный.

если вы посмотрите по сети, есть несколько готовых оберток, которые можно использовать. Некоторые даже могут быть уже упакованы в RedHat. Взгляните на daemonize, например.


рассмотрев все предложения здесь, я обнаружил несколько вещей, которые, я надеюсь, будут полезны другим в моем положении:

  1. хоп прямо в точку меня at /etc/init.d/functions: в


  • некоторые демоны (например, apache) делают это сами, вызывая setuid ()
  • можно использовать setuid-флаг файла для запуска процесса от имени другого пользователя.
  • конечно, решение, которое вы упомянули, также работает.

если вы собираетесь написать свой собственный демон, то я рекомендую вызвать setuid(). Таким образом, ваш процесс может

  1. использовать суперпользователя (например, открытые файлы, создать PID-файлы).
  2. отбросьте свои привилегии root в определенный момент во время запуска.

просто добавить некоторые другие вещи, чтобы следить за:

  • Sudo в init.D скрипт не хорош, так как ему нужен tty ("sudo: извините, у вас должен быть tty для запуска sudo")
  • Если вы демонизируете приложение java, вы можете рассмотреть Java Service Wrapper (который предоставляет механизм для установки идентификатора пользователя)
  • Другой альтернативой может быть su --session-command=[cmd] [пользователь]

на виртуальной машине CENTOS (Red Hat) для сервера svn: отредактировано /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 только root мог там писать.

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

некоторые вещи, чтобы наблюдать за:

  • как вы упомянули, su запросит пароль, если вы уже являетесь целевым пользователем
  • аналогично, setuid (2) потерпит неудачу, если вы уже являетесь целевым пользователем (на некоторых OSs)
  • setuid (2) не устанавливает привилегии или элементы управления ресурсами, определенные в /etc/limits.conf (Linux) или /etc/user_attr (Solaris)
  • Если вы идете по маршруту setgid(2)/setuid(2), Не забудьте вызвать initgroups (3) -- Подробнее об этом здесь

Я обычно использую /sbin / su для переключения на соответствующего пользователя перед запуском демонов.


почему бы не попробовать следующее в скрипт:

setuid $USER application_name

это сработало для меня.


Мне нужно было запустить пружину .jar-приложение как сервис, и нашел простой способ запустить его как конкретного пользователя:

Я изменил владельца и группу моего файла jar на пользователя, которого я хотел запустить. Затем символические ссылки на них эту банку в init.D и начал службу.

Так:

#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