操作系统: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 配置文件中删除user
和group
指令,以便该过程root
在整个执行过程中保持不变,那么我就不会收到错误,并且 iptables 调用会按预期工作,即使使用 systemd 服务来启动和停止也是如此。
因此,看起来 systemd 似乎阻止我sudo
在关闭服务时提升权限。
关于如何克服这个困难同时又能降低非特权用户的权限,有什么想法吗?
答案1
显然,在这种情况下Resource temporarily unavailable
告诉我os.fork
失败是因为非特权用户已经达到了 openvpn 服务的 systemd 配置允许的最大进程数。
为了解决这个问题,我进行了编辑并做了以下更改:/lib/systemd/system/[email protected]
- LimitNPROC=10
+ LimitNPROC=100
随后,iptables
即使使用非特权用户并使用 sudo 提升权限,我的链式拆除命令也能成功。