今天下午总算把整套DHCP实验收尾了,趁着印象还新鲜赶紧记下来。起因是上午办公区传来一声“我上不了网”,过去一看网卡地址是169.254.23.11,Windows在DHCP请求失败后自动生成的APIPA地址,基本等于在喊“我没拿到地址”。查了一圈,有人手动把台式机IP填成了188,而路由器地址池恰好把这个地址分配给了另一台机器,冲突就这么发生了。
这种手工管理IP的方式在小网络里还能勉强维持,设备一多就完全靠碰运气。所以我决定在实验环境里把DHCP从服务器配置、地址池规划、冲突检测到跨网段中继完整跑一遍,不只在模拟器里点两下,而是真刀真枪把客户端、服务器、中继设备都配一遍,有问题当场解决。
1. 实验拓扑与这次要验证的三个问题
1.1 手工配置IP的老毛病
很多刚入行的朋友觉得DHCP简单,不就是“给电脑自动分配IP吗”?其实真正在生产环境里踩过坑才知道,手工IP管理到了几十上百台设备的规模,几乎必然出问题。我自己就遇到过:
- 两台设备被填了同一个IP,后开机的把先开机的踢下线,查半天找不到是谁干的;
- 有人把子网掩码从255.255.255.0填成了255.255.0.0,短时间内看起来能上网,实际已经跨到了另一个广播域,排查时隐蔽性极强;
- 部门调整来了新设备,地址表上全是过期记录,临时给一个“看着没人用”的IP,过几天又冲突。
DHCP的价值不在于“自动分配”这四个字,而在于把地址的管理权收回到网管手里。谁拿到了什么地址、什么时候拿的、租约还剩多久,服务器上一查就清楚。这台设备该用什么网关、什么DNS,也都在服务器上统一下发,不用一台台去改。这就是这次做实验的核心动机:验证清楚之后,把生产环境迁移到DHCP方案上。
1.2 实验台架与设备角色
这次实验用的是eNSP模拟器加真实虚拟机客户端,拓扑不复杂但覆盖了主要场景:
| 设备 | 角色 | 关键配置 |
|---|---|---|
| 华为AR路由器 | DHCP Server + 跨网段中继服务端 | 启用DHCP服务,配置全局地址池 |
| 锐捷RG-S5750三层交换机 | VLAN20网关 + DHCP中继 | 配置ip helper-address指向DHCP服务器 |
| 华为S5700二层交换机 | 接入层设备 | 透明转发二层报文 |
| Windows 10客户端 | 广播域内自动获取 | 验证同网段DORA流程 |
| CentOS虚拟机 | Linux客户端 | 复现dhclient already running报错 |
| Ubuntu虚拟机 | 跨网段客户端 | 验证DHCP中继效果 |
实际连接关系是:华为AR的G0/0/1接口作为VLAN10的网关和DHCP服务器,连接S5700,S5700下挂Windows和CentOS;AR的G0/0/2接口接锐捷交换机,锐捷上划分VLAN20并配置中继,Ubuntu客户端接在VLAN20下面。
1.3 三个必答题:地址池、冲突检测、跨网段
做实验之前,我给这次验证列了三个问题,不是随便点点命令,而是每个都要有明确结论:
- 地址池怎么规划才不容易踩坑——办公网的终端动态获取没问题,但打印机、门禁控制器、无线AP这些设备如果也混在动态池里,迟早出问题。需要明确排除哪些地址、保留哪些地址、租期设多长。
- 服务器怎么避免把已经占用的地址再分配出去——这就是后来实验里重点验证的
dhcp server ping packet参数,很多人根本没注意过它。 - 跨网段的终端怎么才能拿到地址——广播报文过不了三层,这是TCP/IP的基础常识,但实际配置中继时,还是有人会忘了指定服务器地址或者放行UDP 67/68端口。
这三个问题全部跑通之后,我才有底气把它迁移到生产环境。下面按实验顺序记录。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 地址池规划:哪些地址必须提前圈出去
2.1 先把服务器、打印机和网络设备“圈”出动态池
很多第一次做DHCP的人,最多的想法是“动态池越大越好,反正有地址就分配”。这个思路在纯终端环境没问题,但生产网络中设备类型很杂。打印机、门禁控制器、考勤机、IP电话、无线AP的AC管理地址、摄像头NVR,这些设备要么不支持DHCP,要么需要固定IP保证访问连续性。
这些设备如果也靠在DHCP排除列表里,地址池规划就得提前算好。我见过一个案例,公司新装了一批IP摄像头,安装师傅图省事,直接手动填了192.168.1.150,恰好这个地址在DHCP动态池里。第二天上班,有台电脑获取到了同样的地址,摄像头画面时断时续,查了很久才发现是IP冲突。
所以地址池规划的第一步,不是先分配,而是先把不能动的地址“圈”出去。圈出去的手段有两种:
- 排除地址:在DHCP服务器上配置excluded-ip-address,表示这个范围内的地址永远不会被动态分配;
- 固定绑定:用DHCP保留(static-bind),根据MAC地址把某个IP固定分配给某台设备,相当于既有DHCP的自动管理,又能保证地址不变。
生产环境中,网络设备、服务器、打印机一般放排除段,关键业务终端(比如收银台、大屏播放器)用固定绑定。这样既有集中管理的优势,又满足特殊设备的需求。
2.2 租期、DNS、网关option怎么定
地址池里的核心参数不只是网段和掩码,还包括租期、网关和DNS。租期这个参数最容易被拍脑袋决定。实际上租期长短和终端数量、网络稳定性直接相关:
- 终端数量接近地址池容量时,租期要设短一些(比如1小时),否则地址池会被长时间不用的设备占满;
- 终端数量远小于地址池容量,且设备长期在线,租期可以设长一些(比如7天),减少DHCP交互报文,网络也更稳定;
- 办公Wi-Fi环境下,手机、访客设备频繁进出,租期一般设12小时到1天比较合适,既能回收闲置地址,又不会让设备频繁掉线重签。
网关和DNS则是通过DHCP option下发的。网关的option是3,DNS是6。在华为设备上用gateway-list和dns-list配置,客户端拿到地址的同时也会自动拿到网关和DNS,不需要手动配置。
2.3 本次实验的地址规划表
这次实验我规划了两个网段,一张表直接说清楚:
| VLAN | 网段/掩码 | 网关 | 动态分配范围 | 排除范围 | 租期 |
|---|---|---|---|---|---|
| VLAN10 | 192.168.10.0/24 | 192.168.10.1 | 192.168.10.101 - 192.168.10.254 | 192.168.10.1 - 192.168.10.100 | 1天 |
| VLAN20 | 192.168.20.0/24 | 192.168.20.1 | 192.168.20.101 - 192.168.20.254 | 192.168.20.1 - 192.168.20.100 | 1天 |
排除范围里放的是什么?前50个留给了网络设备和管理地址,后50个留给打印机、门禁控制器和测试服务器。这样动态池从.101开始,范围也足够办公终端使用。实验做到后面你会发现,这个规划的合理与否直接影响排障难度。
3. 华为路由器DHCP Server配置:接口池与全局池的取舍
3.1 接口地址池配置与验证(同网段实验)
华为AR路由器做DHCP Server有两种方式:接口地址池和全局地址池。第一种最直观,直接在终端所在的网关接口上选择dhcp select interface,然后以接口的网段作为地址分配范围。
code复制<Huawei> system-view
[Huawei] dhcp enable
[Huawei] interface GigabitEthernet0/0/1
[Huawei-GigabitEthernet0/0/1] ip address 192.168.10.1 255.255.255.0
[Huawei-GigabitEthernet0/0/1] dhcp select interface
[Huawei-GigabitEthernet0/0/1] dhcp server dns-list 223.5.5.5 114.114.114.114
[Huawei-GigabitEthernet0/0/1] dhcp server excluded-ip-address 192.168.10.1 192.168.10.100
[Huawei-GigabitEthernet0/0/1] dhcp server lease day 1 hour 0 minute 0
[Huawei-GigabitEthernet0/0/1] dhcp server ping packet 2
这里有个细节:dhcp enable必须在全局视图下先打开,不然接口下配置dhcp select interface会报错。这也是很多新手第一次配置时最容易卡住的地方,敲完命令没反应,一查发现DHCP服务根本没启。
配置完后,把Windows客户端改成“自动获得IP地址”,可以看到端口获得地址的过程。执行ipconfig /all查看详细信息,确认网关是192.168.10.1,DNS是223.5.5.5,DHCP服务器显示192.168.10.1。
在路由器上执行display dhcp server ip-in-use,可以看到已分配的IP、MAC地址和租约剩余时间。这就是DHCP相比手工IP的核心优势:谁拿了哪个地址,一目了然。
3.2 全局地址池配置与适用场景
接口地址池虽然简单,但限制了灵活性。比如DHCP服务器的接口地址和客户端不在同一网段,或者需要多个网段共用一套地址池规则,接口池就不够用了。这时候用全局地址池更合适。
code复制[Huawei] ip pool vlan10
[Huawei-ip-pool-vlan10] network 192.168.10.0 mask 255.255.255.0
[Huawei-ip-pool-vlan10] gateway-list 192.168.10.1
[Huawei-ip-pool-vlan10] dns-list 223.5.5.5 114.114.114.114
[Huawei-ip-pool-vlan10] excluded-ip-address 192.168.10.1 192.168.10.100
[Huawei-ip-pool-vlan10] lease day 1 hour 0 minute 0
[Huawei-ip-pool-vlan10] quit
[Huawei] interface GigabitEthernet0/0/1
[Huawei-GigabitEthernet0/0/1] dhcp select global
接口地址池和全局地址池的使用场景有明显差异。接口池的地址范围自动取自接口的IP网段,配置量小,适合简单的单网段环境;全局池需要手动指定网段、掩码、网关,但可以被多个接口引用,适合中大型网络或者需要配合DHCP中继的场景。后面做跨网段实验时,用的就是全局地址池。
3.3 一个容易踩的坑:接口池和全局池混用
实验中我特意试过一种容易出错的情况:接口下先执行了dhcp select interface,之后又在全局视图下创建了同网段的ip pool,再把接口切换成dhcp select global。如果全局池参数和接口地址不一致,客户端获取到地址后会发现网关不可达。
原因在于接口池的“网段”是自动取接口IP,而全局池的network是手动指定的。两者如果配置不一致,DHCP服务器自己不会报错,但客户端拿到地址后数据包发不出去。排查思路是查看地址池信息和实际接口IP是否匹配:
code复制[Huawei] display ip pool name vlan10
[Huawei] display ip pool interface GigabitEthernet0/0/1
这两个命令列出来的地址池范围,必须和客户端实际所在网段对应。很多新手排错半天,最后发现是全局池的network写错了,这种低级错误一次实验就能记住。
4. Linux客户端dhclient already running:一次租约进程冲突排查
4.1 报错出现的那一刻
Wi-Fi场景下,我在CentOS虚拟机里试图手动触发DHCP续租,敲了dhclient命令,结果屏幕上直接弹出一行:
code复制dhclient(10109) is already running - exiting.
This version of ISC DHCP is based on the DHCP server...
这种报错的核心含义是:当前系统里已经有一个dhclient进程在监听这个网卡,再手动启动一个新的dhclient,新进程检测到旧进程还在,直接拒绝启动。刚开始我以为只是虚拟机环境的问题,后来在多个Linux发行版上试了,都会出现类似情况。
4.2 通过进程、租约和日志定位
排查链路从确认进程开始:
code复制ps aux | grep dhclient
输出里能看到两个dhclient进程,一个PID 10109,另一个是我手动启动的。这里的10109对应报错信息里的编号。继续查租约文件:
code复制cat /var/lib/dhclient/dhclient.leases
文件里能看到最近几次获取到的IP、租约开始时间、到期时间。接着看系统日志:
code复制journalctl -u NetworkManager -f
日志里明显能看到NetworkManager已经为这个接口维护了DHCP租约。问题的根源就在这:现代Linux发行版默认由NetworkManager或者systemd-networkd管理网络接口,它们内部会自动拉起dhclient。用户再手动敲dhclient,属于“重复造轮子”,新旧进程同时监听同一个网卡,租约管理会混乱,严重的可能导致地址获取异常或者网关丢失。
4.3 处理办法与后续建议
找到原因后,处理就简单了。如果是NetworkManager管理的接口,不要手动执行dhclient,应该用:
code复制nmcli device reapply ens33
nmcli connection up ens33
如果确实需要强制重新获取地址,先释放旧进程的租约,再重新获取:
code复制dhclient -r
dhclient
-r参数会主动向DHCP服务器发送RELEASE报文,释放当前租约,然后再发起Discover流程。如果系统里残留了多个dhclient进程,直接pkill dhclient清干净再操作。
这个坑给我的教训是:在客户机上排查DHCP问题,先搞清楚网络接口到底由谁管理——NetworkManager、systemd-networkd还是纯手工配置文件。不同管理栈的排查方式完全不同,一上来就敲dhclient是典型的“经验主义”错误。
Windows上的对应操作其实更简单:ipconfig /release释放地址,ipconfig /renew重新获取。但要注意,在域环境或需要严格管控IP的环境里,频繁手动release/renew会触发DHCP服务器上的安全策略,操作前最好确认一下策略是否允许。
5. 分配前的ICMP探测:dhcp server ping packet参数实验
5.1 ping packet在哪一步起作用
DHCP服务器在准备给客户端分配一个地址时,并不是“看一眼地址池里没有记录就直接给”。它会先对这个候选地址做ICMP探测,也就是我们常说的ping,目的是确认这个地址在当前网络中是否已经被其他主机使用。
这个机制在华为AR上对应两个参数:
dhcp server ping packet 2:分配前发送2个ICMP Echo Request报文;dhcp server ping timeout 300:等待响应的时间,单位毫秒。
整个流程是:客户端发来DHCP Discover -> 服务器从地址池里选一个候选地址 -> 对这个地址发ICMP探测 -> 如果没有收到响应,认为地址空闲,可以分配;如果收到响应,认为地址已被其他设备占用,换下一个地址继续探测。
5.2 实测:当地址被手工占用
为了验证这个机制,我故意做了个实验:把一台Windows机器手动改成192.168.10.150,然后把192.168.10.150划进DHCP动态池范围。按理说,DHCP服务器不知道这个地址已被手工占用,但如果ping探测生效,它应该会跳过这个地址。
配置好后,在华为AR上开启调试:
code复制<Huawei> debugging dhcp server
<Huawei> terminal debug
让另一台客户端请求地址,观察调试输出。日志里能看到服务器先对192.168.10.150发起ICMP探测,收到响应后判定该地址不可用,继续探测下一个地址,最终分配了192.168.10.151。
这说明ping packet机制确实在正常工作。如果不配置这个参数(或者设置为0),DHCP服务器会把192.168.10.150直接分配出去,结果就是两台设备抢同一个IP,网络时断时续。
5.3 生产环境怎么设
生产环境中这个参数建议设置为1或2,不建议设为0。设为0等于关闭冲突检测,风险很高,尤其在使用手工IP和DHCP混合管理的办公网里,几乎必然出地址冲突。
不过也要注意,这个机制的局限在于:如果目标主机禁ping,或者设备默认丢弃ICMP请求,DHCP服务器认为地址空闲,照样会把地址分配出去。所以它只是一个“基于探测的辅助手段”,不能完全替代DHCP Snooping。在接入层交换机上开启DHCP Snooping,才能真正通过绑定表来防止私接DHCP服务器和地址欺骗。
6. 跨网段分配与接入交换机操作:中继、释放和排障
6.1 广播跨不过三层,中继来接力
DHCP客户端的Discover报文是广播报文,而路由器默认不转发广播,所以如果DHCP服务器和客户端不在同一个网段,客户端直接发广播肯定是拿不到地址的。解决办法是让客户端所在网段的网关设备变成“中继”,把原本的广播请求转成单播报文,发给指定的DHCP服务器。
这次实验里,VLAN20的网关是锐捷RG-S5750,DHCP服务器在192.168.0.50和192.168.0.51。在锐捷上配置中继的命令很直观:
code复制Ruijie# configure terminal
Ruijie(config)# interface vlan 20
Ruijie(config-if-VLAN 20)# ip address 192.168.20.1 255.255.255.0
Ruijie(config-if-VLAN 20)# ip helper-address 192.168.0.50
Ruijie(config-if-VLAN 20)# ip helper-address 192.168.0.51
配置两条ip helper-address,相当于告诉中继:收到来自VLAN20的DHCP请求后,分别转发给这两个服务器地址。这样即使192.168.0.50这台服务器宕机,客户端还能从192.168.0.51拿到地址,形成简单冗余。
华为或者华三设备上对应的配置略有不同,思路一样:
code复制[Huawei] interface Vlanif20
[Huawei-Vlanif20] ip address 192.168.20.1 255.255.255.0
[Huawei-Vlanif20] dhcp select relay
[Huawei-Vlanif20] dhcp relay server-address 192.168.0.50
[Huawei-Vlanif20] dhcp relay server-address 192.168.0.51
6.2 锐捷交换机上的中继与释放操作
实验做完后,锐捷接入交换机上还做了一次DHCP Snooping的验证。办公网里经常有人私自接一个小路由器当Wi-Fi热点,这种路由器自带DHCP功能,如果它的LAN口接到了公司网络,就可能给其他用户分配错误的IP和网关,导致大面积上不了网。DHCP Snooping能解决这个问题:只有信任端口(连接合法DHCP服务器的端口)发出的DHCP Offer才被放行,非信任端口发来的直接丢弃。
排查时经常需要看Snooping的绑定表:
code复制Ruijie# show ip dhcp snooping binding
如果表里有残留,可以清理:
code复制Ruijie# clear ip dhcp snooping binding all
有人问我“锐捷交换机怎么释放某个客户端的DHCP地址”,严格来说,交换机不是DHCP服务器,它没有客户端租约的直接控制权。真正的租约在服务器上,交换机能做的主要是清理Snooping绑定表,或者配合服务器端操作。如果锐捷设备本身开启了DHCP Server功能,清理已分配地址的通用命令是clear ip dhcp binding这一类,不同版本具体命令略有差异,输入clear ip dhcp ?会让设备自己列出可用参数。
所以实际工作中,想要客户端立刻释放地址,最快还是在客户端上操作:
- Windows:
ipconfig /release后ipconfig /renew - Linux:
dhclient -r后dhclient
6.3 “虚拟机拿不到地址”排查顺序
实验过程中顺手帮朋友排查了一个问题:PVE上的新虚拟机一直拿不到DHCP地址,物理机没问题,虚拟机就是上不了网。这个案例很有代表性,排查顺序
