自定义DNS解析器无法解析Type.ANY记录的问题咨询
自定义DNS解析器无法解析Type.ANY记录的问题咨询
这是一个很常见的DNS查询问题,我来帮你分析原因并给出针对性的解决方案:
问题核心原因
你遇到的结果差异,本质是主流公共DNS服务器与本地DNS缓存服务对ANY类型查询的处理逻辑完全不同:
- 公共DNS的安全限制:像1.1.1.1(Cloudflare)、8.8.8.8(Google)这类公共DNS服务商,出于防范DNS放大DDoS攻击的考虑,已经直接停止响应
ANY类型的查询请求——这类查询曾被攻击者用来生成大体积响应流量,淹没目标服务器。所以你用SimpleResolver(1.1.1.1)查询时会返回空结果。 - 本地DNS的模拟处理:你的系统默认DNS(这里是
127.0.0.53,一般是本地缓存服务如systemd-resolved)并不会真正转发ANY请求到上游,而是会自动分别查询A、AAAA等常用记录类型,再把结果汇总返回,所以看起来ANY查询能正常工作。
代码与日志验证
先看你的格式化后代码:
package za.co.dns; import lombok.CustomLog; import org.xbill.DNS.*; import java.net.InetSocketAddress; @CustomLog public class LookupIssue { public static void main(String[] args) throws TextParseException { SimpleResolver resolver = new SimpleResolver(new InetSocketAddress("1.1.1.1", 53)); final String domainName = "www.google.com"; log.debug(" ########## Doing first lookup ########## "); Lookup lookup = getLookup(domainName, resolver); doLookup(lookup); log.debug(" ########## Doing second lookup ########## "); lookup = getLookup(domainName); doLookup(lookup); } private static void doLookup(final Lookup lookup) { final Record[] records = lookup.run(); if (records == null) { log.debug("NULL Returned for records lookup"); } else { for (Record record : records) { log.debug(record.toString()); } } } private static Lookup getLookup(final String domain) throws TextParseException { final Name name = Name.fromString(domain); final Lookup lookup = new Lookup(name, Type.ANY, DClass.IN); return lookup; } private static Lookup getLookup(final String domain, final Resolver resolver) throws TextParseException { final Lookup lookup = getLookup(domain); lookup.setResolver(resolver); return lookup; } }
你的日志也直接验证了这个逻辑:
DEBUG za.co.dns.LookupIssue - ########## Doing first lookup ########## DEBUG org.xbill.DNS.SimpleResolver - Sending www.google.com./ANY, id=50170 to udp/1.1.1.1:53 DEBUG za.co.dns.LookupIssue - NULL Returned for records lookup DEBUG za.co.dns.LookupIssue - ########## Doing second lookup ########## DEBUG org.xbill.DNS.SimpleResolver - Sending www.google.com./ANY, id=36672 to udp/127.0.0.53:53 DEBUG za.co.dns.LookupIssue - www.google.com. 19 IN A 142.251.216.68 DEBUG za.co.dns.LookupIssue - www.google.com. 19 IN AAAA 2c0f:fb50:4002:80c:0:0:0:2004
- 1.1.1.1对
ANY查询直接返回空 - 本地127.0.0.53返回了A/AAAA记录(这是本地DNS模拟
ANY查询的结果)
可行解决方案
由于ANY查询已经被主流公共DNS弃用,不建议再依赖Type.ANY进行查询,推荐以下两种替代方案:
方案1:查询具体业务需要的记录类型
直接查询你实际需要的DNS类型(比如A、AAAA、CNAME、MX等),再合并结果。这种方式兼容性最好,所有DNS服务器都支持:
private static void doTargetedLookup(String domain, Resolver resolver) throws TextParseException { Name domainName = Name.fromString(domain); DClass inetClass = DClass.IN; // 查询A记录(IPv4地址) Lookup aLookup = new Lookup(domainName, Type.A, inetClass); if (resolver != null) aLookup.setResolver(resolver); Record[] aRecords = aLookup.run(); // 查询AAAA记录(IPv6地址) Lookup aaaaLookup = new Lookup(domainName, Type.AAAA, inetClass); if (resolver != null) aaaaLookup.setResolver(resolver); Record[] aaaaRecords = aaaaLookup.run(); // 输出合并后的结果 log.debug("=== A 记录(IPv4) ==="); if (aRecords != null) { for (Record record : aRecords) log.debug(record.toString()); } log.debug("=== AAAA 记录(IPv6) ==="); if (aaaaRecords != null) { for (Record record : aaaaRecords) log.debug(record.toString()); } }
方案2:使用支持ANY查询的小众DNS(不推荐)
如果你确实需要原生ANY查询结果,可以寻找仍支持该类型的小众DNS服务器,但这类服务器数量极少,且可能存在安全风险,绝对不建议在生产环境使用。
内容来源于stack exchange
相关产品推荐
相关产品推荐

