Linux 策略路由: Linux 下使用基于源地址的策略路由来实现 VPN 隧道流量转接功能

2015-03-29 09:55:37 +08:00
 liuchen9586
实验是我在CentOS 6.5 x86_64上做的,现在已经投入到生产环境中。
网络一直很稳定,带10个人一起玩东南亚CSGO毫无压力。
拓扑是这样的:


其他发行版的Linux可以把命令翻译下,原理是一模一样的。

需要工具:
1、OpenVPN (UDP封装速度快,效率高。玩游戏必备。PPTP VPN也行,但是速度没那么快。)
2、ShadowVPN (虽然是Beta状态,使用的效率还是很高的。因为无状态,所以不被干扰。)
3、IP rule
4、iptables

步骤:

------先做好基本环境配置------

0、更新生产环境(因为我是在纯净的系统上做的)

sudo yum -y groupinstall "Development Tools"
yum -y install openssl*

1、打开ipv4转发功能。

vim /etc/sysctl.conf
net.ipv4.ip_forward = 0 修改成 net.ipv4.ip_forward = 1
sysctl -p

2、添加epel源,直接从源安装openvpn,让用户通过openvpn接入国内中转服务器。

我使用的是中科大的源(因为我就在合肥所以速度快 :P)
wget http://mirrors.ustc.edu.cn/epel/6/x86_64/epel-release-6-8.noarch.rpm
rpm -ivh epel-release-6-8.noarch.rpm
yum makecache
yum -y install openvpn

签发证书的教程:
http://blog.chinaunix.net/uid-29746173-id-4351133.html
做完后记得打开openvpn使用的端口。

3、安装ShadowVPN,使用ShadowVPN将国内中转服务器和国外服务器对接起来

项目地址: https://github.com/clowwindy/ShadowVPN/

wget https://github.com/clowwindy/ShadowVPN/releases/download/0.1.6/shadowvpn-0.1.6.tar.gz
tar zxvf shadowvpn-0.1.6.tar.gz
./configure --enable-static --sysconfdir=/etc
make && sudo make install

记得打开ShadowVPN用的端口,不然隧道起不来。

记得清除掉ShadowVPN client_up.sh中的一段命令:

# change routing table
echo changing default route
if [ pppoe-wan = "$old_gw_intf" ]; then
route add $server $old_gw_intf
else
route add $server gw $old_gw_ip
fi
route del default
route add default gw 10.7.0.1
echo default route changed to 10.7.0.1

不然ShadowVPN up后,你所有的流量都从ShadowVPN隧道走了。

测试隧道通信是否成功:
sudo route add -host 8.8.8.8 dev tunX (tunX是你ShadowVPN的interface)
然后nslookup twitter.com 8.8.8.8
如果返回的地址是无污染的IP,说明隧道已经UP了。

OpenVPN这块,如果签发证书后接入成功,且能ping通网关地址,就没问题。

------再开始做流量的对接------

我这里的ShadowVPN interface IP使用的是10.20.0.1(境外服务器),10.20.0.2(境内服务器)
OpenVPN使用的IP段是10.200.0.0/24,请各位写iptables规则的时候替换成你们正在使用的IP段。

1、首先先定义自定义的路由表,不然写路由条目的时候会写到主路由表,那就会导致选路错乱了。

vim /etc/iproute2/rt_tables
添加一行
200 netgamesg
然后保存,退出。
编号是可以自己自定义的,名字也是可以自定义的,我这里为了好记所以写了这个。
(编号不可以和系统路由表编号重复)

2、添加静态默认路由。

ip route add default dev tunX (你的ShadowVPN interface) table netgamesg

这里是在netgamesg这张路由表里面添加一个默认路由,默认网关出口是shadowvpn的接口。

3、给用户接入进来的地址打上标记,然后强制打上标记的数据使用netgamesg这张路由表。

iptables -A PREROUTING -t mangle -s 10.200.0.0/24 -j MARK --set-mark 3
ip rule add fwmark 3 table netgamesg

4、使用ip rule来根据源地址来使用路由表。

ip rule add from 10.200.0.0/24 table netgamesg

这里是规定源地址为10.200.0.0/24的IP数据包使用netgamesg这张路由表。

5、最后一步,设置iptables转发。

iptables -A POSTROUTING -s [你的openvpn源地址段] -j SNAT --to-source [你的ShadowVPN interface IP]

6、刷新路由表。

ip route flush cache

7、添加脚本,让它开机启动自动执行即可。

vim route.sh

shadowvpn -c /etc/shadowvpn/client.conf -s start
ip route add default dev tun10 table netgamesg
ip rule add fwmark 3 table netgamesg
ip rule add from 10.200.0.0/24 table netgamesg

这样就大功告成了。拨入中国的服务器,你访问ip.cn会显示的是外国的IP,原理就是中国服务器无条件将你的数据转发到国外服务器了。

这个模型里面不需要考虑MTU的问题,至少我这边做了3次是没出现因为MTU问题导致的数据不通。如果数据不通的话看看哪一步没做对。

如果有什么地方写的不对,敬请批评指正。

