服务默认启动为 root 在我的 RHEL 机器上启动时。如果我没记错的话,其他使用 init 脚本的 Linux 发行版也是如此。 /etc/init.d.

您认为让进程以我选择的(静态)用户身份运行的最佳方法是什么?

我到达的唯一方法是使用类似的东西:

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

但这似乎有点不整洁......

是否有一些隐藏的魔法可以提供一种简单的机制来像其他非 root 用户一样自动启动服务?

编辑: 我应该说,我在这个实例中启动的进程要么是 Python 脚本,要么是 Java 程序。我不想围绕它们编写本机包装器,所以不幸的是我无法调用 setuid() 作为 黑色的 建议。

有帮助吗?

解决方案

在Debian我们使用start-stop-daemon工具,它处理的PID文件,改变了用户,把守护到背景等等。

我不熟悉红帽,而是你已经在使用(在daemon定义,顺便说一句。)的/etc/init.d/functions效用处处提及相当于start-stop-daemon,所以无论它也可以改变你的程序的UID ,或者你做的方式已经是正确的。

如果你看看周围净,有可以使用几种现成的包装。有的甚至可能已经打包在红帽。看看 daemonize 时,例如

其他提示

在查看了这里的所有建议之后,我发现了一些我希望对其处于我的位置的其他人有用的东西:

  1. 正确地指向我 /etc/init.d/functions:这daemon 功能已经允许您设置替代用户:

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

    这是通过将过程调用与 runuser - 稍后再详细介绍。

  2. 乔纳森·莱夫勒 是对的:Python中有setuid:

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

    但是,我仍然认为您无法从JVM内部进行固定。

  3. 两者都不 su 也不 runuser优雅地处理您要求作为已经使用的用户运行命令的情况。例如。:

    [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)
    

要解决该行为 surunuser, ,我已将初始化脚本更改为:

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

感谢你的帮助!

  • 一些守护进程(例如apache)通过调用自己完成此操作 setuid()
  • 你可以使用 setuid 文件标志 以不同用户身份运行该进程。
  • 当然,你提到的解决方案也是有效的。

如果您打算编写自己的守护进程,那么我建议调用 setuid()。这样,您的流程就可以

  1. 利用其 root 权限(例如打开日志文件,创建 pid 文件)。
  2. 在启动过程中的某个时刻删除其 root 权限。

只是添加一些其他需要注意的事情:

  • init.d 脚本中的 Sudo 不好,因为它需要 tty (“sudo:抱歉,您必须有 tty 才能运行 sudo”)
  • 如果您正在守护 Java 应用程序,您可能需要考虑 Java Service Wrapper(它提供了设置用户 ID 的机制)
  • 另一种选择可能是 su --session-command=[cmd] [用户]

上的CENTOS(红帽)虚拟机为SVN服务器: 编辑/etc/init.d/svnserver 更改svn的可以写入的PID的东西:

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) 将失败
  • setuid(2) 不会安装 /etc/limits.conf (Linux) 或 /etc/user_attr (Solaris) 中定义的权限或资源控制
  • 如果您采用 setgid(2)/setuid(2) 路线,请不要忘记调用 initgroups(3) ——有关此的更多信息 这里

我通常在启动守护程序之前使用 /sbin/su 切换到适当的用户。

为什么不尝试在init脚本如下:

setuid $USER application_name

这为我工作。

我需要运行一个Spring的.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
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top