如何禁用或修复OpenStack拦截DNS PTR查询的问题
我在OpenStack上运行了几台Debian/GNU Linux虚拟机,最近解析内部IPv4地址时遇到了挺奇怪的问题,跟大家分享下排查过程和解决思路。
问题现象
首先看虚拟机的网卡配置,执行ip -c addr show dev eth0得到的结果是正常的:
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 inet 10.201.2.214/16 brd 10.201.255.255 scope global dynamic eth0 …
但用dig查询反向PTR记录时,就出问题了:
dig 214.2.201.10.in-addr.arpa. ptr
返回的结果里看不到预期的PTR答案,反而有一堆警告:
;; Warning: Message parser reports malformed message packet.
;; WARNING: recursion requested but not available
;; WARNING: Message has 70 extra bytes at end
而且只显示了EDNS OPT伪区段,完全没打印PTR记录。
后来我用Python的dns库做查询,却能拿到正确结果:
python3 -c 'import dns.resolver r = dns.resolver.Resolver() q = r.query("214.2.201.10.in-addr.arpa.", "PTR") print(q.rrset[0])'
输出:dc0.a.customers.regiocloud.tech.
更诡异的是,哪怕我把DNS服务器换成外部的(比如Quad9、Google DNS,甚至随便填个1.2.3.4),用Python查询还是返回同样的结果,这说明OpenStack在做DNS中间人拦截,不管我指定哪个DNS,请求都被它截胡了。
Wireshark抓包的发现
我给另一台不同IP的虚拟机抓了dig查询的包,发现DNS响应包的Answer RRs字段标了1,但实际包里有两条记录:一条是EDNS OPT,另一条才是PTR记录。这就导致dig认为包格式有问题,直接忽略了PTR记录;后来我手动把抓包文件里的Answer RRs改成2,Wireshark就能正常显示出PTR记录了。
我试过的其他排查操作
- 查了OpenStack的DNS集成文档,但因为我不是OpenStack管理员,环境也不是我维护的,没找到可操作的配置项
- 用
dig +tcp强制走TCP查询,结果不会被拦截,能拿到真实DNS服务器的响应 - 用
dig … any查询也能得到正确结果,看来OpenStack只拦截特定的PTR查询 - 把主机IP从
/etc/hosts里删掉后,用getent hosts查询还是返回OpenStack拦截的结果,说明NSS也被影响了
解决思路与方法
分两种情况来说:
如果你是OpenStack管理员
需要调整OpenStack的DNS相关配置:
- 检查Neutron的DNS代理(比如dnsmasq)的设置,看看有没有针对PTR查询的拦截或篡改规则
- 确保DNS响应包的
Answer RRs计数和实际包含的记录数一致,避免因为计数错误导致dig这类严格校验的工具失败 - 关闭不必要的DNS中间人拦截功能,让PTR查询直接转发到虚拟机配置的DNS服务器
如果你只是虚拟机用户(没法改OpenStack配置)
可以用这些临时方案绕过问题:
- 强制TCP查询:每次用dig时加
+tcp参数,比如dig +tcp 214.2.201.10.in-addr.arpa. ptr,UDP拦截对TCP无效,能拿到真实结果 - 换用其他DNS工具:比如Python的dns库(就像之前那样),或者
drill这类工具,它们对格式不标准的DNS响应兼容性更好 - 修改dig默认行为:在
~/.digrc文件里添加+tcp,这样dig默认就用TCP查询,不用每次手动加参数 - 调整NSS配置:如果不需要OpenStack返回的PTR记录,可以修改
/etc/nsswitch.conf,调整hosts字段的顺序(比如把dns放在前面),不过这个要根据自己的环境测试,避免影响其他解析
为什么dig失败但Python的dns库能正常工作?
dig对DNS响应的格式校验非常严格,当响应包的记录计数和实际记录数不匹配时,它会判定包有问题,直接丢弃无效部分;而Python的dns库对这种不规范的包兼容性更强,会尝试解析所有存在的记录,所以能拿到正确的PTR结果。
备注:内容来源于stack exchange,提问作者pmhahn




