Módulo iptables não carregado após atualizar o Ubuntu 14.04 para 16.04

Módulo iptables não carregado após atualizar o Ubuntu 14.04 para 16.04

Então decidi dar uma chance ao Ubuntu 16.04, apesar de uma visão um pouco desfavorável sobre o systemd.

Após a atualização, minha conexão OpenVPN anteriormente persistente não funciona mais. Felizmente, o log do sistema é bastante útil para apontar a causa raiz.

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: estes openvpn-upforam produzidos removendo o comentário da segunda linha do /etc/openvpn/openvpn-up.shscript (a linha diz: exec &> >(logger -s -t openvpn-up) && set -x).

Hmm, por algum motivo o ip_tablesmódulo não pôde ser carregado. Depois de me certificar de que todos os módulos do kernel estavam lá apt-get install --reinstall linux-image-$(uname -r), tentei usá-lo modprobe ip_tablese com certeza o vi agora carregado, lsmodmas também no log do sistema:

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

E com certeza, ao executar systemctl restart openvpnapós esse ponto, parecia trazer à tona a conexão e iptables-savea saída prova que a regra SNAT apropriada foi adicionada.

Meuadivinharé agora que a unidade OpenVPN é executada com algum contexto de usuário que não possui privilégios suficientes para usar, modprobeetc.

No entanto, não consegui confirmar essa suspeita. E, de fato, a saída de systemctl cat openvpnme confunde muito:

# 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

Tem algumacapacidadeque preciso para ativar os scripts para invocar insmod/ modprobe? Eu gostaria de evitar adicionar, CAP_SYS_ADMINpois isso parece um tanto grosseiro. Ou a única maneira de carregar o ip_tablesmódulo é inserindo um .confem /etc/modprobe.d?

Essencialmente, o que estou perguntando é o seguinte: como funciona um Ubuntu 16.04 padrão (que temnãofoi atualizado a partir de 14.04) realizar esta tarefa? Ou seja, qual é o canônico (eManeira canônica) de fazer isso? E por último, mas não menos importante, como posso determinar em qual contexto de usuário uma unidade específica é executada (ou, para ser mais preciso: com quais recursos)?

Responder1

A documentação para qualquer diretiva systemd pode ser consultada em man system.directives. A partir daí, descobri que CapabilityBoundingSet=está documentado em man systemd.exec.

Isso me levou até man 7 capabilitiesonde os diferentes recursos estão documentados. Procurando por "módulo" lá, encontrei isto, que parece ser um recurso que você precisa:

CAP_SYS_MODULE Carregar e descarregar módulos do kernel

Não está claro quando esse recurso não está incluído por padrão. Talvez os casos de uso comuns do OpenVPN não precisem disso.

A maneira mínima de adicionar esse recurso à configuração do systemd de um pacote é com uma "unidade drop-in". Crie este arquivo:

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

Com este conteúdo:

[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

Isso ampliará o serviço com os recursos existentes mais CAP_SYS_MODULE.

Eu também estava hesitante, systemdmas descobri muito do que gostar. O timersistema é uma atualização bem-vinda para o sistema cron de mais de 20 anos.

informação relacionada