ubuntu18.04的dns配置有点与众不同

ubuntu18.04的dns配置有点与众不同

转自:https://www.keepnight.com/archives/1772/

ubuntu18.04设置dns方法
以下两种方法都可以永久设置dns

直接修改interfaces文件
强烈推荐用这个方法,省心。
文件位置为/etc/network/interfaces,修改方法自行百度,反正有用,以前用过。
修改之后运行service networking restart,重启一下networking服务就行了。
直接修改base文件
文件位置为/etc/resolvconf/resolv.conf.d/base或者修改/etc/resolvconf/resolv.conf.d/tail
base、tail文件格式如下:

nameserver 114.114.114.114
nameserver 8.8.8.8
Bash
nameserver后面跟的是DNS的ip,修改之后运行service resolvconf restart,重启一下resolvconf服务就行了。

删除/etc/resolv.conf软链接

rm -rf /etc/resolv.conf
echo -e "nameserver 114.114.114.114\nnameserver 8.8.8.8\n" > /etc/resolv.conf
Bash
这种方法会导致系统不能使用网卡通过dhcp得来的dns。

ubuntu18.04下的域名解析机制
首先介绍下systemd-resolved和resolvconf的作用,忍不住吐槽一下linux配置dns好复杂。

/etc/resolved.conf是整个dns解析的核心文件,应该是一个规范文件,linux的有关的解析域名的系统api只从这个文件里面获取dns server。

resolvconf
resolvconf是一个ubuntu上管理配置本机dns地址的工具,不提供dns解析,可以使用它来配置修改/etc/resolved.conf的指向,不同程序运行的时候有时需要不同dns,而resolvconf使用了一个通用的接口文件让我们去配置不同程序的dns。

resolvconf提供修改dns的接口,程序中大致采用如下方式 使用resolvconf修改/etc/resolved.conf的指向(只是一个示意)。

将主机的dns配置文件/etc/resolved.conf/run/resolvconf/interface/systemd-resolved绑定,其实就是个软链接

yishen@ubuntu:/$ resolvconf -a /run/resolvconf/interface/systemd-resolved

更新/etc/resolv.conf文件的内容

yishen@ubuntu:/$ resolvconf -u
Bash
systemd-resolved
ubuntu中systemd-resolved服务为本地应用程序提供了域名解析服务, 实质上就是个二道贩子。
系统使用systemd-resolved进行dns请求的时候,除了一些localhost等特殊域名,它需要去外部dns服务器寻找答案,这个外部dns的地址可以手动配置或者自动配置。

systemd-resolved相关配置文件如下:

/etc/systemd/resolved.conf
/usr/lib/systemd/resolv.conf
/run/systemd/resolve/stub-resolv.conf
/run/systemd/resolve/resolv.conf
Bash
systemd-resolved的作用归纳起来就两种:

第一种作用:在自己本地上虚拟一个dns服务器,然后这个dns服务器在向别的dns服务器发起域名解析请求,好处就是所有的域名解析请求都需要从systemd-resolved经过,systemd-resolved可以对域名解析请求做些处理,比如分流,然后再转发给公网dns。
第二种作用:systemd-resolved读取/etc/resolved.conf文件,域名解析请求直接走linux的有关的解析域名的系统api,不经过systemd-resolved,这种情况systemd-resolved貌似没啥作用,应该可以直接卸载。


systemd-resolved总共有三种模式:

使用 ln -s /run/systemd/resolve/resolv.conf /etc/resolv.conf 。通过修改/etc/systemd/resolved.conf来修改systemd-resolved使用的dns服务器,这个时候systemd-resolved没啥作用,应该可以直接卸载。该种模式属于第二种作用。
使用 ln -s /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf。所有的域名解析请求都需要从systemd-resolved经过,systemd-resolved可以对域名解析请求做些处理,/run/systemd/resolve/stub-resolv.conf文件内容修改后重启服务失效,通过修改/etc/systemd/resolved.conf来修改systemd-resolved中的Global中的Current DNS Server。该种模式属于第一种作用。

/run/systemd/resolve/stub-resolv.conf 内容如下:

可以看到127.0.0.53就是在自己本地上虚拟一个dns服务器

使用ln -s /usr/lib/systemd/resolv.conf /etc/resolv.conf。/usr/lib/systemd/resolv.conf这个文件内容和/run/systemd/resolve/stub-resolv.conf 文件内容相同,但是对/usr/lib/systemd/resolv.conf的修改不影响/run/systemd/resolve/stub-resolv.conf,/usr/lib/systemd/resolv.conf 应该就是个模板文件,通过修改/etc/systemd/resolved.conf来修改systemd-resolved使用的dns服务器。该种模式属于第一种作用。
systemd-resolved从哪获得要使用的dns服务器?
使用systemd-resolve --status来查看目前systemd-resolved使用的dns服务器。
使用resolvectl status或者resolvectl来查看resolvconf设置的dns服务器。

Global中的Current DNS Server选项是由/etc/systemd/resolved.conf决定的,Link 2中的Current DNS Server选项是由/etc/network/interfaces或者/etc/netplan/50-cloud-init.yaml文件决定的(ps:其实就是DHCP自动设置的DNS)。这个时候域名解析请求请求的流程如下:

systemd-resolved会同时向Global和Link2中的Current DNS Server发出域名解析请求。

DNS服务器来自于 全局配置文件(/etc/systemd/resolved.conf)、 针对单个连接的静态配置文件(/etc/systemd/network/*.network)、 针对单个连接的动态配置(从DHCP或其他系统服务得到的DNS服务器)。为了提高兼容性, 仅在 /etc/resolv.conf 不是一个指向 /run/systemd/resolve/resolv.conf 的软连接的情况下, 才会从 /etc/resolv.conf 读取全局DNS服务器。
Bash
使用systemctl restart systemd-resolved.service重启systemd-resolved服务

resolvconf从哪获得要使用的dns服务器?
使用resolvectl status或者resolvectl来查看resolvconf设置的dns服务器(ps:其实就是/run/resolvconf/resolv.conf这个文件的内容)。

Global中的Current DNS Server选项无法设置。Link 2中的Current DNS Server选项是由/run/resolvconf/resolv.conf文件决定的。

默认情况下ubuntu16.04和ubuntu18.04系统中/etc/resolv.conf软连接指向/run/resolvconf/resolv.conf,原因是ubuntu一般会安装resolvconf去管理dns地址。resolvconf通过获取DHCP自动设置的DNS(/etc/network/interfaces或者/etc/netplan/50-cloud-init.yaml)来维护/run/resolvconf/resolv.conf从而维护整个系统默认使用的dns)。

resolvconf没有提供修改/run/resolvconf/resolv.conf的直接方法。要修改/run/resolvconf/resolv.conf必须通过修改/etc/resolvconf/resolv.conf.d/base或者/etc/resolvconf/resolv.conf.d/tail文件,不然重启会失效。

使用service resolvconf restart重启resolvconf服务

分流DNS
设想一个这样的场景,使域名解析请求被发送到指定的dns服务器上。
修改/etc/systemd/resolved.conf为下面的:

[Resolve]
DNS=202.101.224.68
Domains=~qq.com
Bash
重启systemed-resolved服务
这样域名解析请求会被优先发送到Global中的Current DNS Server。

设置默认后缀
修改/etc/systemd/resolved.conf为下面的:

[Resolve]
DNS=202.101.224.68
Domains=moneyslow.com
Bash
重启systemed-resolved服务
然后ping www,会被默认解析为ping www.moneyslow.com