DD Wrt 路由器級VPN翻牆方案

最近終於抽出時間, 在家裡的dd wrt路由器上配置了VPN ,實現區域網內所有設備透明翻牆。這裡稍微整理一下。

(註:以下內容適用於使用PPPoE協議連接公網的網路環境;並且要求dd wrt路由器具有jffs空間和USB口)

基本方案還是chnroutes的思路,通過添加國內IP路由表實現國內外IP分流:國內IP直接走ISP,國外IP全部走VPN。之所以沒有用autoddvpn方案是因為autoddvpn的graceMode並不完美,它對GFW的關鍵字封鎖(包括url query string關鍵字封鎖和深度包檢測)無能為力,仍然會被reset。而且現在大部分國外IP通過VPN訪問還能起到加速作用(我用的是Linode東京機房自己架設的OpenVPN)

準備工作:開啟路由器jffs空間;掛載USB存儲設備到/opt;然後根據這裡說明安裝Optware組件。

安裝配置OpenVPN

請不要使用dd wrt的Web界面,而是手工將配置文件和證書放到路由器上,然後通過命令行啟動OpenVPN。配置文件和證書可以放在/jffs或/opt目錄里。

創建dd wrt自啟動文件 /jffs/etc/config/openvpn.startup,設置許可權為+x

#!/bin/sh
openvpn --config /jffs/openvpn/client.conf

在DD Wrt Web界面 Administration – Commands里添加並保存iptables防火牆規則

# allow OpenVPN
iptables -I FORWARD -i br0 -o tun0 -j ACCEPT
iptables -I FORWARD -i tun0 -o br0 -j ACCEPT
iptables -t nat -A POSTROUTING -o tun0 -j MASQUERADE

創建國內外IP分流腳本

下載chnroutes項目提供的python腳本,運行

python chnroutes.py -p openvpn

會生成vpn-up.sh和vpn-down.sh兩個文件,按照下面的說明將這兩個文件做一些修改,然後分別重命令為 script.ipup和script.ipdown,放到/jffs/etc/config/目錄下,同樣設置許可權+x。

script.ipup:在vpn-up.sh開頭添加幾行內容,然後刪去一些行

#!/bin/sh -

OLDGW=$(nvram get wan_gateway)
if [ $OLDGW == '' ]
then
    exit 1
fi

route add -net 1.0.1.0 netmask 255.255.255.0 gw $OLDGW
route add -net 1.0.2.0 netmask 255.255.254.0 gw $OLDGW
route add -net 1.0.8.0 netmask 255.255.248.0 gw $OLDGW
#.....

script.ipdown:將vpn-down.sh第一行的#!/bin/bash -改為#!/bin/sh -,然後刪去下面幾行內容

#!/bin/sh -

route del -net 1.0.1.0 netmask 255.255.255.0
route del -net 1.0.2.0 netmask 255.255.254.0
route del -net 1.0.8.0 netmask 255.255.248.0
#......

這裡使用的方式是利用dd wrt的腳本自動執行機制,在PPPoE撥號連接和斷開時自動添加或刪除分流路由表。之所以在PPPoE狀態改變而不是在OpenVPN連接和斷開時添加 / 刪除路由表的原因,是因為OpenVPN在使用中很可能因為網路不穩定等因素斷開;而PPPoE連接通常比較穩定,連上後很少中斷。目前的國內IP直連路由表共3500多條,每次執行添加或刪除操作時都需要較長時間(在我的華碩RT-N16路由器上接近5分鐘),將腳本放在PPPoE連接和斷開時執行就意味著通常只需要在路由器啟動後執行一次,避免了(OpenVPN不穩定中斷時)的反覆執行。

部署pwx-dns-proxy

這是一個Python寫的DNS代理,它的作用是監聽LAN內的DNS解析請求,根據域名不同分別轉交給不同DNS解析:cn域名和國內常見網站的域名以UDP方式轉發給本地ISP解析,快速並且能夠享受CDN加速;其它所有域名以TCP方式轉發給Google Public DNS解析,避免DNS劫持。

首先請在DD Wrt WEB界面禁用dnsmasq(它會佔用53埠,並且現在已經不需要它了。之所以不用dnsmasq是因為它無法將接受的UDP DNS解析請求通過TCP轉發給上游DNS伺服器。)

