java从DNS获取完整的区域记录,DNSJava不会返回所有记录
下午好
我正在进行网络发现工作,需要获取域的所有记录。当我使用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 楼答案
首先,您应该更精确地定义“获取域的所有记录”。 此外,顺便说一句,如果您在一个区域的顶点,您不能有
CNAME
记录,因为它们不能与任何其他记录共存,并且apex在设计上已经有NS
和SOA
记录第二,不要使用类型
ANY
进行DNS查询。无论出于何种原因,它被理解为ALL
,但它根本没有这种语义,也不会产生您期望的结果ANY
递归缓存名称服务器将使您返回冲突解决程序缓存中当前记录的列表,该列表不是与域相关的所有记录。事实上,有一些工作完全反对这种(虚拟)类型,请参见: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,事实上,您需要查询具有特定结构的域(如SRV的_service._transport.example.com
),因此您无法“自动发现”所有记录,您需要知道您需要哪一个(或从要测试的列表开始)我还建议您指定您正在使用的名称服务器,因为如果它是递归的,您将从它的缓存中获得结果,以及相关的TTL,它可能是您想要/需要的,也可能不是。因此,您最好查询域的(一个)权威名称服务器