【问题标题】:How to extract the domain name from a dns query?如何从 dns 查询中提取域名?
【发布时间】:2020-12-03 18:41:01
【问题描述】:

所以我要做的是提取域名,例如youtube.com,来自使用 python 的 dns 查询。

这是我用来生成查询数据的代码。 :

import socket

port = 53
ip = '127.0.0.1'

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind((ip, port))

while 1:
    data, addr = sock.recvfrom(512)
    print(data)

代码返回的查询数据为十六进制字符串:

                              e2 58 01 00 00 01                   
00 00 00 00 00 01 07 79 6f 75 74 75 62 65 03 63                   
6f 6d 00 00 1c 00 01 00 00 29 02 00 00 00 00 00                   
00 00

我想提取域名:

07 79 6f 75 74 75 62 65 03 63                   
6f 6d 00

可能与 answer 类似,但查询不是响应

我正在使用 python 3.8

【问题讨论】:

  • 您可以使用struct 模块来分解构成DNS 消息头和包含部分的字节/单词。多年来对 DNS 进行了许多更新,但 RFC 1035 可能是您在这里所需要的。第 4 节定义了标头和一般消息结构,第 3 节定义了资源记录。
  • 为什么不使用dnspython 库?事情比你想象的要复杂得多,特别是对于可以压缩的名称,所以重点不仅仅是从数据包中读取一些字节。

标签: python dns


【解决方案1】:

dnspython 库中包含您需要的一切,而且由于 DNS 消息很复杂(名称压缩、伪记录等),它会为您省去很多麻烦

没有任何预防措施或错误处理:


In [1]: stream='e2 58 01 00 00 01 00 00 00 00 00 01 07 79 6f 75 74 75 62 65 03 63 6f 6d 00 00 1c 00 01 00 00 29 02 00 00 00 00 00 00 00'

In [7]: data=''.join(chr(int(x, base=16)) for x in stream.split(' '))

In [8]: print data
�Xyoutubecom)

In [9]: import dns

In [10]: import dns.message

In [11]: m = dns.message.from_wire(data)

In [12]: print m
id 57944
opcode QUERY
rcode NOERROR
flags RD
edns 0
payload 512
;QUESTION
youtube.com. IN AAAA
;ANSWER
;AUTHORITY
;ADDITIONAL

In [15]: print m.question[0].name
youtube.com.

在 DNS 中,查询和响应共享相同的格式,因此 dnspython 库为您提供了一个 Message 类来处理这些。

【讨论】:

  • 感谢您的回答。效果很好!
猜你喜欢
  • 2015-08-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多