从DNS获取完整的区域记录,DNSJava不会返回所有记录

时间:2018-11-13 17:54:40

标签: java dns

下午好,

我正在努力进行网络发现,并且需要获取域的所有记录。当我使用DNSJava时,它不是完整的。 CNAME并不存在,也并非所有TXT记录或A记录都存在。

有更好的方法吗?

这是我的代码:

    package iMCDNS;
    import java.util.Hashtable;

    import javax.naming.Context;
    import javax.naming.NamingEnumeration;
    import javax.naming.directory.Attribute;
    import javax.naming.directory.Attributes;
    import javax.naming.directory.DirContext;
    import javax.naming.directory.InitialDirContext;

    import org.xbill.DNS.Lookup;
    import org.xbill.DNS.Record;
    import org.xbill.DNS.Type;

    public class iMCDNS {

    public static void main(String[] args) {

        System.out.println("Running iMCDNS");

        try {

            //this returned no records

//          DirContext ctx = new InitialDirContext(env);
//          Attributes atts = ctx.getAttributes("iditsecurity.com", new String[] {"CNAME"});
//          
//          System.out.println("Attributes size: " + atts.size());
//
//          NamingEnumeration<? extends Attribute> e = atts.getAll();
//          
//          
//          while(e.hasMore()) {
//              System.out.println(e.next().get());
//          }

            //this also returns no CNAME records
            Record[] rs = new Lookup("iditsecurity.com", Type.ANY).run();

            if (rs!=null)
            {
                int javaDNSLen = rs.length;

                for (int i = 0;i < javaDNSLen; i++)
                {
                    System.out.println("record: " + rs[i].toString());
                }

            } else {
                System.out.println("No records found");
            }

        } catch (Exception ex) {

            System.out.println("Exception occurred: " + ex.toString());
        }



    }




    }

提供的结果是: 应该有2条A记录,4条CNAME和5条TXT记录...

Running iMCDNS
record: iditsecurity.com.   4503    IN  TXT "google-site-verification=VvXfVc-hr0dK3pzjc3yiAaDsK-tlFAMX7Xt3soYXByc"
record: iditsecurity.com.   4503    IN  TXT "google-site-verification=8W17El_6uLvJ0WLxEsgIKt9hKRPuz6yN9U_ke9l0i7E"
record: iditsecurity.com.   4360    IN  MX  10 mx1.netsolmail.net.

1 个答案:

答案 0 :(得分:0)

首先,您应该更精确地定义“获取域的所有记录”。 另外,通过时,如果您位于区域的顶点,则不能有NS条记录,因为它们不能与任何其他记录共存,并且顶点已经有SOAANY条记录通过设计。

第二,请勿使用类型ALL进行DNS查询。无论出于何种原因,它都被读为ANY,但它根本没有这种语义,也不会产生您期望的结果。向递归缓存名称服务器使用A会将您带回到解析程序缓存中的当前记录列表,该列表与该域相关的所有记录。实际上,有一些工作可以完全弃用这种(虚拟)类型,请参见:https://datatracker.ietf.org/doc/draft-ietf-dnsop-refuse-any/(以及更多关于非技术术语的解释,请参见https://nelsonslog.wordpress.com/2016/09/07/dns-any-requests-are-deprecated/https://blog.cloudflare.com/what-happened-next-the-deprecation-of-any/

那么您会问:这很好,但是那怎么办?

然后循环回到第一点。您将需要使用所需的记录类型(AAAATXTTXT等)进行定义,然后遍历它们以检索所有记录类型。 至少由于以下两个原因,它并不总是那么简单: * _service._transport.example.com如今已成为一个万能的事物,它可以传输很多东西:SPF,DKIM,DMARC等。 *,特别是对于DKIM或实际上与SRV相同的文件,您需要查询具有特定结构的域(例如对于SRV的#footer),因此您不能“自动发现”所有记录,需要知道哪个记录您需要(或从列表开始进行测试)

我还建议您指定要使用的名称服务器,因为如果它是递归名称服务器,则可以从其缓存中获取结果,并带有关联的TTL(可能是或不需要的)。因此,最好查询该域的(一个)权威名称服务器。