我正在使用python-daemon包在python中编写一个守护进程 。 守护进程在启动时(init.d)启动,需要访问各种设备。 守护进程是运行在embedded式系统( beaglebone )运行Ubuntu的。
现在我的问题是,我想运行守护进程作为非特权用户,而不是root
(例如mydaemon
)。
为了允许守护进程访问设备,我将该用户添加到所需的组。 在python代码中,我使用daemon.DaemonContext(uid=uidofmydamon)
。
由root
启动的进程很好地守护进程,并由正确的用户拥有,但是当尝试访问设备时,我得到了权限被拒绝的错误。 我写了一个小testing应用程序,似乎该过程不会inheritance用户的组成员资格。
#!/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]
我怎样才能创build一个守护进程,由root启动,但有不同的有效uid 和完整的组成员身份?
我当前的解决方案涉及在启动实际守护进程之前删除根chuid
,使用start-stop-daemon
的chuid
参数:
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写这个逻辑。
现在这个工作,但我认为这应该是一个更优雅的方式可以解决。