在路由器上安裝python環境。

ipkg-opt update
ipkg-opt install python26
ipkg-opt install py26-twisted

修改pwx-dns-proxy配置文件dnsproxy.conf

#這裡修改為你路由器的LAN IP
listen_tcp(53, "192.168.0.1")
listen_udp(53, "192.168.0.1")

#將ISP DNS修改為你的本地ISP DNS
# add_server(name, address, port, is_tcp, [timeout])
add_server("google", "8.8.8.8", 53, True)
add_server("isp", "218.2.135.1", 53, False) #218.2.135.1 江蘇電信主DNS伺服器

#設置使用ISP解析的域名, 以下是我的設置,包含了國內常見主要網站。
# 在 domain_list 中的域,將使用指定 server 查詢。
# example.tld 僅精確匹配這個二級域。若要匹配其子域,
# 請使用 .example.tld。
add_lookups("isp", [
	".cn",
	
	#baidu
	".baidu.com",
	".bdimg.com",
	
	#sohu
	".sohu.com",
	".sogou.com",
	
	#163
	".163.com",
	".126.net",
	".126.com",
	".netease.com",
	".youdao.com",
	
	#cctv
	".cctv.com",
	".cctvpic.com",
	
	#tencent
	".qq.com",
	".gtimg.com",
	".paipai.com",
	".soso.com",
	
	#sina
	".sina.com",
	".weibo.com",
	".iask.com",
	
	#taobao
	".taobao.com",
	".taobaocdn.com",
	".tmall.com",
	".etao.com",
	
	#cdn
	".lxdns.com",
	
	#360buy
	".360buy.com",
	".360buyimg.com",
	".minitiao.com",
	
	#51buy
	".51buy.com",
	".icson.com",
	
	#general
	".qidian.com",
	".renren.com",
	".115.com",
	".hao123.com",
	".youku.com",
	".tudou.com",
	".56.com",
	".pptv.com",
	".ku6.com",
	".iqiyi.com",
	".xunlei.com",
	".vancl.com",
	".mop.com",
	".cn.yahoo.com",
	".china.com",
	".gougou.com",
])

修改pwx-dns-proxy啟動腳本run.sh里的Python路徑:

python2.6 src/dnsproxy.py

將pwx-dns-proxy上傳到路由器上,創建開機自運行文件/jffs/etc/config/dns.startup

#!/bin/sh

ps | grep dnsproxy.py | grep -v grep | head -n1 | awk '{print $1}' | xargs kill -9
cd /jffs/pwx-dns-proxy
./run.sh &

在dd wrt Web管理界面 Setup頁DHCP設置里將Static DNS 1,Static DNS 2,Static DNS 3分別設為你的路由器LAN IP (在我這裡就是192.168.0.1)、8.8.8.8和8.8.4.4。

最後

回過頭編輯你的OpenVPN配置文件,加入一行

route 8.8.8.8 255.255.255.255 net_gateway 5

強迫8.8.8.8直連而不走VPN,因為我們已經通過pwx-dns-proxy的本地DNS代理使用TCP方式查詢Google DNS伺服器,所以直連它並不會被DNS劫持,反而有助於增加網路穩定性,提高速度並減輕OpenVPN連接不穩定時對網路的影響。

以上就是主要步驟。一些細節我省略了。如設置OpenVPN配置文件里”max-routes 3535″最大路由條數,這個我是通過腳本在每次生成ip-pre-up和ip-down時自動修改的:

#!/bin/sh

ROUTES_FILE=/jffs/openvpn/ip-pre-up
ROUTE_COUNT=$(wc -l $ROUTES_FILE | awk '{print $1}' )
ROUTE_COUNT=$(awk -v a=$ROUTE_COUNT -v b=20 'BEGIN{printf "%d",a+b}')

sed -i "s/max-routes[ \t]*[0-9]*/max-routes $ROUTE_COUNT/" /jffs/openvpn/client.conf

按照上面步驟全部設置好後,路由器開機後就自動連接VPN並且國內外IP分流,所有設備連上路由器直接翻牆,無需設置。

0 Responses to “DD Wrt 路由器級VPN翻牆方案”


Comments are currently closed.