β

如何让路由器科学上网

Cloud Chou's Tech Blog 128 阅读

身处墙内的我们,大多数时候并不是为了看一些政治方面的东西,只是想畅快的享受自由网络而已,能够自由地学习技术而已。本篇讲述如何让家中的路由器科学上网,这样家中的电脑,手机,ipad等设备都能畅快上网,再也不用担心浏览网页时,浏览器突然告诉你连接已中断,或者装个浏览器插件时,浏览器告诉你安装失败,一看原因说是image decode failed。另外,参考本方案可以让你搭建翻墙环境时少遇一些坑。

背景

以前我通过让路由器连接公司VPN来翻墙,于是受限于公司网络,连接速度很慢,有时候打开Google都要10s,最近终于忍受不了了。同事和我分享了他翻墙的方法,并且他家中的网络能非常畅快地上网,甚至有时候打开墙外网站比打开国内网站更快。心里痒痒,折腾了一个星期,终于让自己家的路由器也能畅快地上网了。

同事用的路由器是华硕的路由器,固件是koolshare的,而我家中的路由器是netgear wndr3800ch,用的固件是openwrt,实现翻墙的配套应用是shadowsocks+chinadns。同事家中的koolshare固件自带了shadowsocks+chinadns,可以让用户直接在路由器的局域网网站上设置, 而我家中的openwrt需要安装shadowsocks+chinadns+luci-app-shadowsocks+luci-app-chinadns,也能实现在局域网设置网站上进行相关设置就可以翻墙(不需要在命令行操作),luci-app-*都是路由器网站的lua插件,它们会调用shadowsocks和chinadns。

折腾过程中遇到的最大的问题是系统和app之间,app和app之间的兼容性问题,因此选择正确的系统版本和app版本是能快速实现翻墙的前提。

准备工作

  1. 选择可以刷openwrt或者koolshare的路由器

    比如netgear wndr3800ch,在这个网站上可以查找openwrt支持的路由器:

    https://wiki.openwrt.org/toh/start

    选择时需要考虑是否支持挂载硬盘

  2. 准备ShadowSocks服务器

    如果已有国外VPS的话,可以在VPS上安装ShadowSocks服务,现在已有一键安装脚本,可以参考:

    https://teddysun.com/357.html

    但是需要注意: ShadowSocks服务有一个选项–fast-open,如果没有开启该选项,则路由器连接到服务器时会出现错误:

    getpeername transport endpoint is not connected
    

    但是开启该选项要求Linux内核必须在3.7以上,所以如果VPS内核低于3.7,就升级内核把。我的VPS先前使用ubuntu,内核是2.6的,后来换成了centos,并用yum update命令从centos 6.4 升级到了 6.5,然后又升级了内核,可参考 使用Yum快速更新升级CentOS内核

    如果使用一键安装脚本安装的ShadowSocks,在连接服务器时会做一次性验证,路由器连接Vps的ShadowSocks也需要开启一次性验证,否则连接会失败

    安装好之后,可查看配置文件/etc/shadowsocks-libev/config.json,里面有ShadowSocks的各种配置。另外启动ShadowSocks服务的脚本是/etc/init.d/shadowsocks。

    如果没有国外VPS的话,那么也没必要为了翻墙去买一个国外的VPS,直接买ShadowSocks服务,更划算。 可以在 http://cloudss.org 上购买,试用1个星期3G流量只需5块钱。

