DHCP 与自动配置
为什么需要 DHCP
手动配置 IP 地址容易出错:
- 地址冲突:两台电脑设成 192.168.1.100,同时开机就打架
- 网关填错:能访问内网,但上不了互联网
- DNS 填错:能 ping 通 IP,但打不开网页
- 人员流动:新员工入职、设备更换,IT 部门疲于奔命
DHCP(Dynamic Host Configuration Protocol,动态主机配置协议,RFC 2131) 自动分配 IP 地址、子网掩码、网关、DNS,让设备"插上网线就能上网"。
DHCPv4 的 DORA 流程
DHCP 采用客户端-服务器模型,核心流程四个步骤:
第一步:Discover(发现)
新设备开机,没有 IP,不知道 DHCP 服务器在哪。它发送广播:
源 IP: 0.0.0.0(我还没地址)
目的 IP: 255.255.255.255(广播)
源 MAC: 00:AA:BB:CC:DD:EE
消息类型: DHCP Discover
参数请求: 子网掩码、路由器、DNS、域名
生活例子:你刚搬进小区,不知道物业在哪,就在楼下大喊"我是新住户,需要分配门牌号!"
DORA 流程中第三步 Request 是广播而非单播,目的是通知所有 DHCP 服务器:"我选了 A 的 Offer,B 和 C 可以收回你们的 IP 了。"这种设计避免了地址池中的 IP 被多个客户端同时占用。
第二步:Offer(提供)
DHCP 服务器收到 Discover 后,从地址池选一个可用 IP,发送 Offer:
源 IP: 192.168.1.1(DHCP 服务器)
目的 IP: 255.255.255.255(广播,因为客户端还没 IP)
提供 IP: 192.168.1.100
子网掩码: 255.255.255.0
网关: 192.168.1.1
DNS: 8.8.8.8, 114.114.114.114
租约时间: 86400 秒(1 天)
如果有多个 DHCP 服务器,客户端可能收到多个 Offer,通常先到的优先。
第三步:Request(请求)
客户端选择一个 Offer,广播发送 Request:
源 IP: 0.0.0.0
目的 IP: 255.255.255.255
请求 IP: 192.168.1.100
服务器标识: 192.168.1.1
为什么是广播? 告诉所有 DHCP 服务器:"我选了 A 的 Offer,B 和 C 可以收回你们的 IP 了。"
第四步:Acknowledge(确认)
DHCP 服务器正式分配 IP,发送 ACK:
源 IP: 192.168.1.1
目的 IP: 192.168.1.100(现在客户端有 IP 了,可以单播)
确认 IP: 192.168.1.100
租约时间: 86400 秒
T1(续租时间): 43200 秒(租约的 50%)
T2(重绑定时间): 75600 秒(租约的 87.5%)
客户端收到 ACK 后,配置 IP,开始上网。
租约更新机制
IP 不是永久拥有的,是"租"来的。租约到期前需要续租:
续租(Renew)
- T1 = 租约的 50%:客户端单播向原 DHCP 服务器发 Request
- 如果服务器回复 ACK,租约刷新
- 如果服务器无响应,继续尝试直到 T2
重绑定(Rebind)
- T2 = 租约的 87.5%:原服务器仍无响应,客户端广播向任意 DHCP 服务器发 Request
- 如果有新服务器响应,获得新租约
- 如果到期仍无响应,客户端必须释放 IP,回到初始状态,重新 DORA
生活例子:租房合同一年,到期前半年你开始联系房东续签(Renew)。如果房东失联,到期前 1 个月你开始找其他房东(Rebind)。如果到期还没找到,只能搬出去重新找房(重新 DORA)。
DHCP Relay(中继)
DHCP 依赖广播,而路由器不转发广播。如果 DHCP 服务器和客户端不在同一子网怎么办?
DHCP Relay Agent(RFC 3046) 解决此问题:
PC (192.168.2.10) → 广播 Discover
↓
路由器 R(配置了 ip helper-address 192.168.1.1)
↓
R 把广播改为单播,目的 IP 改为 192.168.1.1(DHCP 服务器)
↓
R 在包中插入 Option 82(Agent Information):
- Circuit ID:标识来自哪个子网/端口
- Remote ID:标识客户端位置
- GIADDR(Gateway IP Address):192.168.2.1(R 的接口 IP)
↓
DHCP 服务器根据 GIADDR 判断该从哪个地址池分配(192.168.2.0/24 池)
↓
服务器回复 Offer,发给 R,R 转发给 PC
GIADDR 是关键:DHCP 服务器靠它判断客户端来自哪个子网,从而分配正确网段的 IP。
DHCP Relay 的核心机制是路由器把客户端的广播 Discover 转换为单播,并在包中插入 GIADDR(Gateway IP Address)字段。DHCP 服务器根据 GIADDR 判断该从哪个地址池分配 IP——上图中的 GIADDR=192.168.2.1 告诉服务器:"这个请求来自 192.168.2.0/24 子网,请从对应池分配。"
IPv6 自动配置:SLAAC vs DHCPv6
IPv6 有三种地址配置方式:
1. SLAAC(无状态自动配置,RFC 4862)
完全不需要服务器,主机自己生成地址:
- 主机生成 Link-Local 地址(FE80::/64)
- 发送 RS(Router Solicitation)
- 路由器回复 RA(Router Advertisement),包含前缀(如 2001:db8:1:2::/64)
- 主机把前缀 + 接口标识符(EUI-64 或随机)拼成全球地址
- DAD 检测地址唯一性
优点:零配置,路由器一宣告,主机自动可用 缺点:只能获得地址、前缀长度、默认网关,无法获得 DNS
2. DHCPv6 有状态(Stateful)
类似 DHCPv4,服务器分配完整地址和 DNS:
Solicit → Advertise → Request → Reply
3. DHCPv6 无状态(Stateless)
混合方案:地址由 SLAAC 生成,DNS 等额外信息由 DHCPv6 提供。
路由器 RA 中设置 O 位(Other Configuration)=1,告诉主机:"地址你自己生成,但 DNS 来找我拿。"
| 方式 | 地址来源 | DNS 来源 | 适用场景 |
|---|---|---|---|
| SLAAC | 自动生成 | 无(需 RDNSS) | 简单网络 |
| DHCPv6 有状态 | 服务器分配 | 服务器分配 | 企业网络(需审计) |
| DHCPv6 无状态 | 自动生成 | 服务器分配 | 主流方案,兼顾灵活与管理 |
现代网络的主流方案是 DHCPv6 无状态(Stateless):地址由 SLAAC 自动生成(零配置、无单点故障),DNS 等额外信息由 DHCPv6 统一分配(便于集中管理)。这种混合方案兼顾了灵活性和可管理性。
DHCP 安全
DHCP 欺骗攻击
攻击者私接一台 DHCP 服务器,抢先响应 Discover,给客户端分配错误的网关和 DNS:
攻击者 DHCP:分配 192.168.1.100,网关 192.168.1.200(攻击者自己),DNS 恶意服务器
客户端流量被引向攻击者,实现中间人攻击。
防御:DHCP Snooping
交换机开启 DHCP Snooping 后:
- 信任端口(Trusted):连接合法 DHCP 服务器的端口,允许 DHCP Offer/ACK 通过
- 非信任端口(Untrusted):连接终端的端口,丢弃 DHCP Offer/ACK(防止非法服务器)
- 交换机记录 DHCP Snooping Binding 表:MAC ↔ IP ↔ 端口 ↔ VLAN 的绑定关系
RA Guard(IPv6)
类似 DHCP Snooping,防止非法路由器发送 RA。交换机信任端口允许 RA,非信任端口丢弃 RA。
本篇小结
- DHCPv4 四步:Discover → Offer → Request → ACK
- 租约 50% 时 Renew(单播原服务器),87.5% 时 Rebind(广播任意服务器)
- DHCP Relay 用 GIADDR 和 Option 82 跨网段分配地址
- IPv6 SLAAC 自动生成地址,但需 DHCPv6 或 RDNSS 获取 DNS
- DHCP Snooping 和 RA Guard 防止非法地址分配
动手实践
查看本机 DHCP 获取的信息:
# Windows ipconfig /all # 观察 DHCP Enabled、Lease Obtained、Lease Expires # Linux sudo dhclient -v eth0Wireshark 抓包过滤
bootp,观察完整的 DORA 过程查看 DHCP 续租:
# Linux sudo dhclient -r eth0 # 释放 sudo dhclient -v eth0 # 重新获取,观察 Renew 时间在支持 DHCP Snooping 的交换机上查看绑定表:
show ip dhcp snooping binding思考:如果 DHCP 服务器宕机,已获取租约的客户端还能上网多久?T1 和 T2 的设计为什么分别是 50% 和 87.5%?