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-up
se produjeron descomentando la segunda línea del /etc/openvpn/openvpn-up.sh
guión (la línea dice exec &> >(logger -s -t openvpn-up) && set -x
:).
Hmm, entonces por alguna razón el ip_tables
mó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_tables
y efectivamente lo vi ahora cargado lsmod
pero 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 openvpn
después de este punto, pareció aparecer la conexión y iptables-save
el 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, modprobe
etc.
Sin embargo, no he podido confirmar esta sospecha. Y, de hecho, el resultado de systemctl cat openvpn
me 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_ADMIN
ya que parece bastante crudo. ¿O la única forma de cargar el ip_tables
módulo es colocar a .conf
en /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 capabilities
donde 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, systemd
pero encontré muchas cosas que me gustaron. El timer
sistema es una actualización bienvenida del sistema cron de más de 20 años.