以不同用户身份运行 Linux 服务的最佳实践
在我的 RHEL 机器上,服务默认在启动时以 root
身份启动。 如果我没记错的话,其他使用 /etc/init.d
中的 init 脚本的 Linux 发行版也是如此。
您认为让进程以我选择的(静态)用户身份运行的最佳方法是什么?
我找到的唯一方法是使用类似的方法:
su my_user -c 'daemon my_cmd &>/dev/null &'
但这似乎有点不整洁...
是否有一些隐藏的魔法可以提供一种简单的机制来像其他非 root 用户一样自动启动服务?
编辑:我应该说我在这个实例中启动的进程要么是Python脚本,要么是Java程序。 我不想围绕它们编写本机包装器,所以不幸的是我无法调用 setuid() 正如 Black 建议的那样。
Services default to starting as root
at boot time on my RHEL box. If I recall correctly, the same is true for other Linux distros which use the init scripts in /etc/init.d
.
What do you think is the best way to instead have the processes run as a (static) user of my choosing?
The only method I'd arrived at was to use something like:
su my_user -c 'daemon my_cmd &>/dev/null &'
But this seems a bit untidy...
Is there some bit of magic tucked away that provides an easy mechanism to automatically start services as other, non-root users?
EDIT: I should have said that the processes I'm starting in this instance are either Python scripts or Java programs. I'd rather not write a native wrapper around them, so unfortunately I'm unable to call setuid() as Black suggests.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
在 Debian 上,我们使用
start-stop-daemon
实用程序,它可以处理 pid 文件、更改用户、将守护进程置于后台等等。我不熟悉 RedHat,但提到了您已经在使用的
daemon
实用程序(在/etc/init.d/functions
中定义,顺便说一句。)无处不在,相当于start-stop-daemon
,因此它也可以更改程序的 uid,或者您执行此操作的方式已经是正确的方式。如果您环顾网络,您会发现有几种现成的包装纸可供您使用。 有些甚至可能已经打包在 RedHat 中。 例如,看看
daemonize
。On Debian we use the
start-stop-daemon
utility, which handles pid-files, changing the user, putting the daemon into background and much more.I'm not familiar with RedHat, but the
daemon
utility that you are already using (which is defined in/etc/init.d/functions
, btw.) is mentioned everywhere as the equivalent tostart-stop-daemon
, so either it can also change the uid of your program, or the way you do it is already the correct one.If you look around the net, there are several ready-made wrappers that you can use. Some may even be already packaged in RedHat. Have a look at
daemonize
, for example.在查看了这里的所有建议之后,我发现了一些我希望对其处于我的位置的其他人有用的东西:
hop 正确地指出了我的方向
在
/etc/init.d/functions
处:daemon
功能已经允许您设置备用用户:
这是通过包装来实现的
使用
runuser
进行流程调用 -稍后再详细介绍。
乔纳森·莱夫勒是正确的:
Python中有setuid:
我仍然认为你不能setuid
然而,来自 JVM 内部。
既不是
su
也不是runuser
优雅地处理你的情况
要求以您的用户身份运行命令
已经是了。 例如:
<前><代码>[my_user@my_host]$ id
uid=500(my_user) gid=500(my_user) 组=500(my_user)
[my_user@my_host]$ su my_user -c "id"
密码:# 不想被提示!
uid=500(my_user) gid=500(my_user) 组=500(my_user)
为了解决
su
和runuser
的行为,我已将初始化脚本更改为:感谢大家的帮助!
After looking at all the suggestions here, I've discovered a few things which I hope will be useful to others in my position:
hop is right to point me back
at
/etc/init.d/functions
: thedaemon
function already allows youto set an alternate user:
This is implemented by wrapping the
process invocation with
runuser
-more on this later.
Jonathan Leffler is right:
there is setuid in Python:
I still don't think you can setuid
from inside a JVM, however.
Neither
su
norrunuser
gracefully handle the case where you
ask to run a command as the user you
already are. E.g.:
To workaround that behaviour of
su
andrunuser
, I've changed my init script to something like:Thanks all for your help!
如果您打算编写自己的守护进程,那么我建议调用 setuid()。
这样,您的进程就可以
If you intend to write your own daemon, then I recommend calling setuid().
This way, your process can
只是添加一些其他需要注意的事情:
Just to add some other things to watch out for:
在 svn 服务器的 CENTOS (Red Hat) 虚拟机上:
编辑
/etc/init.d/svnserver
将 pid 更改为 svn 可以写入的内容:
并添加选项
--user=svn
:原始 pid 文件是
/var/run/svnserve.pid
。 该守护进程没有启动,因为只有 root 可以在那里写入。on a CENTOS (Red Hat) virtual machine for svn server:
edited
/etc/init.d/svnserver
to change the pid to something that svn can write:
and added option
--user=svn
:The original pidfile was
/var/run/svnserve.pid
. The daemon did not start becaseu only root could write there.需要注意的一些事情:
我通常使用/sbin/su 在启动守护程序之前切换到适当的用户。
Some things to watch out for:
I generally use /sbin/su to switch to the appropriate user before starting daemons.
为什么不在初始化脚本中尝试以下操作:
它对我有用。
Why not try the following in the init script:
It worked for me.
我需要将 Spring .jar 应用程序作为服务运行,并找到了一种以特定用户身份运行它的简单方法:
我将 jar 文件的所有者和组更改为我想要运行的用户。
然后在 init.d 中符号链接这个 jar 并启动服务。
所以:
I needed to run a Spring .jar application as a service, and found a simple way to run this as a specific user:
I changed the owner and group of my jar file to the user I wanted to run as.
Then symlinked this jar in init.d and started the service.
So: