关闭 systemd 服务时,openvpn 无法在“down”脚本内使用 sudo

关闭 systemd 服务时,openvpn 无法在“down”脚本内使用 sudo

操作系统:Ubuntu 16.04.2 LTS

我的VPN配置有指令:

user ovpn
group ovpn
up "/path/to/my/script"
down "/path/to/my/script"

我的 visudo 文件有以下指令:

%ovpn ALL=(ALL:ALL) NOPASSWD: /sbin/iptables

这允许 openvpn 降级到root非特权用户ovpn(出于安全原因),但仍用于iptables启动和关闭从数据库加载的路由。如果我直接从 shell 调用 openvpn 进程,它就会起作用,即:

$ sudo openvpn /etc/openvpn/vpn0.conf

然后使用CTRL-将其杀死C。我说的“它起作用了”是指 iptables 规则可以根据需要添加和删除,没有任何错误。

但是,如果我使用 vanilla Ubuntu systemd openvpn 服务启动和停止 openvpn 进程。即

$ sudo systemctl start openvpn
$ sudo systemctl stop openvpn

然后“--down”脚本在执行“stop”命令时失败。当我检查 syslog 时,我发现 --down 脚本在调用 shell 命令时失败sudo /sbin/iptables,具体来说是在尝试分叉进程时。(关于错误消息,我的脚本是使用 的 python 脚本subprocess.call(['/usr/bin/sudo', '/sbin/iptables', ...])。错误消息是:

File "/usr/lib/python2.7/subprocess.py", line 523, in call
  return Popen(*popenargs, **kwargs).wait()
File "/usr/lib/python2.7/subprocess.py", line 711, in __init__
  errread, errwrite)
File "/usr/lib/python2.7/subprocess.py", line 1235, in _execute_child
  self.pid = os.fork()
OSError: [Errno 11] Resource temporarily unavailable

如果我从 openvpn 配置文件中删除usergroup指令,以便该过程root在整个执行过程中保持不变,那么我就不会收到错误,并且 iptables 调用会按预期工作,即使使用 systemd 服务来启动和停止也是如此。

因此,看起来 systemd 似乎阻止我sudo在关闭服务时提升权限。

关于如何克服这个困难同时又能降低非特权用户的权限,有什么想法吗?

答案1

显然,在这种情况下Resource temporarily unavailable告诉我os.fork失败是因为非特权用户已经达到了 openvpn 服务的 systemd 配置允许的最大进程数。

为了解决这个问题,我进行了编辑并做了以下更改:/lib/systemd/system/[email protected]

- LimitNPROC=10
+ LimitNPROC=100

随后,iptables即使使用非特权用户并使用 sudo 提升权限,我的链式拆除命令也能成功。

相关内容