DNS 解析是一项重要的服务,如果它不能正常运行,域名将无法正确解析为 IP 地址,从而阻止其他网络服务正常工作。
因此,了解如何解决 Linux 客户端上的 DNS 问题并修复任何问题以减少中断同样重要。
在 DNS 查找过程中存在多个潜在故障点,例如在执行查找的系统、DNS 缓存或者外部 DNS 服务器上。
在这里,我们将介绍如何检查这些并执行各种测试以确定问题的确切位置。
本地服务器配置
首先,了解 /etc/nsswitch.conf 文件的“主机”部分很重要,主机的默认配置如下所示。
hosts: files dns myhostname
本质上,这意味着主机名解析将按照指定的顺序执行,从左到右。
首先检查文件,然后检查 DNS。
由于文件是第一个,这些将首先被检查,这引用了本地 /etc/hosts 文件,其中包含静态主机名到 IP 地址的映射。
此文件优先于任何 DNS 解析,对文件的任何更改都将直接放入该本地服务器的 DNS 缓存中。
下面是来自 /etc/hosts 的配置示例行
1.1.1.1 google.com
由于此条目位于我们本地的主机文件中,如果我们尝试访问 google.com,我们的本地计算机会认为 1.1.1.1 是 google.com 的正确 IP 地址,因此不会执行 DNS 查找。
下面通过尝试 ping google.com 来证明这一点,由于有一个优先级的主机文件条目,因此不会咨询 DNS。
[jack@onitroad ~]# ping google.com PING google.com (1.1.1.1) 56(84) bytes of data.
如果主机文件中没有条目,则接下来将根据 /etc/nsswitch.conf 使用 DNS。
用于 DNS 解析的服务器将在 /etc/resolv.conf 文件中指定,下面是该文件的示例配置。
nameserver 192.168.0.1
在这种情况下,我们系统的所有 DNS 查询都将转到位于 192.168.0.1 的 DNS 服务器。
其他二级和三级 DNS 服务器也可以在此处指定为备份。
测试 DNS
为了使 DNS 解析成功到 192.168.0.1,位于 192.168.0.1 的 DNS 服务器需要接受来自我们服务器的端口 53 上的 TCP 和 UDP 流量。
可以使用端口扫描器(例如 nmap 工具)来确认 DNS 服务器在端口 53 上是否可用,如下所示。
注意:要安装 nmap,请运行“yum install nmap -y”。
[jack@onitroad ~]# nmap -sU -p 53 192.168.0.1 Starting Nmap 6.40 ( http://nmap.org ) at 2014-08-26 15:22 AEST Nmap scan report for 192.168.0.1 Host is up (0.00091s latency). PORT STATE SERVICE 53/udp open|filtered domain MAC Address: 02:00:79:55:00:0D (Unknown) Nmap done: 1 IP address (1 host up) scanned in 0.29 seconds [jack@onitroad ~]# nmap -sT -p 53 192.168.0.1 Starting Nmap 6.40 ( http://nmap.org ) at 2014-08-26 15:22 AEST Nmap scan report for 192.168.0.1 Host is up (0.00099s latency). PORT STATE SERVICE 53/tcp open domain MAC Address: 02:00:79:55:00:0D (Unknown) Nmap done: 1 IP address (1 host up) scanned in 0.07 seconds
值得注意的是,由于 UDP 的性质,使用 nmap 扫描 UDP 是不可靠的,这就是为什么状态被列为打开或者过滤的原因。
我们可以清楚地看到 TCP 53 肯定是打开和响应的,这是一个好兆头,如果状态被报告为已过滤,接下来要调查的将是与 DNS 服务器的连接,特别是在 DNS 服务器上运行的任何防火墙都需要配置为允许 TCP 和 UDP 端口 53 流量进入。
通过运行数据包捕获,我们可以查看网络上的任何 DNS 查询,在此示例中,我们将 tcpdump 运行到位于 192.168.0.1 的本地 DNS 服务器,我们可以看到来自 192.168.0.100 的请求请求 google.com 的 A 记录为以及从我们本地 DNS 服务器返回的 216.58.220.142 的响应。
[jack@onitroad ~]# tcpdump -n host 192.168.0.1 tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes 15:29:52.439222 IP 192.168.0.100.32811 > 192.168.0.1.domain: 8134+ A? google.com. (28) 15:29:52.440153 IP 192.168.0.1.domain > 192.168.0.100.32811: 8134 1/0/0 A 216.58.220.142 (44)
Domain Information Groper (dig) 工具可用于执行 DNS 查询,如下所示。
我们再次查询 google.com,我们再次返回 A 记录 IP 地址 216.58.220.142.
注意:Dig 是由 bind-utils 包提供的,它可以通过 'yum install bind-utils' 安装。
[jack@onitroad ~]# dig google.com ; <<>> DiG 9.9.4-RedHat-9.9.4-18.el7_1.3 <<>> google.com ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 32536 ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0 ;; QUESTION SECTION: ;google.com. IN A ;; ANSWER SECTION: google.com. 65 IN A 216.58.220.142
dig 查询的状态正确返回了来自我们本地 DNS 服务器 192.168.0.1 的 IP 地址,状态为 NOERROR,当查询成功解析时返回。
响应代码可以进行故障排除过程,有关它们的完整列表,请参阅 RFC 5395.
测试权威 DNS 服务器
使用 dig 我们还可以直接查询域的权威名称服务器,这些是保存域 DNS 区域权威记录的 DNS 服务器,这是真实的来源。
如果从权威 DNS 服务器收到正确响应,但在查询我们自己的 DNS 服务器时没有收到正确响应,那么我们应该调查为什么本地 DNS 服务器无法解析记录。
要获取域的名称服务器,我们可以使用“whois”命令,如下所示。
这是 whois 包的一部分,如果不存在,可以使用“yum install whois -y”进行安装。
[jack@onitroad ~]# whois google.com | grep -i "name server" Name Server: NS1.GOOGLE.COM Name Server: NS2.GOOGLE.COM Name Server: NS3.GOOGLE.COM Name Server: NS4.GOOGLE.COM
如图所示,google.com 目前有 4 个权威名称服务器,如果我们直接针对其中任何一个运行 dig,我们应该会收到权威响应,这是直接来自源而不是来自我们本地 DNS 服务器的最新且非缓存的响应.在下面的示例中,我们针对 @ns1.google.com 运行了查询
[jack@onitroad ~]# dig @NS1.GOOGLE.COM google.com ; <<>> DiG 9.9.4-RedHat-9.9.4-18.el7_1.3 <<>> @NS1.GOOGLE.COM google.com ; (1 server found) ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 3477 ;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0 ;; WARNING: recursion requested but not available ;; QUESTION SECTION: ;google.com. IN A ;; ANSWER SECTION: google.com. 300 IN A 216.58.220.142
虽然在此实例中返回的 A 记录是相同的,但请注意,在此 dig 响应中,我们现在在标头中有“aa”标志,表示这是一个权威答案,而不是缓存响应。
如果我们再次运行相同的 dig 命令,则在答案部分返回的 300 秒 TTL 将不断声明 TTL 为 300 秒,因为响应是权威的。
但是,如果我们在不指定 @ns1.google.com 的情况下运行此 dig,我们将查询对 google.com 域不具有权威性的 192.168.0.1 DNS 服务器,在第一个结果之后,记录将在本地缓存。
这可以通过再次运行 dig 命令来确认,因为 TTL 值将下降直到达到 0 并从缓存中完全删除。
通过直接查询权威名称服务器,我们确保我们获得最新的响应,而不是来自我们自己的本地 DNS 服务器或者本地 DNS 缓存的潜在旧缓存响应。