使用ipfilter过滤GFW滴DNS污染喵~

嗯嗯,最原始文档请参考AutoVPN上滴 这篇文章 喵~

咱将其原始脚本修订了一些,并添加了 OpenWRT滴正确使用姿势喵~

一、OpenWRT的准备工作

普通Linux用户可以直接跳过这一节,因为大多数发行版已经安装了这些必要的软件包了喵~

opkg update opkg install iptables-mod-filter bind-dig 

二、脚本本体及注释

#!/bin/ash  #这行是用一个不存在的域名解析来钓出强制跳转地址  NONEXISTDOMAIN="non.exist.domain.cn"  #这行写入一些会被污染的域名 POSIONEDDOMAIN="www.twitter.com www.facebook.com www.youtube.com plus.google.com"  #下面这行写入本地的DNS地址,即被污染的DNS服务地址 WALLSERVER="61.139.2.69" LOOPTIMES=9  badip=""  #钓出非法域名强制跳转地址  for DOMAIN in $NONEXISTDOMAIN ; do for IP in $(dig $DOMAIN +time=1 +tries=1 +retry=0 | grep ^$DOMAIN | grep -o -E "([0-9]+\.){3}[0-9]+") ; do if [ -z "$(echo $badip | grep $IP)" ] ; then badip="$badip $IP" fi done done  echo First Step: $badip  #钓出污染的IP地址(GFW反馈的)  for i in $(seq $LOOPTIMES) ; do for DOMAIN in $POSIONEDDOMAIN ; do for IP in $(dig @$WALLSERVER $DOMAIN +time=1 +tries=1 +retry=0 | grep ^$DOMAIN | grep -o -E "([0-9]+\.){3}[0-9]+") ; do if [ -z "$(echo $badip | grep $IP)" ] ; then badip="$badip $IP" echo $IP $DOMAIN fi done done done  echo Second Step: $badip  #将这些地址在 Firewall里面过滤掉 for IP in $badip do hexip=$(printf '%02X ' ${IP//./ }; echo) # echo $hexip iptables -I INPUT -p udp --sport 53 -m string --algo bm --hex-string "|$hexip|" --from 60 --to 180 -j DROP iptables -I FORWARD -p udp --sport 53 -m string --algo bm --hex-string "|$hexip|" --from 60 --to 180 -j DROP done 

三、原理介绍

因为DNS是使用UDP数据包进行发送的,正常的查询如下:

PC 查询域名 -查询UDP包-> 网关 -查询UDP包-> DNS服务器 -返回UDP包-> 网关 -返回UDP包-> PC结束查询

被GFW污染之后,GFW抢先在DNS服务器正确包到达之前返回被污染结果:

PC 查询域名 -查询UDP包-> 网关(路由旁路触发GFW) -查询UDP包-> DNS服务器 -返回UDP包-> (GFW抢先返回)网关 -GFW返回UDP包-> PC结束查询 -正确的UDP包-> 被遗弃

但是GFW只能固定返回几个IP(返回正确IP风险很高,比如暴风上次导致的故障),所以只要找到这几个IP,加以过滤,则能够将GFW抢答的包在防火墙上设置无效丢包即可,正确的包就会在稍加等待后返回。

原文:http://kouga.us/?p=642724

发表评论