Модуль iptables не загружается после обновления Ubuntu 14.04 до 16.04

Модуль iptables не загружается после обновления Ubuntu 14.04 до 16.04

Поэтому я решил дать Ubuntu 16.04 шанс, несмотря на несколько неблагоприятное мнение о systemd.

После обновления мое ранее постоянное соединение OpenVPN больше не работает. К счастью, системный журнал довольно полезен для указания на основную причину.

openvpn-up: + /sbin/iptables -t nat -D POSTROUTING -o tun0 -s 192.168.x.x -j SNAT --to-source 10.x.x.x
openvpn-up: modprobe: ERROR: could not insert 'ip_tables': Operation not permitted
openvpn-up: iptables v1.6.0: can't initialize iptables table `nat': Table does not exist (do you need to insmod?)
openvpn-up: Perhaps iptables or your kernel needs to be upgraded.
openvpn-up: + /sbin/iptables -t nat -A POSTROUTING -o tun0 -s 192.168.x.x -j SNAT --to-source 10.x.x.x
openvpn-up: modprobe: ERROR: could not insert 'ip_tables': Operation not permitted
openvpn-up: iptables v1.6.0: can't initialize iptables table `nat': Table does not exist (do you need to insmod?)
ovpn-conn[613]: WARNING: Failed running command (--up/--down): external program exited with error status: 3
openvpn-up: Perhaps iptables or your kernel needs to be upgraded.
ovpn-conn[613]: Exiting due to fatal error

Примечание: они openvpn-upбыли получены путем раскомментирования второй строки скрипта /etc/openvpn/openvpn-up.sh(строка читается как: exec &> >(logger -s -t openvpn-up) && set -x).

Хм, значит, по какой-то причине ip_tablesмодуль не может быть загружен. Убедившись, что все модули ядра там с apt-get install --reinstall linux-image-$(uname -r), я попробовал использовать modprobe ip_tablesи, конечно же, увидел, что он теперь загружен с , lsmodно также и в системном журнале:

kernel: [  446.293882] ip_tables: (C) 2000-2006 Netfilter Core Team

И действительно, при запуске systemctl restart openvpnпосле этого момента соединение, похоже, восстанавливается, а iptables-saveвывод доказывает, что было добавлено соответствующее правило SNAT.

Мойпредполагатьтеперь модуль OpenVPN запускается с некоторым пользовательским контекстом, у которого недостаточно привилегий для использования modprobeи т. д.

Однако я не смог подтвердить это подозрение. И на самом деле вывод systemctl cat openvpnменя просто сбивает с толку:

# systemctl cat [email protected]
# /lib/systemd/system/[email protected]
[Unit]
Description=OpenVPN connection to %i
PartOf=openvpn.service
ReloadPropagatedFrom=openvpn.service
Before=systemd-user-sessions.service
Documentation=man:openvpn(8)
Documentation=https://community.openvpn.net/openvpn/wiki/Openvpn23ManPage
Documentation=https://community.openvpn.net/openvpn/wiki/HOWTO

[Service]
PrivateTmp=true
KillMode=mixed
Type=forking
ExecStart=/usr/sbin/openvpn --daemon ovpn-%i --status /run/openvpn/%i.status 10 --cd /etc/openvpn --script-security 2 --config /etc/openvpn/%i.conf --writepid /run/openvpn/%i.pid
PIDFile=/run/openvpn/%i.pid
ExecReload=/bin/kill -HUP $MAINPID
WorkingDirectory=/etc/openvpn
ProtectSystem=yes
CapabilityBoundingSet=CAP_IPC_LOCK CAP_NET_ADMIN CAP_NET_BIND_SERVICE CAP_NET_RAW CAP_SETGID CAP_SETUID CAP_SYS_CHROOT CAP_DAC_READ_SEARCH CAP_AUDIT_WRITE
LimitNPROC=10
DeviceAllow=/dev/null rw
DeviceAllow=/dev/net/tun rw

[Install]
WantedBy=multi-user.target

Есть лиспособностькоторый мне нужен, чтобы скрипты успешно вызывали insmod/ modprobe? Я бы хотел избежать добавления, CAP_SYS_ADMINтак как это выглядит довольно грубо. Или единственный способ загрузить ip_tablesмодуль — это поместить a .confв /etc/modprobe.d?

По сути, я спрашиваю следующее: как работает стандартная версия Ubuntu 16.04 (которая имеетнетобновлен с 14.04) выполнить эту задачу? То есть какой канонический (иКанонический) способ сделать это? И последнее, но не менее важное: как я могу определить, в каком пользовательском контексте работает конкретный блок (или, если быть точнее: с какими возможностями)?

решение1

Документацию по любой директиве systemd можно посмотреть через man system.directives. Оттуда я обнаружил, что CapabilityBoundingSet=документация находится в man systemd.exec.

Это привело меня к man 7 capabilitiesтому месту, где документируются различные возможности. Поискав там "модуль", я нашел это, что похоже на необходимую вам возможность:

CAP_SYS_MODULE Загрузка и выгрузка модулей ядра

Неясно, почему эта возможность не включена по умолчанию. Возможно, общие случаи использования OpenVPN не нуждаются в ней.

Минимальный способ добавить эту возможность в конфигурацию systemd пакета — это использовать «drop-in unit». Создайте этот файл:

/etc/systemd/system/[email protected]/add-module-loading.conf

С таким содержанием:

[Service]
CapabilityBoundingSet=CAP_IPC_LOCK CAP_NET_ADMIN CAP_NET_BIND_SERVICE CAP_NET_RAW CAP_SETGID CAP_SETUID CAP_SYS_CHROOT CAP_DAC_READ_SEARCH CAP_AUDIT_WRITE CAP_SYS_MODULE

Это расширит услугу с существующими возможностями плюс CAP_SYS_MODULE.

Я тоже колебался, systemdно нашел много того, что понравилось. timerСистема является долгожданным обновлением для 20-летней (более) летней системы cron.

Связанный контент