MENU

记一次阿里云F5VPN路由配置

June 13, 2016 • 其他

前言

项目这版要上一个图书馆查询功能,而学校的图书馆查询系统只能内网访问,在内网写完后端之后,问题来了,如何让部署在外网的服务器访问学校内网?

几番周折拿到了学校VPN,用的是f5vpn(从未听过...),在服务器中安装官网提供的Client,问题多多。最后在Github上看到大牛写的 f5vpn-login。这个f5vpn客户端基于Python(太好了,起码能看懂源码...),能在类Unix上运行,OSX和Ubuntu测试可用。

然而,这只是开始...

Overview


f5vpn本地测试通过,但在服务器测试发现:当连接上vpn时,SSH立即中断。

猜想是VPN配置路由时出现问题了,由于我们的主服务器和这台用来代理内网的服务器是同一个地域,可以互通。用主服务器SSH登录上这台服务器,服务器确实是连接上学校VPN了,但ping不通学校内网。

断开VPN,查看阿里云默认的路由表

~ route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         120.27.119.247  0.0.0.0         UG    0      0        0 eth1
10.0.0.0        10.174.247.247  255.0.0.0       UG    0      0        0 eth0
10.174.240.0    *               255.255.248.0   U     0      0        0 eth0
100.64.0.0      10.174.247.247  255.192.0.0     UG    0      0        0 eth0
121.41.76.0     *               255.255.252.0   U     0      0        0 eth1
172.16.0.0      10.174.247.247  255.240.0.0     UG    0      0        0 eth0

默认路由表中可见,10.0.0.0 和 172.16.0.0 会通过阿里云内网。

再次连接VPN,查看连接VPN后路由表,此时网络架构如下图。

~ route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         172.16.16.233   128.0.0.0       UG    0      0        0 ppp0
default         172.16.16.233   0.0.0.0         UG    0      0        0 ppp0
default         120.27.119.247  0.0.0.0         UG    0      0        0 eth1
10.0.0.0        10.174.247.247  255.0.0.0       UG    0      0        0 eth0
10.174.240.0    *               255.255.248.0   U     0      0        0 eth0
100.64.0.0      10.174.247.247  255.192.0.0     UG    0      0        0 eth0
121.41.76.0     *               255.255.252.0   U     0      0        0 eth1
172.16.0.0      10.174.247.247  255.240.0.0     UG    0      0        0 eth0
128.0.0.0       172.16.16.233   128.0.0.0       UG    0      0        0 ppp0
172.16.16.1     *               255.255.255.255 UG    0      0        0 ppp0

Screen Shot 2016-06-14 at 3.06.16 PM.png

有三个默认路由,但最终走的是 172.16.16.233(学校VPN),这可以解析为何我们不能通过外网连接服务器。而当我们ping 10.1.18.2(学校内网) 时,因为匹配到路由表中的 10.0.0.0,强制使用阿里云的路由 10.174.247.247,所以会通过阿里云内网访问 10.1.18.2(学校内网) ,也就ping不通啦。

解决方案


阿里云默认路由设置造成的IP网段冲突,可以通过网卡配置文件 /etc/network/interfaces 修改

# up route add -net 172.16.0.0 netmask 255.240.0.0 gw 10.174.247.247 dev eth0
up route add -net 100.64.0.0 netmask 255.192.0.0 gw 10.174.247.247 dev eth0 # 并不知道这是啥
up route add -net 10.174.0.0 netmask 255.255.0.0 gw 10.174.247.247 dev eth0 # 本服务器网段
up route add -net 10.251.0.0 netmask 255.255.0.0 gw 10.174.247.247 dev eth0 # 主服务器网段
up route add -net 10.202.0.0 netmask 255.255.0.0 gw 10.174.247.247 dev eth0 # DNS服务器网段

先将与vpn网段冲突的 172.16.0.0 路由注释掉(谷歌后发现这个路由好像没啥用),然后将 10.0.0.0 细分成主服务器网段(便于内网互通)、DNS服务器网段和服务器自身网段。

