Назад | Перейти на главную страницу

openvpn не может выполнить sudo в сценарии «выключения» при завершении работы службы systemd

ОС: 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 для отображения маршрутов, загруженных из базы данных. Он работает, если я вызываю процесс openvpn непосредственно из оболочки, то есть:

$ sudo openvpn /etc/openvpn/vpn0.conf

а затем убить его CTRL-C. Под «работает» я имею в виду, что правила iptables добавляются и удаляются по желанию без каких-либо ошибок.

Однако, если я запускаю и останавливаю процесс openvpn с помощью службы openvpn vanilla Ubuntu systemd. т.е.

$ sudo systemctl start openvpn
$ sudo systemctl stop openvpn

тогда сценарий «--down» завершается ошибкой во время выполнения команды «стоп». Когда я просматриваю системный журнал, я вижу, что сценарий --down завершился ошибкой при вызове команды оболочки 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

Если я удалю user и group директивы из файла конфигурации openvpn, чтобы процесс оставался root на протяжении всего выполнения я не получаю сообщение об ошибке, и вызовы iptables работают должным образом, даже при использовании службы systemd для запуска и остановки.

Так что похоже, что systemd не позволяет мне повышать привилегии с помощью sudo при закрытии службы.

Есть идеи о том, как преодолеть эту трудность, оставаясь при этом деэскалацией для непривилегированного пользователя?

Видимо, в этом случае Resource temporarily unavailable говорил мне, что os.fork сбой, потому что непривилегированный пользователь достиг максимального количества процессов, разрешенных конфигурацией systemd службы openvpn.

Чтобы исправить это, я отредактировал /lib/systemd/system/openvpn@.service и внес следующее изменение:

- LimitNPROC=10
+ LimitNPROC=100

И впоследствии мой iptables Команды разрыва цепочки выполняются успешно даже при использовании непривилегированного пользователя и повышении привилегий с помощью sudo.