欢迎光临
我们一直在努力

别把地址分配和域名解析绕晕:一篇讲透 Linux DHCP 与 DNS 服务

别把地址分配和域名解析绕晕:一篇讲透 Linux DHCP 与 DNS 服务

本文以实践总结的视角,记录 Linux 命令行学习中「DHCP 动态主机配置」和「DNS 域名解析」两大主题的实际操作、踩过的坑和心得,适合新手照着动手练习。 示例提示符:root 用户为 [root@server ~]#,普通用户为 [user@host ~]$,客户端为 [root@client ~]#。 全文分两大块:

  • DHCP:让客户端「自动拿到 IP、网关、DNS」,理解 DISCOVER → OFFER → REQUEST → ACK 四次握手,并实战部署一台 DHCP 服务器。
  • DNS:把好记的域名翻译成 IP,理解层次结构、递归/迭代查询,并用 BIND 部署一台权威名称服务器。
  • 一句话点题:DHCP 解决「地址怎么自动发下去」,DNS 解决「域名怎么翻译成地址」。两者常配合出现——DHCP 下发 DNS 服务器地址,DNS 再把域名解析成 IP。


    第一部分:DHCP 动态主机配置协议

    一、DHCP 是什么

    在大型网络中,靠手动静态分配 IP 地址会面临两个问题:

  • 容易冲突:要确保不会同时给多个系统分配同一个地址。
  • 部署繁琐:每台新系统都要手动指定 IP。而在云环境里,实例的网络都是自动化配置的。
  • DHCP(Dynamic Host Configuration Protocol,动态主机配置协议) 就是用来自动配置网络参数的,包括:IP 地址、默认网关、DNS 服务器、域、NTP 服务器等。在网络里部署一台 DHCP 服务器,就能集中控制这些参数,既省事又不容易出错。

    DHCP 有两大版本:

    协议面向网络说明
    DHCPv4 IPv4 网络 本文重点
    DHCPv6 IPv6 网络 本课程不展开

    二、DHCP 通信过程(四次握手)

    DHCP 分配地址靠「一问一答」的四次数据包交互,理解这套流程是后续配置的基础。 在这里插入图片描述

    四次握手过程:

    步骤报文方向说明
    1 DHCPDISCOVER 客户端 → 广播 客户端广播「谁给我一个 IP」
    2 DHCPOFFER 服务器 → 客户端 服务器回应「我可以给你 IP,租期是 X」
    3 DHCPREQUEST 客户端 → 广播 客户端广播「我要服务器 A 给我的那个 IP」
    4 DHCPACK 服务器 → 客户端 服务器确认「成交,这个 IP 归你了」

    逐步说明:

  • DHCPDISCOVER(发现):客户端用 DHCPv4 配置网卡时,把 DHCPDISCOVER 包发到广播地址 255.255.255.255。因为路由器通常不转发该广播地址,所以 DHCP 服务器必须和客户端在同一个物理网络里(或者把路由器配置成 DHCP 中继代理,把消息转发到其他网段)。
  • DHCPOFFER(提供):服务器收到后响应 DHCPOFFER 包,里面包含服务器自己的 IP、准备给客户端的 IP、租约期限,以及默认网关、DNS 服务器等其他参数。
  • DHCPREQUEST(请求):客户端收到 DHCPOFFER 后,发送 广播 的 DHCPREQUEST 包,请求使用某台服务器提供的 IP。这一步看着「多余」,其实有道理——网络上可能有多台 DHCP 服务器,客户端可能收到多个 offer。客户端在 DHCPREQUEST 包里写明自己接受的那台服务器 IP,其他服务器看到就自动放弃。
  • DHCPACK(确认):服务器收到 DHCPREQUEST 后,回一个 DHCPACK,确认客户端独占这个 IP,直到租约到期。
  • 一句话记住顺序:发现(找)→ 提供(报价)→ 请求(下单)→ 确认(成交),口诀「D-O-R-A」。

    租约续期:

    在这里插入图片描述

  • 租约到期前,客户端定期向服务器发 DHCPREQUEST,请求续约,确保服务器不会把 IP 收回。
  • 服务器同意续约,重新给客户端一个租期。
  • 租约没到期时,客户端会周期性发 DHCPREQUEST 续约;真正到期了,就会重新走一遍完整的 D-O-R-A。

    查看通信消息:

    在 DHCP 服务器上,用 journalctl –unit=dhcpd.service 查看客户端与服务端的通信消息,下面的输出就是客户端通过 DHCP 申请 IP 的记录:

    [root@server ~]# journalctl –unit=dhcpd.service
    Feb 21 17:11:25 server dhcpd[1234]: DHCPDISCOVER from 00:0c:29:b3:48:05 via ens32
    Feb 21 17:11:25 server dhcpd[1234]: DHCPOFFER on 10.1.8.101 to 00:0c:29:b3:48:05 via ens32
    Feb 21 17:11:25 server dhcpd[1234]: DHCPREQUEST for 10.1.8.101 from 00:0c:29:b3:48:05 via ens32
    Feb 21 17:11:25 server dhcpd[1234]: DHCPACK on 10.1.8.101 to 00:0c:29:b3:48:05 via ens32

    从日志能完整看到 DISCOVER → OFFER → REQUEST → ACK 四次交互,和上面表格一一对应。

    多个 DHCP 服务器时的行为

    尽管网络里能跑多台 DHCP 服务器,但不建议这么做。正常同一个物理网络里只要一台服务器响应客户端即可。

    同一网络跑多台服务器时:

    • 新客户端发 DHCPDISCOVER,可能收到多个 DHCPOFFER。
    • 客户端只接受其中一台的配置,并广播包含该服务器 IP 的 DHCPREQUEST。其他服务器看到后释放自己准备给客户端的 IP。

    但续约时,服务器行为取决于它是否权威(authoritative):

    • 非权威 DHCP 服务器会忽略 DHCPREQUEST 里它不认识(不是它分配)的地址。
    • 当客户端请求的 IP 在权威服务器管理的地址范围内、但服务器之前不认识这个 IP 时,它会拒绝并回 DHCPNAK 包。这通常意味着客户端当初是从另一台非权威服务器拿到的地址。收到 DHCPNAK 的客户端不能再使用该地址,必须重新申请。

    默认配置启动的 DHCP 服务器不是权威服务器,这是为了防止非权威服务器「抢走」权威服务器分配的地址。

    三、部署 DHCP 服务器

    3.1 环境准备(服务器要有静态 IP)

    配置 DHCPv4 服务器前,先用 ip addr 确认网卡配置了 BROADCAST(广播) 地址:

    [root@server ~ 16:59:09]# ip addr
    1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
    valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
    valid_lft forever preferred_lft forever
    2: ens32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:0c:29:12:dd:ff brd ff:ff:ff:ff:ff:ff
    inet 10.1.8.10/24 brd 10.1.8.255 scope global noprefixroute ens32
    valid_lft forever preferred_lft forever
    inet6 fe80::20c:29ff:fe12:ddff/64 scope link
    valid_lft forever preferred_lft forever

    这里的 ens32 网卡有 brd 10.1.8.255 广播地址,且 IP 是静态的 10.1.8.10/24。DHCP 服务器自身必须用静态 IP(不能自己给自己发地址)。

    3.2 安装并启动 DHCP 软件

    # 安装 DHCP 软件包
    [root@server ~ 17:00:38]# yum install -y dhcp

    # 关闭防火墙并启动服务(DHCP 用 UDP 67/68 端口,实验环境先关防火墙简化排错)
    [root@server ~ 17:02:57]# systemctl stop firewalld
    [root@server ~ 17:02:53]# systemctl enable dhcpd –now

    systemctl enable dhcpd –now 等价于「设置开机自启 + 立即启动」两步合一。–now 表示顺带执行 start。

    3.3 配置 DHCP 服务器

    dhcpd 服务使用 /etc/dhcp/dhcpd.conf 配置文件。dhcp 软件包提供了一个示例:/usr/share/doc/dhcp-*/dhcpd.conf.example,可以直接复制过来改。

    [root@server ~ 17:04:58]# cp /usr/share/doc/dhcp-*/dhcpd.conf.example /etc/dhcp/dhcpd.conf
    cp:是否覆盖"/etc/dhcp/dhcpd.conf"? y
    [root@server ~ 17:06:47]# vim /etc/dhcp/dhcpd.conf
    [root@server ~ 17:09:54]# cat /etc/dhcp/dhcpd.conf
    subnet 10.1.8.0 netmask 255.255.255.0 {
    range 10.1.8.101 10.1.8.130;
    option domain-name-servers ns1.internal.example.org;
    option domain-name "feiyun.cloud";
    option routers 10.1.8.2;
    option broadcast-address 10.1.8.255;
    default-lease-time 600;
    max-lease-time 7200;
    }

    配置项说明:

    配置项作用
    authoritative 声明服务器对其管理的子网具有权威性(本示例省略,默认非权威)
    subnet 声明要分配的子网段,这里是 10.1.8.0/24
    range 指定从该范围内分配 IP(10.1.8.101 ~ 10.1.8.130)
    option routers 下发给客户端的默认网关地址
    option domain-name-servers 下发给客户端的 DNS 服务器
    option domain-name 下发给客户端的域名
    option broadcast-address 下发给客户端的广播地址
    default-lease-time 默认租期,客户端没特别要求时使用,单位秒
    max-lease-time 服务器能接受的最大租期,单位秒

    客户端上的 NetworkManager 会用收到的 domain-name-servers 和 domain-search 去更新 /etc/resolv.conf 里的 nameserver 和 search 参数——这就是「DHCP 自动配 DNS」的实现方式。

    3.4 验证 DHCP 配置

    [root@server ~ 17:09:58]# dhcpd -t
    Internet Systems Consortium DHCP Server 4.2.5
    Copyright 2004-2013 Internet Systems Consortium.
    All rights reserved.
    For info, please visit https://www.isc.org/software/dhcp/
    Not searching LDAP since ldap-server, ldap-port and ldap-base-dn were not specified in the config file

    dhcpd -t 是配置文件语法检查(-t = test)。没报 error 就说明配置语法没问题,可以放心重启服务。改完配置先 dhcpd -t 再重启,是个好习惯。

    3.5 启动服务并查看日志与租约

    # 重启服务,让新配置生效
    [root@server ~ 17:10:56]# systemctl restart dhcpd

    # 实时查看 DHCP 分配、报错、地址冲突、授权问题
    [root@server ~ 17:11:25]# tail -f /var/log/messages

    # 查看已分配 IP、租期、客户端 MAC
    [root@server ~ 17:14:43]# cat /var/lib/dhcpd/dhcpd.leases

    两个关键位置:/var/log/messages 记录实时分配过程(谁申请了、失败了),/var/lib/dhcpd/dhcpd.leases 记录当前租约状态(哪些 IP 发给了哪些 MAC、租期到什么时候)。

    四、配置 DHCP 客户端

    给客户端添加一块新网卡,让它自动获取 IP。下面是客户端上的验证过程:

    [feiyun@client ~ 17:00:14]$ ip -br a
    lo UNKNOWN 127.0.0.1/8 ::1/128
    ens32 UP 10.1.8.11/24 fe80::20c:29ff:feb3:48fb/64
    ens33 UP 10.1.8.101/24 fe80::467:bde8:8bcc:b070/64
    # 自动获取 ip 10.1.8.101/24
    [feiyun@client ~ 17:12:07]$ ip addr show ens33
    3: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:0c:29:b3:48:05 brd ff:ff:ff:ff:ff:05
    inet 10.1.8.101/24 brd 10.1.8.255 scope global noprefixroute dynamic ens33
    valid_lft 531sec preferred_lft 531sec
    inet6 fe80::467:bde8:8bcc:b070/64 scope link noprefixroute
    valid_lft forever preferred_lft forever

    注意 ens33 的 IP 那行多了个 dynamic 标记,10.1.8.101 正好落在服务器配置的 range 10.1.8.101 ~ 10.1.8.130 里,说明这块网卡是通过 DHCP 自动拿到的地址,且租期剩 531 秒(valid_lft 531sec)。

    五、基于 MAC 地址预留 IP

    有些场景希望某台机器永远拿到同一个 IP(比如 Web、数据库服务器),可以配置 host 声明,把 MAC 地址绑定到固定 IP。

    先查客户端 MAC 地址:

    [feiyun@client ~ 17:17:57]$ ip link show ens33
    3: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
    link/ether 00:0c:29:b3:48:05 brd ff:ff:ff:ff:ff:ff

    link/ether 后面的 00:0c:29:b3:48:05 就是这块网卡的 MAC 地址。

    在配置文件末尾追加 host 声明(server 端):

    [root@server ~ 17:15:50]# vim /etc/dhcp/dhcpd.conf
    [root@server ~ 17:24:52]# tail -n4 /etc/dhcp/dhcpd.conf
    host client.feiyun.cloud {
    hardware ethernet 00:0c:29:b3:48:05;
    fixed-address 10.1.8.30;
    }

    hardware ethernet 指定 MAC,fixed-address 指定要固定分配的 IP。这样 MAC 为 00:0c:29:b3:48:05 的机器永远拿到 10.1.8.30(注意:这个地址要避开 range 的自动分配区间,避免冲突)。

    重启服务并让客户端重新获取:

    [root@server ~ 17:24:47]# systemctl restart dhcpd

    [root@client ~ 17:28:29]# nmcli c
    NAME UUID TYPE DEVICE
    ens32 0ab465dc-f36c-49d0-be85-bf705a465f22 ethernet ens32
    有线连接 1 2d56f9f1-9425-3839-8803-83ff02e1be9e ethernet ens33
    [root@client ~ 17:28:37]# nmcli c up 2d56f9f1-9425-3839-8803-83ff02e1be9e
    连接已成功激活(D-Bus 活动路径:/org/freedesktop/NetworkManager/ActiveConnection/3)
    [root@client ~ 17:28:49]# ip addr show ens33
    3: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:0c:29:b3:48:05 brd ff:ff:ff:ff:ff:ff
    inet 10.1.8.30/24 brd 10.1.8.255 scope global noprefixroute dynamic ens33
    valid_lft 581sec preferred_lft 581sec
    inet6 fe80::467:bde8:8bcc:b070/64 scope link noprefixroute
    valid_lft forever preferred_lft forever

    重启后客户端重新激活连接,ens33 的 IP 从原来的 10.1.8.101 变成了固定的 10.1.8.30,说明 MAC 预留生效了。


    第二部分:DNS 域名系统

    六、DNS 是什么与层次结构

    DNS(Domain Name System,域名系统) 是一种把域名转换成 IP 地址的分布式数据库服务,是互联网的核心服务之一。有了它,用户用易记的域名就能访问网站,而不用背一串 IP。

    DNS 也是一个分层命名系统,用来存储网络主机和资源的目录,目录里的信息把网络名称映射到不同的资源记录。

    层次结构(从顶层往下):

    • 根域:DNS 最顶层,用独立的「.」表示。
    • 顶级域(一级域):第二层,例如 .com、.net、.org 等。
    • 二级域:第三层,例如 laoma.cloud、redhat.fun,由各个组织使用。
    • 以此类推(还可以有三级、四级域)。

    在这里插入图片描述

    学习层次结构前,先搞清楚几个术语:domain(域)、subdomain(子域)、zone(区域)。

    Domain(域)

    domain 是 resource records(资源记录)的集合,以通用名结尾,表示 DNS 命名空间的整个子树,如 laoma.cloud。

    top-level domain(TLD,顶级域) 由 IANA(互联网号码分配机构) 管理,负责委派顶级域。

    常见 TLD 类型:

    类型全称说明举例
    gTLD Generic TLD(通用顶级域) 按主题组织 .com、.edu、.net
    ccTLD Country code TLD(国家代码顶级域) 按 ISO 3166-1 国家标准组织 .us、.uk、.cn、.ru

    更多顶级域可参考根域数据库。

    在这里插入图片描述

    Subdomain(子域)

    Subdomain 是另一个域的完整子树。 讨论两个域之间的关系时用。例如 lab.laoma.cloud 是 laoma.cloud 的子域,laoma.cloud 又是 .com 的子域。也可以把 laoma.cloud 叫二级域、lab.laoma.cloud 叫三级域。

    Zone(区域)

    Zone 是特定名称服务器直接负责的域,可能是整个域,也可能只是域的一部分。Zone 可以把部分或全部子域委派给其他名称服务器。

    例如:根名称服务器对根区域有权威性,但它们把 .com 的职责委派给其他名称服务器,这些服务器再为 .com 区域提供权威应答,还可以继续往下委派。

    domain / subdomain / zone 三者关系:domain 是「名词(一类叫什么)」,subdomain 是「关系(谁是谁的儿子)」,zone 是「职责(谁负责管哪块)」。

    七、DNS 查询:递归 vs 迭代

    DNS 查询主要有两种方式:递归查询和迭代查询,由 DNS 请求报文头部里的 RD 字段决定:

    RD 字段查询类型说明
    1 递归查询 默认查询方式
    0 迭代查询 需要客户端自己一步步查

    递归查询:以本地名称服务器为中心。客户端只发一个原始查询请求,然后一直等,本地名称服务器把它当「中介代理」,帮客户端查到底,最后把结果一次性返回。

    迭代查询:以 DNS 客户端自己为中心。所有查询都由客户端自己完成——客户端按顺序向本地名称服务器、根服务器、一级服务器、二级服务器……挨个问,每一级都返回「下一个该问谁」的参考信息,客户端再接着问,直到找到权威名称服务器得到最终结果。

    一句话区分:递归是「你帮我查到底」,迭代是「我按提示一步步自己查」。

    有些 DNS 服务器为了减轻负载,会配置禁止递归查询,这时客户端就只能用迭代查询了。

    7.1 迭代查询详解

    迭代查询也叫迭代解析,所有查询工作都由客户端自己进行。若主名称服务器(如 Windows 里的「首选 DNS」)解析不了,客户端会继续向其他服务器(如「备用 DNS」)查询。

    考虑缓存的情况下,迭代解析流程如下:

  • DNS 客户端向本机配置的本地名称服务器发出域名查询请求。
  • 本地名称服务器收到后先查本地缓存:
    • 有记录 → 直接返回给客户端。
    • 没有 → 返回一条 DNS 应答,给出根名称服务器地址等参考信息。
  • 客户端根据根名称服务器地址,向根名称服务器再次发出同样的查询。
  • 根名称服务器查自己的库,返回顶级名称服务器(如 .com 的服务器)地址。
  • 客户端向顶级名称服务器继续发同样的查询。
  • 顶级名称服务器先查缓存:
    • 有记录 → 直接返回记录。
    • 没有 → 返回二级名称服务器地址。
  • 客户端继续向三级、四级名称服务器查询,直到查到的权威名称服务器返回最终记录。
  • 若权威名称服务器都说找不到,就返回负响应;若配置了转发器,权威服务器还会在转发的服务器上继续查;客户端配了多个 DNS 也会挨个问。

    迭代查询示例

    在这里插入图片描述

    假设访问站点 www.example.com,迭代查询路径如下:

  • 客户端向本地名称服务器发解析 www.example.com 的请求。
  • 本地名称服务器查缓存没有,把根名称服务器 a.rootserver.net 地址返回给客户端。
  • 客户端向根名称服务器发同样的查询。
  • 根名称服务器查得 .com 顶级名称服务器地址,返回给客户端。
  • 客户端向 .com 顶级名称服务器发查询。
  • 顶级服务器查缓存没有,返回 example.com 二级名称服务器地址。
  • 客户端向二级名称服务器发查询。
  • 二级服务器查缓存没有,返回 www.example.com 权威名称服务器地址。
  • 客户端向权威名称服务器发查询。
  • 权威服务器在区域库中找到 www.example.com 对应的 IP,返回给客户端,客户端就可以访问了。
  • 7.2 递归查询详解

    递归查询是默认方式。客户端配置的本地名称服务器解析不了时,后续查询全部由本地名称服务器代替客户端进行,直到拿到结果再告诉客户端。整个过程以本地名称服务器为中心,客户端只发一次请求然后等待,本地名称服务器相当于「中介代理」。

    递归解析流程:

  • 客户端向本地名称服务器发查询。
  • 本地名称服务器查缓存;没有就用「DNS 客户端」的身份再向根名称服务器发同样的查询。
  • 根服务器返回顶级名称服务器地址。
  • 本地名称服务器向顶级名称服务器发查询。
  • 顶级服务器查缓存;有则返回记录,没有则返回二级名称服务器地址。
  • 本地名称服务器向二级名称服务器发查询。
  • 二级服务器查缓存;有则返回记录,没有则返回三级名称服务器地址。
  • 本地名称服务器重复上述步骤,直到权威名称服务器返回最终记录。
  • 本地名称服务器把结果返回给客户端,同时缓存本次查询结果。
  • 简单三步记递归:① 客户端问本地 DNS 后一直等;② 本地 DNS 查缓存,没有就自己一路向上查;③ 查到结果返回给客户端。

    递归查询示例

    在这里插入图片描述

    还是访问 www.example.com,递归查询路径如下:

  • 客户端向本地名称服务器 dns.example.com 发请求。
  • 本地服务器查缓存没有,向根服务器 a.rootserver.net 发请求(代替客户端去查)。
  • 根服务器返回 .com 顶级名称服务器地址。
  • 本地服务器向顶级名称服务器发请求。
  • 顶级服务器返回 example.com 二级名称服务器地址。
  • 本地服务器向二级名称服务器发请求。
  • 二级服务器返回 www.example.com 权威名称服务器地址。
  • 本地服务器向权威名称服务器发请求。
  • 权威服务器在区域库中找到 www.example.com 对应的 IP,返回给本地名称服务器。
  • 本地名称服务器把 IP 返回给客户端,客户端即可正常访问。
  • 递归 vs 迭代的本质区别就一句话:递归里「每一跳」都是本地名称服务器在跑,客户端只等结果;迭代里「每一步」都是客户端自己发请求,服务器只给方向提示。

    八、配置权威名称服务器(BIND)

    8.1 权威名称服务器架构

    权威名称服务器存储 DNS 资源记录,并为其管理的区域提供权威答案。

    Linux 中用 BIND(Berkeley Internet Name Domain) 软件实现权威名称服务器。BIND 允许把权威服务器配置为区域的主服务器(master)或辅助服务器(slave):

    • 一个区域只有一台主服务器,但可以有多台辅助服务器。
    • 辅助服务器通过区域转移(Zone Transfer),定期从主服务器下载区域信息的最新版本。
    • 转移频率、数据是否过期,由区域的 SOA 记录控制。

    名称服务器可以是某些区域的主服务器,同时又是其他区域的辅助服务器。

    目前 BIND 服务器的角色叫 master / slave,以后会改名为 primary / secondary(例如 BIND 9.16 ESV 版本)。

    注册新 DNS 域时,必须提供该域所有公共权威名称服务器的名称和 IP。注册商把这些信息放进父域的区域文件(NS、A、AAAA 记录),让解析器能找到名称服务器。为保证可靠,应有至少两台公共 DNS 服务器,且分布在不同站点,避免网络故障导致中断。

    并非所有权威服务器都必须是公共的。 常见做法:用 primary 服务器管理区域文件,再把区域信息发布到面向公众的 secondary 服务器。primary 私有,secondary 对外提供权威答案,这样能保护 primary 免受攻击。

    架构示例 1(只用公共辅助服务器):

    在这里插入图片描述

    查找过程:客户的仅缓存名称服务器先查根名称服务器 → 被导向负责 .com 域的名称服务器池 → 其中一台用 laoma.cloud 的 NS 记录响应 → 仅缓存名称服务器查询某个面向公众的辅助名称服务器。

    架构示例 2(增加内部 slave 权威服务器):

    在这里插入图片描述

    更好的做法是提供内部 slave 权威服务器:查询本地域时消除了外部查询,而且更安全。

    在这里插入图片描述

    8.2 安装 BIND

    安装 bind 软件包后,名称服务器以 named 服务运行。bind 包还会把 HTML / PDF 格式的文档装到 /usr/share/doc/bind/ 目录。

    [root@server ~]# yum install -y bind bind-utils

    软件包说明:

    软件包作用
    bind BIND 服务器软件
    bind-utils BIND 工具(dig、host、nslookup 等)

    bind 默认把服务配置成基本的递归缓存名称服务器,并作为 localhost、相关域和地址的 primary 服务器,以减轻根名称服务器负担;同时只允许本机程序访问,监听 IPv4/IPv6 环回接口的 53 端口 UDP/TCP。

    8.3 配置 BIND

    named 的主配置文件是 /etc/named.conf,它控制 BIND 的基本操作:

    • 属主为 root(属组 named),权限 0640,SELinux 类型 named_conf_t。
    • 文件里还指定了各区域的配置文件位置,通常在 /var/named 下。

    配置权威 DNS 服务器的一般步骤:

  • 配置地址匹配列表(acl)。
  • 配置 named 侦听的 IP 地址。
  • 配置客户端的访问控制。
  • 配置 zone。
  • 编写区域文件。
  • (1) 定义地址匹配列表(acl)

    在 /etc/named.conf 开头,用 acl 指令定义地址匹配列表。acl 不是用来控制客户端访问,而是定义一组 IP 地址/网络的别名,方便在访问控制等指令中复用,也便于维护。

    条目可以是:完整 IP、用尾点表示的网络(10.1.8.)、CIDR 表示(192.168.0/24 或 2001:db8::/32),也可以是之前定义过的 acl 名称。

    name 内置了四个预定义 ACL:

    ACL说明
    none 不匹配任何主机
    any 匹配所有主机
    localhost 匹配 DNS 服务器本身的全部 IP
    localnets 匹配 DNS 服务器所在本地子网的全部主机
    (2) 配置 named 侦听的 IP 地址

    在 /etc/named.conf 的 options 块中指定全局设置,其中 listen-on(IPv4)和 listen-on-v6(IPv6)指令指定 named 监听的接口和端口(默认 53)。

    • listen-on 用分号分隔的 IPv4 地址列表。
    • listen-on-v6 用 IPv6 地址。

    示例 1:只监听 10.1.8.10 和回环地址 127.0.0.1。

    [root@server ~]# vim /etc/named.conf
    options {
    listen-on port 53 { 127.0.0.1; 10.1.8.10; };
    ......
    };

    示例 2:结合 acl 指令配置。

    acl interfaces { 127.0.0.1; 10.1.8.10; };
    acl interfacesv6 { ::1; 2001:db8:2020::5300; };
    options {
    listen-on port 53 { interfaces; };
    listen-on-v6 port 53 { interfacesv6; };
    ...output omitted...
    };

    (3) 配置客户端的访问控制

    在 options 块中用三个指令控制访问:

    指令作用默认 / 建议
    allow-query 控制哪些客户端能查询 默认 localhost;公开权威服务器要设 allow-query { any; };
    allow-recursion 控制谁能用递归查询 权威服务器应禁止递归,防止 DNS 放大攻击和缓存中毒
    allow-transfer 控制谁能做区域转移(获取整个区域数据的转储) 应限制,只允许辅助服务器和 localhost

    关闭递归(最省事的做法):

    options {
    ......
    recursion no;
    ......
    };

    只允许信任客户端递归:

    options {
    ……
    recursion yes;
    allow-recursion { trusted-nets; };
    ……
    };

    权威服务器不应允许递归查询,以免被用于 DNS 放大 DDoS 攻击,也能更好地防缓存中毒。

    主服务器必须允许辅助服务器做区域转移(否则辅助服务器同步不了数据),但应禁止其他主机转移,并允许 localhost 转移以便排错。

    可以用 dig 查询区域的 AXFR(Zone Transfer)记录来验证:

    [user@host ~]$ dig axfr @classroom.laoma.cloud laoma.cloud

    实验环境采用如下配置:

    [root@server ~ 23:03:47]# vim /etc/named.conf
    13 listen-on port 53 { 127.0.0.1;10.1.8.10; };
    21 allow-query { localhost;any; };
    35 dnssec-enable no;
    61 include "/etc/named.feiyun.cloud.zone";

    行首的数字(13、21、35、61)是 vim 的行号。要在 vim 里显示行号,进入命令行模式输入 :set nu 即可。

    (4) 配置 zone

    示例:让服务器承载 laoma.cloud 的正向区域和对应的反向区域 8.1.10.in-addr.arpa,同时充当 example.net 域的辅助服务器(区域文件从 ACL 标识的服务器获取)。

    [root@server ~ 23:05:11]# cp -a /etc/named.rfc1912.zones /etc/named.feiyun.cloud.zone
    [root@server ~ 23:12:02]# vim /etc/named.feiyun.cloud.zone
    [root@server ~ 23:14:32]# cat /etc/named.feiyun.cloud.zone
    zone "feiyun.cloud" IN {
    type master;
    file "named.feiyun.cloud";
    allow-update { none; };
    };

    zone "8.1.10.in-addr.arpa" IN {
    type master;
    file "named.10.1.8";
    allow-update { none; };
    };

    配置说明:

    字段作用
    type 指定服务器角色:master(主)/ slave(辅助)/ forward 等
    file 指定区域文件的相对路径,相对路径由 options 块里的 directory 指令指定(默认 /var/named)
    allow-update 是否允许动态更新(none = 禁止)
    (5) 创建区域文件

    区域文件应放在 /var/named 下(辅助区域文件在 /var/named/slaves)。辅助服务器启动时会把缓存的区域版本与主服务器比较:版本最新则直接用;不是最新或文件缺失,就执行区域转移并缓存结果。

    BIND 应能读取这些区域文件但不能写入,所以文件归 root:named,避免守护进程被攻破后篡改文件。

    [root@server named 23:15:43]# cp -a named.localhost named.feiyun.cloud
    [root@server named 23:16:01]# vim named.feiyun.cloud
    [root@server named 23:22:18]# cp -a named.loopback named.10.1.8
    [root@server named 23:23:25]# vim named.10.1.8

    区域文件格式:

    • 每行包含一个指令或资源记录。
    • 资源记录数据含括号(( )时可跨多行。
    • 同一行里分号(;)右侧的内容是注释。

    区域文件以 $TTL 指令开头,为没有单独列出的记录设置默认 TTL:

    $TTL 3600

    数字后可跟单个字母表示其他时间单位:

    单位含义秒数
    M 分钟 1M = 60
    H 小时 1H = 3600
    D 天 1D = 86400
    W 周 1W = 604800

    每个区域文件只包含一条 SOA(Start of Authority,授权开始)记录。

    示例:example.com 域的 SOA 记录

    在这里插入图片描述

    SOA 记录各字段含义:

  • 区域名称(这里指 example.com),后跟 IN SOA,标识记录的类别(Internet)和类型(SOA)。
  • 该区域主名称服务器的名称(primary.example.com)。
  • 区域负责人的联系邮箱,第一个点(.)当作 @,如 root.example.com. 代表 root@example.com.。
  • 序列号(serial):代表文件的修订版本,每次修改都要手动 +1。
  • refresh:辅助服务器多久向主服务器查一次是否需要刷新。
  • retry:辅助服务器刷新失败后多久重试。
  • expire:辅助服务器连接不上主服务器后,放弃前坚持的时间;超时则认定区域已不存在、停止应答。
  • minimum:其他名称服务器缓存该区域 NXDOMAIN 记录的时间。
  • 6、7、8 三个时间值容易混,记法:refresh「多久刷新」、retry「失败重试」、expire「坚持多久」、minimum「缓存多久」。

    (6) 添加记录

    正向记录(把名称映射到 IP 等记录),区域文件必须包含:

    • SOA 记录。
    • 每个公共名称服务器的 NS 记录。
    • 该区域的其他 A、AAAA、CNAME、MX、SRV、TXT 记录。

    示例:feiyun.cloud 域

    [root@server named 23:23:50]# vim named.feiyun.cloud
    [root@server named 23:25:04]# cat named.feiyun.cloud
    $TTL 1D
    @IN SOAdns.feiyun.cloud. admin.feiyun.cloud. (
    0; serial
    1D; refresh
    1H; retry
    1W; expire
    3H ); minimum
    IN NS dns.feiyun.cloud.
    dns IN A 10.1.8.10
    web IN CNAME www
    www IN A 10.1.8.10
    mail1IN MX 10 10.1.8.101
    mail2 IN MX 20 10.1.8.102
    client IN A 10.1.8.11

    说明:

    • @ 代表区域名称,避免重复输入。
    • SOA 记录与前面示例等价。
    • 记录名称为空时,值沿用前一条记录的名称。

    记录类型速记:A = 域名→IPv4,AAAA = 域名→IPv6,CNAME = 别名,MX = 邮件服务器(后面数字是优先级,越小越优先),NS = 名称服务器,PTR = 反向记录。

    反向记录(把 IP 映射到主机名),区域文件必须包含:SOA 记录、NS 记录、PTR 记录。

    示例:8.1.10.in-addr.arpa 区域

    [root@server named 23:27:08]# vim named.10.1.8
    [root@server named 23:30:24]# cat named.10.1.8
    $TTL 1D
    @IN SOAdns.feiyun.cloud. admin.feiyun.cloud. (
    0; serial
    1D; refresh
    1H; retry
    1W; expire
    3H ); minimum
    IN NS dns.feiyun.cloud.
    10IN PTR dns.feiyun.cloud.
    10 IN PTR web.feiyun.cloud.
    10 IN PTR www.feiyun.cloud.
    101IN PTR mail1.feiyun.cloud.
    102 IN PTR mail2.feiyun.cloud.
    11IN PTR client.feiyun.cloud.

    反向记录里的「名称」只需写 IP 的最后一段,比如 10 就代表 10.8.1.10.in-addr.arpa(网络段反着写后补上 .in-addr.arpa)。所以反向区域的名称 8.1.10 就是把子网 10.1.8.0/24 的网络位倒过来。

    8.4 运行 BIND

    [root@server ~ 23:26:26]# systemctl enable named –now
    Created symlink from /etc/systemd/system/multi-user.target.wants/named.service to /usr/lib/systemd/system/named.service.
    [root@server ~ 23:32:51]# systemctl status named
    ● named.service – Berkeley Internet Name Domain (DNS)
    Loaded: loaded (/usr/lib/systemd/system/named.service; enabled; vendor preset: disabled)
    ...

    看到 active (running) 且没有报错,就说明 named 服务正常起动了。改完区域文件记得 systemctl restart named 让新记录生效。

    九、客户端测试

    方式 1:配置 DNS 后 ping

    [root@client ~ 23:05:14]# nmcli c
    NAME UUID TYPE DEVICE
    ens32 0ab465dc-f36c-49d0-be85-bf705a465f22 ethernet ens32
    有线连接 1 2d56f9f1-9425-3839-8803-83ff02e1be9e ethernet ens33
    [root@client ~ 23:33:57]# nmcli c modify ens32 ipv4.dns 10.1.8.10
    [root@client ~ 23:34:23]# nmcli c up ens32
    连接已成功激活(D-Bus 活动路径:/org/freedesktop/NetworkManager/ActiveConnection/3)

    [root@client ~ 23:34:52]# ping web.feiyun.cloud
    PING www.feiyun.cloud (10.1.8.10) 56(84) bytes of data.
    64 bytes from server.feiyun.cluod (10.1.8.10): icmp_seq=1 ttl=64 time=0.266 ms
    64 bytes from server.feiyun.cluod (10.1.8.10): icmp_seq=2 ttl=64 time=0.365 ms
    64 bytes from server.feiyun.cluod (10.1.8.10): icmp_seq=3 ttl=64 time=0.240 ms
    ^C
    — www.feiyun.cloud ping statistics —
    3 packets transmitted, 3 received, 0% packet loss, time 1999ms
    rtt min/avg/max/mdev = 0.240/0.290/0.365/0.055 ms

    ping web.feiyun.cloud 能正确解析成 10.1.8.10,说明客户端用我们配的 DNS 服务器 10.1.8.10 解析出了 web(CNAME 指向 www)的地址,正向解析成功。

    方式 2:dig 工具测试

    # 安装工具(提供 dig)
    [root@client ~ 23:35:12]# yum install -y bind-utils

    # 查询 NS 记录
    [root@client ~ 23:37:07]# dig @10.1.8.10 feiyun.cloud NS | grep feiyun.cloud
    ; <<>> DiG 9.11.4-P2-RedHat-9.11.4-26.P2.el7_9.16 <<>> @10.1.8.10 feiyun.cloud NS
    ;feiyun.cloud.INNS
    feiyun.cloud.86400INNSdns.feiyun.cloud.
    dns.feiyun.cloud.86400INA10.1.8.10

    # 查询 MX 记录
    [root@client ~ 23:38:01]# dig @10.1.8.10 feiyun.cloud MX | grep feiyun.cloud
    ; <<>> DiG 9.11.4-P2-RedHat-9.11.4-26.P2.el7_9.16 <<>> @10.1.8.10 feiyun.cloud MX
    ;feiyun.cloud.INMX
    feiyun.cloud.10800INSOAdns.feiyun.cloud. admin.feiyun.cloud. 0 86400 3600 604800 10800

    # 查询 A 记录
    [root@client ~ 23:38:21]# dig @10.1.8.10 client.feiyun.cloud | grep feiyun.cloud
    ; <<>> DiG 9.11.4-P2-RedHat-9.11.4-26.P2.el7_9.16 <<>> @10.1.8.10 client.feiyun.cloud
    ;client.feiyun.cloud.INA
    client.feiyun.cloud.86400INA10.1.8.11
    feiyun.cloud.86400INNSdns.feiyun.cloud.
    dns.feiyun.cloud.86400INA10.1.8.10

    # 查询 PTR(反向)记录:-x 后面直接跟 IP
    [root@client ~ 23:39:15]# dig @10.1.8.10 -x 10.1.8.101 | grep feiyun.cloud
    101.8.1.10.in-addr.arpa. 86400INPTRmail1.feiyun.cloud.
    8.1.10.in-addr.arpa.86400INNSdns.feiyun.cloud.
    dns.feiyun.cloud.86400INA10.1.8.10

    dig @服务器 域名 记录类型 是最常用的 DNS 排错命令:@ 后指定要问的 DNS 服务器,-x 表示反向解析 IP。上面依次验证了 NS、MX、A、PTR 记录,全部正常返回。

    递归查询与迭代查询的 dig 截图

    递归查询:以 DNS 服务器为中心查,最终把结果返回给客户端。

    在这里插入图片描述

    迭代查询:以客户端为中心查,逐步获取最终结果。

    迭代查询可以用 +trace 选项,让 dig 从根开始一步步追踪整个解析过程:

    [root@client ~]# dig +trace @server www.baidu.com

    在这里插入图片描述

    dig +trace 会显示「根 → .com → 权威服务器」的完整迭代链路,是理解迭代查询、排查 DNS 问题的利器。


    全文小结(实践心得)

    1. 核心概念速查表

    概念说明
    DHCP 自动下发 IP、网关、DNS 等网络参数
    D-O-R-A DHCP 四次握手:DISCOVER / OFFER / REQUEST / ACK
    权威(authoritative) 服务器对自己管理的地址段拥有最终决定权
    DNS 把域名解析成 IP 的分布式数据库
    递归查询 以本地名称服务器为中心,客户端只等结果(默认)
    迭代查询 以客户端为中心,自己一步步查(dig +trace)
    TLD / 域 / 子域 / 区域 顶级域 / 域 / 子域 / 名称服务器直接负责的域
    SOA / NS / A / CNAME / MX / PTR 授权开始 / 名称服务器 / IPv4 / 别名 / 邮件 / 反向记录

    2. 命令速查表

    命令作用
    yum install -y dhcp 安装 DHCP 服务器
    vim /etc/dhcp/dhcpd.conf 编辑 DHCP 配置(subnet/range/option)
    dhcpd -t 检查 DHCP 配置语法
    systemctl restart dhcpd 重启 DHCP 服务
    tail -f /var/log/messages 实时看 DHCP 分配日志
    cat /var/lib/dhcpd/dhcpd.leases 查看已分配租约
    yum install -y bind bind-utils 安装 BIND 与 dig 工具
    vim /etc/named.conf 配置 BIND(acl/listen-on/allow-*)
    systemctl restart named 重启 DNS 服务
    dig @10.1.8.10 域名 类型 查询指定 DNS 服务器的记录
    dig -x IP 反向解析 IP
    dig +trace 域名 追踪迭代解析全过程

    3. 核心要点

  • DHCP 分配是「广播 + 四次握手」:客户端广播 DISCOVER,服务器回 OFFER,客户端广播 REQUEST 选一台,服务器回 ACK 确认。
  • DHCP 服务器必须用静态 IP,且要与客户端同网段(或用中继代理转发广播)。
  • 改完 DHCP/DNS 配置都要先「检查语法」再重启:dhcpd -t、named 启动时的日志,是好习惯。
  • DNS 查询两种方式:递归(服务器代查,默认)和迭代(客户端自查);权威服务器应关闭递归防攻击。
  • DNS 正向解析是「域名→IP」,反向解析是「IP→域名」,反向区域名要倒着写(8.1.10.in-addr.arpa 对应 10.1.8.0/24)。
  • SOA 的 serial 每次改区域文件都要手动 +1,否则辅助服务器不会同步最新记录。
  • 4. 记忆口诀

    • DHCP 四步:发现(找)→ 提供(报价)→ 请求(下单)→ 确认(成交),念作 D-O-R-A。
    • DNS 两种查法:递归「别人帮你查到底」,迭代「自己按提示步步查」。
    • 记录类型:A 找 IP、AAAA 找 IPv6、CNAME 是别名、MX 管邮件、NS 管服务器、PTR 反着查。
    • SOA 时间:refresh 多久刷、retry 失败重试、expire 坚持多久、minimum 缓存多久。
    • DHCP 排错:改配置先 dhcpd -t,看分配查 messages、看租约查 leases。

    5. 三个易错点

  • DHCP 服务器忘了设静态 IP(或网卡没有 BROADCAST),客户端广播的 DISCOVER 根本收不到,自然拿不到地址。
  • DHCP/DNS 配置改完没重启服务:restart dhcpd / restart named,否则新配置不生效。
  • SOA 的 serial 没递增:辅助服务器以为数据没变,就不会来同步,导致新解析记录一直不生效。反向区域的名称还容易把网络位写反。

  • 持续更新中……下一部分继续学习新的 Linux 技能。

    赞(0)
    未经允许不得转载:171主机测评 » 别把地址分配和域名解析绕晕:一篇讲透 Linux DHCP 与 DNS 服务
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址