繁体   English   中英

以不同用户身份运行Linux服务的最佳实践

[英]Best practice to run Linux service as a different user

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

您认为最好的方法是让流程作为我选择的(静态)用户运行?

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

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

但这似乎有点凌乱......

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

编辑:我应该说我在这个实例中开始的过程是Python脚本或Java程序。 我宁愿不在它们周围写一个原生包装器,所以不幸的是我无法像Black建议的那样调用setuid()

在Debian上,我们使用start-stop-daemon实用程序,它处理pid文件,更改用户,将守护进程放入后台等等。

我不熟悉RedHat,但你已经使用的daemon实用程序(在/etc/init.d/functions 。中定义)随处可见,相当于start-stop-daemon ,所以要么也可以更改你的程序的uid,或者你的方式已经是正确的。

如果您环顾网络,可以使用几种现成的包装纸。 有些甚至可能已经包装在RedHat中。 例如,看看daemonize

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

  1. hop是正确的回到/etc/init.d/functionsdaemon功能已经允许你设置一个替代用户:

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

    这是通过使用runuser包装进程调用来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) 

为了解决surunuser行为,我将我的init脚本更改为:

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

感谢你的帮助!

  • 一些守护进程(例如apache)通过调用setuid()自己完成
  • 您可以使用setuid-file标志以另一个用户身份运行该进程。
  • 当然,您提到的解决方案也适用。

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

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

在用于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 守护进程没有开始,因为只有root才能在那里写。

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

只是添加一些其他注意事项:

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

有些事需要注意:

  • 如前所述,如果您已经是目标用户,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中对这个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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM