03 基于 java udp 做一个dns服务器 和 一个dns代理服务器

打印 上一主题 下一主题

主题 2070|帖子 2070|积分 6210

媒介

这个也是 来自于一个朋侪的需求 
终极的目标是实现一个 dns 代理服务器, 当然 这本质也是一个 dns 服务器 
并且 dns 代理服务器是依赖于 一个 dns 服务器的, 因此 趁便给一个 dns 服务器的 demo 
这里 主要是 基于 udp 的一个 dns 哀求, 响应数据的交互 

 
 
dns 服务器 

一个基础的 dns 服务器 demo 如下 
为了方便测试, 可以将 端口改为 53, 然后使用 System.out.println 之类的举行调试 
  1. package com.hx.test15;
  2. import org.xbill.DNS.*;
  3. import java.io.ByteArrayOutputStream;
  4. import java.net.DatagramPacket;
  5. import java.net.DatagramSocket;
  6. import java.net.InetAddress;
  7. import java.nio.ByteBuffer;
  8. /**
  9. * @author Jerry.X.He <970655147@qq.com>
  10. * @version 1.0
  11. * @date 2024-07-02 22:33
  12. */
  13. public class Test25SimpleDnsServer {
  14.     public static void main(String[] args) throws Exception {
  15.         DatagramSocket socket = new DatagramSocket(8053);
  16.         System.out.println("DNS Server listening on port 8053...");
  17.         while (true) {
  18.             byte[] receiveData = new byte[512];
  19.             DatagramPacket requestPacket = new DatagramPacket(receiveData, receiveData.length);
  20.             socket.receive(requestPacket);
  21.             byte[] data = requestPacket.getData();
  22.             int offset = requestPacket.getOffset();
  23.             int length = requestPacket.getLength();
  24.             Message request = new Message(ByteBuffer.wrap(data, offset, length));
  25.             Message response = handleRequest(request);
  26.             ByteArrayOutputStream baos = new ByteArrayOutputStream();
  27.             DNSOutput out = new DNSOutput();
  28.             baos.write(out.toByteArray());
  29.             baos.write(response.toWire());
  30.             byte[] responseData = baos.toByteArray();
  31.             DatagramPacket responsePacket = new DatagramPacket(responseData, responseData.length,
  32.                     requestPacket.getAddress(), requestPacket.getPort());
  33.             socket.send(responsePacket);
  34.         }
  35.     }
  36.     private static Message handleRequest(Message request) throws Exception {
  37.         Message response = new Message(request.getHeader().getID());
  38.         response.getHeader().setFlag(Flags.QR);
  39.         response.getHeader().setOpcode(Opcode.QUERY);
  40.         Record question = request.getQuestion();
  41.         if (question.getName().toString().startsWith("www.abc.com") && question.getType() == Type.A) {
  42.             ARecord answer = new ARecord(question.getName(), DClass.IN, 300, InetAddress.getByName("172.0.0.2"));
  43.             response.addRecord(answer, Section.ANSWER);
  44.         } else {
  45.             // apply default
  46.         }
  47.         return response;
  48.     }
  49. }
复制代码
 
 
终极实现效果如下, dns 服务器中仅仅配置了 "www.abc.com" -> "172.0.0.2" 
因此 www.abc.com 能够拿到查询效果, www.baidu.com 拿不到查询效果 

 
 
dns 代理服务器

主需求是实现一个 dns 的代理服务器  
实现如下, 无非就是 代理发送一次 dns 的哀求 到目标 dns 服务器, 拿到响应之后 响应给客户端 
  1. package com.hx.test15;
  2. import org.xbill.DNS.Message;
  3. import java.io.ByteArrayOutputStream;
  4. import java.io.IOException;
  5. import java.net.DatagramPacket;
  6. import java.net.DatagramSocket;
  7. import java.net.InetAddress;
  8. import java.nio.ByteBuffer;
  9. /**
  10. * Test25JavaDnsForwardServer
  11. *
  12. * @author Jerry.X.He <970655147@qq.com>
  13. * @version 1.0
  14. * @date 2024-07-02 22:10
  15. */
  16. public class Test25JavaDnsForwardServer {
  17.     public static void main(String[] args) throws IOException {
  18.         DatagramSocket serverSocket = new DatagramSocket(53);
  19.         System.out.println("DNS Proxy Server listening on port 53...");
  20.         while (true) {
  21.             byte[] receiveData = new byte[512];
  22.             DatagramPacket requestPacket = new DatagramPacket(receiveData, receiveData.length);
  23.             serverSocket.receive(requestPacket);
  24.             Message request = readMessage(requestPacket);
  25.             Message response = proxyRequest(request);
  26.             ByteArrayOutputStream baos = new ByteArrayOutputStream();
  27.             baos.write(response.toWire());
  28.             byte[] responseData = baos.toByteArray();
  29.             DatagramPacket responsePacket = new DatagramPacket(responseData, responseData.length,
  30.                     requestPacket.getAddress(), requestPacket.getPort());
  31.             serverSocket.send(responsePacket);
  32.         }
  33.     }
  34.     private static Message readMessage(DatagramPacket packet) throws IOException {
  35.         byte[] data = packet.getData();
  36.         int offset = packet.getOffset();
  37.         int length = packet.getLength();
  38.         return new Message(ByteBuffer.wrap(data, offset, length));
  39.     }
  40.     private static Message proxyRequest(Message request) throws IOException {
  41.         DatagramSocket upstreamSocket = new DatagramSocket();
  42.         InetAddress upstreamAddress = InetAddress.getByName("127.0.0.1");
  43.         int upstreamPort = 8053;
  44.         ByteArrayOutputStream baos = new ByteArrayOutputStream();
  45.         baos.write(request.toWire());
  46.         byte[] requestData = baos.toByteArray();
  47.         DatagramPacket upstreamRequest = new DatagramPacket(requestData, requestData.length, upstreamAddress, upstreamPort);
  48.         upstreamSocket.send(upstreamRequest);
  49.         byte[] upstreamResponseData = new byte[512];
  50.         DatagramPacket upstreamResponse = new DatagramPacket(upstreamResponseData, upstreamResponseData.length);
  51.         upstreamSocket.receive(upstreamResponse);
  52.         Message response = new Message(ByteBuffer.wrap(upstreamResponseData, upstreamResponse.getOffset(), upstreamResponse.getLength()));
  53.         upstreamSocket.close();
  54.         return response;
  55.     }
  56. }
复制代码
 
终极实现效果如下, dns 服务器中仅仅配置了 "www.abc.com" -> "172.0.0.2" 
因此 www.abc.com 能够拿到查询效果, www.baidu.com 拿不到查询效果 
假如 关闭 目标dns服务, 代理服务器会阻塞住 

 
 
完 
 
 
 
 
 

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

老婆出轨

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表