Skip to main content

openvpn can't sudo within "down" script when shutting down systemd service [Resolved]

OS: Ubuntu 16.04.2 LTS

My VPN config has directives:

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

My visudo file has the directive:

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

This allows openvpn to deescalate from root to the unprivileged user ovpn (for security reasons), but still use iptables to bring up and down routes loaded from a database. It works if I invoke the openvpn process directly from a shell, i.e.:

$ sudo openvpn /etc/openvpn/vpn0.conf

and then kill it with CTRL-C. By "it works" I mean that the iptables rules are added and removed as desired without any errors.

However, if I start and stop the openvpn process using the vanilla Ubuntu systemd openvpn service. i.e.

$ sudo systemctl start openvpn
$ sudo systemctl stop openvpn

then the "--down" script fails during execution of the "stop" command. When I examine the syslog I see that the --down script has failed at the shell command invoking sudo /sbin/iptables, specifically where it is attempting to fork the process. (regarding error message, my script is a python script using['/usr/bin/sudo', '/sbin/iptables', ...]). Error message is:

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

If I remove the user and group directives from the openvpn configuration file so that the process remains root throughout execution, then I don't get the error, and the iptables invocations work as expected, even when using the systemd service to start and stop.

So it smells like systemd is preventing me from escalating privileges using sudo while shutting down the service.

Any ideas on how to overcome this difficulty while still deescalating to an unprivileged user?

Question Credit: Isaac Sutherland
Question Reference
Asked October 6, 2019
Posted Under: Network
1 Answers

Apparently, in this case Resource temporarily unavailable was telling me that os.fork was failing because the unprivileged user had hit the maximum number of processes allowed by the openvpn service's systemd config.

To fix this, I edited /lib/systemd/system/openvpn@.service and made the following change:

- LimitNPROC=10
+ LimitNPROC=100

And subsequently my iptables chain tear down commands are succeeding even when using an unprivileged user and elevating privileges using sudo.

credit: Isaac Sutherland
Answered October 6, 2019
Your Answer