赞
踩
nslookup 是一个查询 Internet 域名服务器的程序。我们通常使用nslookup工具来测试DNS解析,获取DNS报文的详细数据,这也是我们想要使用协议分析工具nslookup来分析DNS流量进行分析。
只要你上网,都会涉及DNS解析。简单起见,我们这里不会搭建一个DNS服务器,而是使用Internet域名解析来分析验证。
使用nslookup工具进行DNS查询
nslookup 命令可用于许多操作系统,如 Windows、macOS 和 Linux 发行版。 您可以使用它来执行 DNS 查询并接收:域名或 IP 地址,或任何其他特定的 DNS 记录。
nslookup命令可以在两种模式下允许:交互式和非交互式。当需要返回单一查询的结果,可以使用非交互式模式,语法如下:
nslookup [-option] [name | -] [server]
例如我们查询一个baidu.com的命令结果如下
nslookup 后跟域名将显示域的“A 记录”(IP 地址)。 使用此命令查找域的地址记录。 它查询域名服务器并获取详细信息。
如何检查反向 DNS 查找?
很多时候您会检查 A 记录以查看域的 IP,但有时您需要验证 IP 地址是否与特定域相关。 为此,我们需要反向 DNS 查找。
下面来看看如何开启nslookup调试模式。
下面给出的是debug模式下部分代码具体实现。
puts("------------"); /*detailheader(query, msg);*/ detailsection(query, msg, 1, DNS_SECTION_QUESTION); detailsection(query, msg, 1, DNS_SECTION_ANSWER); detailsection(query, msg, 1, DNS_SECTION_AUTHORITY); detailsection(query, msg, 1, DNS_SECTION_ADDITIONAL); puts("------------"); 1234567 static isc_result_t detailsection(dig_query_t *query, dns_message_t *msg, int headers, dns_section_t section) { isc_result_t result, loopresult; dns_name_t *name; dns_rdataset_t *rdataset = NULL; dns_rdata_t rdata = DNS_RDATA_INIT; char namebuf[DNS_NAME_FORMATSIZE]; UNUSED(query); debug("detailsection()"); if (headers) { switch (section) { case DNS_SECTION_QUESTION: puts(" QUESTIONS:"); break; case DNS_SECTION_ANSWER: puts(" ANSWERS:"); break; case DNS_SECTION_AUTHORITY: puts(" AUTHORITY RECORDS:"); break; case DNS_SECTION_ADDITIONAL: puts(" ADDITIONAL RECORDS:"); break; } } result = dns_message_firstname(msg, section); if (result == ISC_R_NOMORE) return (ISC_R_SUCCESS); else if (result != ISC_R_SUCCESS) return (result); for (;;) { name = NULL; dns_message_currentname(msg, section, &name); for (rdataset = ISC_LIST_HEAD(name->list); rdataset != NULL; rdataset = ISC_LIST_NEXT(rdataset, link)) { if (section == DNS_SECTION_QUESTION) { dns_name_format(name, namebuf, sizeof(namebuf)); printf("\t%s, ", namebuf); dns_rdatatype_format(rdataset->type, namebuf, sizeof(namebuf)); printf("type = %s, ", namebuf); dns_rdataclass_format(rdataset->rdclass, namebuf, sizeof(namebuf)); printf("class = %s\n", namebuf); } loopresult = dns_rdataset_first(rdataset); while (loopresult == ISC_R_SUCCESS) { dns_rdataset_current(rdataset, &rdata); dns_name_format(name, namebuf, sizeof(namebuf)); printf(" -> %s\n", namebuf); switch (rdata.type) { case dns_rdatatype_soa: printsoa(&rdata); break; default: printf("\t"); printrdata(&rdata); } dns_rdata_reset(&rdata); printf("\tttl = %u\n", rdataset->ttl); loopresult = dns_rdataset_next(rdataset); } } result = dns_message_nextname(msg, section); if (result == ISC_R_NOMORE) break; else if (result != ISC_R_SUCCESS) { return (result); } } return (ISC_R_SUCCESS); }
nslookup的交互模式
nslookup在交互模式下使用,进入交互状态并执行相应的子命令,交互命令如下:
static void setoption(char *opt) { size_t l = strlen(opt); if (CHECKOPT("all", 3)) { show_settings(1, 0); } else if (strncasecmp(opt, "class=", 6) == 0) { if (testclass(&opt[6])) strlcpy(defclass, &opt[6], sizeof(defclass)); } else if (strncasecmp(opt, "cl=", 3) == 0) { if (testclass(&opt[3])) strlcpy(defclass, &opt[3], sizeof(defclass)); } else if (strncasecmp(opt, "type=", 5) == 0) { if (testtype(&opt[5])) strlcpy(deftype, &opt[5], sizeof(deftype)); } else if (strncasecmp(opt, "ty=", 3) == 0) { if (testtype(&opt[3])) strlcpy(deftype, &opt[3], sizeof(deftype)); } else if (strncasecmp(opt, "querytype=", 10) == 0) { if (testtype(&opt[10])) strlcpy(deftype, &opt[10], sizeof(deftype)); } else if (strncasecmp(opt, "query=", 6) == 0) { if (testtype(&opt[6])) strlcpy(deftype, &opt[6], sizeof(deftype)); } else if (strncasecmp(opt, "qu=", 3) == 0) { if (testtype(&opt[3])) strlcpy(deftype, &opt[3], sizeof(deftype)); } else if (strncasecmp(opt, "q=", 2) == 0) { if (testtype(&opt[2])) strlcpy(deftype, &opt[2], sizeof(deftype)); } else if (strncasecmp(opt, "domain=", 7) == 0) { strlcpy(domainopt, &opt[7], sizeof(domainopt)); set_search_domain(domainopt); usesearch = 1; } else if (strncasecmp(opt, "do=", 3) == 0) { strlcpy(domainopt, &opt[3], sizeof(domainopt)); set_search_domain(domainopt); usesearch = 1; } else if (strncasecmp(opt, "port=", 5) == 0) { set_port(&opt[5]); } else if (strncasecmp(opt, "po=", 3) == 0) { set_port(&opt[3]); } else if (strncasecmp(opt, "timeout=", 8) == 0) { set_timeout(&opt[8]); } else if (strncasecmp(opt, "t=", 2) == 0) { set_timeout(&opt[2]); } else if (CHECKOPT("recurse", 3)) { recurse = 1; } else if (CHECKOPT("norecurse", 5)) { recurse = 0; } else if (strncasecmp(opt, "retry=", 6) == 0) { set_tries(&opt[6]); } else if (strncasecmp(opt, "ret=", 4) == 0) { set_tries(&opt[4]); } else if (CHECKOPT("defname", 3)) { usesearch = 1; } else if (CHECKOPT("nodefname", 5)) { usesearch = 0; } else if (CHECKOPT("vc", 2) == 0) { tcpmode = 1; } else if (CHECKOPT("novc", 4) == 0) { tcpmode = 0; } else if (CHECKOPT("debug", 3) == 0) { short_form = 0; showsearch = 1; } else if (CHECKOPT("nodebug", 5) == 0) { short_form = 1; showsearch = 0; } else if (CHECKOPT("d2", 2) == 0) { debugging = 1; } else if (CHECKOPT("nod2", 4) == 0) { debugging = 0; } else if (CHECKOPT("search", 3) == 0) { usesearch = 1; } else if (CHECKOPT("nosearch", 5) == 0) { usesearch = 0; } else if (CHECKOPT("sil", 3) == 0) { /* deprecation_msg = 0; */ } else if (CHECKOPT("fail", 3) == 0) { nofail=0; } else if (CHECKOPT("nofail", 5) == 0) { nofail=1; } else if (strncasecmp(opt, "ndots=", 6) == 0) { set_ndots(&opt[6]); } else { printf("*** Invalid option: %s\n", opt); } } static void interactive_command(char *input) { char *ptr, *arg; ptr = next_token(&input, " \t\r\n"); if (ptr == NULL) return; arg = next_token(&input, " \t\r\n"); if (strcasecmp(ptr, "set") == 0) { if (arg == NULL) printf("Usage: set keyword=value, or set all\n"); else setoption(arg); } else if ((strcasecmp(ptr, "server") == 0) || (strcasecmp(ptr, "lserver") == 0)) { isc_result_t res; if (arg == NULL) printf("usage: server hostname\n"); else if ((res = set_nameserver(arg))) { printf("couldn't get address for '%s': %s\n", arg, isc_result_totext(res)); } else { check_ra = 0; show_settings(1, 1); } } else if (strcasecmp(ptr, "exit") == 0) { in_use = 0; } else if (strcasecmp(ptr, "help") == 0 || strcasecmp(ptr, "?") == 0) { printf("The '%s' command is not yet implemented.\n", ptr); } else if (strcasecmp(ptr, "finger") == 0 || strcasecmp(ptr, "root") == 0 || strcasecmp(ptr, "ls") == 0 || strcasecmp(ptr, "view") == 0) { printf("The '%s' command is not implemented.\n", ptr); } else addlookup(ptr); }
常用的子命令为
nslookup [exit | finger | help | ls | lserver | root | server | set | view] [options]
exit :退出 nslookup 命令行工具
finger :与当前计算机上的finger 服务器连接
help : 显示子命令的简短摘要
ls: 列出 DNS 域的信息
lserver : 改变默认域名服务器
root :将默认服务器挂到DNS域名空间根的服务器上
server :指定域名服务器
set :此命令用于更改影响查找的状态信息
view:排序并列出前一个 ls 子命令或命令的输出
在交互模式下正向解析,查询域名信息。要中断交互命令,可以使用ctrl + c组合键,要退出交互模式并返回到命令提示符,在命令提示符下输入“exit”即可。
直接输入要查询的域名可返回域名的IP地址。输入server可返回当前DNS服务器的信息。
无论是交互式和非交互式,如果没有指定DNS服务器地址,nslookup命令将查询当前计算机的默认DNS服务器。
默认查询主机地址,想要测试其他类型的资源记录,先使用 set type命令设置要查询的DNS记录类型,然后输入域名,可得到相应类型的域名测试结果。
类型值如下:
TYPE: A IPv4 地址记录 AAAA IPv6 地址记录 AFSDB Andrew文件系统数据库服务器记录 ATMA ATM地址记录 CNAME 别名记录 HINFO 硬件配置记录,包括CPU、操作系统信息 ISDN 域名对应的ISDN号码 MB 存放指定邮箱的服务器 MG 邮件组记录 MINFO 邮件组和邮箱的信息记录 MR 改名的邮箱记录 MX 邮件服务器记录 NS 名字服务器记录 PTR 反向记录 RP 负责人记录 RT 路由穿透记录 SRV TCP服务器信息记录 TXT 域名对应的文本信息 X25 域名对应的X.25地址记录
举例如下:
如何查找域的所有可用 DNS 记录。
nslookup -type=any baidu.com
这个查找范围很大。 在这里,我们要查看所有可用的 DNS 记录。 在看到所有这些之后,我们可以对不同类型的 DNS 记录进行特定查找。
捕获DNS流量验证报文格式
网络访问只要涉及域名,都会执行DNS解析,如ping ,web访问等等。下面我们使用nslookup命令查询域名baidu.com 。
下图是使用tcpdump抓包的过程
tcpdump -i eth0 -nt -s 500 port domain
使用
tcpdump
工具进行DNS包的抓取,我们制定的参数:
- -i eth0 指定我们的网卡
- -n 按照IP地址和端口的数字形式进行输出
- -s 我们制定抓取数据包的Size
- port domain 指定域名服务
先开启抓包,然后执行nslookup
# nslookup www.baidu.com
Server: 183.60.82.98
Address: 183.60.82.98#53
Non-authoritative answer:
www.baidu.com canonical name = www.a.shifen.com.
Name: www.a.shifen.com
Address: 14.215.177.38
Name: www.a.shifen.com
Address: 14.119.104.189
抓到的包内容
IP 172.16.0.15.57526 > 183.60.82.98.domain: 4507+ A? www.baidu.com. (31) IP 183.60.82.98.domain > 172.16.0.15.57526: 4507 3/0/0 CNAME www.a.shifen.com., A 14.215.177.38, A 14.119.104.189 (90) IP 172.16.0.15.33202 > 183.60.82.98.domain: 4131+ AAAA? www.a.shifen.com. (34) IP 183.60.82.98.domain > 172.16.0.15.33202: 4131 0/1/0 (97) IP 172.16.0.15.56784 > 183.60.82.98.domain: 62464+ A? nfsd. (22) IP 183.60.82.98.domain > 172.16.0.15.56784: 62464 NXDomain 0/1/0 (97) IP 172.16.0.15.52671 > 183.60.82.98.domain: 62680+ A? time1.tencentyun.com. (38) IP 172.16.0.15.52671 > 183.60.82.98.domain: 26338+ AAAA? time1.tencentyun.com. (38) IP 183.60.82.98.domain > 172.16.0.15.52671: 26338 0/0/0 (38) IP 183.60.82.98.domain > 172.16.0.15.52671: 62680 1/0/0 A 169.254.0.79 (54) IP 172.16.0.15.37530 > 183.60.82.98.domain: 38947+ A? time2.tencentyun.com. (38) IP 172.16.0.15.37530 > 183.60.82.98.domain: 43047+ AAAA? time2.tencentyun.com. (38) IP 183.60.82.98.domain > 172.16.0.15.37530: 38947 1/0/0 A 169.254.0.80 (54) IP 183.60.82.98.domain > 172.16.0.15.37530: 43047 0/0/0 (38) IP 172.16.0.15.56400 > 183.60.82.98.domain: 33849+ A? time3.tencentyun.com. (38) IP 172.16.0.15.56400 > 183.60.82.98.domain: 31293+ AAAA? time3.tencentyun.com. (38) IP 183.60.82.98.domain > 172.16.0.15.56400: 31293 0/0/0 (38) IP 183.60.82.98.domain > 172.16.0.15.56400: 33849 1/0/0 A 169.254.0.81 (54) IP 172.16.0.15.52006 > 183.60.82.98.domain: 6166+ A? time4.tencentyun.com. (38) IP 172.16.0.15.52006 > 183.60.82.98.domain: 3610+ AAAA? time4.tencentyun.com. (38) IP 183.60.82.98.domain > 172.16.0.15.52006: 6166 1/0/0 A 169.254.0.82 (54) IP 183.60.82.98.domain > 172.16.0.15.52006: 3610 0/0/0 (38) IP 172.16.0.15.51365 > 183.60.82.98.domain: 37514+ A? time5.tencentyun.com. (38) IP 172.16.0.15.51365 > 183.60.82.98.domain: 34958+ AAAA? time5.tencentyun.com. (38) IP 183.60.82.98.domain > 172.16.0.15.51365: 37514 1/0/0 A 169.254.0.83 (54) IP 183.60.82.98.domain > 172.16.0.15.51365: 34958 0/0/0 (38)
下图是使用wireshark进行抓取DNS数据包
这是一个简单的DNS解析过程,序号为56的数据包显示的是DNS查询报文,序号为57是数据包是DNS应答报文。
下面我们讲讲56序号的详细数据。
这里我们展开了Domain Name System节点。客户端向服务器发送DNS查询报文,这是一个标准查询(Standard Query),我们可以理解为正向解析。
查询报文分为首部和问题两个部分。首部包含ID,标志和计数器3类字段。Opcode值为0表示标准查询。
Question为1表示只有一个查询报文,其他3个资源记录数均为0。问题部分给出了要查询的域名、类型、和类。
这个报文封装在UDP协议上,发往DNS服务器,传输的目的端口号为53.
下面我们讲讲57序号的详细数据。
这里我们展开了Domain Name System节点。服务器返回客户端DNS应答报文。应答报文分为首部、问题、回答、权威、附加5个部分。
首部包含ID,标志和计数器3类字段。ID与查询报文相同。Question为1表示只有一个查询报文,其他3个资源记录数给出了相应的数目,问题部分与查询部分相同
在展开Answers节点。每条记录都包括名称、类型、类、生存时间、数据长度和数据6个字段。
总结
nslookup 是流行的 DNS 探测命令行软件之一。 可以使用它来监控您的网络并发现有问题的区域。如果大家感兴趣,可以研究研究类似的工具,比如dig、traceroute 、ping等等。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。