分享一个VPN自动检测和断线重连

由于很多你懂得的原因,我们不得不通过一些技术手段来访问技术网站。由于线路不稳定或者很多其他的因素,会引起PPTP的假死和中断。所以我在服务器上写了一个PPTP Client的自动检测拉起脚本,来确保线路畅通。

不多说了,上代码。

#!/bin/bash

SCRIPT_PIDS=$(pidof -x $0)
if [ `echo $SCRIPT_PIDS | awk -F' ' '{print NF; exit}'` -gt 1 ]; then
    echo "VPN Guard is already running..."
    exit
fi

function select_fast_server() {
    LIST=""
    for ip in `cat /etc/ppp/peers/vpn-server`
    do
        LIST=$LIST"$ip `ping -c 3 -t 3 $ip | grep 'time=' | awk '{print $7}' | cut -f 2 -d '=' | awk '{sum += $1};END { if (NR > 0) print sum / NR }'`\n"
    done

    FAST_HOST=$(echo -e $LIST | awk 'NR == 1 {ip = $1; min = 99999} $2 > 0 && $2 < min {ip = $1; min = $2} END {print ip}')

    sed -i "s|pptp.*--nolaunchpppd|pptp ${FAST_HOST} --nolaunchpppd|g" /etc/ppp/peers/vpn

    echo "Fast vpn server is ${FAST_HOST}"
}

while [ true ]; do
    if [ `ps -ef | grep "pptp" | grep -v grep | wc -l` -lt 1 ]; then
        select_fast_server
        sleep 1
        /usr/sbin/pppd call vpn
        sleep 15
    else
        if [ `httping -G -c 3 -i 3 -t 2 http://www.google.com 2>&1 | grep "connected to" | wc -l` -lt 1 ]; then
            kill -9 `ps -ef | grep -E '(pptp|pppd)' | grep -v grep | awk '{print $2}'`
        fi
    fi
    sleep 3
done

将所有可用服务器的IP列表放置在/etc/ppp/peers/vpn-server这个文件中,一行一个,脚本会自动选择延迟最低的服务器进行连接,2016-04-26新增。

可以使用nohup来让它保持在后台运行:

nohup /usr/local/sbin/vpn-guard.sh > /dev/null &

脚本很简单,首先检查自己是否在运行,保证全局只有一个脚本在运行。检查PPTP进程是否存在,不存在就拉起,存在就进行通断检测。我用httping命令向谷歌发送请求,只要3次请求都没有成功返回,就关掉当前的PPTP连接。3秒后再重新拉起。

如果你没有httping,可以通过yum/apt进行安装。

这台服务器上还开启了包转发,允许网内的其他机器通过这台机器发送请求:

/etc/ppp/ip-up.local

#!/bin/bash

VPN_GW=`ip addr show dev ppp0 | grep inet | awk '{print $2}'`

route add default gw $VPN_GW
iptables -t nat -A  POSTROUTING -o ppp0 -j  MASQUERADE

exit 0

这样可以在出口路由器上设置静态路由表,把一些想要通过VPN发送的包,转向到这台服务器。