如何为使用down-root插件的OpenVPN实例configuration新手

  • Ubuntu 14.04
  • OpenVPN 2.3.2
  • Init守护进程:新贵

服务器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 

我有一些疑问:

  1. 为什么OpenVPN仍然这样调用?

     /sbin/ip addr del dev tun1 local 192.168.0.1 peer 192.168.0.2 
  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' 

我尝试以相反的顺序回答问题:

2.为什么我得到这个?

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守护进程)一起发生的,它将向两个进程发送SIGTERMdown-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>startstoprestart

这应该删除上面的错误并正确运行down.sh脚本,但是仍然会显示以下错误:

 Linux ip addr del failed: external program exited with error status: 2 

这个错误首先发生,因为在TUN / TAP接口已经closures之后, ip addr del被执行。

更多关于这个下面。


1.为什么OpenVPN仍然会这样调用?

/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 

或者使用一个持久的TUN接口

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