服务器configuration文件:
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 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
问题:每当重新启动服务时,我都在日志文件中看到了这一点:
May 17 14:32:08 t-xhyve vpn-devops[21013]: TCP/UDP: Closing socket May 17 14:32:08 t-xhyve vpn-devops[21013]: Closing TUN/TAP interface May 17 14:32:08 t-xhyve vpn-devops[21013]: /sbin/ip addr del dev tun1 local 192.168.0.1 peer 192.168.0.2 May 17 14:32:08 t-xhyve vpn-devops[21013]: Linux ip addr del failed: external program exited with error status: 2
原因是OpenVPN以nobody
权限删除通道接口的nobody
用户身份运行。 所以,我想用down-root插件来调用具有root权限的下来的脚本。
plugin /usr/lib/openvpn/openvpn-plugin-down-root.so /usr/share/openvpn/down.sh
/usr/share/openvpn/down.sh
#!/bin/sh /sbin/ip addr del dev $1 local $4 peer $5
然后尝试重新启动,但我得到这个:
May 17 14:49:47 t-xhyve vpn-devops[23001]: /sbin/ip addr del dev tun1 local 192.168.0.1 peer 192.168.0.2 May 17 14:49:47 t-xhyve vpn-devops[23228]: PKCS#11: __pkcs11h_forkFixup entry pid=23228, activate_slotevent=1 May 17 14:49:47 t-xhyve vpn-devops[23228]: PKCS#11: __pkcs11h_forkFixup return May 17 14:49:47 t-xhyve vpn-devops[23001]: Linux ip addr del failed: external program exited with error status: 2 May 17 14:49:47 t-xhyve vpn-devops[23001]: PLUGIN_CALL: PRE type=PLUGIN_DOWN May 17 14:49:47 t-xhyve vpn-devops[23001]: ARGV[0] = '/usr/lib/openvpn/openvpn-plugin-down-root.so' May 17 14:49:47 t-xhyve vpn-devops[23001]: ARGV[1] = 'tun1' May 17 14:49:47 t-xhyve vpn-devops[23001]: ARGV[2] = '1500' May 17 14:49:47 t-xhyve vpn-devops[23001]: ARGV[3] = '1542' May 17 14:49:47 t-xhyve vpn-devops[23001]: ARGV[4] = '192.168.0.1' May 17 14:49:47 t-xhyve vpn-devops[23001]: ARGV[5] = '192.168.0.2' May 17 14:49:47 t-xhyve vpn-devops[23001]: ARGV[6] = 'init' May 17 14:49:47 t-xhyve vpn-devops[23001]: ENVP[0] = 'dev=tun1' May 17 14:49:47 t-xhyve vpn-devops[23001]: ENVP[1] = 'link_mtu=1542' May 17 14:49:47 t-xhyve vpn-devops[23001]: ENVP[2] = 'tun_mtu=1500' May 17 14:49:47 t-xhyve vpn-devops[23001]: ENVP[3] = 'script_context=init' May 17 14:49:47 t-xhyve vpn-devops[23001]: ENVP[4] = 'signal=sigterm' May 17 14:49:47 t-xhyve vpn-devops[23001]: ENVP[5] = 'redirect_gateway=0' May 17 14:49:47 t-xhyve vpn-devops[23001]: ENVP[6] = 'dev_type=tun' May 17 14:49:47 t-xhyve vpn-devops[23001]: ENVP[7] = 'ifconfig_remote=192.168.0.2' May 17 14:49:47 t-xhyve vpn-devops[23001]: ENVP[8] = 'ifconfig_local=192.168.0.1' May 17 14:49:47 t-xhyve vpn-devops[23001]: ENVP[9] = 'config=/etc/openvpn/devops/config' May 17 14:49:47 t-xhyve vpn-devops[23001]: ENVP[10] = 'verb=15' May 17 14:49:47 t-xhyve vpn-devops[23001]: ENVP[11] = 'daemon=0' May 17 14:49:47 t-xhyve vpn-devops[23001]: ENVP[12] = 'daemon_log_redirect=0' May 17 14:49:47 t-xhyve vpn-devops[23001]: ENVP[13] = 'daemon_start_time=1463471367' May 17 14:49:47 t-xhyve vpn-devops[23001]: ENVP[14] = 'daemon_pid=23001' May 17 14:49:47 t-xhyve vpn-devops[23001]: ENVP[15] = 'proto_1=udp' May 17 14:49:47 t-xhyve vpn-devops[23001]: ENVP[16] = 'local_port_1=1196' May 17 14:49:47 t-xhyve vpn-devops[23001]: ENVP[17] = 'remote_port_1=1196' May 17 14:49:47 t-xhyve vpn-devops[23001]: PLUGIN_CALL: POST /usr/lib/openvpn/openvpn-plugin-down-root.so/PLUGIN_DOWN status=1 May 17 14:49:47 t-xhyve vpn-devops[23001]: PLUGIN_CALL: plugin function PLUGIN_DOWN failed with status 1: /usr/lib/openvpn/openvpn-plugin-down-root.so May 17 14:49:47 t-xhyve vpn-devops[23001]: ERROR: up/down plugin call failed May 17 14:49:47 t-xhyve vpn-devops[23001]: Exiting due to fatal error May 17 14:49:50 t-xhyve openvpn-devops-upstart: RTNETLINK answers: Operation not permitted May 17 14:49:50 t-xhyve openvpn-devops-upstart: DOWN-ROOT: Error sending script execution signal to background process
我有一些疑问:
为什么OpenVPN仍然这样调用?
/sbin/ip addr del dev tun1 local 192.168.0.1 peer 192.168.0.2
为什么我得到这个?
May 17 14:49:47 t-xhyve vpn-devops[23001]: ERROR: up/down plugin call failed May 17 14:49:47 t-xhyve vpn-devops[23001]: Exiting due to fatal error May 17 14:49:50 t-xhyve openvpn-devops-upstart: RTNETLINK answers: Operation not permitted May 17 14:49:50 t-xhyve openvpn-devops-upstart: DOWN-ROOT: Error sending script execution signal to background process
如何解决?
有没有任何应用程序装甲configuration文件?
没有。
尝试修改shell脚本来执行cat / proc / self / status> /tmp/temp.txt并在这里打印结果。
/usr/share/openvpn/down.sh
#!/bin/sh cat /proc/self/status >/tmp/temp.txt #/sbin/ip addr del dev $1 local $4 peer $5
重启时:
May 18 16:51:00 t-xhyve vpn-devops[17930]: TCP/UDP: Closing socket May 18 16:51:00 t-xhyve vpn-devops[17930]: Closing TUN/TAP interface May 18 16:51:00 t-xhyve vpn-devops[17930]: /sbin/ip addr del dev tun1 local 192.168.0.1 peer 192.168.0.2 May 18 16:51:00 t-xhyve vpn-devops[18520]: PKCS#11: __pkcs11h_forkFixup entry pid=18520, activate_slotevent=1 May 18 16:51:00 t-xhyve vpn-devops[18520]: PKCS#11: __pkcs11h_forkFixup return May 18 16:51:00 t-xhyve vpn-devops[17930]: Linux ip addr del failed: external program exited with error status: 2 May 18 16:51:00 t-xhyve vpn-devops[17930]: PLUGIN_CALL: PRE type=PLUGIN_DOWN May 18 16:51:00 t-xhyve vpn-devops[17930]: ARGV[0] = '/usr/lib/openvpn/openvpn-plugin-down-root.so' May 18 16:51:00 t-xhyve vpn-devops[17930]: ARGV[1] = 'tun1' May 18 16:51:00 t-xhyve vpn-devops[17930]: ARGV[2] = '1500' May 18 16:51:00 t-xhyve vpn-devops[17930]: ARGV[3] = '1542' May 18 16:51:00 t-xhyve vpn-devops[17930]: ARGV[4] = '192.168.0.1' May 18 16:51:00 t-xhyve vpn-devops[17930]: ARGV[5] = '192.168.0.2' May 18 16:51:00 t-xhyve vpn-devops[17930]: ARGV[6] = 'init' May 18 16:51:00 t-xhyve vpn-devops[17930]: ENVP[0] = 'dev=tun1' May 18 16:51:00 t-xhyve vpn-devops[17930]: ENVP[1] = 'link_mtu=1542' May 18 16:51:00 t-xhyve vpn-devops[17930]: ENVP[2] = 'tun_mtu=1500' May 18 16:51:00 t-xhyve vpn-devops[17930]: ENVP[3] = 'script_context=init' May 18 16:51:00 t-xhyve vpn-devops[17930]: ENVP[4] = 'signal=sigterm' May 18 16:51:00 t-xhyve vpn-devops[17930]: ENVP[5] = 'redirect_gateway=0' May 18 16:51:00 t-xhyve vpn-devops[17930]: ENVP[6] = 'dev_type=tun' May 18 16:51:00 t-xhyve vpn-devops[17930]: ENVP[7] = 'ifconfig_remote=192.168.0.2' May 18 16:51:00 t-xhyve vpn-devops[17930]: ENVP[8] = 'ifconfig_local=192.168.0.1' May 18 16:51:00 t-xhyve vpn-devops[17930]: ENVP[9] = 'config=/etc/openvpn/devops/config' May 18 16:51:00 t-xhyve vpn-devops[17930]: ENVP[10] = 'verb=15' May 18 16:51:00 t-xhyve vpn-devops[17930]: ENVP[11] = 'daemon=0' May 18 16:51:00 t-xhyve vpn-devops[17930]: ENVP[12] = 'daemon_log_redirect=0' May 18 16:51:00 t-xhyve vpn-devops[17930]: ENVP[13] = 'daemon_start_time=1463564660' May 18 16:51:00 t-xhyve vpn-devops[17930]: ENVP[14] = 'daemon_pid=17930' May 18 16:51:00 t-xhyve vpn-devops[17930]: ENVP[15] = 'proto_1=udp' May 18 16:51:00 t-xhyve vpn-devops[17930]: ENVP[16] = 'local_port_1=1196' May 18 16:51:00 t-xhyve vpn-devops[17930]: ENVP[17] = 'remote_port_1=1196' May 18 16:51:00 t-xhyve vpn-devops[17930]: PLUGIN_CALL: POST /usr/lib/openvpn/openvpn-plugin-down-root.so/PLUGIN_DOWN status=1 May 18 16:51:00 t-xhyve vpn-devops[17930]: PLUGIN_CALL: plugin function PLUGIN_DOWN failed with status 1: /usr/lib/openvpn/openvpn-plugin-down-root.so May 18 16:51:00 t-xhyve vpn-devops[17930]: ERROR: up/down plugin call failed May 18 16:51:00 t-xhyve vpn-devops[17930]: Exiting due to fatal error May 18 16:51:00 t-xhyve [2016-05-18 16:51:00,738][WARN ]May 18 16:51:01 t-xhyve openvpn-devops-upstart: RTNETLINK answers: Operation not permitted May 18 16:51:01 t-xhyve openvpn-devops-upstart: DOWN-ROOT: Error sending script execution signal to background process
该进程重新启动,但未创build日志文件( /tmp/temp.txt
)。
当然,手动运行该脚本工作正常:
bash -x /usr/share/openvpn/down.sh + cat /proc/self/status + cat /tmp/temp.txt Name: cat State: R (running) Tgid: 19246 Ngid: 0 Pid: 19246 PPid: 19245 ...
指定完整path没有帮助:
May 19 03:52:11 t-xhyve openvpn-devops-upstart: RTNETLINK answers: Operation not permitted May 19 03:52:11 t-xhyve openvpn-devops-upstart: DOWN-ROOT: Error sending script execution signal to background process May 19 03:52:11 t-xhyve openvpn-devops-upstart: DOWN-ROOT: BACKGROUND: INIT command='/bin/cat /proc/self/status > /tmp/temp.txt'
你如何开始/停止服务?
@rda:这是新贵档案:
start on (net-device-up and local-filesystems and runlevel [2345] and started rsyslog) stop on runlevel [!2345] respawn respawn limit 6 60 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 post-stop exec sleep 5
没有使用
start-stop-daemon
的另一个脚本,它将SIGTERM
发送到pre-stop
脚本节中的主进程,如下所示:
我按照你的build议添加了一个pre-stop
脚本:
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 '$NAME'" fi end script post-stop exec sleep 5
然后我尝试重新启动使用restart openvpn-devops
,仍然得到这个:
May 25 02:41:54 t-xhyve openvpn-devops-upstart: RTNETLINK answers: Operation not permitted May 25 02:41:54 t-xhyve openvpn-devops-upstart: DOWN-ROOT: Error sending script execution signal to background process May 25 02:41:54 t-xhyve openvpn-devops-upstart: DOWN-ROOT: BACKGROUND: INIT command='/bin/cat /proc/self/status > /tmp/temp.txt'
我尝试以相反的顺序回答问题:
DOWN-ROOT: Error sending script execution signal to background process
当使用down-root
插件时,主进程将在fork()
之前放弃root权限。 然后,模块将保持等待状态,直到通过pipe道从主进程接收到消息来执行down脚本(请参阅自述文件 )。 主进程在接收到SIGTERM
的时候会把这个消息发送给down-root
模块的进程。
正如在OpenVPN的systemd
服务configuration文件中所提到的bug ,这个错误很可能是与upstart
(ubuntu 14.04使用的默认init守护进程)一起发生的,它将向两个进程发送SIGTERM
。 down-root
模块的进程将在它有机会完成其工作之前终止,调用down脚本。
使用Ubuntu附带的/etc/init.d/openvpn
来启动和停止服务,或者在upstart
脚本中修复它。 一个非常简单的新贵脚本可以看起来如下。 请注意,它使用start-stop-daemon
来发送正确的信号。
创build一个文件/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
没有使用start-stop-daemon
的另一个脚本,它将SIGTERM
发送到主pre-stop
脚本节中的主进程,如下所示:
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
控制upstart
工作:
initctl <command> openvpn
<command>
: start
, stop
, restart
这应该删除上面的错误并正确运行down.sh
脚本,但是仍然会显示以下错误:
Linux ip addr del failed: external program exited with error status: 2
这个错误首先发生,因为在TUN / TAP接口已经closures之后, ip addr del
被执行。
更多关于这个下面。
/sbin/ip addr del dev tun1 local 192.168.0.1 peer 192.168.0.2
这是由ifconfig
命令引起的,它会在启动/停止服务时添加/删除TUN / TAP接口的IP地址。 (请参阅联机帮助页 )
为了规避这种行为,请按如下所示修改configuration。
OpenVPN服务器configuration文件:
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
:不执行ifconfig命令,传递--ifconfig
参数给脚本。 up
:由于ifconfig-noexec
原因,需要运行up-script来设置IP地址 down-pre
:在TUN / TAPclosures之前而不是之后调用脚本。 script-security 2
:允许调用内置的可执行文件和用户定义的脚本。 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
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
UP / DOWN脚本也将使界面上下(尽pipe不是必需的)。
确保它们是可执行的:
chmod +x /usr/share/openvpn/up.sh chmod +x /usr/share/openvpn/down.sh
OpenVPN服务器configuration文件(编辑/添加这些行):
dev tun1 # down-pre
dev tun1
:我们将使用一个持久的TUN接口 # down-pre
:不需要使用持久性接口 最后创build一个持久的TUN接口 :
openvpn --mktun --dev tun1
这会build立一个永久隧道tun1
,它通过OpenVPN的多个实例存在,并且只有在openvpn --rmtun --dev tun1
删除时openvpn --rmtun --dev tun1
或者机器重新启动。
如果configuration如上所示是正确的,那么以下是一些其他的故障排除步骤,但仍然显示以下错误:
DOWN-ROOT: Error sending script execution signal to background process
开始OpenVPN的实例,即与upstart
:
initctl start openvpn
检查过程有什么PID
:
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
在对日志进行拖尾处理时,用SIGTERM
使用PID
手动杀死主openvpn进程(以nobody
用户身份运行)
kill -15 3590
或者在一行中:
kill -15 `ps -ef | grep "^[n]obody .* /usr/sbin/openvpn --config /etc/openvpn/devops/config$" | awk '{print $2}'`
浓缩的日志输出应该如下所示(没有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