自实现DNSLog服务器的意义及作用:
以下将介绍DNS,理解以下概念,对我们理解DNSLog的原理并实现DNSLog非常重要。如果您已了解这部分知识,请跳过本节,直接阅读 DNSLog实现 一节。
DNS 是一个分布式分层数据库,用于存储 IP 地址和其他数据,提供从域名到网络地址的查询服务。DNS 目录存储在全球范围内分布的域名服务器上,并会定期更新。
记录是 DNS 资源和域名之间的映射。一些常用的记录类型如下:
权威性 DNS 服务器是实际持有并负责 DNS 资源记录(包括 A、AAAA 和 CNAME)的服务器。这是位于 DNS 查找链底部的服务器。
最终我们要实现的服务器就是这个。

递归解析器是将查询发送到权威服务器或非权威服务器以进行解析的服务器。我们上网有时候手动设置的8.8.8.8,114.114.114.114等就属于递归解析器。递归解析器正如其名,它对给定名称依次执行查询,并返回最终结果。
为执行此操作,其发出一系列请求,直至到达用于所请求的记录的权威性 DNS 域名服务器为止。


至此,根据上面的解析原理,我们要做的事情就很简单了,我们只需要在顶级域名服务器上添加一条NS记录,将NS权威服务器指向我们自己的服务器,然后再编写DNS处理程序部署在我们自己的服务器上就好了。
DNS服务运行在53端口的UDP协议上。
DNS服务器部分我们使用python3编写,对DNS数据包的处理使用dnslib库。
项目地址
GitHub - paulc/dnslib: A Python library to encode/decode DNS wire-format packets
dnslib · PyPI
- # SimpleServer.py
- import socket
- from dnslib import DNSRecord, DNSHeader, RR, A
-
- dns_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
- dns_socket.bind(('0.0.0.0', 53))
-
- while True:
- data, address = dns_socket.recvfrom(1024)
- request = DNSRecord.parse(data)
- qname = request.q.qname
- reply = DNSRecord(
- DNSHeader(id=request.header.id, qr=1, aa=1, ra=1),
- q=request.q,
- a=RR(qname, rdata=A("127.0.0.1"))
- )
- dns_socket.sendto(reply.pack(), address)
- print(qname) #此处可以打印到输出,也可以自行保存到数据库或者文件中
首先我们需要一个域名和一个带公网ip的服务器
假设服务器ip为 1.1.1.1,服务器ip为fflag.cn

1、给我们自己的服务器添加一条A记录域名解析
ns.fflag.cn A 记录指向 1.1.1.1
2、将NS权威服务器指向我们自己的服务器
dns.fflag.cn NS 记录指向 ns.fflag.cn
3、在Linux服务器上,需要先关闭named和systemd-resolve服务,否则数据包到不了我们的处理程序
- systemctl stop named
- systemctl stop resolved
4、运行代码
- git clone https://github.com/chenzhouwen/DNSLog.git
- # 或者自己下载
- cd DNSLog
-
- python3 SimpleServer.py
5、测试运行效果

客户端成功记录下 dnslog
项目所有代码已发布至GitHub
GitHub - czhouw/DNSLog
参考文章:
[1] https://cloud.google.com/dns/docs/dns-overview
[2] https://www.cloudflare.com/zh-cn/learning/dns/what-is-dns/