Ubuntu系列

Ubuntu 16.x

1)编辑或创建 /etc/dhcp/dhclient.conf文件。

注意:您必须拥有根用户权限才能编辑此文件。您可以使用sudo -i成为根用户,或者使用 sudo 执行所有命令。

2)将 supersede 命令添加到文件以覆盖 domain-name-servers。:

1
2
3
4

# /etc/dhcp/dhclient.conf 文件尾部追加
supersede domain-name-servers 172.22.xxx.xxx,10.xx.xx.202,10.xx.xx.244;
supersede domain-name "xxx.bilibili.xxx";

在此修改之后,resolv.conf 文件将在实例重启时或重启网络时更新,以仅包含您在 dhclient 文件中指定的 DNS 服务器。有关 supersede 命令的更多信息,请参阅 Linux 手册页上的 dhclient.conf(5)

3)重启实例或网络。

1
systemctl restart networking

Ubuntu 18.x ~ 22

默认情况下,在 Ubuntu 18.x 上,由 netplan.io 软件包处理网络接口配置,且由启用系统解析的服务使用存根解析程序处理 DNS 查询。存根解析程序 IP 位于 /etc/resolv.conf

在这些发行版中DNS被systemd-resolved模块接管。原来配置DNS的文件 /etc/resolv.conf 已经变成了指向systemd-resolve服务在本地侦听的端口 127.0.0.53:53。这个文件本身标注了不要修改,因为它已经变成了软连接,指向了systemd-resolve控制的配置文件。且修改完重启会被DHCP的配置覆盖,所以不能手动修改
ubuntudns
在18~22发行版中,所有的dns解析请求都会被劫持到本地127的这个localdns。再由localdns向上游云厂商提供的dns请求解析。
在不改的情况下,127.0.0.53:53的上游服务器是由云厂商dhcp服务器统一分配。这里100.100.2.x由阿里云分配而来
ubuntudns
运行以下步骤以覆盖厂商 DNS 服务器值:

1)Netplan 通常将配置文件存储在 /etc/netplan 目录中。创建名为 /etc/netplan/dns.yaml 的文件,然后通过以下行填充此文件。请务必将占位符 DNS 服务器 IP 地址替换为首选地址:

1
2
3
4
5
6
7
8
9
10
11
cat <<EOF > /etc/netplan/dns.yaml
network:
version: 2
ethernets:
eth0:
nameservers:
search: [host.bilibili.co]
addresses: [172.22.xxx.xx, 10.66.xxx.xxx, 10.68.xxx.xxx]
dhcp4-overrides:
use-dns: false
EOF

在进行这些更改后,仍然可以在 /etc/resolv.conf 中看到类似127.0.0.53。这是正常的。存根解析程序 IP 对于您的操作系统来说是本地的,在后台中,存根解析程序将使用您在前述 dns.yaml 文件中指定的 DNS 服务器。

2)重启服务器或运行 netplan apply 使生效

ubuntudns
符合预期

ubuntu 22验证方法
ubuntudns

Debian系列 8~11

debian的 /etc/resolv.conf配置文件中 也提示我们不要直接修改这个文件。
debiandns
它是一个软链接,指向 /run/resolvconf 目录下的“真实文件”。该文件是在系统启动时生成的;同时也是注释告诉我们不要直接修改该文件的原因。

经过了解,在网卡启动或机器启动时。系统中的dhclient程序即dhcp客户端。会向厂商的虚拟交换机发送dhcp请求获得网卡的 ip 网关 dns 等信息,并覆盖/etc/resolvconf/run/resolv.conf 文件。大致流程如下图:
debiandns
1)这里可以修改dhclient配置文件达到修改dns的目的,运行以下步骤以覆盖厂商 DNS 服务器值:

1
2
echo "supersede domain-name-servers 172.22.xxx.xxx,10.66.xxx.xxx,10.68.xxx.xxx;" >> /etc/dhcp/dhclient.conf
echo 'supersede domain-name "xxx.bilibili.xxx";' >> /etc/dhcp/dhclient.conf

