在 macOS 取消了 PPTP 后使用 chnroutes 手动分流

还是老方法,依旧使用 chnroutes 生成路由表。并且非常不优雅,但是在找不到解决方案的时候可以暂时解决问题。

在使用 PPTP 方式连接 VPN 的时代,只要将生成的 ip-upip-down 拷贝到 /etc/ppp 目录下并且 sudo chmod +x ip-up ip-down 赋予执行权限,在连接 VPN 时会自动调用 ip-up 添加静态路由,在断开 VPN 时会自动调用 ip-down 删除静态路由。

现在 macOS 取消了 PPTP 方式的 VPN,那要怎么样来做分流呢,根据 PPTP 时代的经验,原理无非就是写静态路由,所以还是使用 chnroutes 生成 ip-upip-down 放在你喜欢的目录下,现在就到了最脏的时候,没有找到合适的自动运行的方式,所以我们手动运行。在每次进入到一个新的网络环境时 sudo ./ip-up 添加静态路由,在使用过后 sudo ./ip-down 删除静态路由。

那么问题来了,既然是静态路由,可不可以添加一次就好了?如果你这辈子都不会变更网络环境,理论上是的。为什么这么说,我们来看代码。

# ip-up 文件
#!/bin/sh
export PATH="/bin:/sbin:/usr/sbin:/usr/bin"

OLDGW=`netstat -nr | grep '^default' | grep -v 'ppp' | sed 's/default *\([0-9\.]*\) .*/\1/' | awk '{if($1){print $1}}'`

if [ ! -e /tmp/pptp_oldgw ]; then
    echo "${OLDGW}" > /tmp/pptp_oldgw
fi

dscacheutil -flushcache

route add 10.0.0.0/8 "${OLDGW}"
route add 172.16.0.0/12 "${OLDGW}"
route add 192.168.0.0/16 "${OLDGW}"

ip-up 的工作是获取当前网络的网关,添加静态路由,在静态路由里面将白名单 IP 转发到当前网络的网关上,这样流量就不会通过 VPN 了。所以说如果你确定这辈子都不会变更网络环境可以只执行一次 ip-up 就可以愉快的上网了。如果不是,老老实实在每次使用前执行 ip-up 添加静态路由,使用后执行 ip-down 删除静态路由,否则上不了网可别怨天尤人。

知道了原理后,我们还可以定制静态路由,将 chnroutes 生成的静态路由里缺少的部分自己手动添加进去。

# ip-up 文件
#!/bin/sh
export PATH="/bin:/sbin:/usr/sbin:/usr/bin"

OLDGW=`netstat -nr | grep '^default' | grep -v 'ppp' | sed 's/default *\([0-9\.]*\) .*/\1/' | awk '{if($1){print $1}}'`

if [ ! -e /tmp/pptp_oldgw ]; then
    echo "${OLDGW}" > /tmp/pptp_oldgw
fi

dscacheutil -flushcache

route add 10.0.0.0/8 "${OLDGW}"
route add 172.16.0.0/12 "${OLDGW}"
route add 192.168.0.0/16 "${OLDGW}"

# 自定义
route add 103.235.46.0/22 "${OLDGW}"  # 百度
# ip-down 文件
#!/bin/sh
export PATH="/bin:/sbin:/usr/sbin:/usr/bin"

if [ ! -e /tmp/pptp_oldgw ]; then
        exit 0
fi

ODLGW=`cat /tmp/pptp_oldgw`

route delete 10.0.0.0/8 "${OLDGW}"
route delete 172.16.0.0/12 "${OLDGW}"
route delete 192.168.0.0/16 "${OLDGW}"

# 自定义
route delete 103.235.46.0/22 "${OLDGW}"  # 百度

注意:一定要在 ip-upip-down 中成对添加自定义 IP。

以上就是以非常脏的方式实现手动分流的全过程,下一步就是要像 PPTP 时代一样在使用 VPN 能自动执行上述过程。由于我对 macOS 仅限于使用,也不是 *nix 大神,暂时没有想到什么特别好的解决方案,准备试试使用 AppleScript 能不能监听到 VPN 连接与断开事件来实现自动化。

2016-09-28 16:31146