DNS 服务器
一、DNS 基础概念
1. DNS 定义与作用
- 全称:Domain Name System(域名系统),是互联网核心服务之一。
- 核心功能 :将易于记忆的域名(如www.example.com)转换为机器可识别的 IP 地址,同时作为存储网络主机和资源目录的分层命名系统,通过资源记录映射网络名称与资源。
2. DNS 层次结构
DNS 采用树形分层结构,从上至下依次为:
层级 | 名称 | 说明 | 示例 |
---|---|---|---|
第 1 层 | 根域 | 层次结构最顶层,用独立的 "." 表示,由 IANA(互联网号码分配机构)管理 | . |
第 2 层 | 顶级域(TLD) | 根域下的第一层域,分为通用顶级域和国家代码顶级域 | 通用 TLD:.com、.edu、.net;国家代码 TLD:.cn、.uk、.us |
第 3 层 | 二级域 | 顶级域下的自定义域,由组织 / 个人申请使用 | linux.fun、redhat.com、baidu.com |
第 4 层及以下 | 子域(Subdomain) | 二级域下的细分域,可无限层级划分 | lab.linux.fun(linux.fun 的子域)、server.lab.linux.fun(lab.linux.fun 的子域) |
最底层 | 主机(Host) | 具体的网络设备(服务器、客户端) | www.baidu.com(主机 www)、dns.linux.fun(主机 dns) |
3. 关键术语区分
术语 | 定义 | 核心差异 |
---|---|---|
Domain(域) | 资源记录(RR)的集合,以通用名结尾,代表 DNS 命名空间的整个子树 | 域是 "逻辑概念",包含整个子树的所有资源记录 |
Subdomain(子域) | 另一个域的完整子树的域,描述域之间的从属关系 | 子域是域的 "子集",如 lab.linux.fun 是 linux.fun 的子域 |
Zone(区域) | 特定名称服务器直接负责的域,可能是整个域或域的一部分,可将子域委派给其他服务器 | 区域是 "管理单元",对应名称服务器的管理范围,一个域可拆分为多个区域 |
4. 顶级域(TLD)分类
- 通用顶级域(gTLD):按主题组织,由 IANA 委派管理,如.com(商业)、.edu(教育)、.org(非营利组织)、.gov(政府),部分 gTLD 由特定机构管理(如.abarth 由菲亚特克莱斯勒管理)。
- 国家代码顶级域(ccTLD):按 ISO3166-1 标准划分,对应国家 / 地区,如.cn(中国)、.uk(英国)、.jp(日本),由各国本地机构管理。
- 参考来源:IANA 根域数据库
二、DNS 查询机制
DNS 查询核心目的是获取域名对应的 IP 地址,主要分为递归查询 和迭代查询,查询类型由 DNS 请求报头的 RD 字段决定(RD=1 为递归,RD=0 为迭代)。
1. 递归查询(默认方式)
核心逻辑
以本地名称服务器为中心,DNS 客户端仅发送 1 次查询请求,之后等待本地服务器返回最终结果(本地服务器代替客户端完成后续所有查询步骤)。
查询流程(以解析www.example.com为例)
- 客户端向本地名称服务器(如 dns.linux.fun)发送 "解析www.example.com" 的请求,随后等待结果。
- 本地服务器先查本地缓存:若有记录,直接返回结果;若无,以 "客户端身份" 向根服务器发起查询。
- 根服务器返回.com 顶级域对应的顶级名称服务器地址。
- 本地服务器向.com 顶级名称服务器查询,获取example.com二级域对应的二级名称服务器地址。
- 本地服务器向example.com二级名称服务器查询,获取www.example.com对应的权威名称服务器地址。
- 本地服务器向权威名称服务器查询,获取www.example.com的 IP 地址。
- 本地服务器将 IP 地址返回给客户端,并缓存该记录(供后续查询复用)。
特点
- 客户端操作简单:仅发起 1 次请求,等待最终结果。
- 本地服务器负担重:需完成所有中间查询步骤。
- 部分服务器可能禁用递归(避免负载过高或 DNS 放大攻击)。
2. 迭代查询
核心逻辑
以DNS 客户端为中心,客户端需自行向各级名称服务器(本地、根、顶级、二级、权威)依次发起查询,每级服务器仅返回 "下一级服务器地址",直至客户端从权威服务器获取最终结果。
查询流程(以解析www.example.com为例)
- 客户端向本地名称服务器发送查询请求,本地服务器若无缓存,返回根服务器地址。
- 客户端向根服务器查询,根服务器返回.com 顶级名称服务器地址。
- 客户端向.com 顶级名称服务器查询,返回example.com二级名称服务器地址。
- 客户端向example.com二级名称服务器查询,返回www.example.com的权威名称服务器地址。
- 客户端向权威名称服务器查询,获取www.example.com的 IP 地址。
特点
- 客户端操作复杂:需多次发起查询,跟踪查询链。
- 服务器负担轻:仅返回下一级服务器地址,不代查。
- 适合客户端具备自主查询能力的场景(如服务器间通信)。
3. 两种查询对比
对比维度 | 递归查询 | 迭代查询 |
---|---|---|
核心角色 | 本地名称服务器(代理) | DNS 客户端(自主查询) |
客户端请求次数 | 1 次(仅初始请求) | 多次(每级服务器 1 次) |
服务器响应内容 | 最终结果(IP 或查询失败) | 下一级服务器地址(中间结果) |
适用场景 | 普通用户客户端(如 PC、手机) | 名称服务器间通信、特殊需求客户端 |
三、DNS 资源记录(RR)
资源记录是 DNS 区域文件的核心内容,用于存储域名与资源的映射关系,所有记录遵循统一格式:
owner-name [TTL] class type data
字段 | 说明 | 示例 |
---|---|---|
owner-name | 资源记录对应的域名(主机名 / 域) | server.linux.fun.、linux.fun. |
TTL | 生存时间(秒),表示记录在缓存中保留的时间,可省略(使用默认值) | 3600(1 小时)、86400(1 天) |
class | 地址类别,几乎均为 "IN"(Internet) | IN |
type | 资源记录类型,决定 data 字段的格式和含义 | A、AAAA、CNAME、PTR、NS、SOA、MX |
data | 记录的具体数据,格式随 type 变化 | 192.168.1.10(A 记录)、mail.linux.fun.(MX 记录) |
常见资源记录类型详解
记录类型 | 作用 | 数据格式 | 示例 | 注意事项 |
---|---|---|---|---|
A | 将主机名映射到 IPv4 地址 | IPv4 地址 | server.linux.fun. 3600 IN A 10.1.8.10 | 一个主机可对应多个 A 记录(实现 DNS 轮询) |
AAAA | 将主机名映射到 IPv6 地址 | IPv6 地址 | a.root-servers.net. 604800 IN AAAA 2001:503:ba3e::2:30 | 与 A 记录功能类似,仅适用于 IPv6 |
CNAME | 将一个域名(别名)映射到另一个域名(规范名) | 规范域名(需有 A/AAAA 记录) | www-dev.linux.fun. 30 IN CNAME ab.linux.fun. | 1. 避免 CNAME 链(如 A→B→C),影响效率;2. NS/MX 记录不可指向 CNAME;3. 最终需解析到 A/AAAA 记录 |
PTR | 将 IP 地址反向映射到主机名(反向 DNS 解析) | 主机名 | 10.8.1.10.in-addr.arpa. 7200 IN PTR server.linux.fun. | 1. IPv4:IP 反转后加.in-addr.arpa(如 10.1.8.10→10.8.1.10.in-addr.arpa);2. IPv6:IP 按半字节拆分反转后加.ip6.arpa |
NS | 指定对某个域具有权威性的名称服务器 | 名称服务器主机名(需有 A/AAAA 记录) | linux.fun. 86400 IN NS dns.linux.fun. | 1. 一个域至少需 2 个 NS 记录(提高可靠性);2. 父域的 NS 记录指向子域的权威服务器 |
SOA | 起始授权机构记录,每个区域必须有 1 个,包含区域管理信息 | 主服务器名、管理员邮箱、序列号、刷新时间等 | linux.fun. 86400 IN SOA dns.linux.fun. root.linux.fun. (2024050101 3600 300 604800 60) | 关键参数:- 序列号:区域文件版本号,修改后需递增;- 刷新时间:从服务器向主服务器同步的频率;- 过期时间:从服务器同步失败后,停止响应查询的时间 |
MX | 指定接收某个域电子邮件的邮件服务器 | 优先级(数字越小优先级越高)+ 邮件服务器主机名 | linux.fun. 86400 IN MX 10 mail.linux.fun. | 1. 多个 MX 记录可设置不同优先级(实现冗余);2. 邮件服务器需有 A/AAAA 记录 |
TXT | 存储任意 ASCII 文本,用于验证域所有权、电子邮件认证(如 SPF、DKIM) | 文本字符串(需用引号包裹) | linux.fun. 27272 IN TXT "v=spf1 a:mail.linux.fun -all" | 常见用途:Google 站点验证、防止邮件伪造 |
SRV | 指示域中提供特定服务的主机(如 LDAP、SIP) | 优先级、权重、端口、服务主机名 | _ldap._tcp.linux.fun. 86400 IN SRV 0 100 389 server.linux.fun. | 格式:_服务._协议.域. TTL class SRV 优先级 权重 端口 主机名 |
四、权威名称服务器配置(BIND)
权威名称服务器存储 DNS 区域的资源记录,为客户端提供 "权威答案"。Linux 中常用BIND(Berkeley Internet Name Domain) 软件实现,支持主服务器(Primary)和从服务器(Secondary)架构。
1. BIND 核心架构
- 主服务器(Primary):直接管理区域文件,是区域的 "权威源",可修改资源记录。
- 从服务器(Secondary):从主服务器同步区域文件(区域传输),仅提供查询服务,不可直接修改记录,用于分担负载和提高可靠性。
- 注意:BIND 旧版本中主 / 从服务器称为 Master/Slave,BIND 9.16 ESV 及以后版本统一为 Primary/Secondary。
2. BIND 安装与基础配置
(1)安装软件包
bash
# RHEL/CentOS 8+
dnf install -y bind bind-utils # bind:服务器端;bind-utils:客户端工具(dig、host等)
# Ubuntu/Debian
apt install -y bind9 bind9utils
(2)核心配置文件
路径 | 作用 | 权限要求 |
---|---|---|
/etc/named.conf | BIND 主配置文件,定义监听地址、访问控制、区域关联等 | 所有者 root:named,权限 0640,SELinux 标签 named_conf_t |
/var/named/ | 区域文件存储目录,存放正向 / 反向区域的资源记录文件 | 区域文件所有者 root:named,权限 0640,SELinux 标签 named_zone_t |
(3)关键配置步骤
以配置linux.fun
正向区域和10.1.8.0/24
反向区域为例:
步骤 1:定义地址匹配列表(ACL)
在/etc/named.conf
开头添加 ACL,用于简化访问控制配置:
bash
acl trusted-nets { 10.1.8.0/24; 192.168.1.0/24; }; # 信任的网络
acl classroom { 10.1.8.0/24; }; # 教室网络(示例)
BIND 内置 4 个 ACL:
none
:不匹配任何主机;any
:匹配所有主机;localhost
:匹配 DNS 服务器自身的所有 IP;localnets
:匹配 DNS 服务器所在的本地子网。
步骤 2:配置监听地址
在/etc/named.conf
的options
块中指定 BIND 监听的 IP 和端口(默认端口 53):
bash
options {
listen-on port 53 { 127.0.0.1; 10.1.8.10; }; # IPv4监听地址(本地回环+服务器IP)
listen-on-v6 port 53 { ::1; 2001:db8:2020::5300; }; # IPv6监听地址(可选)
directory "/var/named"; # 区域文件存放目录
dump-file "/var/named/data/cache_dump.db";
statistics-file "/var/named/data/named_stats.txt";
};
步骤 3:配置访问控制
在options
块中添加查询、递归、区域传输的控制规则:
bash
options {
# 允许所有主机查询(公开权威服务器需设置)
allow-query { any; };
# 禁止递归(权威服务器建议禁用,防止DNS放大攻击)
recursion no;
# 仅允许从服务器和本地进行区域传输
allow-transfer { 10.1.8.11; localhost; }; # 10.1.8.11为从服务器IP
};
步骤 4:配置区域(正向 + 反向)
在/etc/named.conf
末尾添加区域定义,关联区域名称与区域文件:
bash
# 正向区域:linux.fun(主服务器)
zone "linux.fun" IN {
type master; # 角色:主服务器
file "linux.fun.zone"; # 区域文件路径(相对/var/named)
};
# 反向区域:10.1.8.0/24(IP反转后为8.1.10.in-addr.arpa)
zone "8.1.10.in-addr.arpa" IN {
type master;
file "8.1.10.zone";
};
步骤 5:创建区域文件
-
正向区域文件(/var/named/linux.fun.zone):
bash$TTL 3600 # 默认TTL:1小时 @ IN SOA dns.linux.fun. root.linux.fun. ( 2024050101 # 序列号(格式:年月日+版本,如2024050101表示2024年5月1日第1版) 3600 # 刷新时间(从服务器同步频率:1小时) 300 # 重试时间(同步失败后重试间隔:5分钟) 604800 # 过期时间(同步失败后停止响应:7天) 60 # 负缓存时间(记录不存在时缓存:1分钟) ) @ IN NS dns.linux.fun. # 区域的权威名称服务器 dns IN A 10.1.8.10 # dns.linux.fun的IPv4地址 server IN A 10.1.8.10 # server.linux.fun的IPv4地址 client IN A 10.1.8.11 # client.linux.fun的IPv4地址 www IN A 10.1.8.200 # www.linux.fun的IPv4地址 student IN CNAME client.linux.fun. # student是client的别名 @ IN MX 10 mail.linux.fun. # 邮件服务器(优先级10) mail IN A 10.1.8.253 # mail.linux.fun的IPv4地址
说明:
@
代表区域名称(如linux.fun
),避免重复书写;无owner-name
的记录,继承上一条的owner-name
。 -
反向区域文件(/var/named/8.1.10.zone):
bash$TTL 3600 @ IN SOA dns.linux.fun. root.linux.fun. ( 2024050101 3600 300 604800 60 ) @ IN NS dns.linux.fun. 10 IN PTR server.linux.fun. # 10.1.8.10 → server.linux.fun 11 IN PTR client.linux.fun. # 10.1.8.11 → client.linux.fun 11 IN PTR student.linux.fun. # 10.1.8.11 → student.linux.fun(一个IP可对应多个PTR) 200 IN PTR www.linux.fun. # 10.1.8.200 → www.linux.fun 253 IN PTR mail.linux.fun. # 10.1.8.253 → mail.linux.fun
说明:反向区域中,
owner-name
为 IP 的最后一段(如 10.1.8.10 的最后一段为 10)。
(4)验证配置与启动服务
bash
# 1. 验证主配置文件语法
named-checkconf # 无输出表示语法正确
# 2. 验证区域文件语法
named-checkzone linux.fun /var/named/linux.fun.zone # 正向区域
named-checkzone 8.1.10.in-addr.arpa /var/named/8.1.10.zone # 反向区域
# 3. 启动BIND服务并设置开机自启
systemctl enable --now named
systemctl status named # 查看服务状态
# 4. 开放防火墙DNS服务(端口53,UDP+TCP)
firewall-cmd --add-service=dns --permanent
firewall-cmd --reload
3. 客户端测试
bash
# 1. 配置客户端DNS(指向BIND服务器IP 10.1.8.10)
nmcli connection modify ens32 ipv4.dns 10.1.8.10
nmcli connection up ens32
# 2. 测试域名解析(使用host/dig工具)
host www.linux.fun # 解析www.linux.fun
dig @10.1.8.10 linux.fun MX # 指定服务器查询MX记录
dig @10.1.8.10 -x 10.1.8.11 # 反向解析10.1.8.11
4.总结
bash
`# 配置DNS服务器过程
#1. 安装软件包
[root@server ~]# yum install -y bind bind-utils
#2. 修改配置文件
[root@server ~ 14:59:13]# vim /etc/named.conf
#2.1 增加监听ip
listen-on port 53 { 127.0.0.1;10.1.8.10; };
#2.2 放行客户端
allow-query { localhost;10.1.8.0/24; };
// allow-query { localhost;any; };
#2.3 关闭安全认证
dnssec-enable yes;
dnssec-validation no;
#2.4 最后添加正向解析和反向解析配置
zone "qy.cloud." IN {
type master;
file "qy.cloud.zone";
};
zone "8.1.10.in-addr.arpa" IN {
type master;
file "10.1.8.zone";
};
额外说明:
// dns服务器相关文件存放位置
directory "/var/named";
// 允许递归查询
recursion yes;
#2.5 在 /var/named 目录中创建文件 qy.cloud.zone
[root@server ~ 15:13:13]# cd /var/named/
[root@server named 15:13:24]# cp -a named.localhost qy.cloud.zone
[root@server named 15:13:24]# vim qy.cloud.zone
$TTL 3600
@ IN SOA dns.qy.cloud. admin.qy.cloud. (
42 ; serial
3H ; secondary refresh
15M ; secondary retry
1W ; secondary timeout
15M ; minimum cache TTL for negative answers
)
IN NS dns.qy.clound.
dns IN A 10.1.8.10
server IN A 10.1.8.10
student IN CNAME client.qy.cloud.
client IN A 10.1.8.11
www 30 IN A 10.1.8.200
@ IN MX 10 mail.qy.cloud.
mail IN A 10.1.8.253
#说明:
#示例说明:
#- @字符代表区域的名称,避免重复键入,并且在某些情况下允许重复使用。
#- 区域文件中的SOA记录与前面的示例中的SOA记录是等效的。
#- 如果记录的名称为空,则其值与前面的记录相同。
#-因此,在前面的示例中:
#- 第一个记录是qy.cloud.的SOA记录
#- 接下来的记录是qy.cloud.的NS记录
#- 然后有一个dns的A记录。
#- 然后有一个server的A记录。
#- 然后有一个student的CNAME记录。
#- 然后有一个client的A记录。
#- 然后有一个域的MX记录。
#- 然后有一个mail的A记录。
#2.6 在 /var/named 目录中创建文件 10.1.8.zone
[root@server named 15:17:59]# cp -a named.loopback 10.1.8.zone
[root@server named 15:19:15]# vim 10.1.8.zone
$TTL 3600
@ IN SOA dns.qy.cloud. admin.qy.cloud. (
42 ; serial
3H ; secondary refresh
15M ; secondary retry
1W ; secondary timeout
15M ; minimum cache TTL for negative answers
)
IN NS dns.qy.cloud.
10 IN PTR server.qy.cloud.
10 IN PTR dns.qy.cloud.
11 IN PTR client.qy.cloud.
11 IN PTR student.qy.cloud.
200 IN PTR www.qy.cloud.
253 IN PTR mail.qy.cloud.
#2.7 验证配置
验证 总配置文件
[root@server ~]# named-checkconf
验证 zone 文件
[root@server ~]# named-checkzone qy.cloud /var/named/qy.cloud.zone
#2.8 启动服务
[root@server ~]# systemctl enable named --now
[root@server ~]# systemctl status named
#2.9 配置客户端dns为10.1.8.10
[root@client ~ 15:57:15]# nmcli connection modify ens33 ipv4.dns 10.1.8.10
[root@client ~ 15:57:27]# nmcli connection up ens33
#2.10 确保客户端/etc/hosts 只有localhost记录
[root@client ~ 15:58:57]# cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
#2.11 使用 getent 尝试解析相关域名
[root@client ~ 16:03:15]# getent hosts student
10.1.8.11 client.qy.cloud student.qy.cloud
[root@client ~ 16:04:42]# getent hosts dns
10.1.8.10 dns.qy.cloud
[root@client ~ 16:06:07]# getent hosts www
10.1.8.200 www.qy.cloud
#2.12 使用 dig 尝试解析
[root@client ~ 16:07:51]# yum install -y bind-utils
[root@client ~ 16:11:07]# dig @10.1.8.10 server.qy.cloud
; <<>> DiG 9.11.4-P2-RedHat-9.11.4-26.P2.el7_9.16 <<>> @10.1.8.10 server.qy.cloud
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 63645
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 2
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;server.qy.cloud. IN A
;; ANSWER SECTION:
server.qy.cloud. 3600 IN A 10.1.8.10
;; AUTHORITY SECTION:
qy.cloud. 3600 IN NS dns.qy.cloud.
;; ADDITIONAL SECTION:
dns.qy.cloud. 3600 IN A 10.1.8.10
;; Query time: 2 msec
;; SERVER: 10.1.8.10#53(10.1.8.10)
;; WHEN: 四 9月 25 16:11:17 CST 2025
;; MSG SIZE rcvd: 97
[root@client ~ 16:11:17]# dig @10.1.8.10 -x 10.1.8.200
; <<>> DiG 9.11.4-P2-RedHat-9.11.4-26.P2.el7_9.16 <<>> @10.1.8.10 -x 10.1.8.200
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 18723
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 2
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;200.8.1.10.in-addr.arpa. IN PTR
;; ANSWER SECTION:
200.8.1.10.in-addr.arpa. 3600 IN PTR www.qy.cloud.
;; AUTHORITY SECTION:
8.1.10.in-addr.arpa. 3600 IN NS dns.qy.cloud.
;; ADDITIONAL SECTION:
dns.qy.cloud. 3600 IN A 10.1.8.10
;; Query time: 1 msec
;; SERVER: 10.1.8.10#53(10.1.8.10)
;; WHEN: 四 9月 25 16:12:11 CST 2025
;; MSG SIZE rcvd: 115`
五、缓存名称服务器配置
缓存名称服务器(Caching-only Server)不管理任何区域,仅缓存其他服务器的查询结果,减少重复查询,提高解析效率。常用软件包括Unbound 、Dnsmasq、BIND(可配置为缓存模式)。
1. Unbound 配置(轻量级缓存服务器)
(1)安装与基础配置
bash
# 安装Unbound
dnf install -y unbound
# 核心配置文件:/etc/unbound/unbound.conf
(2)关键配置项
bash
server:
# 1. 配置监听地址(允许局域网客户端访问)
interface: 10.1.8.20 # 服务器IP(缓存服务器IP)
interface: 127.0.0.1 # 本地回环
interface-automatic: no # 手动指定监听地址时设为no
# 2. 配置访问控制(仅允许信任网络递归查询)
access-control: 127.0.0.0/8 allow # 本地
access-control: 10.1.8.0/24 allow # 局域网
access-control: 0.0.0.0/0 refuse # 拒绝其他网络
# 3. 转发查询(可选,转发至权威服务器或公网DNS)
forward-zone:
name: "." # 转发所有查询
forward-addr: 10.1.8.10 # 转发至BIND权威服务器
# forward-addr: 8.8.8.8 # 或转发至Google DNS
# 4. 禁用DNSSEC验证(可选,内部域未签名时设置)
domain-insecure: "linux.fun"
(3)启动与测试
bash
# 验证配置
unbound-checkconf
# 启动服务
systemctl enable --now unbound
firewall-cmd --add-service=dns --permanent && firewall-cmd --reload
# 客户端测试(客户端DNS指向缓存服务器10.1.8.20)
dig @10.1.8.20 www.linux.fun
(4)缓存管理
bash
# 导出缓存到文件
unbound-control dump_cache > /tmp/dns_cache.txt
# 清空指定域名缓存
unbound-control flush student.linux.fun
# 清空整个区域缓存
unbound-control flush_zone linux.fun
# 导入缓存(从文件恢复)
unbound-control load_cache < /tmp/dns_cache.txt
2. Dnsmasq 配置(多功能轻量工具)
Dnsmasq 集DNS 缓存 、DHCP 服务器 、DHCP 中继 、PXE 引导于一体,适合小型网络(如家庭、办公室)。
(1)安装与核心功能
bash
# 安装Dnsmasq
dnf install -y dnsmasq
# 核心配置文件:/etc/dnsmasq.conf
(2)DNS 缓存关键配置
bash
# 1. 指定上游DNS服务器(从该文件获取上游地址)
resolv-file=/etc/resolv.dnsmasq.conf
# 2. 严格按上游顺序解析
strict-order
# 3. 监听地址(局域网IP+本地回环)
listen-address=127.0.0.1,10.1.8.30
# 4. 自定义解析(A记录):将ad域名解析到127.0.0.1(屏蔽广告)
address=/ad.youku.com/127.0.0.1
address=/ad.iqiyi.com/127.0.0.1
# 5. 按域指定上游DNS(智能DNS)
server=/cn/114.114.114.114 # .cn域使用114DNS
server=/google.com/8.8.8.8 # Google域使用Google DNS
# 6. 禁止DNS劫持(将劫持IP设为无效)
bogus-nxdomain=10.0.0.1 # 假设10.0.0.1是ISP劫持IP
(3)创建上游 DNS 文件
bash
# /etc/resolv.dnsmasq.conf(上游DNS列表)
nameserver 8.8.8.8
nameserver 8.8.4.4
nameserver 114.114.114.114
(4)启动与测试
bash
# 验证配置
dnsmasq -test # 输出"dnsmasq: syntax check OK."表示正确
# 启动服务
systemctl enable --now dnsmasq
firewall-cmd --add-service=dns --permanent && firewall-cmd --reload
# 客户端测试(DNS指向10.1.8.30)
dig @10.1.8.30 www.baidu.com
(5)解析流程
Dnsmasq 按以下顺序解析域名:
/etc/hosts
文件 → 2./etc/dnsmasq.d/*.conf
(自定义配置) → 3./etc/dnsmasq.conf
→ 4. 上游 DNS 服务器。
六、DNS 问题排查
1. 网络连接问题
(1)核心排查点
- 端口连通性:DNS 使用端口 53(UDP 为主,大响应时用 TCP),需确保客户端与服务器间 53 端口双向通畅。
- 防火墙规则 :检查服务器和客户端防火墙是否放行 DNS 服务(
firewall-cmd --list-services
)。
(2)测试命令
bash
# 测试UDP端口53连通性
nc -zv -u 10.1.8.10 53
# 测试TCP端口53连通性
nc -zv 10.1.8.10 53
# 若dig提示"Truncated, retrying in TCP mode",表示UDP响应超过512字节,需检查TCP端口
2. DNS 响应代码解析
DNS 查询响应的status
字段反映查询结果,常见代码及排查方向:
响应代码 | 含义 | 可能原因 | 排查建议 |
---|---|---|---|
NOERROR | 查询成功,但记录可能来自缓存 | - | 1. 用dig 查看aa 标志(aa=1 表示权威响应,aa=0 表示缓存响应);2. 检查记录 TTL 是否过期 |
SERVFAIL | 名称服务器处理查询时出错 | 1. 权威服务器不可达;2. 服务器间网络故障;3. DNSSEC 验证失败 | 1. 用dig +trace 跟踪查询链;2. 检查权威服务器状态;3. 禁用 DNSSEC 测试(如 Unbound 的domain-insecure ) |
NXDOMAIN | 查询的域名不存在 | 1. 域名拼写错误;2. 区域文件中无该记录;3. CNAME 记录孤立(规范名无 A/AAAA 记录);4. 负缓存未过期 | 1. 检查区域文件是否有该记录;2. 清除本地缓存(systemctl restart named/unbound );3. 验证 CNAME 链是否完整 |
REFUSED | 服务器因策略拒绝查询 | 1. 客户端 IP 不在allow-query /allow-recursion 列表;2. 服务器禁用递归;3. 客户端查询错误的服务器 |
1. 检查服务器allow-query /allow-recursion 配置;2. 确认客户端 DNS 指向正确;3. 权威服务器需开启allow-query { any; } |
3. 常见 Zone 数据问题
(1)DNS 轮询配置错误
- 问题:添加新 A 记录后未删除旧记录,导致部分客户端解析到退役 IP。
- 排查 :
dig www.linux.fun
查看是否有多个 A 记录,确认所有 IP 均有效。
(2)反向查询失败(缺少 PTR 记录)
- 问题:SSH 连接延迟、邮件发送被拒(部分邮件服务器验证反向 DNS)。
- 排查 :
dig -x 10.1.8.11
查看是否有 PTR 记录,缺失则添加到反向区域文件。
(3)通配符记录残留
- 问题 :删除某记录后,查询仍返回结果(如
*.linux.fun IN A 172.25.254.254
)。 - 排查 :检查区域文件是否有通配符(
*
)记录,不需要则删除。
(4)CNAME 循环
- 问题 :CNAME 记录相互指向(如
test → lab
且lab → test
),导致解析无限循环。 - 排查 :
dig test.linux.fun
查看 CNAME 链,确保最终指向 A/AAAA 记录。
(5)主从服务器数据不一致
- 问题:从服务器返回旧记录,主服务器已更新。
- 排查 :
- 检查主服务器 SOA 序列号是否递增(修改区域文件后必须递增);
- 确认主服务器
allow-transfer
包含从服务器 IP; - 从服务器手动同步:
rndc reload
(BIND)。
七、关键工具总结
工具 | 用途 | 常用命令 |
---|---|---|
dig | DNS 查询工具,支持递归 / 迭代、指定记录类型 | dig @10.1.8.10 linux.fun MX 、dig -x 10.1.8.10 、dig +trace www.baidu.com |
host | 简单 DNS 查询工具,适合快速验证 | host www.linux.fun 、host -t PTR 10.1.8.11 |
named-checkconf | 验证 BIND 主配置文件语法 | named-checkconf 、named-checkconf /etc/named.conf |
named-checkzone | 验证区域文件语法 | named-checkzone linux.fun /var/named/linux.fun.zone |
unbound-control | Unbound 缓存管理工具 | unbound-control dump_cache 、unbound-control flush_zone linux.fun |
dnsmasq -test | 验证 Dnsmasq 配置语法 | dnsmasq -test |