Loading... 在互联网业务中,时常遇到客户端无法正常解析域名的情况,而获取客户端dns服务器配置有助于及时分析问题进而保障客户体验。 对于技术人员来说,获取客户端服务器地址的方法大概有以下几种: 1. 打开终端,使用命令ipconfig /all获取 2. 对于将路由器地址(比如192.168.0.1)作为客户端DNS服务器地址的情况,可以登录路由器检查配置情况 3. 也可以通过已有的网站,例如https://ip.skk.moe/,查看“DNS”出口查询栏目获得。 那么,我们是否有方法可以搞一搞一个方案,可以获取终端的DNS服务器地址呢? 就这个问题,咨询了GPT,其给了一段代码,可以直接返回当前来解析DNS的客户端的地址。代码如下: ``` #!/bin/env python3 import socket import dnslib def handle_dns_request(data, client_address): """ Handle the DNS request and return a response with the client's IP address as A record. """ try: # Parse the DNS request request = dnslib.DNSRecord.parse(data) # Get the client's IP address client_ip = client_address[0] # Create a DNS response response = dnslib.DNSRecord( dnslib.DNSHeader(id=request.header.id, qr=1, aa=1, ra=1), q=request.q ) # Add the A record with the client's IP response.add_answer(dnslib.RR( rname=request.q.qname, rtype=dnslib.QTYPE.A, rclass=dnslib.CLASS.IN, ttl=1, rdata=dnslib.A(client_ip) )) with open("./getdnsserver.log","w") as f: f.write(client_ip) return response.pack() except Exception as e: print(f"Error handling request: {e}") return None def start_dns_server(address='0.0.0.0', port=53): """ Start a simple DNS server that returns the client's IP address in A records. """ with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as server_socket: server_socket.bind((address, port)) print(f"DNS Server started on {address}:{port}") try: while True: data, client_address = server_socket.recvfrom(512) print(f"Received request from {client_address}") response = handle_dns_request(data, client_address) if response: server_socket.sendto(response, client_address) except KeyboardInterrupt: print("DNS Server stopped") # Start the DNS server (Note: This requires root privileges for port 53) start_dns_server() # The above line is commented out to prevent the server from starting automatically in this environment. # You can uncomment it and run in your local environment with appropriate permissions. ``` 打包软件 ``` pyinstaller -F main.py ``` 打包容器 ``` #Dockerfile #FROM alpine:3.14 FROM ubuntu:22.04 WORKDIR /app COPY ./dist/main /app/main ENTRYPOINT ["./main"] ``` ``` version: '3' services: getdnsserver: image: zzlyzq/getdnsserver:1.0 volumes: - ./getdnsserver.log:/app/getdnsserver.log build: context: ./ dockerfile: Dockerfile container_name: getdnsserver restart: always ports: - "53:53/udp" networks: getdnsserver-network: ipv4_address: 172.18.26.31 # entrypoint: # - sh # - -euc # - sleep 600 networks: getdnsserver-network: driver: bridge ipam: config: - subnet: 172.18.26.0/24 ``` 测试效果 使用本地直接测试,无论测试什么域名,总会返回返回访问该程序的SRC IP地址。 ![2023-12-15T07:26:30.png][1] 将程序部署到公网服务器 对于我的域名sddts.cn 设置一个A记录,将dnscheck.sddts.cn CNAME hk.hlab.sddts.cn 设置一个NS记录,将check.sddts.cn NS dnscheck.sddts.cn 这样,当用户解析所有xx.check.sddts.cn 都会去dnscheck.sddts.cn服务器去进行DNS解析,而会得到终端DNS服务器地址。 ![2023-12-15T07:28:31.png][2] 当然,这个地方虽然我们本地配置的可能是119.29.29.29,但是去获取xx.check.sddts.cn的SRC IP不一定是119.29.29.29,而是其周围相关的IP地址。 另外,经过一段时间测试,使用公共的DNS服务器119.29.29.29解析xx.check.sddts.cn后,陆续还会有一批地址去解析,而这些地址可能是北京、上海、广州的腾讯云(移动)相关的地址。 [1]: https://www.sddts.cn/usr/uploads/2023/12/220381089.png [2]: https://www.sddts.cn/usr/uploads/2023/12/102350225.png 最后修改:2024 年 05 月 11 日 © 允许规范转载 赞 如果觉得我的文章对你有用,请随意赞赏