操作步骤

  1. 刷入正确版本的openwrt

    我选择的openwrt版本是15.05,注意选择正确的版本很重要,否则很容易出现不兼容的问题,大家可以和我选择一样的版本。openwrt固件的下载地址是:

    https://downloads.openwrt.org/chaos_calmer/15.05/

    在该页面先选择路由器对应的cpu型号,wndr3800ch对应的cpu型号是ar71xx,进去后再选择generic,进去之后再查找路由器型号,wndr3800ch对应的固件的下载地址是

    https://downloads.openwrt.org/chaos_calmer/15.05/ar71xx/generic/openwrt-15.05-ar71xx-generic-wndr3800ch-squashfs-factory.img

    升级固件的下载地址是:

    https://downloads.openwrt.org/chaos_calmer/15.05/ar71xx/generic/openwrt-15.05-ar71xx-generic-wndr3800ch-squashfs-sysupgrade.bin

    每个路由器的刷机方式会有所差异,大家可以自己Google如何刷如openwrt。

  2. 准备墙内ip名单

    使用如下命令将墙内ip地址段保存到/etc/ignore.list, 这样翻墙时遇到这些ip就会直接连接,不走翻墙线路:

    wget -O- 'http://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-latest' | awk -F\| '/CN\|ipv4/ { printf("%s/%d\n", $4, 32-log($5)/log(2)) }' > /etc/ignore.list
    
  3. 安装ipset等依赖软件

    opkg update
    opkg install ip ipset libopenssl iptables-mod-tproxy
    
  4. 安装正确版本的shadowsocks, chinadns, luci-app-shadowsocks,luci-app-chinadns

    shadowsocks使用的版本是spec_2.4.8,注意必须使用spec版本,非spec版本的shadowsocks不能和luci-app-shadowsocks配合使用,它会缺少/etc/init.d/shadowsocks。

    可以在下述网站上查找对应cpu的shadowsocks:

    https://sourceforge.net/projects/openwrt-dist/files/shadowsocks-libev/2.4.8-8816fa1/

    我选择的shadowsocks的下载地址是:

    https://sourceforge.net/projects/openwrt-dist/files/shadowsocks-libev/2.4.8-8816fa1/ar71xx/shadowsocks-libev-spec_2.4.8-2_ar71xx.ipk/download

    chinadns使用的版本是1.3.2,可以在下述网站上查找cpu对应的chinadns:

    https://sourceforge.net/projects/openwrt-dist/files/chinadns/1.3.2-761183b/

    我选择的chinadns的下载地址是:

    https://sourceforge.net/projects/openwrt-dist/files/chinadns/1.3.2-761183b/ChinaDNS_1.3.2-4_ar71xx.ipk/download

    luci-app-shadowsocks的下载地址是:

    https://sourceforge.net/projects/openwrt-dist/files/luci-app/shadowsocks-spec/

    我选择的luci-app-shadowsocks的下载地址是:

    https://sourceforge.net/projects/openwrt-dist/files/luci-app/shadowsocks-spec/luci-app-shadowsocks-spec_1.5.0-1_all.ipk/download

    luci-app-chinadns的下载地址是:

    http://openwrt-dist.sourceforge.net/releases/luci/packages/

    我选择的luci-app-chinadns的下载地址是:

    http://openwrt-dist.sourceforge.net/releases/luci/packages/luci-app-chinadns_1.5.0-1_all.ipk

    下载这些app之后,将这些app使用winscp上传到路由器,然后使用opkg install命令安装这些应用。

  5. 开启shadowsocks和chinadns

    使用如下命令开启shadowsocks和chinadns,这样luci-app-shadowsocks和luci-app-chinadns才可以调用shadowsocks和chinadns

    /etc/init.d/shadowsocks enable
    /etc/init.d/chinadns enable
    
  6. 在路由器设置界面配置shadowsocks

    现在打开路由器网站 http://192.168.1.1 ,在Services节点下就可以看到ShadowSocks和ChinaDns了,选择ShadowSocks后针对ShadowSocks进行配置,配置示意图如下图所示:

    shadow-config

    配置ShadowSocks服务器时,注意Onetime Authentication必须和服务器一致,cloudss上申请的体验服务器是不可以勾选Onetime Authentication的。

    如果想让ShadowSocks辅助做Dns解析,可以勾选UDP Forward(本步骤是可选的,不勾选也能正常工作),这样做的效果是将Dns解析请求通过ShadowSocks的隧道转发给ShadowSocks服务器,然后再让ShadowSocks服务器将Dns请求转发给你设置好的域名服务器(通过Forwarding Tunnel设置),这样做的好处是你可以选择和你的ShadowSocks服务器最近的Dns服务器,这样Dns服务器解析的ip地址和你的ShadowSocks服务器最近,ShadowSocks服务器去做其他请求时会最快,这种方案也不用担心域名被污染。设置示意图如下图所示:

    shadowsocks-config-udpforard

    上面的设置只是让ShadowSocks支持做udp转发而已,为了使用这个udp转发,后续还要配置chinadns来使用这个udp转发。

    接下来配置外网连接的直连ip规则(也就是说决定哪些ip直接连接服务器,不走代理),在AccessControl配置段的Bypassed IP List里输入/etc/ignore.list,后续在chinadns里也会选择这个/etc/ignore.list,在chinadns里配置后,这边会显示ChinaDNS CHNRoute。配置示意图如下图所示:

    shadowsocks-config-wan-bypass

    还可以针对局域网配置,我的设置都是默认的

    shadowsocks-config-lan-bypass

    配置好之后,点击Save&Apply,等一会之后,在页面上方可以看到Running的状态,说明配置成功了,如下图所示:

    shadowsocks-config-success

  7. 在路由器设置界面配置chinadns

    接下来再在路由器上配置chinadns,示意图如下图所示:

    chinadns-config

    LocalPort是本地服务端口,CHNRoute File填写国内ip配置文件/etc/ignore.list,在Upstream Servers里配置上游Dns服务器,国内的Dns服务器和国外的Dns服务器需分别配置至少1个,114.114.114.114是国内比较稳定的dns服务器,8.8.4.4是国外比较稳定的Google Dns服务器,然后我还配置了一个本地的Dns服务: 127.0.0.1:25353,其实这个是在ShadowSocks里配置的Dns转发服务,实际上会转发到Shadows Socks服务器,然后再转发到ShadowSocks服务器最近的Dns服务器进行Dns解析

    设置好之后点击Save & Apply之后,过一会就能看到ChinaDNS is running的提示语,就说明配置成功了。

  8. 将路由器的Dns解析请求转发给ChinaDns

    选择菜单栏Network的DHCP and DNS, 然后进行下述配置:

    dhcp-config

    通过设置DNS forwardings,将局域网的dns请求都转发给ChinaDNS,这里注意设置的端口必须和ChinaDNS的端口一样

    接下来操作Reslove and HostFiles, 将resolve file的解析忽略,勾选 Ignore resolve file 和 Ignore Hosts files

    resolve-config

  9. 测试

    上Google看看能不能畅快的搜索吧!!!!

