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

自定义DNS解析器无法解析Type.ANY记录的问题咨询

自定义DNS解析器无法解析Type.ANY记录的问题咨询

这是一个很常见的DNS查询问题,我来帮你分析原因并给出针对性的解决方案:


问题核心原因

你遇到的结果差异,本质是主流公共DNS服务器与本地DNS缓存服务对ANY类型查询的处理逻辑完全不同:

  1. 公共DNS的安全限制:像1.1.1.1(Cloudflare)、8.8.8.8(Google)这类公共DNS服务商,出于防范DNS放大DDoS攻击的考虑,已经直接停止响应ANY类型的查询请求——这类查询曾被攻击者用来生成大体积响应流量,淹没目标服务器。所以你用SimpleResolver(1.1.1.1)查询时会返回空结果。
  2. 本地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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.08 07:58:03