You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何禁用或修复OpenStack拦截DNS PTR查询的问题

如何禁用或修复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

火山引擎 最新活动