感谢@zk8802 @gamexg 的点拨。
@hjc4869 嘿,你要的教程,我写好了。
24442 次点击
所在节点    分享创造
73 条回复
liuchen9586
2015-04-06 23:51:13 +08:00
@loca1h0st chnroute下一跳写物理网卡出接口。
loca1h0st
2015-04-07 08:33:33 +08:00
@liuchen9586 物理网卡是eth0...
liuchen9586
2015-04-07 09:53:18 +08:00
@loca1h0st 知道,Chnroute下一跳写eth0,default gw写ShadowVPN的interface
loca1h0st
2015-04-07 09:56:58 +08:00
@liuchen9586 不是特别懂这个意思。。
default gw是指ip route add default dev tun0?
ip rule抓取的流量只能匹配自定义路由表呀
liuchen9586
2015-04-07 10:00:01 +08:00
@loca1h0st ip rule抓的流量是让它强制使用这个路由表,真正控制数据包走向还是靠路由表里面的路由条目。
default gw就是你写的这个。
chnroute下一跳写eth0就是指明它直接走物理网卡。
然后补上一条NAT语句:
iptables -t nat -A POSTROUTING -s [你的openvpn源地址段] -j SNAT --to-source [你的eth0 IP]
NAT Translation只有在数据包到达接口的时候才会触发。
kacong
2015-04-07 11:36:56 +08:00
终极解决方案之一,只要出国网络还通,就有希望ok,谢谢。
loca1h0st
2015-04-07 19:49:43 +08:00
@liuchen9586 刚刚测试了下还是不行。。
默认情况:
ip route add default dev tun0 table vpn
ip rule add from openvpn table vpn
iptables -t nat -A POSTROUTING -s [你的openvpn源地址段] -j SNAT --to-source [你的tun0 IP]

chnroutes
ip route add default dev eth0 table china
ip rule add from openvpn to chnroutes table china
iptables -t nat -A POSTROUTING -s [你的openvpn源地址段] -j SNAT --to-source [你的eth0 IP]

ip route flush cache

访问国内的网站还是出现网络防火墙或代理错误
loca1h0st
2015-04-07 19:58:20 +08:00
@liuchen9586 按如上的配置完成之后本地访问的同时对网卡进行抓包。
出现的是10.7.0.2(shadowvpn的interface ip)发出的arp报文,报文内容为ARP, Request who-has a.b.c.d tell 10.7.0.2, length 28
liuchen9586
2015-04-07 21:51:05 +08:00
@loca1h0st chnroute的路由条目放到vpn路由表内
loca1h0st
2015-04-07 21:56:01 +08:00
@liuchen9586 已经解决了,非常谢谢指导。

记录下解决方案,也许会对别人有帮助

1.把两条SNAT的命令修改成如下:
iptables -t nat -A POSTROUTING -s [你的openvpn源地址段] -o tun[x] -j SNAT --to-source [你的tun0 IP]
iptables -t nat -A POSTROUTING -s [你的openvpn源地址段] -o eth[x] -j SNAT --to-source [你的eth0 IP]

然后再抓包发现还是有ARP报文,但是IP地址从10.7.0.2变成了eth0的IP地址。
这里是感到奇怪的一点,明明有子网掩码的计算了,不应该出现ARP,应该就去找网关地址了。
2.然后修改自定义路由表的默认网关信息。
由ip route add default dev eth0 table china修改为:
ip route add default via [gw_ip] dev eth0 table china

ip route flush cache之后达到目标。。。
KCheshireCat
2015-04-27 10:55:26 +08:00
其实还有个隧道选项 走UDP的静态l2tpV3,比较新的内核直接就支持。
然后3.18内核开始还有个foo over udp的新静态隧道。
UDP的好处是可以穿ISP的NAT。
1nt
2015-05-22 11:45:58 +08:00
@liuchen9586

想请教一下楼主用的境内服务器是哪家的?
我试过阿里云的杭州和深圳节点,出国线路都好慢,
连 Krypt SGP 只能跑到 10 多 Mbps 的带宽呢。
liuchen9586
2015-05-22 13:38:54 +08:00
@1nt 我用的是Ustack,30Mbps能跑到28Mbps,还可以
g552656
2015-06-08 16:10:55 +08:00
@liuchen9586 愿意有偿咨询几个问题,可否给个联系方式?
liuchen9586
2015-06-08 17:01:21 +08:00
@g552656 其实我对linux不太熟悉
你可以发邮件到我ID@google邮箱
NickLiulol
2015-07-03 00:04:33 +08:00
@liuchen9586 太感谢了,AZURE北京+日本某机房成功配置,但是北京机房ping还是丢包,所以买了个softlayer香港的机房试试
NickLiulol
2015-07-03 23:41:39 +08:00

IP是pmang黑色沙漠游戏服务器,国内是ping不通的,现在是武汉电信+香港CN2+日本ConoHa,原本ConoHa机房是丢包之王不用看,其他的KDDI/NTT/IIJ机房半夜不丢包稳定下来也70左右。
另外我不知道为什么用OPENVPN会莫名其妙200+ms,以为是干扰,但是XOR PATCH也没有用,就索性改了PPTP+shadowvpn的组合,把MTU改成1396,之后就成功了。
多谢楼主,简直是完美解决我玩日服的难题。
liuchen9586
2015-07-04 00:30:07 +08:00
@NickLiulol 我现在都已经淘汰了这种双重NAT的方案了……直接在内网跑个BGP路由,添加删除服务器更方便,而且还能自动愈合自动切换
NickLiulol
2015-07-04 01:25:16 +08:00
@liuchen9586 这应该就很接近/就是很多网游加速器的做法了吧,
liuchen9586
2015-07-04 01:46:46 +08:00
@NickLiulol 这个嘛,就不知道了
因为BGP方便,没双重NAT那么死板,加一台服务器/一个网段只要一条命令就够了

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/180070

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX