2. DHCP服务器搭建:从协议原理到多子网实战

DHCP,说白了就是让设备上网时自动拿到IP地址,不用你一台台去配。我刚开始做网络那会儿,公司几十台机器全是手动配IP,后来有一次机房搬迁,光改IP就改了一整天……从那以后,我就再也没离开过DHCP。

这一章我们重点讲isc-dhcp-server,它是Linux上最成熟的DHCP实现。我会把协议原理、配置细节、还有那些容易踩的坑,一次性说清楚。

2.1 DHCP协议原理:你设备是怎么拿到IP的?

先看一个完整的交互流程。设备开机后,网卡一激活,就会发出一个广播包去找DHCP服务器。整个过程分四步,业内叫DORA:

  1. Discover(发现):客户端发广播,问“谁有IP给我一个?”
  2. Offer(提供):服务器回应,说“我这有个IP,你要不要?”
  3. Request(请求):客户端说“好,我就要这个IP。”
  4. Ack(确认):服务器确认“OK,这个IP归你了,租约开始。”

嗯,这里要注意:如果网络里有多个DHCP服务器,客户端会选第一个收到的Offer。我在项目中遇到过,有人不小心在同一个网段里起了两个DHCP,结果设备IP时好时坏,排查了半天才发现。

核心要点:DHCP是基于UDP的,客户端用端口68,服务器用端口67。广播只在同一广播域内有效,跨子网需要DHCP中继(relay)。

DHCP DORA 交互流程 客户端 (Client) DHCP 服务器 ① Discover(广播) ② Offer(单播/广播) ③ Request(广播) ④ Ack(单播) 注意 如果客户端之前有过该网段的租约,会直接发 Request 请求续约,跳过 Discover 阶段

2.2 安装isc-dhcp-server

在Ubuntu/Debian上安装很简单,一条命令搞定:

sudo apt update
sudo apt install isc-dhcp-server -y

安装完成后,主配置文件在 /etc/dhcp/dhcpd.conf。我个人习惯先备份一份原始配置,万一改坏了还能恢复:

sudo cp /etc/dhcp/dhcpd.conf /etc/dhcp/dhcpd.conf.bak

小技巧:安装后先别急着改配置。先检查一下服务状态,确认进程能正常启动:sudo systemctl status isc-dhcp-server。如果报错,多半是配置文件语法有问题。

2.3 核心配置详解:地址池、租约、option 66/67/150

我们直接看一个完整的配置示例。我会把每个参数的作用说清楚。

# /etc/dhcp/dhcpd.conf

# 全局设置
option domain-name "example.com";
option domain-name-servers 8.8.8.8, 8.8.4.4;
default-lease-time 600;
max-lease-time 7200;
authoritative;

# 子网声明
subnet 192.168.1.0 netmask 255.255.255.0 {
    range 192.168.1.100 192.168.1.200;
    option routers 192.168.1.1;
    option subnet-mask 255.255.255.0;

    # PXE 启动相关选项
    option option-66 code 66 = text;
    option option-67 code 67 = text;
    option option-150 code 150 = ip-address;

    option option-66 "192.168.1.10";       # TFTP 服务器地址
    option option-67 "pxelinux.0";         # 启动文件名
    option option-150 192.168.1.10;        # TFTP 服务器地址(思科设备用)
}

我来拆解一下关键点:

  • default-lease-time / max-lease-time:默认租约600秒,最大7200秒。PXE启动场景下,租约时间可以设短一些,避免IP被长时间占用。
  • authoritative:告诉客户端“我是这个网段的权威服务器”。如果不加,客户端可能会拒绝你给的IP。
  • range:地址池范围。我建议留出一段IP做静态分配,比如1-99留给服务器和打印机。
  • option routers:网关地址,必须配,否则设备出不去。

2.3.1 option 66、67、150 详解

这三个选项是PXE网络启动的关键。很多新手在这里栽跟头,我详细说一下:

选项 类型 作用 常见值
option 66 text(字符串) 指定TFTP服务器的IP地址或主机名 "192.168.1.10"
option 67 text(字符串) 指定启动文件名(如pxelinux.0) "pxelinux.0"
option 150 ip-address(IP地址) 思科设备专用的TFTP服务器地址 192.168.1.10

避坑指南:option 66和150虽然都指向TFTP服务器,但类型不同。66是字符串,150是IP地址。我曾经见过有人把66写成IP地址格式,结果客户端死活拿不到启动文件。记住:66用引号,150不用。

2.4 地址池与租约管理

租约文件默认在 /var/lib/dhcp/dhcpd.leases。你可以直接查看当前有哪些设备拿到了IP:

sudo cat /var/lib/dhcp/dhcpd.leases | grep -E "lease|hardware|client-hostname"

输出大概长这样:

lease 192.168.1.100 {
    starts 2 2025/03/18 09:15:22;
    ends 2 2025/03/18 09:25:22;
    hardware ethernet 00:1a:2b:3c:4d:5e;
    client-hostname "pxe-client-01";
}

如果你想手动清理租约,可以停掉服务后删除租约文件,再重启:

sudo systemctl stop isc-dhcp-server
sudo rm /var/lib/dhcp/dhcpd.leases
sudo touch /var/lib/dhcp/dhcpd.leases
sudo systemctl start isc-dhcp-server

小技巧:调试阶段,我习惯把 default-lease-time 设成60秒。这样设备断线后IP很快释放,方便反复测试。上线前再改回正常值。

2.5 多子网配置实战

如果你的服务器有多个网卡,或者需要为不同网段分配IP,就要配多子网。假设我们有两张网卡:

  • eth0:192.168.1.0/24,连接办公网
  • eth1:10.0.0.0/24,连接PXE启动网

配置如下:

# 告诉DHCP监听哪张网卡
# 编辑 /etc/default/isc-dhcp-server
INTERFACESv4="eth0 eth1"

# dhcpd.conf 中配置两个子网
subnet 192.168.1.0 netmask 255.255.255.0 {
    range 192.168.1.100 192.168.1.200;
    option routers 192.168.1.1;
    option domain-name-servers 8.8.8.8;
    default-lease-time 600;
    max-lease-time 7200;
}

subnet 10.0.0.0 netmask 255.255.255.0 {
    range 10.0.0.100 10.0.0.200;
    option routers 10.0.0.1;
    option domain-name-servers 8.8.8.8;
    default-lease-time 300;
    max-lease-time 1800;

    # PXE 启动选项
    option option-66 "10.0.0.10";
    option option-67 "pxelinux.0";
    option option-150 10.0.0.10;
}

这里有个关键点:每个子网必须有一个独立的地址池,不能重叠。我见过有人把两个子网的range写成一样的,结果客户端拿到冲突的IP,网络直接瘫痪。

多子网注意事项:

  • 确保每个子网的网关(option routers)能路由到其他网段
  • 如果客户端和服务器不在同一个广播域,需要配置DHCP中继(dhcrelay)
  • 不同子网的租约时间可以不同——PXE网可以设短一些,办公网设长一些

2.6 验证与调试

配置改完后,先检查语法:

sudo dhcpd -t -cf /etc/dhcp/dhcpd.conf

如果没有报错,重启服务:

sudo systemctl restart isc-dhcp-server

查看日志确认是否正常:

sudo tail -f /var/log/syslog | grep dhcpd

你会在日志里看到类似这样的信息:

Mar 18 09:30:15 dhcp-server dhcpd[1234]: DHCPDISCOVER from 00:1a:2b:3c:4d:5e via eth1
Mar 18 09:30:15 dhcp-server dhcpd[1234]: DHCPOFFER on 10.0.0.100 to 00:1a:2b:3c:4d:5e via eth1
Mar 18 09:30:15 dhcp-server dhcpd[1234]: DHCPREQUEST for 10.0.0.100 from 00:1a:2b:3c:4d:5e via eth1
Mar 18 09:30:15 dhcp-server dhcpd[1234]: DHCPACK on 10.0.0.100 to 00:1a:2b:3c:4d:5e via eth1

看到这四条日志,说明DORA流程走完了,客户端成功拿到了IP。

常见问题:如果客户端一直发Discover但收不到Offer,先检查防火墙。DHCP用的是UDP 67/68端口,很多系统默认会拦截广播包。执行 sudo ufw allow 67/udp 放行即可。