翻墙原理

网络连接主要分两个步骤,第1步Dns解析将域名解析为ip,第2步客户端连接到ip对应的服务器。

国外网站被墙的原因是国家在这两个步骤上搞了鬼,国外网站的很多域名被国内的Dns服务器污染,所以dns解析时将域名指定到虚假ip,所以不能正常打开国外网站,还有一种情况是,政府网络检测到你连接的ip是那些他不让你访问的ip后,就直接断掉你的连接。

那么翻墙的原理也是针对这两种手段进行反制,我们在路由器上进行翻墙时,通过将路由器的DNS转发给ChinaDNS,ChinaDNS解析Dns时,会既利用国内的DNS服务器进行解析,也会利用国外的DNS服务器进行解析,如果是国内域名,则用国内ip,如果是国外域名则用国外ip。我们在配置ChinaDns有一个双向过滤选项,如果勾选的话,当国外DNS服务器返回的查询结果是国内IP,或者当国内DNS服务器返回的查询结果是国外IP,则过滤掉这个结果(较为严格的模式);去掉勾选的话只是过滤国内DNS的国外IP结果。

连接到国外ip时,通过iptables将国外ip的访问请求都转发给ShadowSocks,然后由路由器上的ShadowSocks请求服务器的shadowsocks,再由服务器的shadowsocks去请求你想访问的国外网站,路由器上的ShadowSocks和服务器的shadowsocks通信的内容是加密的,所以政府也不好断掉连接。

我们在路由器网站上设置ShadowSocks时,会操作Access Control,决定哪些ip直接连接,那些IP必须转发,在网站上设置后,会将这些参数传递给脚本/etc/init.d/shadowsocks,然后shadowsocks脚本会调用ss-rule进行设置,ss-rule其实就是一个Shell脚本(这个脚本执行完就退出,和ss-redir不一样),它会利用ipset为/etc/ignore.list建立ip段集合,我们可以通过如下命令查看建好的ip集合

ipset -L

ss-rule一共会建立5个ip段集合:

Name: ss_spec_lan_no #局域网禁止访问的ip段集合
Name: ss_spec_lan_bp #局域网可以直连的ip段集合
Name: ss_spec_lan_fw #局域网需要转发的ip段集合
Name: ss_spec_wan_sp #局域网或者是shadowsocks服务器等ip段集合
Name: ss_spec_wan_bp #外网需要直连的ip段集合 这个集合非常大
Name: ss_spec_wan_fw #外网需要转发的ip段集合

ss-rule 还会调用iptables为nat表建立转发规则,我们可以使用如下命令查看:

iptables -t nat --list

我们针对外网代理看一下是如何建立转发的:

#NAT table的 PREROUTING链
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination         
SS_SPEC_LAN_AC  tcp  --  anywhere             anywhere            
delegate_prerouting  all  --  anywhere             anywhere     

#NAT table的 OUTPUT链
Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         
SS_SPEC_WAN_AC  tcp  --  anywhere             anywhere    

Chain SS_SPEC_LAN_AC (1 references)
target     prot opt source               destination         
#### 如果源地址在局域网内要放过的ip段集合ss_spec_lan_bp里,则直接访问
RETURN     all  --  anywhere             anywhere             match-set ss_spec_lan_bp src
#### 如果源地址在局域网内要转发的ip段集合ss_spec_lan_fw里,则直接使用规则SS_SPEC_WAN_FW
SS_SPEC_WAN_FW  all  --  anywhere             anywhere             match-set ss_spec_lan_fw src
#### 其他情况则使用规则SS_SPEC_WAN_AC
SS_SPEC_WAN_AC  all  --  anywhere             anywhere             match-set ss_spec_lan_no src
SS_SPEC_WAN_AC  all  --  anywhere             anywhere            

