使用 OpenVPN 服务器翻墙的相关问题解决
June 20th, 2010
前一段时间参照这篇在Ubuntu上搭建OpenVPN服务器,并配合Mac和Windows的客户端 (一)在自己的 VPS 上装好 OpenVPN 服务器后使用一直不太正常,这两天花了点时间调试解决,结果总结如下。调试期间多次得到 @yegle @ChandleWEi @Greendamn 和 @FretiaX 等推友的帮助,尤其是 @ChandleWEi 深夜还在我家现场调试 iptables,特此感谢。
MTU 太大造成的连接不稳定
症状
刚连接上 OpenVPN 只用浏览器打开一两个页面时速度很正常,但随着流量加大网络就会开始阻塞,直到完全无法连接任何服务器。而且与 OpenVPN 服务器之间的连接容易自动断开。
解决方案
在 OpenVPN 服务器的 server.conf 里加入 mssfix 1300。此方案由 @yegle 提供。数字应该是他多次测试得出的较优选择,我试过设为 mssfix 1400 自己的 PC 没问题,而朋友的机器会速度奇慢。
DNS 污染造成的部分墙外网站无法访问
症状
连接 OpenVPN 后 Twitter 可以正常访问,被严重 DNS 污染的 Facebook 则会被浏览器提示无法连接。
解决方案
在 OpenVPN 服务器上使用 iptables 强行劫持客户端对任何 DNS 服务器的查询请求,将请求的目标 IP 地址修改为墙外的 DNS 服务器,例如 Google 的公共 DNS 服务器 8.8.8.8 和 8.8.4.4。此方案参照 @yegle 的方案稍作修改,不需要 OpenVPN 服务器自己提供 DNS 服务。iptables 命令如下:
iptables -t nat -A PREROUTING -p udp --dport 53 -j DNAT --to-destination 8.8.8.8
残留问题
虽然这个近乎暴力的方式可以很有效并且是一劳永逸地从服务器端解决 DNS 污染问题,但还是有一种情况必须由客户端自己更改 DNS 地址。这种情况为,客户端的 DHCP 设备(一般就是共享上网用的路由器)为其分配的 DNS 地址与网关地址在同一个网段,或者通常就是同一个地址。这样就算是连接上 OpenVPN 后默认网关变成了 OpenVPN 服务器的 IP 地址,但由于 DNS 跟原网关在同一个网段,客户端的 DNS 查询请求还是会不进入 OpenVPN 而直接从原网关发出,导致得到被污染的错误结果。
解决方案
手动设置客户端的 DNS 地址为任意墙外 DNS 地址,例如 Google 的公共 DNS 服务器 8.8.8.8 和 8.8.4.4。
Windows UAC(用户帐户控制)导致 OpenVPN GUI 无法设置 OpenVPN 服务器为默认网关
症状
在服务器端解决了以上问题之后,客户端 OpenVPN GUI 可以连接成功。但仍然无法访问墙外网站,nslookup www.facebook.com 会得到明显被污染的 IP 地址。route print 可以观察到路由表中的默认网关没有 OpenVPN 服务器 IP 地址。
解决方案
关掉 UAC,或者以管理员身份启动 OpenVPN GUI。
标签:DNS 污染, FuckGFW, GFW, OpenVPN, 翻墙
June 20th, 2010 at 10:31
有没有需要把 iptables -t nat -A PREROUTING -p udp --dport 53 -j DNAT --to-destination 8.8.8.8 加到 rc.local 里面?
June 20th, 2010 at 17:49
其实我是设置好 iptables 以后用
iptables-save > /etc/iptables.rules把规则保存到这个文件里,rc.local里就只需要写iptables-restore < /etc/iptables.rules。June 20th, 2010 at 20:18
哈哈!刚刚试了一下,没问题!谢谢!
June 20th, 2010 at 22:20
别谢我,谢小狐狸 @yegle~
July 14th, 2010 at 08:59
在server.conf里面加上 push "redirect-gateway def1" push "dhcp-option DNS 8.8.8.8" push "dhcp-option DNS 208.67.222.222" 就可以了
July 14th, 2010 at 23:42
redirect-gateway def1 是必须的,否则客户端不会把 OpenVPN 服务器 IP 设为默认网关。后面两个选项不是在所有系统上都有效,例如 Android。所以最保险最省事的做法是用 @yegle 提出的这个 DNS 劫持方案。
August 5th, 2010 at 21:25
想问一下,你的OpenVPN用的是什么连接方式TCP还是UDP?
August 6th, 2010 at 01:51
UDP 的,@yegle 说 TCP 性能差很多,我也没比较过。
August 6th, 2010 at 12:04
那就和我一样了。用TCP的时候我抓过数据包,数据量大时有很多TCP快速重传,然后一会就断了。但是UDP在某些网络环境下根本连接不上去,只有TCP可以。纠结~
August 6th, 2010 at 19:17
开两个 OpenVPN 服务好了……不过我倒是没遇到过 UDP 连不上的情况。
September 13th, 2010 at 09:33
[...] 使用 OpenVPN 服务器翻墙的相关问题解决 « Rainux's Journal 前一段时间参照这篇在Ubuntu上搭建OpenVPN服务器,并配合Mac和Windows的客户端 (一)在自己的 VPS 上装好 OpenVPN 服务器后使用一直不太正常,这两天花了点时间调试解决,结果总结如下。调试期间多次得到 @yegle @ChandleWEi @Greendamn 和 @FretiaX 等推友的帮助,尤其是 @ChandleWEi 深夜还在我家现场调试 iptables,特此感谢。 (tags: openvpn linux networks) [...]
November 3rd, 2010 at 23:04
上次rails聚会听你说可以用你的 API 代理来翻墙上twitter回家看了一下,没明白怎么用,在我自己的Mac上已经登录过twitter了,用的那个VPN不是很稳定,经常上不去。
March 16th, 2011 at 19:50
[...] 第三步:参考这篇博客,在服务器server.conf里,加入“mssfix 1300”。再运行下边这条规则: [...]
March 16th, 2011 at 19:51
谢谢,真有用!
March 26th, 2011 at 11:10
[...] 第三步:参考这篇博客,在服务器server.conf里,加入”mssfix 1300″。再运行下边这条规则: [...]
August 5th, 2011 at 17:14
/etc/init.d/iptables save /etc/init.d/iptables restart
这两行代码就可以保存并重启iptables,不用手动修改配置文件! @opalhair @Rainux (建议你装个@Somebody回复的功能,不然根本无法回复评论)
July 1st, 2012 at 22:51
我参考的教程中, 多了一个-m参数(iptables -t nat -A PREROUTING -p udp -m udp --dport 53 -j DNAT --to-destination 8.8.8.8),理论上和你的没有差别。不知是否是长城升级了,对于windows客户端无效。fb仍然被劫。你现在用的还正常吗?
July 1st, 2012 at 22:59
hmm...找到原因了。以前使用过修改hosts的方法,于是有些冲突了。把之前的hosts删除后正常了。
September 9th, 2012 at 11:54
你好,我在使用了这条命令后客户端就无法登录openvpn服务器了。轻问是不是服务器把登录的链接也转向dns服务器了?可以告诉下yegle的具体方法吗,十分感谢。
September 12th, 2012 at 00:56
@jade 你好。yegle 的具体方法是在运行 OpenVPN server 的服务器上配置 BIND 作为 DNS server,然后在 iptables 那一步把 destination 设置为服务器 IP 地址。但其实从我的经验来看这种劫持 DNS 请求的做法实际效果并不好,最可靠的办法还是在客户端手动设置 DNS 为 8.8.8.8。
January 10th, 2013 at 13:40
请问海外最近openvpn被GFW封锁了,UDP端口都不行,TCP端口非知名端口只能挨个换,但是过不了2天又不知道被什么方式给挡了,telnet那个端口虽然还有效但是VPN连接时直接就超时了,
February 28th, 2013 at 17:09
OpenVPN配置静态共享密钥,应对防火长城(GFW)封锁
http://3forever.com