如何从 java 中的 dns 数据报中提取网站名称
how to extract the name of website from dns datagram in java
我想读取浏览器发出的 DNS 请求,然后从 DNS UDP 数据报中提取网站名称。
我可以捕获数据报,然后我使用 getData() 找到网站的标签,但我没有得到明确的数据。
public static void main(String args[]) throws Exception
{
DatagramSocket serverSocket = new DatagramSocket(53);
byte[] receiveData = new byte[512];
while(true)
{
DatagramPacket receivePacket = new DatagramPacket(receiveData,
receiveData.length);
serverSocket.receive(receivePacket);
byte telegramContent[] = receivePacket.getData();
String sentence = new String( telegramContent);
System.out.println("RECEIVED: " + sentence);
我 www.google.com
的结果
我的问题是如何像www.google.com
一样清楚地获取网站的全名
你需要阅读 RFC1034 和 1035。DNS 协议远比这复杂,你需要更多的代码来解析它。
首先,为什么不使用特定的 Java 确实存在并且可以生成和解析 DNS 数据包的 DNS 库?即使您不想使用它,阅读它的源代码也可以帮助您了解解析是如何发生的。
其次,如果你真的想自己动手,你将不得不了解DNS数据包的通用格式(具有将问题、权限部分、答案部分、附加部分分开的结构), DNS 数据包结构见第 4 节,然后具体的名称,你需要了解 "DNS compression",见同一 RFC 的第 4.1.4 节。
DNS 数据包中不会出现这样的名称。每个标签(两个点之间的字符串)都在线路上用它的长度编码,然后是标签,除了在某些情况下,指针被用来指向 DNS 数据包的另一部分,以便永远不会重复相同的标签或标签序列.
最后,您不仅需要尝试获取 DNS 数据包中的任何字符串。回复可以有很多其他内容,比如如果你得到一个 CNAME
回复,你将得到两个 "strings",即两个域名,记录的所有者和关联的 RDATA。您将需要关注这些 CNAME
记录(如果您想找出所请求的名字),然后解析 A
和 AAAA
请求的回复。显然,您还需要考虑对查询的任何名称都可能发生的否定答复 (NXDOMAIN
)。
至于
i want to read the DNS requests made by the browser
,有一个更简单的解决方案。
安装递归名称服务器,例如 unbound
并确保您的浏览器指向它。然后您将很容易地在名称服务器日志文件中看到所有主机名。
还有另一个解决方案,最近的浏览器版本实现了 DoH(基于 HTTPS 的 DNS):再次安装一个使用 DoH 的名称服务器,并将您的浏览器配置为指向它(参见 https://www.internetsociety.org/blog/2018/12/dns-privacy-support-in-mozilla-firefox/ 例如 Firefox)。
我想读取浏览器发出的 DNS 请求,然后从 DNS UDP 数据报中提取网站名称。 我可以捕获数据报,然后我使用 getData() 找到网站的标签,但我没有得到明确的数据。
public static void main(String args[]) throws Exception
{
DatagramSocket serverSocket = new DatagramSocket(53);
byte[] receiveData = new byte[512];
while(true)
{
DatagramPacket receivePacket = new DatagramPacket(receiveData,
receiveData.length);
serverSocket.receive(receivePacket);
byte telegramContent[] = receivePacket.getData();
String sentence = new String( telegramContent);
System.out.println("RECEIVED: " + sentence);
我 www.google.com
的结果我的问题是如何像www.google.com
一样清楚地获取网站的全名你需要阅读 RFC1034 和 1035。DNS 协议远比这复杂,你需要更多的代码来解析它。
首先,为什么不使用特定的 Java 确实存在并且可以生成和解析 DNS 数据包的 DNS 库?即使您不想使用它,阅读它的源代码也可以帮助您了解解析是如何发生的。
其次,如果你真的想自己动手,你将不得不了解DNS数据包的通用格式(具有将问题、权限部分、答案部分、附加部分分开的结构), DNS 数据包结构见第 4 节,然后具体的名称,你需要了解 "DNS compression",见同一 RFC 的第 4.1.4 节。
DNS 数据包中不会出现这样的名称。每个标签(两个点之间的字符串)都在线路上用它的长度编码,然后是标签,除了在某些情况下,指针被用来指向 DNS 数据包的另一部分,以便永远不会重复相同的标签或标签序列.
最后,您不仅需要尝试获取 DNS 数据包中的任何字符串。回复可以有很多其他内容,比如如果你得到一个 CNAME
回复,你将得到两个 "strings",即两个域名,记录的所有者和关联的 RDATA。您将需要关注这些 CNAME
记录(如果您想找出所请求的名字),然后解析 A
和 AAAA
请求的回复。显然,您还需要考虑对查询的任何名称都可能发生的否定答复 (NXDOMAIN
)。
至于
i want to read the DNS requests made by the browser
,有一个更简单的解决方案。
安装递归名称服务器,例如 unbound
并确保您的浏览器指向它。然后您将很容易地在名称服务器日志文件中看到所有主机名。
还有另一个解决方案,最近的浏览器版本实现了 DoH(基于 HTTPS 的 DNS):再次安装一个使用 DoH 的名称服务器,并将您的浏览器配置为指向它(参见 https://www.internetsociety.org/blog/2018/12/dns-privacy-support-in-mozilla-firefox/ 例如 Firefox)。