https://github.com/lifetyper/FreeRouter_V2/blob/master/FreeRouterV2_HandBook.pdf?raw=true,里面提到了GFW的工作方式和FreeRouter_V2的技术原理,非常值得一读。
-------------------------------
FreeRouter V2调试中的几个Dnsmasq问题和更新
刚开始搞FreeRouter V2的时候,一切都很顺利,就是没搞明白为什么有的路由器上防火墙命令可以单独写在/etc/firewall.user里,有些就只能一次性的和别的启动命令一起写入/etc/rc.local里面,当时的初步感觉是某些路由的防火墙启动有问题,没想到今天这个问题在处理另一个问题的时候意外找到了原因.
因为前两天有人在github上提交了一个issue,我看了一下是很明显的DNS污染问题,不过他说是看我wiki以为只需要给VPN设置Google的DNS,WAN接口的不需要管…..这,反正我没说过这种话.不管怎么样,我想是不是有什么办法可以绕过WAN或者VPN接口的设置,不管在什么环境下让Dnsmasq都只默认使用Google DNS,所以,只好重新读了一遍Dnsmasq的Man Page-
http://www.thekelleys.org.uk/dnsmasq/docs/dnsmasq-man.html
Dnsmasq几乎是整个FreeRouter V2的核心构成,关于它的内容必须很仔细的了解.从Man Page中我大概了解了Dnsmasq是如何设定DNS服务器的:
1.默认有一个–resolv-file=<file>的参数,这里的file一般是一个*.conf解析文件(格式不重要,内容才重要),这个*.conf解析文件里应该通过nameserver 参数告知Dnsmasq DNS服务器的IP.
nameserver 8.8.8.8
nameserver 4.2.2.4
2.如果你启用了–no-resolv参数,Dnsmasq就不会去通过读任何文件来找DNS服务器,你必须在Dnsmasq的配置文件中通过server命令指定DNS的IP.
server=//8.8.8.8
server=/taobao.com/114.114.114.114
3.如果没有–no-resolv参数,也没有–resolve-file参数,Dnsmasq默认会去读/etc/resolv.conf这个文件抓取DNS服务器的IP,所以其实–refolv-file是默认启用了一个参数,只是你可以修改为别的解析文件而已.
4.OpenWRT中,默认在/etc/config/dhcp文件中,配置了–resolv-file参数,这个参数的值一般是:
resolv-file=/tmp/resolv.conf.auto
这个resolv.conf.auto,是当一个网络接口启用后,如果被配置了DNS,或者被配置了使用通告DNS(上级网络通过DHCP通告给下级设备的DNS,Dnsmasq也可以做到),就会把这个DNS写入/tmp/resolv.conf.auto文件中,所以如果你同时在WAN和VPN都设置了DNS,那么这两个接口的DNS都会在接口连接上之后被写入/tmp/resolv.conf.auto中,然后Dnsmasq会把这些DNS都抓过来作为默认的DNS,即使两个接口的DNS是一样的.
所以在logread查看系统记录的时候,你可能会看到Dnsmasq设置了两次同样的DNS,这就分别是WAN和VPN接口自动传入的DNS设置.
5.所以我们要做的,就是修改/etc/config/dhcp中的resolv-file配置,把他修改为:
option resolvfile '/etc/resolv.conf'
然后删除/etc/resolv.conf文件(因为这其实默认是一个/tmp/resolv.conf的symbol link,删除后才能建立独立的文件),重建一个/etc/resolv.conf文件,写入我们要用的DNS服务器IP:
#Google DNS
nameserver 8.8.8.8
nameserver 8.8.4.4
#Nortorn DNS
nameserver 199.85.127.20
nameserver 199.85.126.20
#Comodo DNS
nameserver 8.26.56.26
nameserver 8.20.247.20
#DNS Advantage
nameserver 156.154.70.1
nameserver 156.154.71.1
#Verizon DNS
nameserver 4.2.2.4
nameserver 4.2.2.6
#NTT DNS
nameserver 129.250.35.250
nameserver 129.250.35.251
这里我们把所知道的所有支持DNSSEC的公共服务器都写进去,这些都会起作用的,为什么写这么多看下面.
6.如果你的网络环境经常变化,那么不同的DNS速度可能差非常多,有没有办法让Dnsmasq自动找最快的DNS呢?通过Dnsmasq的–all-servers参数就可以.
–all-servers参数启用后,Dnsmasq会对所有配置好的DNS服务器发起解析请求,并使用最快返回的那个结果给客户端,这完全就是我们所期望的.不过要注意的是,其实在VPN启动后,Free Router的VPNUP脚本默认会把所有配置的DNS服务器加入VPN路由表里面,保证DNS解析走VPN通道,这样可能你到DNS服务器的速度可能看起来差不过,基本都取决于你到VPN的速度.但是在VPN断线后,这个选项的作用就很明显了,例如我这里的联通网络,在没有VPN的情况下Google DNS的延时高达400毫秒,而UltraDNS才90毫秒,体验就完全不同了.
注意,如果你在路由上用Dig命令查域名的话,默认可能还是以第一个DNS查询,并不会做最优选择,因为路由上Dig命令的实行并不受Dnsmasq的管控和优化.但在路由后面接的设备上,用dig命令查询就可以明显看出区别.
Update:如果你的整个DNS系统中最终使用到了被污染的国内DNS,最好不要使用这个选项.我测试下来发现:在启用了DNSSEC的服务器签名检查之后,如果twitter.com这样的域名因为验证失败近而导致解析结果被丢弃的话,Dnsmasq似乎在某些时候会接受114这类DNS返回的未签名的数据,这个参数和dnssec的检查参数似乎会有冲突,不知道是不是bug.
7.前面提到我碰到了一个问题,这个问题就是我在Buffalo的路由上设置的好好的resolv.conf配置,在WNDR3800上面就报错,查logread显示Dnsmasq无法读取/etc/resolv.conf文件:
failed to access /tmp/resolv.conf.auto: Permission Denied
搜了一下,发现是/etc目录的权限属性要设置成755才行,否则默认/etc目录下的文件只有root才有权限读取,而Dnsmasq本身读取的时候并没有root权限.其实默认这个属性是对的,只是我以前从windows把配置文件传入虚拟机里面的时候造成了属性的修改,全变成了644,打包固件的时候这个属性也就跟着被修改了.只要把/etc目录的权限属性改回755就可以正常读取了.
8.这个问题一解决,就让我想到了最上面提到的防火墙问题,以前WNDR3800的防火墙命令写入/etc/firewall.user里就不能执行会不会也是一样的原因?把rc.local里的防火墙命令全部剥离出来,修改好/etc目录的权限后,重启.发现这次防火墙命令放在firewall.user下也可以正常执行了.而且,这其实才是防火墙命令正确的放置位置,否则每次防火墙重启(虽然几乎没人故意重启路由防火墙),防火墙规则都要丢失,需要通过重启来还原防火墙规则是不正确的做法.
9.不过这样做了之后,我发现不能翻墙了,检查了一下,原来是第一条把vpn IPSET的IP全部添加fwmark的命令没有被执行.想了想有没有可能是防火墙的启动其实先于了rc.local里创建ipset的命令?在两个地方分别写入时间log,看了下果然如此:
firewall rule @Wed Jul 9 21:05:33 CST 2014
ipset create @Wed Jul 9 21:05:39 CST 2014
VPN UP @21:05:40@2014-07-0
可以看到防火墙的规则在ipset创建前6秒就开始了,在ipset都没有建立的情况下,对应这个ipset的防火墙规则当然会无效.
解决思路有几个:
A.把防火墙命令移回rc.local文件,虽然防火墙实际上极少重启,但这是原则问题…..不考虑
B.在执行那条防火墙命令前先判断一下ipset是否存在,不存在就等待,IPSET好像没有专门判断一个IPSET是否存在的选项,其他途径倒是可以,不简洁.
C.把ipset的创建也一起放进firewall.user.这是最终采用的方法,本来想先destroy再create,不过会提示IPSET被内核模块使用无法摧毁,只能改成每次都创建,但加入-exist参数,如果IPSET已经存在就忽略创建,所以即使防火墙重启,IPSET还是只会被创建一次,而防火墙规则可以正常重启不丢失:
pset create vpn iphash -exist
在这个正确的方法下,FreeRouter V2越来越难用直接提供配置文件覆盖的方法来实现了,dhcp的覆盖就很麻烦,不同设备可能有不同的默认配置,直接覆盖可能有不良后果,最好是自己修改要改的部分.至于resolv.conf这个的修改,移除symbol link的过程就不是单纯的覆盖了,不过总体来说难度还是很低的,因为Dnsmasq的重编译其实已经不需要,用Dnsmasq-full替代即可了.
总的来说,防火墙是个很细致的工作,它在很多地方用很多途径阻碍你,所以你要应对的东西也很多,要传播翻墙路由的话,最好还是把原理和方法都详细的写清楚,否则即使是定制路由固件也会有麻烦.例如前两天给同学送的翻墙路由就反馈说在家里不能用在公司可以用,一方面是家里的网络是要拨号的,定制固件你还不可能做到连PPP账号密码都打包进去,另一方面碰到不同网络还要能自动切换到DHCP或者静态IP协议也够呛.
所以,刚好可以重新捡一下5年前学过一点点的latex,试着用latex写一本翻墙路由的原理和方法的小手册,github那糟糕透顶的mark down格式wiki,光换行问题都快我把折腾死了,换行竟然要手工空两格,纯蛋疼.
提到latex,顺便又更新了一下WinEdt的License,没想到版本号已经从5.4升到8.2了,时光飞逝啊.SlickEdit这种土豪专用的东西,购买+升级+维护已经花了我618美元了,反正我现在已经基本改用VIM,续费装这种事还是留给真土豪去干吧,而且听说他们因为专利问题打官司都没工夫更新了,说不定等他们更新都是N年后的事,N>=3的话,维护费就没什么意思了.
from http://www.lifetyper.com/2014/07/some-tips-for-dnsmasq-during-free-router-v2-debug.html
----------------
-------------------------------
FreeRouter V2调试中的几个Dnsmasq问题和更新
刚开始搞FreeRouter V2的时候,一切都很顺利,就是没搞明白为什么有的路由器上防火墙命令可以单独写在/etc/firewall.user里,有些就只能一次性的和别的启动命令一起写入/etc/rc.local里面,当时的初步感觉是某些路由的防火墙启动有问题,没想到今天这个问题在处理另一个问题的时候意外找到了原因.
因为前两天有人在github上提交了一个issue,我看了一下是很明显的DNS污染问题,不过他说是看我wiki以为只需要给VPN设置Google的DNS,WAN接口的不需要管…..这,反正我没说过这种话.不管怎么样,我想是不是有什么办法可以绕过WAN或者VPN接口的设置,不管在什么环境下让Dnsmasq都只默认使用Google DNS,所以,只好重新读了一遍Dnsmasq的Man Page-
http://www.thekelleys.org.uk/dnsmasq/docs/dnsmasq-man.html
Dnsmasq几乎是整个FreeRouter V2的核心构成,关于它的内容必须很仔细的了解.从Man Page中我大概了解了Dnsmasq是如何设定DNS服务器的:
1.默认有一个–resolv-file=<file>的参数,这里的file一般是一个*.conf解析文件(格式不重要,内容才重要),这个*.conf解析文件里应该通过nameserver 参数告知Dnsmasq DNS服务器的IP.
nameserver 8.8.8.8
nameserver 4.2.2.4
2.如果你启用了–no-resolv参数,Dnsmasq就不会去通过读任何文件来找DNS服务器,你必须在Dnsmasq的配置文件中通过server命令指定DNS的IP.
server=//8.8.8.8
server=/taobao.com/114.114.114.114
3.如果没有–no-resolv参数,也没有–resolve-file参数,Dnsmasq默认会去读/etc/resolv.conf这个文件抓取DNS服务器的IP,所以其实–refolv-file是默认启用了一个参数,只是你可以修改为别的解析文件而已.
4.OpenWRT中,默认在/etc/config/dhcp文件中,配置了–resolv-file参数,这个参数的值一般是:
resolv-file=/tmp/resolv.conf.auto
这个resolv.conf.auto,是当一个网络接口启用后,如果被配置了DNS,或者被配置了使用通告DNS(上级网络通过DHCP通告给下级设备的DNS,Dnsmasq也可以做到),就会把这个DNS写入/tmp/resolv.conf.auto文件中,所以如果你同时在WAN和VPN都设置了DNS,那么这两个接口的DNS都会在接口连接上之后被写入/tmp/resolv.conf.auto中,然后Dnsmasq会把这些DNS都抓过来作为默认的DNS,即使两个接口的DNS是一样的.
所以在logread查看系统记录的时候,你可能会看到Dnsmasq设置了两次同样的DNS,这就分别是WAN和VPN接口自动传入的DNS设置.
5.所以我们要做的,就是修改/etc/config/dhcp中的resolv-file配置,把他修改为:
option resolvfile '/etc/resolv.conf'
然后删除/etc/resolv.conf文件(因为这其实默认是一个/tmp/resolv.conf的symbol link,删除后才能建立独立的文件),重建一个/etc/resolv.conf文件,写入我们要用的DNS服务器IP:
#Google DNS
nameserver 8.8.8.8
nameserver 8.8.4.4
#Nortorn DNS
nameserver 199.85.127.20
nameserver 199.85.126.20
#Comodo DNS
nameserver 8.26.56.26
nameserver 8.20.247.20
#DNS Advantage
nameserver 156.154.70.1
nameserver 156.154.71.1
#Verizon DNS
nameserver 4.2.2.4
nameserver 4.2.2.6
#NTT DNS
nameserver 129.250.35.250
nameserver 129.250.35.251
这里我们把所知道的所有支持DNSSEC的公共服务器都写进去,这些都会起作用的,为什么写这么多看下面.
6.如果你的网络环境经常变化,那么不同的DNS速度可能差非常多,有没有办法让Dnsmasq自动找最快的DNS呢?通过Dnsmasq的–all-servers参数就可以.
–all-servers参数启用后,Dnsmasq会对所有配置好的DNS服务器发起解析请求,并使用最快返回的那个结果给客户端,这完全就是我们所期望的.不过要注意的是,其实在VPN启动后,Free Router的VPNUP脚本默认会把所有配置的DNS服务器加入VPN路由表里面,保证DNS解析走VPN通道,这样可能你到DNS服务器的速度可能看起来差不过,基本都取决于你到VPN的速度.但是在VPN断线后,这个选项的作用就很明显了,例如我这里的联通网络,在没有VPN的情况下Google DNS的延时高达400毫秒,而UltraDNS才90毫秒,体验就完全不同了.
注意,如果你在路由上用Dig命令查域名的话,默认可能还是以第一个DNS查询,并不会做最优选择,因为路由上Dig命令的实行并不受Dnsmasq的管控和优化.但在路由后面接的设备上,用dig命令查询就可以明显看出区别.
Update:如果你的整个DNS系统中最终使用到了被污染的国内DNS,最好不要使用这个选项.我测试下来发现:在启用了DNSSEC的服务器签名检查之后,如果twitter.com这样的域名因为验证失败近而导致解析结果被丢弃的话,Dnsmasq似乎在某些时候会接受114这类DNS返回的未签名的数据,这个参数和dnssec的检查参数似乎会有冲突,不知道是不是bug.
7.前面提到我碰到了一个问题,这个问题就是我在Buffalo的路由上设置的好好的resolv.conf配置,在WNDR3800上面就报错,查logread显示Dnsmasq无法读取/etc/resolv.conf文件:
failed to access /tmp/resolv.conf.auto: Permission Denied
搜了一下,发现是/etc目录的权限属性要设置成755才行,否则默认/etc目录下的文件只有root才有权限读取,而Dnsmasq本身读取的时候并没有root权限.其实默认这个属性是对的,只是我以前从windows把配置文件传入虚拟机里面的时候造成了属性的修改,全变成了644,打包固件的时候这个属性也就跟着被修改了.只要把/etc目录的权限属性改回755就可以正常读取了.
8.这个问题一解决,就让我想到了最上面提到的防火墙问题,以前WNDR3800的防火墙命令写入/etc/firewall.user里就不能执行会不会也是一样的原因?把rc.local里的防火墙命令全部剥离出来,修改好/etc目录的权限后,重启.发现这次防火墙命令放在firewall.user下也可以正常执行了.而且,这其实才是防火墙命令正确的放置位置,否则每次防火墙重启(虽然几乎没人故意重启路由防火墙),防火墙规则都要丢失,需要通过重启来还原防火墙规则是不正确的做法.
9.不过这样做了之后,我发现不能翻墙了,检查了一下,原来是第一条把vpn IPSET的IP全部添加fwmark的命令没有被执行.想了想有没有可能是防火墙的启动其实先于了rc.local里创建ipset的命令?在两个地方分别写入时间log,看了下果然如此:
firewall rule @Wed Jul 9 21:05:33 CST 2014
ipset create @Wed Jul 9 21:05:39 CST 2014
VPN UP @21:05:40@2014-07-0
可以看到防火墙的规则在ipset创建前6秒就开始了,在ipset都没有建立的情况下,对应这个ipset的防火墙规则当然会无效.
解决思路有几个:
A.把防火墙命令移回rc.local文件,虽然防火墙实际上极少重启,但这是原则问题…..不考虑
B.在执行那条防火墙命令前先判断一下ipset是否存在,不存在就等待,IPSET好像没有专门判断一个IPSET是否存在的选项,其他途径倒是可以,不简洁.
C.把ipset的创建也一起放进firewall.user.这是最终采用的方法,本来想先destroy再create,不过会提示IPSET被内核模块使用无法摧毁,只能改成每次都创建,但加入-exist参数,如果IPSET已经存在就忽略创建,所以即使防火墙重启,IPSET还是只会被创建一次,而防火墙规则可以正常重启不丢失:
pset create vpn iphash -exist
在这个正确的方法下,FreeRouter V2越来越难用直接提供配置文件覆盖的方法来实现了,dhcp的覆盖就很麻烦,不同设备可能有不同的默认配置,直接覆盖可能有不良后果,最好是自己修改要改的部分.至于resolv.conf这个的修改,移除symbol link的过程就不是单纯的覆盖了,不过总体来说难度还是很低的,因为Dnsmasq的重编译其实已经不需要,用Dnsmasq-full替代即可了.
总的来说,防火墙是个很细致的工作,它在很多地方用很多途径阻碍你,所以你要应对的东西也很多,要传播翻墙路由的话,最好还是把原理和方法都详细的写清楚,否则即使是定制路由固件也会有麻烦.例如前两天给同学送的翻墙路由就反馈说在家里不能用在公司可以用,一方面是家里的网络是要拨号的,定制固件你还不可能做到连PPP账号密码都打包进去,另一方面碰到不同网络还要能自动切换到DHCP或者静态IP协议也够呛.
所以,刚好可以重新捡一下5年前学过一点点的latex,试着用latex写一本翻墙路由的原理和方法的小手册,github那糟糕透顶的mark down格式wiki,光换行问题都快我把折腾死了,换行竟然要手工空两格,纯蛋疼.
提到latex,顺便又更新了一下WinEdt的License,没想到版本号已经从5.4升到8.2了,时光飞逝啊.SlickEdit这种土豪专用的东西,购买+升级+维护已经花了我618美元了,反正我现在已经基本改用VIM,续费装这种事还是留给真土豪去干吧,而且听说他们因为专利问题打官司都没工夫更新了,说不定等他们更新都是N年后的事,N>=3的话,维护费就没什么意思了.
from http://www.lifetyper.com/2014/07/some-tips-for-dnsmasq-during-free-router-v2-debug.html
----------------
FreeRouter
V1已经基本停止更新!以后只维护V2版本的数据.
如果你的路由有官方的OpenWRT支持,或者没官方支持但你有能力自己给它编译固件,强烈建议你们看看V2版的FreeRouter项目,这个比V1好用多了.
from https://github.com/lifetyper/FreeRouter