El módulo iptables no se carga después de actualizar Ubuntu 14.04 a 16.04

El módulo iptables no se carga después de actualizar Ubuntu 14.04 a 16.04

Así que decidí darle una oportunidad a Ubuntu 16.04 a pesar de tener una opinión ligeramente desfavorable sobre systemd.

Después de la actualización, mi conexión OpenVPN previamente persistente ya no funciona. Afortunadamente, el registro del sistema es bastante útil para señalar la causa raíz.

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

Nota: estos openvpn-upse produjeron descomentando la segunda línea del /etc/openvpn/openvpn-up.shguión (la línea dice exec &> >(logger -s -t openvpn-up) && set -x:).

Hmm, entonces por alguna razón el ip_tablesmódulo no se pudo cargar. Después de asegurarme de tener todos los módulos del kernel allí apt-get install --reinstall linux-image-$(uname -r), intenté usarlos modprobe ip_tablesy efectivamente lo vi ahora cargado lsmodpero también en el registro del sistema:

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

Y efectivamente, cuando se ejecutó systemctl restart openvpndespués de este punto, pareció aparecer la conexión y iptables-saveel resultado demuestra que se agregó la regla SNAT apropiada.

Miadivinares ahora que la unidad OpenVPN se ejecuta con algún contexto de usuario que no tiene suficientes privilegios para usar, modprobeetc.

Sin embargo, no he podido confirmar esta sospecha. Y, de hecho, el resultado de systemctl cat openvpnme confunde muchísimo:

# 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

Hay unacapacidad¿Cuál necesito para permitir que los scripts tengan éxito al invocar insmod/ modprobe? Me gustaría evitar agregarlo, CAP_SYS_ADMINya que parece bastante crudo. ¿O la única forma de cargar el ip_tablesmódulo es colocar a .confen /etc/modprobe.d?

Esencialmente lo que estoy preguntando es esto: ¿cómo funciona un Ubuntu 16.04 estándar (que tienenoactualizado desde 14.04) ¿realiza esta tarea? Es decir, ¿cuál es el canónico (y¿Canónica) forma de hacerlo? Y por último, pero no menos importante, ¿cómo puedo determinar en qué contexto de usuario se ejecuta una unidad en particular (o para ser más precisos: con qué capacidades)?

Respuesta1

La documentación de cualquier directiva systemd se puede consultar a través de man system.directives. A partir de ahí, encontré que CapabilityBoundingSet=está documentado en man systemd.exec.

Eso me llevó a man 7 capabilitiesdonde están documentadas las diferentes capacidades. Al buscar "módulo" allí, encontré esto, que parece una capacidad que necesitas:

CAP_SYS_MODULE Cargar y descargar módulos del kernel

No está claro por qué esta capacidad no está incluida de forma predeterminada. Quizás los casos de uso comunes de OpenVPN no lo necesiten.

La forma mínima de agregar esta capacidad a la configuración systemd de un paquete es con una "unidad directa". Crea este archivo:

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

Con este contenido:

[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

Eso ampliará el servicio con las capacidades existentes plus CAP_SYS_MODULE.

También tenía dudas, systemdpero encontré muchas cosas que me gustaron. El timersistema es una actualización bienvenida del sistema cron de más de 20 años.

información relacionada