使用特权启动systemd服务

时间:2018-06-17 23:11:59

标签: systemd

我希望systemd管理tup监视器,所以我写了一个服务单元:

[Unit]
Description=Monitor source files for changes

[Service]
Type=simple
ExecStart=/usr/bin/tup monitor -f
ExecStop=/usr/bin/tup stop
WorkingDirectory=/some/dir
StandardOutput=journal+console
StandardError=journal+console

[Install]
WantedBy=multi-user.target

虽然手动启动监视器,但尝试使用systemd失败时会出现以下错误:

setpgid: Operation not permitted
tup error: Unable to set process group for tup's subprocesses.

错误源于this file,似乎是由于systemd没有为进程提供所需的功能,所以我更进一步:

[Unit]
Description=Monitor source files for changes

[Service]
Type=simple
ExecStart=/usr/bin/tup monitor -f
ExecStop=/usr/bin/tup stop
CapabilityBoundingSet=CAP_SETUID CAP_SETGID
AmbientCapabilities=CAP_SETUID CAP_SETGID
WorkingDirectory=/some/dir
StandardOutput=journal+console
StandardError=journal+console

[Install]
WantedBy=multi-user.target

尽管如此,它还不起作用。

如何告诉systemd保留tup所需的权限?

2 个答案:

答案 0 :(得分:1)

systemd默认情况下不限制对服务的任何权限,因此我认为这不是问题。 setpgid(2)联机帮助页中提到了EPERM的三个可能条件,

  

试图将进程移至另一个会话中的进程组,或更改调用进程的子进程之一的进程组ID,并且该子进程位于另一个会话中,或更改进程会话主持人的组ID(setpgid()setpgrp())。

我认为第三个是最可能导致错误的原因:tup可能期望从shell运行,在这种情况下,shell将是会话领导者,并且tup试图建立自己的进程组,但是systemd将每个服务放置在自己的会话中,这是为该服务设置干净执行环境的一部分(另请参见daemon(7)),因此该步骤将失败。

除非您可以通过某种方式禁用tup中的该步骤(也不必fork,或者执行systemd不必要的其他操作),否则我认为唯一的解决方法是成为丑陋的骇客:

ExecStart=/bin/sh -c '/usr/bin/tup monitor -f'

有了这个,会话领导者将成为外壳程序,而不是tup,因此setpgid应该可以再次工作。

答案 1 :(得分:0)

试试这个

[Unit]
Description=Monitor source files for changes
After=network.target

[Service]
Type=simple
ExecStart=/usr/bin/tup monitor -f
ExecStop=/usr/bin/tup stop
CapabilityBoundingSet=CAP_SETUID CAP_SETGID
AmbientCapabilities=CAP_SETUID CAP_SETGID
WorkingDirectory=/some/dir
StandardOutput=journal+console
StandardError=journal+console

[Install]
WantedBy=multi-user.target

我已添加After=network.target,这将确保在网络完全活动后启动TUP服务,并避免因网络问题导致服务失败