提醒:本页面将不再更新、维护或者支持,文章、评论所叙述内容存在时效性,涉及技术细节或者软件使用方面不保证能够完全有效可操作,请谨慎参考!

部署DNSMASQ有一段时间了,最近发现一个奇怪现象,所有内网网站均无法解析,通过 nslookup 命令,得到如下结果:

Server:  192.168.24.6
Address:  223.5.5.5

*** No address (A) records available for oa.example.com

其中 oa.example.com 是内网域名,当然这里我只是举个例子:-) 域名管理员已经将该域名解析到一个私有内网地址上,外部DNS服务器均能正常解析这个域名,唯独部署了DNSMASQ的域名服务器无法解析。

开始时并没有介意,而是通过硬绑定的方式在DNSMASQ的配置文件中将内网地址映射到 oa.example.com ,配置方式如下:

address=/oa.example.com/192.168.25.4

这里 oa.example.com 是我们要映射的域名, 192.168.25.4 是我们要给该域名绑定的IP地址,值得注意的是当你做出这样的配置后,所有查询 oa.example.com 均不在走上游DNS服务器或者权威服务器,而是由DNSMASQ直接返回配置的应答,当然这个方法也可以用作屏蔽网站,只要把要屏蔽的网站映射到 127.0.0.1 即可。

某天域名管理员看到了这样的配置说到:如果我哪天更改了 oa.example.com 的服务器IP地址怎么办,毕竟你这个是硬性编码的,并不能和权威DNS服务器保持同步。域名管理员的话也有道理,虽然域名解析改动不频繁,但是每次改动也不可能及时通知并做出反应。

于是我开始寻找一个正确的解决这个问题的办法,功夫不负有心人我找到了这篇文章 《dnsmasq, Split DNS and the Dreaded “No address (A) records available” Error》

原来DNSMASQ有个的“Prevent DNS-rebind attacks”的安全配置,这个配置参数和描述如下:

–stop-dns-rebind Reject (and log) addresses from upstream nameservers which are in the private IP ranges. This blocks an attack where a browser behind a firewall is used to probe machines on the local network.

这项安全设置是拒绝解析包含私有IP地址的域名,这些IP地址包括如下私有地址范围:

A:10.0.0.0~10.255.255.255     即10.0.0.0/8
B:172.16.0.0~172.31.255.255   即172.16.0.0/12
C:192.168.0.0~192.168.255.255 即192.168.0.0/16

而其初衷是要防止类似上游DNS服务器故意将某些域名解析成特定私有内网IP而劫持用户这样的安全攻击。

了解了这个选项配置的作用,接下来我介绍两个解决的办法:

1. 直接在配置文件中取消 stop-dns-rebind 配置项从而禁用该功能。这个方法确实可以一劳永逸的解决解析内网IP地址的问题,但是我们也失去了这项安全保护的特性,所以在这里我 不推荐 这个办法。

2. 使用 rebind-domain-ok 进行特定配置,顾名思义该配置项可以有选择的忽略域名的rebind行为,其具体官方描述如下:

–rebind-domain-ok=[<domain>]|[[/<domain>/[<domain>/] Do not detect and block dns-rebind on queries to these domains. The argument may be either a single domain, or multiple domains surrounded by '/', like the –server syntax, eg. –rebind-domain-ok=/domain1/domain2/domain3/

举个例子,对于 oa.example.com 这样包含内网IP的域名配置文件这样写:

rebind-domain-ok=/oa.example.com/

经过这样的配置后,DNSMASQ将默认允许 oa.example.com 的rebind行为,也就是说内网IP地址将能够正常返回而不被过滤了。

当然如果某个域名下的包含内网地址的子域名特别多,可以使用通配的方法:

rebind-domain-ok=/.example.com/

这样任何属于 example.com 的子域名将均不接受rebind攻击检测了,所有的关于 example.com 子域名的私有内网IP都能正常解析。注意 .example.com 前面的点。