Eu tento responder as perguntas na ordem inversa:
2. Por que eu recebo isso?
DOWN-ROOT: Error sending script execution signal to background process
Quando o plug-in down-root
for usado, o processo principal será fork()
antes de descartar os privilégios de root. O módulo permanecerá em um estado de espera até receber uma mensagem do processo principal via pipe para executar o script descendente (consulte readme ). O processo principal enviará esta mensagem para o processo do módulo down-root
quando receber SIGTERM
.
Como mencionado neste bug do OpenVPN com o arquivo de configuração do serviço systemd
, Esse erro provavelmente é causado em conjunto com upstart
(o daemon init padrão usado pelo Ubuntu 14.04), que enviará SIGTERM
para ambos os processos. O processo do módulo down-root
terminará, antes que ele tenha a chance de fazer seu trabalho, chamando o script para baixo.
Use o /etc/init.d/openvpn
enviado com o Ubuntu para iniciar e parar o serviço ou corrigi-lo no script upstart
. Um script de inicialização muito simples poderia parecer o seguinte. Note que usa start-stop-daemon
para enviar os sinais corretos.
Crie um arquivo /etc/init/openvpn.conf
start on (net-device-up
and local-filesystems
and runlevel [2345]
and started rsyslog)
stop on runlevel [!2345]
respawn
respawn limit 6 60
env PIDFILE="/var/run/openvpn/devops.pid"
pre-start script
if [ ! -e /var/run/openvpn ]; then
mkdir -m 0770 /var/run/openvpn
chown nobody:nogroup /var/run/openvpn
fi
end script
exec start-stop-daemon --start --quiet --oknodo \
--pidfile /var/run/openvpn/devops.pid \
--exec /usr/sbin/openvpn -- --config /etc/openvpn/devops/config < /dev/null
pre-stop script
exec start-stop-daemon --stop --quiet --oknodo \
--pidfile $PIDFILE --exec /usr/sbin/openvpn --retry 5
if [ "$?" -eq 0 ]; then
rm -f $PIDFILE
else
echo "Unable to stop VPN"
fi
end script
post-stop exec sleep 5
Um script alternativo sem usar start-stop-daemon
, que envia SIGTERM
para o processo principal em uma sub-rotina de script pre-stop
, pode ter a seguinte aparência:
start on (net-device-up
and local-filesystems
and runlevel [2345]
and started rsyslog)
stop on runlevel [!2345]
respawn
respawn limit 6 60
env PIDFILE="/var/run/openvpn/devops.pid"
pre-start script
if [ ! -e /var/run/openvpn ]; then
mkdir -m 0770 /var/run/openvpn
chown nobody:nogroup /var/run/openvpn
fi
end script
exec /usr/sbin/openvpn --config /etc/openvpn/devops/config
pre-stop script
PID='cat $PIDFILE'
kill -15 $PID
sleep 1
if [ "$?" -eq 0 ]; then
rm -f $PIDFILE
else
echo "Unable to stop VPN"
fi
end script
post-stop exec sleep 5
Controlando o trabalho upstart
:
initctl <command> openvpn
-
<command>
:start
,stop
,restart
Isso deve remover o erro acima e executar o script down.sh
corretamente, mas o seguinte erro ainda será exibido:
Linux ip addr del failed: external program exited with error status: 2
Este erro ocorre em primeiro lugar, porque ip addr del
é executado depois que a interface TUN / TAP já foi fechada.
Mais sobre isso abaixo.
1. Por que o OpenVPN ainda chama isso?
/sbin/ip addr del dev tun1 local 192.168.0.1 peer 192.168.0.2
Isso é causado pela diretiva ifconfig
, que adicionará / del o endereço IP da interface TUN / TAP ao iniciar / parar o serviço. (Veja manpage )
Para contornar esse comportamento, modifique a configuração da seguinte forma.
arquivo de configuração do servidor OpenVPN :
topology net30
mode server
tls-server
push "route-gateway 192.168.0.1"
ifconfig 192.168.0.1 192.168.0.2
ifconfig-pool 192.168.0.5 192.168.0.9
ifconfig-noexec
up /usr/share/openvpn/up.sh
down-pre
plugin /usr/lib/openvpn/openvpn-plugin-down-root.so /usr/share/openvpn/down.sh
script-security 2
port 1196
proto udp
dev tun
keepalive 10 120
comp-lzo
user nobody
group nogroup
persist-key
persist-tun
status /var/log/openvpn/devops.log 1
syslog vpn-devops
verb 15
writepid /var/run/openvpn/devops.pid
ca /etc/openvpn/devops/ca.crt
cert /etc/openvpn/devops/server.crt
key /etc/openvpn/devops/server.key
dh /etc/openvpn/dh.pem
ifconfig-pool-persist /var/lib/openvpn/devops.ipp
client-config-dir /etc/openvpn/devops/ccd
crl-verify /etc/openvpn/devops/crl.pem
client-to-client
-
ifconfig-noexec
: não execute comandos ifconfig, passe--ifconfig
parameters para scripts. -
up
: é necessário executar um script para configurar um endereço IP devido aifconfig-noexec
-
down-pre
: chame o script--down
antes, em vez de depois, TUN / TAP fechar. -
script-security 2
: permite a chamada de executáveis internos e scripts definidos pelo usuário.
script UP /usr/share/openvpn/up.sh
:
#!/bin/sh
/sbin/ip addr add dev $1 local $4 peer $5
/sbin/ip link set dev $1 up
Script DOWN /usr/share/openvpn/down.sh
:
#!/bin/sh
/sbin/ip addr del dev $1 local $4 peer $5
/sbin/ip link set dev $1 down
Os scripts UP / DOWN também trazem a interface para cima e para baixo (embora não seja obrigatório).
Verifique se eles são executáveis:
chmod +x /usr/share/openvpn/up.sh
chmod +x /usr/share/openvpn/down.sh
Como alternativa, use uma interface TUN persistente
arquivo de configuração do servidor OpenVPN (edite / adicione as linhas):
dev tun1
# down-pre
-
dev tun1
: usaremos uma interface TUN persistente -
# down-pre
: não é necessário usar a interface persistente
Por fim, crie uma interface TUN persistente :
openvpn --mktun --dev tun1
Isto constrói um túnel persistente tun1
que vive através de múltiplas instanciações do OpenVPN e morre somente quando é deletado com openvpn --rmtun --dev tun1
ou a máquina é reinicializada.
Resolução de problemas
Aqui estão alguns passos adicionais de resolução de problemas, se a configuração estiver correta, conforme mostrado acima, e o seguinte erro ainda será exibido:
DOWN-ROOT: Error sending script execution signal to background process
Inicie a instância do OpenVPN, por exemplo, com upstart
:
initctl start openvpn
Verifique o que PID
dos processos têm:
ps -ef | grep "[o]penvpn"
# or more specific for our devops server example
ps -ef | grep "[o]penvpn/devops"
# this should show 2 openvpn processes
UID PID PPID C STIME TTY TIME CMD
nobody 3590 1 0 21:49 ? 00:00:00 /usr/sbin/openvpn --config /etc/openvpn/devops/config
root 3593 3590 0 21:49 ? 00:00:00 /usr/sbin/openvpn --config /etc/openvpn/devops/config
Enquanto segue os logs, mata o processo principal openvpn (executando como usuário nobody
) manualmente com SIGTERM
usando seu PID
kill -15 3590
Ou alternativamente em uma única linha:
kill -15 'ps -ef | grep "^[n]obody .* /usr/sbin/openvpn --config /etc/openvpn/devops/config$" | awk '{print $2}''
A saída do log condensado deve ficar assim (sem o DOWN-ROOT: Error ...
):
vpn-devops[3590]: TCP/UDP: Closing socket
vpn-devops[3590]: PLUGIN_CALL: PRE type=PLUGIN_DOWN
upstart-devops : DOWN-ROOT: BACKGROUND: received command code: 0
vpn-devops[3590]: PLUGIN_CALL: POST /usr/lib/openvpn/openvpn-plugin-down-root.so/PLUGIN_DOWN status=0
vpn-devops[3590]: Closing TUN/TAP interface
vpn-devops[3590]: PLUGIN_CLOSE: /usr/lib/openvpn/openvpn-plugin-down-root.so
vpn-devops[3590]: PID packet_id_free
vpn-devops[3590]: SIGTERM[hard,] received, process exiting
upstart-devops : DOWN-ROOT: close
upstart-devops : DOWN-ROOT: BACKGROUND: received command code: 1
upstart-devops : DOWN-ROOT: BACKGROUND: EXIT
kernel: init : ovpn-devops main process ended, respawning