译者:AndySong
在LinuxDNS查询分析-第一部份中,我介绍了:
但是发觉大多数程序选择要查询的DNS服务器时会参考/etc/resolv.conf配置文件。
这些方法在Linux上比较普遍1。其实我使用了特定的发行版Ubuntu,但背后的原理与Debian甚至是这些基于CentOS的发行版有相通的地方;其实,与更低或更高的Ubuntu版本相比,差别还是存在的。
也就是说,接出来,你主机上的行为很可能与我描述的不一致。
在第二部份中,我将介绍resolv.conf的更新机制、systemctlrestartnetworking命令的运行机制,以及dhclient是怎么参与其中。
1)自动更新/etc/resolv.conf
我们晓得/etc/resolv.conf(有极大的可能性)被用到,故你自然可以通过该文件降低一个nameserver,这么主机也将会(与已有的nameserver一起)使用新加入的nameserver吧?
你可以尝试如下:
$echonameserver10.10.10.10>>/etc/resolv.conf
看起来新的nameserver早已加入:
#Dynamicresolv.conf(5)fileforglibcresolver(3)generatedbyresolvconf(8)
#DONOTEDITTHISFILEBYHAND--YOURCHANGESWILLBEOVERWRITTEN
nameserver10.0.2.3
searchhome
nameserver10.10.10.10
但主机网路服务重启后问题出现了:
$systemctlrestartnetworking
$cat/etc/resolv.conf
#Dynamicresolv.conf(5)fileforglibcresolver(3)generatedbyresolvconf(8)
#DONOTEDITTHISFILEBYHAND--YOURCHANGESWILLBEOVERWRITTEN
nameserver10.0.2.3
searchhome
我们的10.10.10.10的nameserver不见了!
在上一篇文章中我们忽视了这一点linux什么命令用于dns服务解析,本文进行补充说明。
2)resolvconf
你在/etc/resolv.conf文件中见到generatedbyresolvconf短语了吧?这就是我们的线索。
假如深入研究systemctlrestartnetworking命令wps for linux,你会发觉它做了好多事情,结束时调用了/etc/network/if-up.d/000resolvconf脚本。在该脚本中,可以发觉一次对resolvconf命令的调用:
/sbin/resolvconf-a"${IFACE}.${ADDRFAM}"
稍为研究一下man指南,发觉-a参数容许我们:
AddoroverwritetherecordIFACE.PROGthenruntheupdatescripts
ifupdatingisenabled.
(降低或覆盖IFACE.PROG记录,假如开启更新选项,则运行更新脚本)
故而其实我们可以直接调用该命令降低namserver:
echo'nameserver10.10.10.10'|/sbin/resolvconf-aenp0s8.inet
测试表明确实可以!
$cat/etc/resolv.conf|grepnameserver
nameserver10.0.2.3
nameserver10.10.10.10
是否早已找到答案,这就是/etc/resolv.conf更新的逻辑?调用resolvconf将nameserver添加到某个地方的数据库,之后(“如果配置了更新”,先不管具体哪些含意)更新resolv.conf文件。
并非这么。
$systemctlrestartnetworking
root@linuxdns1:/etc#cat/etc/resolv.conf
#Dynamicresolv.conf(5)fileforglibcresolver(3)generatedbyresolvconf(8)
#DONOTEDITTHISFILEBYHAND--YOURCHANGESWILLBEOVERWRITTEN
nameserver10.0.2.3
searchhome
呃!(网路服务重启后)新增的nameserver再度消失了。
可见,systemctlrestartnetworking不仅仅运行了resolvconf红旗linux安装,还在其它地方获取nameserver信息。具体是那里呢?
3)ifup/ifdown
继续深入研究systemctlrestartnetworking,发觉它完成了一系列工作:
cat/lib/systemd/system/networking.service
[...]
[Service]
Type=oneshot
EnvironmentFile=-/etc/default/networking
ExecStartPre=-/bin/sh-c'["$CONFIGURE_INTERFACES"!="no"]&&[-n"$(ifquery--read-environment--list--exclude=lo)"]&&udevadmsettle'
ExecStart=/sbin/ifup-a--read-environment
ExecStop=/sbin/ifdown-a--read-environment--exclude=lo
[...]
首先,网路服务的重启实质是运行一个单触发(oneshot)的脚本,脚本包含如下命令:
/sbin/ifdown-a--read-environment--exclude=lo
/bin/sh-c'["$CONFIGURE_INTERFACES"!="no"]&&[-n"$(ifquery--read-environment--list--exclude=lo)"]&&udevadmsettle'
/sbin/ifup-a--read-environment
第一行使用ifdown关掉全部的网路插口,但本地回环(local,lo)插口除外。2
(LCTT评注:虽然这是由于很快就又启动了插口,间隔的时间没有超过TCP联接的超时时间,有人在评论中也做了类似回复)
第二行用于确认系统早已完成关掉网路插口相关的全部工作,便于下一步使用ifup启动插口。这也让我们了解到linux什么命令用于dns服务解析,网路服务实质运行的就是ifdown和ifup。
文档中没有找到--read-environment参数的说明,该参数为systemctl正常工作所需。好多人以文档不建立为由不喜欢systemctl。
挺好。这么ifup(和其成对出现的ifdown)究竟做了什么工作呢?长话短说,它运行了/etc/network/if-pre-up.d/和/etc/network/if-up.d/目录下的全部脚本;期间,这种脚本也可能会调用另外的脚本,依这种推。
其中一件工作就是运行了dhclient,但我还不完全确定具体的机理,其实udev参与其中。
4)dhclient
dhclient是一个程序,用于与DHCP服务器协商对应网路插口应当使用的IP地址的详尽信息。同时,它也可以获取可用的DNS服务器并将其替换到/etc/resolv.conf中。
让我们开始跟踪并模拟它的行为,但仅在我实验虚拟机的enp0s3插口上。事先早已删掉/etc/resolv.conf文件中的nameserver配置:
$sed-i'/nameserver.*/d'/run/resolvconf/resolv.conf
$cat/etc/resolv.conf|grepnameserver
$dhclient-renp0s3&&dhclient-venp0s3
Killedoldclientprocess
InternetSystemsConsortiumDHCPClient4.3.3