代码之家  ›  专栏  ›  技术社区  ›  Steve Mansfield

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

  •  0
  • Steve Mansfield  · 技术社区  · 7 年前

    下午好

    我正在进行网络发现工作,需要获取一个域的所有记录。当我使用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 回复  |  直到 7 年前
        1
  •  0
  •   Patrick Mevzek James Dean    7 年前

    首先,您应该更准确地定义“获取域的所有记录”。 此外,顺便说一句,如果你在一个区域的顶点,你不能 CNAME 记录,因为它们不能与任何其他记录共存,而apex已经有了 NS SOA 设计的记录。

    第二,不要使用类型 ANY 进行DNS查询。无论出于何种原因,这被解读为 ALL 但它完全没有这种语义,也不会产生你期望的结果。 任何 使用递归缓存名称服务器将返回解析器缓存中的当前记录列表,即 与域相关的所有记录。事实上,有一些工作可以完全反对这种(虚拟)类型,请参见: 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/ )

    然后你会问:这很好,但是怎么做呢?

    然后循环回到第一个点。您需要定义所需的记录类型( A , AAAA , TXT ,等等),然后在它们上循环以检索所有这些。 这并不总是那么简单,至少有两个原因: * TXT 现在已经成为一个包罗万象的运输工具:SPF、DKIM、DMARC等。 *特别是对于DKIM或SRV,实际上,您需要查询具有特定结构的域(如 _service._transport.example.com 对于SRV),所以你不能“自动发现”所有记录,你需要知道你需要哪一个(或者从一个列表开始测试)

    我还建议您指定正在使用的名称服务器,因为如果它是递归的,您将从其缓存中获得结果,以及相关的TTL,它可能是您想要/需要的,也可能不是。因此,您最好查询域的(一个)权威名称服务器。