近日适逢某平方节日,Google国外网站陆续出现被墙的状况,想必大家都是知道的。

其实本人一直在使用SSH的Socket代理功能爬梯子,效果还是不错的,加上学校有原生IPv6支持,就算不走代理一般也能上各大网站。唯独有一点,不论是浏览器还是操作系统,DNS均使用了UDP协议,而UDP显然是无法走Socket代理的,所以对于Youtube、Facebook这些网站由于域名解析问题,仍旧无法访问。

不过,事情总有解决的办法。

由于习惯于使用UDP协议的DNS,很多人不知道其实DNS也是支持TCP协议的,功夫网只对UDP的DNS进行了劫持和污染,TCP DNS则可畅通无阻。

唯一的问题就是,浏览器、操作系统等都无法直接使用TCP DNS,我前一段时间一直在使用Tcp-DNS-proxy解决这个问题。这是一个基于Python的小程序,可以通过TCP连接DNS服务器,并在本地监听UDP53端口,实现TCP DNS的中转,程序简单运行方便,比较推荐。

不过Tcp-DNS-proxy本身也存在着一些问题,比如没有完整的缓存机制,导致查询速度较慢,程序稳定性和抗并发性一般。于是我考虑能否有更加稳定的解决方案?

最终还是选定了BIND这一老牌的DNS服务器,利用forward功能可以比较容易的实现对DNS的转发。Ubuntu 14.04下修改配置如下:

/etc/bind/named.conf.options
...
options {
directory "/var/cache/bind";
// If there is a firewall between you and nameservers you want
// to talk to, you may need to fix the firewall to allow multiple
// ports to talk. See http://www.kb.cert.org/vuls/id/800113
// If your ISP provided one or more IP addresses for stable
// nameservers, you probably want to use them as forwarders.
// Uncomment the following block, and insert the addresses replacing
// the all-0's placeholder.
forward only;
forwarders {
8.8.8.8;
8.8.4.4;
};
allow-query {
any;
};
//========================================================================
// If BIND logs error messages about the root key being expired,
// you will need to update your keys. See https://www.isc.org/bind-keys
//========================================================================
dnssec-validation auto;
auth-nxdomain no; # conform to RFC1035
listen-on-v6 { any; };
};
...

仅仅这样是不够的,我们需要的是TCP DNS转发(代理),但经过测试BIND会首选UDP解析进行递归查询,经过搜索Google、查看官方文档、查看源代码,我发现从配置上修改这条路是行不通的。

没有办法,只能动手改源代码了。不过还好,最近嵌入式课程实验我尝试把NginX移植到了ARM平台上,对于裁剪代码还是有心理准备的。

经过几个小时的努力,翻看了几个重要的.c文件,最终我确定了BIND9(这里选用bind-9.10.0-P1)发出查询的函数,是位于lib/dns/resolver.c文件第1403行的fctx_query函数,节选其中1446至1451行如下:

  1.     query->mctx = fctx->mctx;
  2.     query->options = options;
  3.     query->attributes = 0;
  4.     query->sends = 0;
  5.     query->connects = 0;
  6.     query->dscp = addrinfo->dscp;

其中query->options = options;这一行中options利用位运算存储了是否使用TCP连接的变量DNS_FETCHOPT_TCP,我们需要做的就是将这一行改为:

  1. query->options = options | DNS_FETCHOPT_TCP;

强制让BIND使用TCP进行递归查询。之后进行编译,覆盖二进制文件即可,在此就不再赘述。效果如下:

可以看到,第1、36报文是客户端查询BIND服务器,为UDP协议;其他报文为BIND查询8.8.8.8,为TCP报文(颜色不同)。

