You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

自制Python DNS服务器与客户端Wireshark畸形数据包问题求助

DNS服务器返回畸形数据包问题排查

我在运行自制的DNS服务器与客户端时,发现Wireshark中显示畸形数据包,无法定位问题所在。该DNS服务器的设计逻辑是嗅探DNS协议传输的数据包、提取信息并向客户端返回响应。

服务器代码

import socket

# Server parameters
server_ip = '127.0.0.1'
server_port = 53

# Create a UDP socket for DNS communication
dns_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
dns_socket.bind((server_ip, server_port))
print(f"DNS server listening on {server_ip}:{server_port}")

# Loop to handle incoming DNS requests
while True:
    # Receive a DNS query from a client
    dns_query, client_address = dns_socket.recvfrom(1024)
    try:
        query_str = dns_query.decode('utf-8')
        print(f"Received DNS query '{query_str}' from {client_address[0]}:{client_address[1]}")
    except UnicodeDecodeError:
        print(f"Received DNS query from {client_address[0]}:{client_address[1]}")

    # Resolve the DNS query and get the corresponding IP address
    # This is where you would implement your own DNS resolution logic
    ip_address = '10.9.1.205'

    # Send the IP address back to the client as the DNS response
    dns_socket.sendto(ip_address.encode(), client_address)
    print(f"Sent DNS response '{ip_address}' to {client_address[0]}:{client_address[1]}")

客户端代码

import socket

# Client parameters
server_ip = '127.0.0.1'
server_port = 53
query_domain = 'www.google.com'

# Create a UDP socket for DNS communication
dns_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
dns_socket.bind((server_ip, 0))  # Use any available port for client

# Construct the DNS query message
# See https://www.cloudflare.com/learning/dns/dns-records/dns-message-format/
# for the format of a DNS query message
dns_query = b'\xab\xcd'  # 2-byte transaction ID
dns_query += b'\x01\x00'  # Standard query with recursion
dns_query += b'\x00\x01'  # One question in the query
dns_query += b'\x00\x00'  # No answers, authority, or additional sections
dns_query += b'\x00\x00'  # No answers, authority, or additional sections
dns_query += bytes.fromhex('03 77 77 77')  # www
dns_query += bytes.fromhex('06 67 6f 6f 67 6c 65')  # google
dns_query += bytes.fromhex('03 63 6f 6d')  # com
dns_query += b'\x00'  # End of domain name
dns_query += b'\x00\x01'  # Type A (IPv4 address) query
dns_query += b'\x00\x01'  # Class IN (Internet)

# Send the DNS query to the DNS server
dns_socket.sendto(dns_query, (server_ip, server_port))
print(f"Sent DNS query '{query_domain}' to {server_ip}:{server_port}")

# Wait for the DNS response from the server
dns_response, server_address = dns_socket.recvfrom(1024)
print(f"Received DNS response '{dns_response.decode()}' from {server_address[0]}:{server_address[1]}")

# Close the socket
dns_socket.close()

补充说明

  • 更换多个客户端后仍存在畸形数据包问题
  • PyCharm中可正常获取信息,但Wireshark显示异常
  • DHCP服务器也出现类似问题

问题原因与解决方法

核心原因

DNS是二进制协议,不是文本协议。你的服务器直接把字符串形式的IP地址编码后发送,完全不符合DNS响应的二进制格式规范,Wireshark解析不了这种非标准数据包,就会标记为畸形。另外,服务器尝试用utf-8解码DNS查询也是错误的——DNS查询是二进制结构,不存在可直接解码的UTF-8文本内容。

解决步骤

1. 构造符合规范的DNS响应数据包

DNS响应必须遵循固定二进制格式,至少包含:事务ID(与请求一致)、标志位、计数字段、问题部分、回答部分。修改服务器的响应构造逻辑:

# 从请求中提取事务ID
transaction_id = dns_query[:2]
# 标志位:响应、无错误、递归可用
flags = b'\x81\x80'
# 问题数、回答数、权威数、附加数
counts = b'\x00\x01\x00\x01\x00\x00\x00\x00'
# 复用请求中的问题部分
question_section = dns_query[12:]
# 回答部分:域名指针、类型A、类别IN、TTL、数据长度、IP二进制
answer_section = b'\xc0\x0c'  # 指针指向问题中的域名
answer_section += b'\x00\x01'  # 类型A
answer_section += b'\x00\x01'  # 类别IN
answer_section += b'\x00\x00\x0e\x10'  # TTL(3600秒)
answer_section += b'\x00\x04'  # IPv4地址长度(4字节)
# 将IP转为二进制
ip_bytes = socket.inet_aton('10.9.1.205')
answer_section += ip_bytes
# 组装完整响应
dns_response = transaction_id + flags + counts + question_section + answer_section
# 发送响应
dns_socket.sendto(dns_response, client_address)

2. 移除错误的UTF-8解码逻辑

服务器不需要把DNS查询解码为字符串,直接处理二进制数据包即可,替换原解码代码为:

print(f"Received DNS query from {client_address[0]}:{client_address[1]}, hex: {dns_query.hex()}")

3. DHCP问题的通用解决思路

DHCP同样是二进制协议,出现类似问题的原因也是直接发送文本而非符合规范的二进制数据包。解决时:

  • 严格遵循DHCP协议的二进制格式构造数据包
  • 不要用文本编码/解码处理DHCP数据包
  • 参考DHCP协议文档构建正确报文结构

内容的提问来源于stack exchange,提问作者Ronin Saad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 07:07:19