重启后再次查看路由表,成功ping到内网

~ route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         172.16.16.233   128.0.0.0       UG    0      0        0 ppp0
default         172.16.16.233   0.0.0.0         UG    0      0        0 ppp0
default         120.27.119.247  0.0.0.0         UG    0      0        0 eth1
10.174.0.0      10.174.247.247  255.255.0.0     UG    0      0        0 eth0
10.174.240.0    *               255.255.248.0   U     0      0        0 eth0
10.202.0.0      10.174.247.247  255.255.0.0     UG    0      0        0 eth0
10.251.0.0      10.174.247.247  255.255.0.0     UG    0      0        0 eth0
100.64.0.0      10.174.247.247  255.192.0.0     UG    0      0        0 eth0
121.41.76.0     *               255.255.252.0   U     0      0        0 eth1
172.16.0.0      10.174.247.247  255.240.0.0     UG    0      0        0 eth0
128.0.0.0       172.16.16.233   128.0.0.0       UG    0      0        0 ppp0
172.16.16.1     *               255.255.255.255 UG    0      0        0 ppp0

ping内网问题解决了,但怎样可以指定特定IP走VPN呢?同样的,只需配置路由。

路由Destination的default表示 0.0.0.0,即使所有流量都通过该路由。我们先将上面路由表中第一第二条via ppp0 的路由删掉。

route del default netmask 128.0.0.0
route del default gw 172.16.16.233

然后将 10.1.18.0(学校查询系统内网段)添加进路由

route add -net 10.1.18.0/24 gw 172.16.16.233
~ route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         120.27.119.247  0.0.0.0         UG    0      0        0 eth1
10.1.18.0       172.16.16.55    255.255.255.0   UG    0      0        0 ppp0
10.174.0.0      10.174.247.247  255.255.0.0     UG    0      0        0 eth0
10.174.240.0    *               255.255.248.0   U     0      0        0 eth0
10.202.0.0      10.174.247.247  255.255.0.0     UG    0      0        0 eth0
10.251.0.0      10.174.247.247  255.255.0.0     UG    0      0        0 eth0
100.64.0.0      10.174.247.247  255.192.0.0     UG    0      0        0 eth0
120.27.116.0    *               255.255.252.0   U     0      0        0 eth1
172.16.16.1     *               255.255.255.255 UH    0      0        0 ppp0

Screen Shot 2016-06-14 at 8.51.20 PM.png

上图为路由表和网络架构

B2613CF2-C1B8-4755-AC9C-84F31EFB5EAA.png

完成后,能通过外网访问测试服务器,后端也能连接学校内网返回数据了!


PS:如何能让 f5vpn-login 添加指定ip的路由?

class Linux2Platform(Platform):
    def setup_route(self, ifname, gateway_ip, net, bits, action):
        if bits == 32:
            host_or_net = ["-host", net]
        else:
            host_or_net = ["-net", net, 'netmask', bits2mask[bits]]
        # run_as_root(['/sbin/route', action] + host_or_net +
        #            ['gw', gateway_ip])

打开f5vpn-login.py,注释上图两行,并添加如下两行,其中"-net"对应的'10.1.18.0'为指定ip。

def ppp_ip_up(iface_name, tty, local_ip, remote_ip):
        revdns_domains = []
        for net, bits in routes_to_add:
            platform.setup_route(iface_name, local_ip, '.'.join(map(str, net)), bits, 'add')
            revdns_domains.extend(routespec_to_revdns(net, bits))
        run_as_root(['/sbin/route', 'add'] + ["-net", '10.1.18.0', "netmask", '255.255.255.0'] +['gw', local_ip]) # 添加的语句,添加的语句,添加的语句

Reference:
[1] http://blog.fens.me/vpn-aliyun/
[2] http://linux.vbird.org/linux_server/0230router.php

Comment Lists