在 python returns 错误主机中进行反向 DNS 查找

Reverse DNS lookup in python returns wrong host

我正在尝试使用 python 套接字来获取 ip 的主机名。但是,出于某种原因,当我尝试这样做时:

import socket
result = socket.gethostbyaddr('216.58.207.46')  # google ip address
print(result[0])

我打印出来了:fra16s24-in-f14.1e100.net.

如何打印出来google.com?

更新:我正在尝试解析 IP 地址范围,然后将它们转换为主机名(如果可以转换的话)。显然,当我转换 3.126.***.192 时,我想看到一个实际的主机名,而不是 ec2-3-126-***-192.eu-central -1.compute.amazonaws.com.

我该怎么做?

虽然您期望的结果与您得到的结果不一致,但是您从Python 的标准socket.gethostbyaddr() 得到的结果是正确的。让我们先看看发生了什么,然后相应地调整您的期望...

在解决此类问题时,dig 等 DNS 实用程序是您的好帮手,因此我会在努力为您解答时展示 dig 的输出。

Reverse DNS lookup 不一定是一对一的关系,正如其他人在上面的评论中指出的那样。它依赖于一种约定,其中(使用上面的 IPv4 地址作为示例)您发出一个 DNS 查询以获取后缀为 .in-addr.arpa 的反向 IP 地址的 PTR 记录;在你的情况下,这是 46.207.58.216.in-addr.arpa:

▶ dig 46.207.58.216.in-addr.arpa in ptr 

; <<>> DiG 9.10.6 <<>> 46.207.58.216.in-addr.arpa in ptr
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 23082
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;46.207.58.216.in-addr.arpa.    IN  PTR

;; ANSWER SECTION:
46.207.58.216.in-addr.arpa. 77579 IN    PTR fra16s24-in-f14.1e100.net.

;; Query time: 85 msec
;; SERVER: 192.168.0.1#53(192.168.0.1)
;; WHEN: Thu May 28 13:17:17 PDT 2020
;; MSG SIZE  rcvd: 83

此处的 DNS 响应是 fra16s24-in-f14.1e100.net 的 PTR 记录,与您使用 Python 的 socket.gethostbyaddr().

时看到的完全一致

虽然您在概念上将此主机与 google.com 相关的内容相关联可能是正确的,但就 DNS 而言,它可能与 google.com 顶级域相关的任何内容无关.

编辑(根据您的更新):

Obviously, when I convert 3.126.***.192, I want to see an actual hostname, and not ec2-3-126-***-192.eu-central-1.compute.amazonaws.com.

在您在这里给出的示例中,您需要意识到 ec2-3-126-***-192.eu-central-1.compute.amazonaws.com 一个实际的主机名。看看我上面链接的关于反向 DNS 查找的文章,也看看 DNS 工作原理的入门文章。值得重复的是,单个名称可能存在 多个 地址记录(负载平衡资源通常就是这种情况)。

这是 whosebug.com 的示例:

▶ dig whosebug.com in a

; <<>> DiG 9.10.6 <<>> whosebug.com in a
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 51644
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;whosebug.com.     IN  A

;; ANSWER SECTION:
whosebug.com.  106 IN  A   151.101.193.69
whosebug.com.  106 IN  A   151.101.129.69
whosebug.com.  106 IN  A   151.101.1.69
whosebug.com.  106 IN  A   151.101.65.69

;; Query time: 81 msec
;; SERVER: 192.168.0.1#53(192.168.0.1)
;; WHEN: Thu May 28 13:25:55 PDT 2020
;; MSG SIZE  rcvd: 99

所有这些 IP 都应该有指向 whosebug.com 的 PTR 记录吗?不,不一定......让我们看一个例子:

▶ dig 69.193.101.151.in-addr.arpa in ptr

; <<>> DiG 9.10.6 <<>> 69.193.101.151.in-addr.arpa in ptr
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 418
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;69.193.101.151.in-addr.arpa.   IN  PTR

;; AUTHORITY SECTION:
151.in-addr.arpa.   3125    IN  SOA pri.authdns.ripe.net. dns.ripe.net. 1586415572 3600 600 864000 3600

;; Query time: 79 msec
;; SERVER: 192.168.0.1#53(192.168.0.1)
;; WHEN: Thu May 28 13:28:03 PDT 2020
;; MSG SIZE  rcvd: 116

在这种情况下,当您对此 IP 地址执行反向 DNS 查找时,没有 PTR 记录。那么,Python 的 gethostbyaddr 会如何处理这种情况?

>>> socket.gethostbyaddr('151.101.193.69')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
socket.herror: [Errno 1] Unknown host

在这种情况下会引发异常。如果 DNS 响应没有反向查找 PTR 记录,Python 无法真正提供任何进一步有用的信息。

如果这个答案不够清楚,请在评论中回复,我会修改这个答案,直到一切都清楚为止。