翻墙路由器的原理与实现(10)_掘图志

返回首页
当前位置: 主页 > 路由器设置 >

翻墙路由器的原理与实现(10)

时间:2016-02-01 13:38点击:

   subprocess.call('iptables -D INPUT -p icmp -m icmp --icmp-type 11 -j QUEUE', shell=True)      

   

signal.signal(signal.SIGINT, clean_up)      

   

try:  

   subprocess.call('iptables -I INPUT -p icmp -m icmp --icmp-type 11 -j QUEUE', shell=True)  

   subprocess.call('iptables -I INPUT -p udp --src %s -j QUEUE' % DNS_IP, shell=True)  

   subprocess.call('iptables -I OUTPUT -p udp --dst %s -j QUEUE' % DNS_IP, shell=True)  

   print('running..')  

   nfqueue.run()  

except KeyboardInterrupt:  

   print('bye') 

执行 dig +tries=30 +time=1 @8.8.8.8 twitter.com 可以得到类似下面的输出:

=== 隐去 ===
=== 隐去 ===
=== 隐去 ===
219.158.100.166
219.158.11.150
* 219.158.97.30
* * 219.158.27.30
* 72.14.215.130
* 209.85.248.60
* 216.239.43.19
* * END

出现*号前面的那个IP就是挂了GFW的路由了。脚本只能执行一次,第二次需要重启。另外同一个DNS不能被同时查询,把8.8.8.8改成你没有在用的DNS。这个脚本的一个“副作用”就是dig返回的答案是正确的了,因为错误的答案被丢弃了。

反向观测

前面我们已经知道从国内请求国外的DNS服务器大体是怎么一个被劫持的过程了。接下来我们在国内搭建一个服务器,从国外往国内发请求,看看是不是可以观测到被劫持的现象。

把路由器的WAN口的防火墙打开。配置本地的dnsmasq为使用非标准端口代理查询从而保证本地做dig查询的时候可以拿到正确的结果。然后在国外的服务器上执行

dig @国内路由器ip twitter.com

可以看到收到的答案是错误的。执行前面的路由跟踪代码,结果如下:

=== 隐去 === === 隐去 === === 隐去 === 115.160.187.13 213.248.76.73 219.158.33.181 219.158.29.129 219.158.19.165 * 219.158.96.225 * * * 219.158.101.233 END

可以看到不但有DNS劫持,而且DNS劫持发生在非常靠近国内路由器的位置。这也证实了论文中提出的观测结果。GFW并没有严格地部署在出国境前第一跳的位置,而是更加靠前。并且是双向的,至少DNS劫持是双向经过实验证实了。

通过避免GFW重建请求反DNS劫持

使用非标准端口

这个实验就非常简单了。使用53之外的端口查询DNS,观测是否有错误答案被返回。

dig @208.67.222.222 -p 5353 twitter.com

使用的DNS服务器是OpenDNS,端口为5353端口。使用非标准端口的DNS服务器不多,并不是所有的DNS服务器都会提供非标准端口供查询。结果如下:

; <<>> DiG 9.9.1-P3 <<>> @208.67.222.222 -p 5353 twitter.com
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 5367
;; flags: qr rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 8192
;; QUESTION SECTION:
;twitter.com. IN A
;; ANSWER SECTION:
twitter.com. 5 IN A 199.59.150.39
twitter.com. 5 IN A 199.59.148.82
twitter.com. 5 IN A 199.59.148.10
;; Query time: 194 msec
;; SERVER: 208.67.222.222#5353(208.67.222.222)
;; WHEN: Mon Jan 14 11:47:46 2013
;; MSG SIZE rcvd: 88

可见,非标准端口还是可以得到正确结果的。但是这种穿墙并不能被应用程序直接使用,因为几乎所有的应用程序都不支持使用非标准端口查询。有很多种办法把端口变成53端口能用。

使用本地DNS服务器转发(dnsmasq,pdnsd)

用NetfilterQueue改写IP包

用iptables改写IP包:iptables -t nat -I OUTPUT --dst 208.67.222.222 -p udp --dport 53 -j DNAT --to-destination 208.67.222.222:5353

使用TCP查询

这个实验就更加简单了,也是一条命令:

dig +tcp @8.8.8.8 twitter.com

GFW在日常是不屏蔽TCP的DNS查询的,所以可以得到正确的结果。但是和非标准端口一样,几乎所有的应用程序都不支持使用TCP查询。已知的TCP转UDP方式是使用pdnsd或者unbound转(?m=1)。

但是GFW现在不屏蔽TCP的DNS查询并不代表GFW不能这么干。做一个小实验:

root@OpenWrt:~# dig +tcp @8.8.8.8 dl.dropbox.com ;; communications error to 8.8.8.8#53: connection reset

可以看到GFW是能够知道你在查询什么的。与HTTP关键字过滤一样,一旦发现查询的内容不恰当,立马就发RST包过来切断连接。那么为什么GFW不审查所有的TCP的DNS查询呢?原因很简单,用TCP查询的绝对少数,尚不值得这么去干。而且就算你能查询到正确域名,GFW自认为还有HTTP关键字过滤和封IP等后着守着呢,犯不着在DNS上卡这么死。

使用单向代理

严格来说单向代理并不是穿墙,因为它仍然需要在国外有一个代理服务器。使用代理服务器把DNS查询发出去,但是DNS查询并不经由代理服务器而是直接发回客户端。这样的实现在目前有更好的反劫持的手段(比如非标准端口)的情况下并不是一个有实际意义的做法。但是对于观测GFW的封锁机制还是有帮助的。据报道在敏感时期,对DNS不仅仅是劫持,而是直接丢包。通过单向代理可以观测丢包是针对出境流量的还是入境流量的。

客户端需要使用iptables把DNS请求转给NetfilterQueue,然后用python代码把DNS请求包装之后发给中转代理。对于应用程序来说,这个包装的过程是透明的,它仍然认为请求是直接发给DNS服务器的。

客户端代码如下,名字叫smuggler.py(https://gist.github.com/4531012):

from netfilterqueue import NetfilterQueue  

import subprocess  

import signal  

import traceback  

import socket      

   

IMPERSONATOR_IP = 'x.x.x.x' 

IMPERSONATOR_PORT = 19840     

   

udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)      

   

def smuggle_packet(nfqueue_element):  

   try:  

       original_packet = nfqueue_element.get_payload()  

       print('smuggled')  

       udp_socket.sendto(original_packet, (IMPERSONATOR_IP, IMPERSONATOR_PORT))  

       nfqueue_element.drop()  

   except:  

       traceback.print_exc()  

       nfqueue_element.accept()      

   

nfqueue = NetfilterQueue()  

nfqueue.bind(0, smuggle_packet)      

   

def clean_up(*args):  

------分隔线----------------------------
推荐内容