如何让路由器***

时间:2022-11-03 04:49:34

如何让路由器***

 

原文:http://www.cloudchou.com/work/post-983.html


本篇讲述如何让家中的路由器***,参考本方案可以让你搭建FQ环境时少遇一些坑。最终可以实现家中的电脑,手机,ipad等设备都能畅快上网。

背景

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

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

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

准备工作

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

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

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

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

  2. 准备*服务器

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

    https://teddysun.com/357.html

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

    1
    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内核

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

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

    如果没有国外VPS的话,那么也没必要为了FQ去买一个国外的VPS,直接买*服务,更划算。 可以在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, 这样FQ时遇到这些ip就会直接连接,不走FQ线路:

    1
    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等依赖软件

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

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

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

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

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

    https://sourceforge.net/projects/openwrt-dist/files/*-libev/2.4.8-8816fa1/ar71xx/*-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-*的下载地址是:

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

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

    https://sourceforge.net/projects/openwrt-dist/files/luci-app/*-spec/luci-app-*-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. 开启*和chinadns

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

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

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

    如何让路由器***

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

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

    如何让路由器***

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

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

    如何让路由器***

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

    如何让路由器***

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

    如何让路由器***

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

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

    如何让路由器***

    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,其实这个是在*里配置的Dns转发服务,实际上会转发到Shadows Socks服务器,然后再转发到*服务器最近的Dns服务器进行Dns解析

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

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

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

    如何让路由器***

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

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

    如何让路由器***

  9. 测试

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

FQ原理

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

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

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

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

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

1
ipset -L

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

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

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

1
iptables -t nat --list

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#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         
#####  如果是局域网或者是*服务器,则直接访问
RETURN     all  --  anywhere             anywhere             match-set ss_spec_wan_sp dst
##### 其他地址的访问则转发到1080端口
REDIRECT   tcp  --  anywhere             anywhere             redir ports 1080

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

遇到问题时如何定位

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

    1
    nslookup www.google.com.hk 192.168.1.1  
    

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

  2. *转发问题

    在路由器和服务器可以通过ps命令查看ss-redir命令的详细参数,可以干掉配置时自动启动的*进程,然后再根据命令参数手动执行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 * not found

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

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

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

  4. getpeername transport endpoint is not connected

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

总结

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

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

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

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

参考资料

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