我有几个在 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 214.2.201.10.in-addr.arpa. ptr
;; Warning: Message parser reports malformed message packet.
; <<>> DiG 9.11.5-P4-5.1+deb10u8A~5.0.2.202210101801-Univention <<>> 214.2.201.10.in-addr.arpa. ptr
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 20796
;; flags: qr rd ad; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
;; WARNING: recursion requested but not available
;; WARNING: Message has 70 extra bytes at end
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
; COOKIE: 881af249ef946da8 (echoed)
;; QUESTION SECTION:
;214.2.201.10.in-addr.arpa. IN PTR
;; Query time: 3 msec
;; SERVER: 10.0.2.3#53(10.0.2.3)
;; WHEN: Tue Jun 13 15:42:59 CEST 2023
;; MSG SIZE rcvd: 136
请注意以下几点:
dig
不打印答案,但是增强型DNSOPT PSEUDISECTION
。- 相反,出现了一些奇怪的警告:
警告:消息解析器报告格式错误的消息包。
和
警告:消息末尾有 70 个额外字节
Python DNS 替代方案
如果我使用它python3
进行 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.
这是预料之中的,因为我在这里使用 OpenStack 通过 DHCP 提供的 DNS 服务器。
但即使我将名称服务器更改为使用任何其他服务器(例如 Quad9、Google8、随机 1.2.3.4 等),我仍然得到相同的答案:
# python3 -c 'import sys,dns.resolver
r = dns.resolver.Resolver()
r.nameservers = [sys.argv[1]]
q = r.query("214.2.201.10.in-addr.arpa.", "PTR")
print(q.rrset[0])' '9.9.9.9'
dc0.a.customers.regiocloud.tech.
OpenStack 似乎做了一些 DNS中间人截距。
Wireshark
dig
对于另一台具有不同 IPv4 的虚拟机,我使用以下方法捕获了原始跟踪wireshark
:
Domain Name System (response)
Transaction ID: 0x5853
Flags: 0x8120 Standard query response, No error
1... .... .... .... = Response: Message is a response
.000 0... .... .... = Opcode: Standard query (0)
.... .0.. .... .... = Authoritative: Server is not an authority for domain
.... ..0. .... .... = Truncated: Message is not truncated
.... ...1 .... .... = Recursion desired: Do query recursively
.... .... 0... .... = Recursion available: Server can't do recursive queries
.... .... .0.. .... = Z: reserved (0)
.... .... ..1. .... = Answer authenticated: Answer/authority portion was authenticated by the server
.... .... ...0 .... = Non-authenticated data: Unacceptable
.... .... .... 0000 = Reply code: No error (0)
Questions: 1
Answer RRs: 1
Authority RRs: 0
Additional RRs: 0
Queries
136.0.201.10.in-addr.arpa: type PTR, class IN
Name: 136.0.201.10.in-addr.arpa
[Name Length: 25]
[Label Count: 6]
Type: PTR (domain name PoinTeR) (12)
Class: IN (0x0001)
Answers
<Root>: type OPT
Name: <Root>
Type: OPT (41)
UDP payload size: 4096
Higher bits in extended RCODE: 0x00
EDNS0 version: 0
Z: 0x0000
0... .... .... .... = DO bit: Cannot handle DNSSEC security RRs
.000 0000 0000 0000 = Reserved: 0x0000
Data length: 12
Option: COOKIE
[Request In: 1]
[Time: 0.003197000 seconds]
请注意Answer RRs: 1
,此处的 解释了dig
对附加数据的抱怨:仅EDNS OPT
记录被考虑,而不是第二个答案。修补捕获的数据包文件后,Answer RRs: 2
我看到了 中的第二个答案记录wireshark
,其中包含缺失的PTR
记录dig
未打印的
136.0.201.10.in-addr.arpa: type PTR, class IN, phahn-1st.a.customers.regiocloud.tech
Name: 136.0.201.10.in-addr.arpa
Type: PTR (domain name PoinTeR) (12)
Class: IN (0x0001)
Time to live: 3600 (1 hour)
Data length: 39
Domain Name: phahn-1st.a.customers.regiocloud.tech
问题
- 如何防止 OpenStack 拦截 DNS PTR 查询并自行应答,它应该转到配置的 DNS 服务器
/etc/resolv.conf
。 - OpenStack 的答案似乎让人困惑
dig
,但 Pythons 却不是这样dns
。需要重新配置什么才能使dig
工作?
额外尝试
我已经读过了OpenStack:DNS 集成,但没有发现任何可操作的内容。(我不是 OpenStack 专家,并且该环境不由我管理)
如果我使用dig +tcp
强制使用TCP
而不是UDP
,则查询不会被拦截,而是由真正的 DNS 服务器应答。
执行dig … any
也会返回预期的答案,因此 OpenStack 似乎仅拦截特定的PTR
。
删除主机 IP 后,/etc/hosts
通过 NSS (Linux 名称服务切换) 执行查询也会返回来自 OpenStack 的答案:
# getent hosts 10.201.2.214
10.201.2.214 dc0.a.customers.regiocloud.tech
答案1
OVN 有一个流程将发往 UDP/53 的流量重定向到其内部 DNS 解析器,但是它不支持 EDNS。
我们在 5 月份向规范支持部门报告了此问题,他们在上游对其进行了修复:https://github.com/ovn-org/ovn/commit/4b10571aa89b226c13a8c5551ceb7208d782b580
就我的情况来说,当我告诉 dig 禁用 edns 或使用 tcp (+noedns, +tcp) 时,它就可以工作了