我正在使用python-守护进程包在python中编写一个守护进程。守护进程是在启动时启动的(init.d),需要访问各种设备。守护进程将在运行ubuntu的嵌入式系统(beaglebone)上运行。
现在,我的问题是,我希望以非特权用户的身份运行守护进程,而不是root (例如root)。
为了允许守护进程访问设备,我将该用户添加到所需的组中。在python代码中,我使用daemon.DaemonContext(uid=uidofmydamon)。
root启动的进程很好地实现了守护,并且由正确的用户拥有,但是当我试图访问设备时,我得到了拒绝权限的错误。我编写了一个小的测试应用程序,而且进程似乎没有继承用户的组成员身份。
#!/usr/bin/python
import logging, daemon, os
if __name__ == '__main__':
lh=logging.StreamHandler()
logger = logging.getLogger()
logger.setLevel(logging.INFO)
logger.addHandler(lh)
uid=1001 ## UID of the daemon user
with daemon.DaemonContext(uid=uid,
files_preserve=[lh.stream],
stderr=lh.stream):
logger.warn("UID : %s" % str(os.getuid()))
logger.warn("groups: %s" % str(os.getgroups()))当我以uid=1001用户的身份运行上面的代码时,我得到了以下内容
$ ./testdaemon.py
UID: 1001
groups: [29,107,1001]然而,当我以根用户(或su)的身份运行上述代码时,我得到:
$ sudo ./testdaemon.py
UID: 1001
groups: [0]如何创建由root启动但具有不同的有效uid和完整的组成员身份的守护进程?
发布于 2013-07-02 15:09:09
我的当前解决方案包括在启动实际守护进程之前删除根私有程序,使用用于chuid的start-stop-daemon参数。
start-stop-daemon \
--start \
--chuid daemonuser \
--name testdaemon \
--pidfile /var/run/testdaemon/test.pid \
--startas /tmp/testdaemon.py \
-- \
--pidfile /var/run/testdaemon/test.pid \
--logfile=/var/log/testdaemon/testdaemon.log此解决方案的缺点是,在启动实际守护进程(具有适当的文件权限)之前,我需要创建守护进程应该写入的所有目录(注意到/var/run/testdaemon和/var/log/testdaemon)。
我更愿意用python而不是bash来编写逻辑。
目前,这是可行的,但我认为,这应该是一个更优雅的解决方式。
发布于 2018-07-06 16:57:56
这可以通过猴子修补守护进程模块来修复,代码如下:
import os, grp, pwd
class DaemonError(Exception):
pass
class DaemonOSEnvironmentError(DaemonError, OSError):
pass
def change_process_owner(uid, gid):
try:
# This line adds all the groups the user is member of
# to keep the expected permissions
os.setgroups(
[g.gr_gid for g in grp.getgrall()
if pwd.getpwuid(uid).pw_name in g.gr_mem
]
)
os.setgid(gid)
os.setuid(uid)
except Exception, exc:
error = DaemonOSEnvironmentError(u"Unable to change process
owner (%(exc)s)" % vars())
raise error然后猴子贴片:
import daemon
daemon.daemon.change_process_owner = change_process_ownerhttps://stackoverflow.com/questions/17404140
复制相似问题