修改BIND9实现TCP DNS的更多相关文章

  1. CentOS 网络设置修改 指定IP地址 DNS 网关(转)

    CentOS 网络设置修改 指定IP地址 DNS 网关(实测 笔记)   环境: 系统硬件:vmware vsphere (CPU:2*4核,内存2G) 系统版本:Centos-6.5-x86_64 ...

  2. 修改linux系统TCP连接数

    修改linux系统TCP连接数 centOS 6.x (1)vi /etc/sysctl.conf (2)添加参数 net.nf_conntrack_max = 655360 (3)sysctl -p ...

  3. 【点滴积累,厚积薄发】修改hosts,并刷新dns缓存

    Windows系统下hosts位置 C:\Windows\System32\drivers\etc 修改hosts后,要想马上生效,需要运行命令来刷新DNS缓存:ipconfig /flushdns

  4. ubuntu 修改静态IP和DNS

    1.修改配置文件/etc/network/interfacesroot@ubuntu:~# sudo vi /etc/network/interfaces 添加以下内容:auto eth0       ...

  5. Linux下修改网卡IP、DNS和网关

    Linux下修改网卡IP和网关 建议通过终端字符方式下来修改 一.修改IP地址 vi /etc/sysconfig/network-scripts/ifcfg-eth0 DEVICE=eth0 BOO ...

  6. CentOS 6 网络设置修改 指定IP地址 DNS 网关

    环境: 系统硬件:vmware vsphere (CPU:2*4核,内存2G) 系统版本:Centos-6.5-x86_64 路由器网关:192.168.1.1 步骤: 1.查看网络MAC地址 [ro ...

  7. 通过JAVA反射修改JDK1.6*当中DNS缓存内容

    时间 2012-05-28 17:09:03  Taobao QA Team原文  http://qa.taobao.com/?p=15523 为了实现性能压测时的域名动态绑定功能,尝试通过java反 ...

  8. 注册表修改IP地址和DNS等信息

    ---------------------win8系统 1. 2. 3. --------------------------------------------------------------- ...

  9. centos7 修改静态ip 和dns

    1.修改对应网卡的IP地址的配置文件# vi /etc/sysconfig/network-scripts/ifcfg-eth0 DEVICE=eth0 #描述网卡对应的设备别名,例如ifcfg-et ...

随机推荐

  1. Mysql 声明变量

    Mysql 声明变量 Mysql中声明变量有两种方式 第一种: set @num=1; 或set @num:=1; //这里要使用变量来保存数据,直接使用@num变量 第二种: select @num ...

  2. apk安全测试思路

    一: apk安全测试 对于一款android的apk程序,主要进行的测试分两部分: 1) 接口测试 ---接口测试实际上是常见的web安全测试 2) android组件测试 --组件测试实际上是and ...

  3. Android入门笔记(重制版)

    Android项目的目录结构(Eclipse版) src:项目源代码文件夹 R.java:存放项目中所有资源文件的资源id,永远不要修改 Android.jar:Android的jar包,导入此包方可 ...

  4. 批量修改sql server 2008的架构

    --批量修改架构.名称为XJADMINATT的所有表修改为dbo-- --把执行的结果,拷贝到命令行,执行命令即可-- declare @name sysname declare csr1 curso ...

  5. C#中的using关键字用法总结

    C#中的using关键字主要有两种用法: 1.using作为指令: (1)用于将命名空间引入当前单元,例如:using System.Windows.Forms; (2)为现有的命名空间创建一个别名, ...

  6. EL总结

    El: 1.el表达式语言(是什么) 2.el是书写到jsp页面 3.el语法格式${ } 4.el算数运算(+,-,*,/,%), 逻辑运算(&&,||,!), 关系运算(>, ...

  7. DHTMLX-第一弹

    DHTMLX 半年前结束了漂泊的工作生活回到了公司,跟着团队开发新产品.忙碌起来就很少有时间静下来好好写点东西.公司既然要开发新的产品当然也会接触一些新的东西,也会面临新的挑战.接下来就将项目前端所用 ...

  8. phpmyadmin的root密码忘记了怎么办?

    管理mysql数据库的工具有网页版的phpmyadmin(开源),也有诸如客户端Navicat for MySQL(商业). 好多环境集成包,比如XAMPP.WampServer等集成了phpmyad ...

  9. C#开发分享:如何改变系统鼠标样式

    开发过程中发现需要用到改变鼠标样式(就是光标的样子),但是在网上找了很多资料,都是介绍在程序中使用,我需要的效果时在系统级使用.现在找到了,分享给大家. [DllImport("user32 ...

  10. iOS开发项目之MVC与MVVM

    MVC MVC,Model-View-Controller,我们从这个古老而经典的设计模式入手.采用 MVC 这个架构的最大的优点在于其概念简单,易于理解,几乎任何一个程序员都会有所了解,几乎每一所计 ...