2)重启网络服务或重启服务器使生效
debiandns

CentOS 7

默认情况下,由 NetworkManager 服务管理 resolv.conf 文件。该服务会通过 DHCP 提供的 DNS 服务器填充此文件。

方案1(推荐): 这里简单操作可以使用如下步骤,写入配置并锁定文件实现:

1
2
3
4
5
6
7
vi /etc/resolv.conf
nameserver 172.22.xxx.xxx
nameserver 10.66.xxx.xxx
nameserver 10.68.xxx.xxx

chattr +i /etc/dhcp/dhclient.conf
lsattr /etc/dhcp/dhclient.conf

方案2: 参照debian方案实现自定义dns

还需:在每个接口的配置文件 (/etc/sysconfig/network-scripts/ifcfg-*) 中将 PEERDNS 参数设置为 yes。

*方案3: 修改NetworkManager配置,阻止其接管 resolv.conf 文件

1)使用以下内容创建 /etc/NetworkManager/conf.d/disable-resolve.conf-managing.conf 文件:

1
2
[main]
dns=none

整理成脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#!/bin/bash
# 脚本支持Debian8~11 Ubuntu16~22 CentOS7 私有dns修改和配置锁定
Netplan(){
cat <<EOF > /etc/netplan/dns.yaml
network:
version: 2
ethernets:
eth0:
nameservers:
addresses: [172.22.xxx.xxx, 10.66.xxx.xxx, 10.68.xxx.xxx]
dhcp4-overrides:
use-dns: false
EOF
return $?
}

Dhclient(){
#查找是否存在配置,不存在则写入
grep "bilibili.co" /etc/dhcp/dhclient.conf
if [ $? -eq 0 ];then
echo "配置已存在"
else
echo "" >> /etc/dhcp/dhclient.conf &&\
echo "supersede domain-name-servers 172.22.xxx.xxx,10.66.xxx.xxx,10.68.xxx.xxx;" >> /etc/dhcp/dhclient.conf &&\
echo 'supersede domain-name "host.bilibili.co";' >> /etc/dhcp/dhclient.conf &&\
echo "dns写入成功"
fi
return $?
}

Ubuntu(){
#如果系统版本大于等于18,那么执行netplan修改dns,
if [ `echo "$os_version >= 18" | bc` -eq 1 ];then
echo "系统为${os}系统版本为${os_version},即将修改配置netplan"
Netplan && netplan apply &&\
chattr +i /etc/netplan/dns.yaml #锁定配置
else
#小于18版本的执行修改dhclient的配置文件
echo "系统为${os}系统版本为${os_version},即将修改dhclient配置文件"
Dhclient && systemctl restart networking &&\
chattr +i /etc/dhcp/dhclient.conf #锁定配置
fi
}

Debian(){
echo "系统为$os,即将修改dhclient配置文件"
Dhclient && systemctl restart networking &&\
chattr +i /etc/dhcp/dhclient.conf #锁定配置
}

Centos(){
\cp /etc/resolv.conf{,.bak}
cat >/etc/resolv.conf <<EOF
nameserver 172.22.xxx.xxx
nameserver 10.66.xxx.xxx
nameserver 10.68.xxx.xxx
options timeout:2 attempts:3 single-request-reopen
EOF
echo "系统为${os}系统版本为${os_version},即将修改/etc/resolv.conf"
chattr +i /etc/resolv.conf #锁定配置
return $?
}

main(){
[ $(id -u) != "0" ] && echo "请使用root身份执行" && exit 1
os=$(awk -F "[=\"]+" '$1~/^ID$/{print $2}' /etc/os-release)
os_version=$(awk -F "[=\"]+" '$1~/^VERSION_ID$/{print $2}' /etc/os-release)
case "$os" in
centos)
Centos
;;
ubuntu)
Ubuntu
;;
debian)
Debian
;;
esac
}

main