#####  外网访问控制规则链条
Chain SS_SPEC_WAN_AC (3 references)
target     prot opt source               destination         
##### 如果目标地址在要转发的ip段集合里ss_spec_wan_fw就使用规则链SS_SPEC_WAN_FW
SS_SPEC_WAN_FW  all  --  anywhere             anywhere             match-set ss_spec_wan_fw dst
##### 如果目标地址在要直连的ip段集合里ss_spec_wan_bp就直接访问
RETURN     all  --  anywhere             anywhere             match-set ss_spec_wan_bp dst
##### 其他情况 则应用规则链SS_SPEC_WAN_FW
SS_SPEC_WAN_FW  all  --  anywhere             anywhere            

####  外网转发控制规则链条
Chain SS_SPEC_WAN_FW (3 references)
target     prot opt source               destination         
#####  如果是局域网或者是shadowsocks服务器,则直接访问
RETURN     all  --  anywhere             anywhere             match-set ss_spec_wan_sp dst
##### 其他地址的访问则转发到1080端口
REDIRECT   tcp  --  anywhere             anywhere             redir ports 1080

通过看上述iptables我们现在就可以知道转发的原理了。

遇到问题时如何定位

  1. 首先使用dig或者nslookup确定dns解析是否有问题,如:

    nslookup www.google.com.hk 192.168.1.1  
    

    dig命令更强大,可以指定dns服务器的ip,端口和协议,通过这些命令可以定位chinadns是否能正常工作,也可以确定它是否使用了我们为它设置的上游服务器,以及它是否能为整个局域网提供dns服务

  2. shadowsocks转发问题

    在路由器和服务器可以通过ps命令查看ss-redir命令的详细参数,可以干掉配置时自动启动的shadowsocks进程,然后再根据命令参数手动执行ss-redir命令和ss-server进程,注意不要添加-f参数,不然会以daemon形式运行,执行ss-redir命令时添加-v参数,这样在路由器和服务器上都可以看到详细的请求记录,我们就知道到底哪个环节出了问题

折腾过程中遇到的那些坑

  1. postinst script returned status 127 或者 prerm script returned status 127

    因为低版本的openwrt固件的/lib/functions.sh缺少这两个函数 postinst prerm,必须选择正确的openwrt版本

  2. ash chinadns not found 或者 ash shadowsocks not found

    这是因为使用的openwrt固件版本是snapshot版本,最新的openwrt固件去掉了libUclib.so,所以导致无法启动chinadns和shadowsocks,必须选择正确的openwrt版本

  3. 安装shadowsocks后缺少脚本/etc/init.d/shadowsocks脚本

    必须选择正确的shadowsocks版本,spec版本的shadowsocks才会携带/etc/init.d/shadowsocks脚本,也才能与luci-app-shadowsocks兼容

  4. getpeername transport endpoint is not connected

    因为shadowsocks没有开启fastopen, 若要开启fastopen,要求linux内核必须是3.7.0以上,所以我的VPS重装了centos,并且升级到6.8,然后再升级了内核, 可参考 使用Yum快速更新升级CentOS内核

总结

要想让路由器科学上网,选择openwrt,shadowsocks,chinadns,luci-app-chinadns,luci-app-shadowsocks时一定要选择相互兼容的版本,否则非常麻烦。

本次折腾过程中,学习到了路由器翻墙原理,简单总结翻墙原理如下所示:

通过chinadns将域名解析到正确的ip,如果是国外ip则走shadowosocks隧道去访问,如果是国内ip则直接访问,这是通过操作iptables实现的。

为了区分ip是国内的还是国外的,我们需要为chinadns和shadowsocks提供中国ip段集合的列表,在操作iptable时,需要使用ipset管理大量ip地址段

参考资料

使用Yum快速更新升级CentOS内核
Shadowsocks + ChnRoute 实现 OpenWRT 路由器自动翻墙
CentOS下shadowsocks-libev一键安装脚本

身处墙内的我们,大多数时候并不是为了看一些政治方面的东西,只是想畅快的享受自由网络而已,能够自由地学习技术而已。本篇讲述如何让家中的路由器科学上网,这样家中的电脑,手机,ipad等设备都能畅快上网,再也不用担心浏览网页时,浏览器突然告诉你连接已中断,或者装个浏览器插件时,浏览器告诉你安装失败,一看原因说是image decode failed。另外,参考本方案可以让你搭建翻墙环境时少遇一些坑。
作者:Cloud Chou's Tech Blog
原文地址:如何让路由器科学上网, 感谢原作者分享。

发表评论