做企业网络维护这些年,我几乎每年都会遇到一次这样的需求:公司办公楼划分了十几个VLAN,终端分散在不同网段,DHCP服务器却只有一台,集中在核心机房。最开始有人图省事,提议在DHCP服务器上把每个网段的地址池都建好,直接广播分配IP地址,结果跨网段根本分配不过去。后来认真研究了H3C设备上的DHCP中继,才把这个看似简单、实际很容易踩坑的问题彻底解决。
今天就把H3C路由器(以及三层交换机、无线控制器这类具备三层转发能力的设备)配置DHCP中继的全过程系统捋一遍,从原理、规划、配置命令到验证抓包,再把我实际运维中踩过的坑和排查思路整理出来。无论你是刚接触企业网络的入门工程师,还是已经独立维护中大型园区的网工,这篇文章都值得收藏备查。
1. 为什么需要DHCP中继,而不是让每个网段自己分配
1.1 一个非常典型的业务场景
先描述一个最常见的场景:公司有三栋办公楼,汇聚层和核心层由几台H3C设备组成,每栋楼的终端划在不同的VLAN里。比如一栋楼是192.168.10.0/24,二栋楼是192.168.20.0/24,三栋楼是192.168.30.0/24。终端的网关分别落在核心设备上,而DHCP服务器放在机房,地址是10.10.0.10/24。
这时候问题就来了:客户端发出的DHCP Discover报文是广播帧,广播帧默认不会跨三层转发。路由器收到广播后会直接丢弃,不会帮你把这帧原封不动地传到机房。结果就是一栋楼的终端只能看到本网段广播,永远等不到DHCP服务器的响应,IP地址始终拿不到,网卡一直显示“未识别的网络”。
这种场景下,DHCP中继就是标准解法。中继功能运行在三层设备上,它把客户端的广播请求转换成单播报文,发给指定的DHCP服务器,再把服务器的单播应答通过广播方式回传给客户端。简单说,它就是一个跨网段的“传话人”。
1.2 DHCP中继的核心逻辑:giaddr字段的作用
要真正理解DHCP中继,必须看一个关键字段:giaddr,也就是网关IP地址(Gateway IP Address)。中继设备收到客户端广播的Discover后,会做两件事:
第一,把报文的目的IP改成DHCP服务器的IP,源IP改成路由器上接收到该广播的接口IP,这样报文就变成了普通单播,可以正常走三层转发到服务器。
第二,在报文的giaddr字段里填上接收接口的IP地址。这个字段非常关键,它告诉DHCP服务器:“发出请求的客户端位于哪个网段”。服务器收到请求后,会根据giaddr从地址池中选择一个与giaddr同网段的地址池,然后从该池里分配一个IP,并通过Offer报文回复给中继设备。
这个过程可以类比成小区物业:业主在楼栋里大喊一声,物业听不见;但业主给楼栋管家打了个电话,管家再把消息转告物业,同时告诉物业业主住在哪栋楼(giaddr),物业才能把对应楼栋的通知送到管家手里,由管家转达给业主。没有giaddr,服务器根本不知道该从哪个地址池里取IP。
还有一点需要留意:DHCP协议使用的UDP端口是67(服务器端)和68(客户端)。中继转发时用的是单播UDP,所以中间所有路由器的ACL、策略如果对UDP 67/68做了限制,也会直接导致中继失效。这个后面排查章节会展开。
1.3 中继方案与多DHCP服务器方案的取舍
有人会问,既然跨网段分配这么麻烦,为什么不每个网段都放一台DHCP服务器,或者直接在核心设备上本地配置多个地址池呢?
把三种方案放在一起对比,答案就很清晰了:
| 方案 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 每个网段独立部署DHCP服务器 | 无跨网段依赖,故障域小 | 设备数量多,维护成本高,地址策略难统一 | 极少用,仅在没有集中管理要求的极简网络 |
| 核心设备本地配置DHCP地址池 | 不依赖外部服务器,配置简单 | 消耗设备CPU和内存,大型园区地址池多时管理混乱,无法与现有账号体系、IPAM系统联动 | 小型网络,或临时应急 |
| 集中DHCP服务器 + 三层设备DHCP中继 | 统一管理、统一审计,服务器只做业务,转发交给网络设备 | 依赖服务器与设备的网络连通性,需要额外规划路由和策略 | 绝大多数企业园区、办公楼、分支机构 |
从我实际运维的角度,企业网里最推荐第三种方案。因为DHCP不仅仅是自动发个IP,它还要配合DNS、域名、PXE引导、终端身份识别等策略。这些逻辑集中放在服务器上,才能统一管控。网络设备只负责“转发”,职责单一,故障也更好定位。H3C设备上的DHCP中继正好承担这个“转发”角色。
2. 动手前的规划和准备
2.1 组网结构与VLAN规划
以我最近做的一个园区项目为例,核心设备是一台H3C S7006X交换机,各楼层汇聚通过光缆接入,网关全部终结在核心交换机上。DHCP服务器部署在机房,承接所有终端的地址分配,服务器自身IP是10.10.0.10/24,和核心交换机之间通过一个专门的业务VLAN互联。
具体规划如下:
| VLAN | 用途 | 网段 | 网关(核心设备接口地址) | 中继指向的服务器 |
|---|---|---|---|---|
| VLAN 10 | 办公楼1层终端 | 192.168.10.0/24 | 192.168.10.1 | 10.10.0.10 |
| VLAN 20 | 办公楼2层终端 | 192.168.20.0/24 | 192.168.20.1 | 10.10.0.10 |
| VLAN 30 | 办公楼3层终端 | 192.168.30.0/24 | 192.168.30.1 | 10.10.0.10 |
| VLAN 100 | 机房服务器互联 | 10.10.0.0/24 | 10.10.0.254 | 无 |
这里有两点值得强调。第一,所有终端的网关必须都在启用DHCP中继的设备上,否则中继根本没有三层接口可以接收客户端的广播请求。第二,DHCP服务器所在网段和终端网段之间必须路由可达,这个可达性不只是“能ping通”,还要确保UDP 67/68端口在途中的所有设备策略中放行。
2.2 设备版本与命令差异:V5和V7别搞混
配置H3C设备前,先确认设备运行的Comware版本,这一点特别重要。我见过太多人在V5老设备上照抄V7配置,结果中继完全不生效。
Comware V5时代,交换机接口下要配dhcp select relay,同时还要配dhcp relay server-select。Comware V7之后,dhcp select relay这个命令已经被移除了,中继功能不再需要显式选择工作模式,只需要在接口下配置dhcp relay server-select即可。假如你在V7设备上执行dhcp select relay,系统会直接报错。
另外,H3C和华为同为华系设备,命令体系一脉相承,但也有细节差异。华为的V200R系列交换机配置中继时同样使用dhcp relay server-select,而H3C V5老设备的dhcp select relay在华为设备上基本见不到。所以跨厂商操作时,最稳妥的办法是用display version先看版本,再用?补全命令,不要凭记忆硬敲。
2.3 DHCP服务器侧的准备工作
中继配置只是链路的一半,服务器侧如果没准备好,照样分配不出IP。建议动手前在DHCP服务器上完成以下检查:
- 为每个终端网段创建对应的地址池,例如192.168.10.0网段的池、192.168.20.0网段的池,名称尽量带业务标识。
- 每个地址池务必配置排除地址,把网关、网络设备的管理IP、打印机等固定地址排除掉,避免冲突。
- 在地址池内配置默认网关、DNS服务器地址,这些参数会随Offer报文一起下发给客户端。
- 确认服务器与各终端网段之间的路由是通的。最直接的办法是在服务器上ping各网段的网关地址,能通再继续。
这些准备工作看起来琐碎,但后续排查时能省很多事。尤其是地址池的网段定义,如果和giaddr对不上,服务器会“答非所问”,终端拿到一个完全不在本网段的IP,网络直接不可用,这个问题在第五章还会专门说。
3. H3C设备完整配置步骤
下面进入正题,以核心交换机为例子,给出完整可复现的配置流程。假设核心交换机的管理VLAN接口已经创建好,VLAN 10、20、30都已存在,只差DHCP中继相关配置。
3.1 第一步:检查三层接口地址
中继配置前,先确认各VLAN的三层接口地址已经配置正确。接口地址就是终端的网关,同时也会作为中继报文的源地址和giaddr,马虎不得。
system-view interface Vlan-interface 10 description Office-Floor1 ip address 192.168.10.1 255.255.255.0同样的操作在VLAN 20、VLAN 30上来一遍。检查成果用display ip interface brief,重点看每个接口的IP地址和物理状态是否UP。
3.2 第二步:开启DHCP服务并定义中继组
H3C设备默认没有开启DHCP服务,需要手动打开。然后定义一个中继组,把DHCP服务器的IP地址放进去。
system-view dhcp enable dhcp relay server-group 1 ip 10.10.0.10这里的server-group 1是组编号,可以自由定义。如果有多台DHCP服务器做冗余,可以在一行里写多个IP:
dhcp relay server-group 1 ip 10.10.0.10 ip 10.10.0.11多服务器的情况下,中继会依次把请求转发给列表中的服务器,直到某一台响应用户请求。这样可以在不增加复杂配置的情况下,实现基础的主备冗余。
3.3 第三步:在终端网段接口上绑定中继组
进入每个终端网段的三层接口,引用刚定义的中继组。这一步是最容易遗漏的,很多工程师配完了中继组但忘了在接口引用,结果客户拿着问题找上门,一查发现接口下空空如也。
interface Vlan-interface 10 dhcp relay server-select 1VLAN 20、VLAN 30的接口也要做同样的绑定。如果网络规模大,建议每个接口都用description写清楚业务用途,方便后续维护。比如dhcp relay server-select 1这行命令,在V5老设备上还需要额外配一条dhcp select relay,但在V7设备上直接配即可。
3.4 第四步:处理客户端的DHCP Inform请求
这一步看起来不起眼,实际很关键,尤其是网络里有IP摄像头、打印机、无线AP这类终端时,设备上线后还会周期性地发送DHCP Inform报文,向服务器确认自己的IP地址和租约信息。H3C设备如果没有配置dhcp relay client-inform relay-to-server,默认情况下中继不会转发Inform报文,而是直接丢弃。
后果就是:摄像头等设备虽然通过中继拿到了IP,但服务器收不到Inform,一段时间后服务器认为租约已经异常,可能触发地址回收或续租失败,设备出现周期性掉线。配置方式是在接口下加上:
interface Vlan-interface 10 dhcp relay client-inform relay-to-server如果你的网络里终端类型比较单一、都是普通PC,这个命令不配也能用。但考虑到园区网络里总会有打印机、门禁、摄像头这些特殊终端,我的建议是无脑全配上,反正不影响正常分配流程。
3.5 完整配置示例与保存
把所有配置串起来,完整的关键配置如下:
system-view dhcp enable dhcp relay server-group 1 ip 10.10.0.10 # interface Vlan-interface 10 description Office-Floor1 ip address 192.168.10.1 255.255.255.0 dhcp relay server-select 1 dhcp relay client-inform relay-to-server # interface Vlan-interface 20 description Office-Floor2 ip address 192.168.20.1 255.255.255.0 dhcp relay server-select 1 dhcp relay client-inform relay-to-server # interface Vlan-interface 30 description Office-Floor3 ip address 192.168.30.1 255.255.255.0 dhcp relay server-select 1 dhcp relay client-inform relay-to-server配置完成后,务必保存配置,否则设备重启后配置全丢:
save系统会询问是否保存配置,输入Y确认即可。这一步我吃过亏,有次新设备配置完中继没有保存,晚上设备升级重启,第二天全员电脑拿不到IP,直接成事故现场。保存配置这个动作,什么时候都不能省。
3.6 配置过程中的几个关键细节
接口同时启用DHCP中继和本地DHCP服务会冲突。如果核心设备上同时还运行了本地DHCP地址池,接口下必须明确选择中继模式或本地模式,不能两头都占,否则报文处理逻辑会混乱。
中继组建议统一编号。项目大了以后,中继组不好记,可以在名字上做文章,比如dhcp relay server-group 10 name OFFICE-DHCP(V7部分版本支持组名称),或者干脆在配置注释里写清楚。
另外,如果条件允许,尽量在测试VLAN先做一个试点。比如只给VLAN 10配中继,验证终端能正常拿到IP、能上网、能解析DNS以后,再批量配置VLAN 20和VLAN 30。这个习惯帮我避免过好几次批量配置错误。
4. 上线验证与抓包分析
配置完成后,不能直接拍胸脯说没问题,必须逐层验证。下面从终端侧、设备侧、报文层面三个角度来说。
4.1 终端侧验证
拿一台连接在VLAN 10下的电脑,打开命令行,释放并重新获取IP地址:
ipconfig /release ipconfig /renew然后查看结果:
ipconfig /all正常情况下,应该能看到IP地址为192.168.10.x网段,子网掩码255.255.255.0,默认网关192.168.10.1,DNS服务器地址也是DHCP服务器下发的。如果看到的IP还是169.254.x.x,说明中继根本没工作,直接跳到第五章排查。
有几类终端验证时要注意。比如有些手机连接WiFi后不会主动重新申请IP,这时候把WiFi断开重连即可。还有的摄像头需要在管理页面里手动点一下“重新获取IP”,否则会一直保留旧地址。
4.2 设备侧核对
在H3C设备上执行以下命令,确认中继配置生效:
display dhcp relay server-group all这个命令能看到所有中继组的编号、组内DHCP服务器地址,以及该组被哪些接口引用。如果接口引用的组不存在,这里会直接反映出来。
再执行:
display dhcp relay statistics这个命令能看到中继处理报文的统计计数,包括收到的请求报文数、转发出去的请求数、收到的响应报文数、丢弃报文数。如果请求数一直在增长但响应数为0,说明请求发出去了但服务器的响应没回来,问题大概率出在路由或防火墙上。
还可以检查接口状态:
display ip interface brief确保VLAN 10、20、30接口的物理状态和协议状态都是UP。接口down掉的话,下面的终端连网关都ping不通,中继自然无从谈起。
4.3 抓包看完整交互过程
如果终端拿不到IP,或者想确认中继转发细节,抓包是最好的手段。可以在终端侧用Wireshark抓包,也可以在中继设备的出接口上抓。
正常的中继交互是四步:Discover、Offer、Request、Ack。终端发出Discover广播,中继设备收到后把它改造成单播发往服务器,服务器回Offer,中继再通过广播转给客户端,同理处理Request和Ack。
抓包时要重点看两个点:
第一,Discover报文的源IP。正常情况下,中继转发出去的Discover源IP是网关接口的IP,比如192.168.10.1,而不是终端的IP。如果发现源IP还是终端IP,说明报文没有被中继处理,而是走了其他路径(比如服务器和终端在同一个二层)。
第二,giaddr字段。中继转发后的Discover里giaddr必须等于192.168.10.1。如果这个字段为空或错误,服务器拿到报文也不知道该从哪个地址池分配,要么不回应,要么分错网段。
4.4 顺带排查IP地址冲突的小技巧
终端通过DHCP拿到IP后,有时还会出现地址冲突的提示。这时候去DHCP服务器上看租约记录,确认该IP是不是被手工绑定过,同时在中继设备的VLAN接口下执行:
display arp看看IP对应的MAC地址有多个,如果同一个IP对应多个MAC,说明地址冲突了。这种问题多半是地址池规划时没有排除掉手工分配的静态地址,解决办法是回到服务器上调整排除项,或者把固定设备改成基于MAC地址的保留绑定。
另外,局域网里查某个IP是否被占用,最直接的方式还是在终端上ping该IP,然后执行arp -a查对应MAC。如果MAC不是目标设备的,那就说明有人占用了。这个方法虽然笨,但在没有IPAM系统的环境下一直很实用。
5. 常见问题与排查技巧实录
配置DHCP中继本身不难,难的是出了故障快速定位。以下是我在实际维护中遇到过的典型问题和排查思路,整理成速查表供参考。
| 现象 | 可能原因 | 排查方法 | 解决办法 |
|---|---|---|---|
| 终端拿不到IP,显示169.254.x.x | 接口未引用中继组 | display dhcp relay server-group all | 在接口下补配dhcp relay server-select |
| 终端拿不到IP,中继统计请求数增长但响应为0 | DHCP服务器路由不可达 | 在服务器上ping各网段网关 | 调整路由或放通中间设备策略 |
| 终端拿到错误网段IP | 服务器地址池与giaddr不匹配 | 抓包确认giaddr,检查服务器地址池定义 | 在服务器上创建正确的地址池并关联 |
| 终端拿到IP但无法上网 | 网关或DNS配置错误 | ipconfig /all查看下发的网关和DNS | 修改DHCP服务器的网关和DNS选项 |
| 终端周期性掉线,尤其摄像头打印机 | 中继未转发Inform报文 | 终端侧抓包,查看是否有Inform请求 | 接口下配置dhcp relay client-inform relay-to-server |
| 部分终端能拿到IP部分不能 | DHCP地址池地址耗尽 | 查看服务器租约和池利用率 | 扩大地址池或回收空闲租约 |
| 所有终端突然全部掉线 | 设备配置丢失或服务器故障 | 检查设备保存配置、服务器服务状态 | 恢复配置或重启DHCP服务 |
5.1 终端一直拿不到IP,第一步应该看什么
终端拿不到IP,优先看两个地方:中继组是否被接口引用,以及DHCP服务器和终端网段之间是否路由可达。我见过太多人一上来就抓包、debugging,绕了一大圈才发现是服务器上少了条回程路由。
路由这块要特别注意回程。中继设备能把Discover转发给服务器,服务器也要能路由到中继设备的接口地址,否则Offer报文发不回来。换句话说,DHCP服务器到各终端网段之间必须双向可达。现实中经常出现服务器能ping通网关,但网关到服务器不同段被封的情况,所以两边的联通性都要验证。
5.2 拿到错误网段IP,百分之八十是地址池选错
终端拿到了IP,但网段不对,比如VLAN 10的终端拿到了192.168.30.x的地址,原因几乎都出在DHCP服务器侧。服务器根据giaddr决定从哪个地址池分配,而giaddr是中继设备填的网关地址。如果服务器上没有配置192.168.10.0/24对应的地址池,它可能会从超级作用域或其他可用池里挑一个下发,终端自然就“串网段”了。
排查时抓包看giaddr,确认无误后去服务器上检查地址池。注意,H3C中继本身不会修改giaddr,所以这个问题基本可以排除设备侧原因。
5.3 终端能拿到IP但无法上网,怎么定位
能拿到IP只能说明DHCP流程走通了,上不了网还要查三层。先从终端ping网关,能通说明二层链路和网关接口正常;再ping远端服务器地址,能通则说明路由没事;最后检查DNS解析是否正常。
最容易忽略的是DHCP下发的DNS错误。有人把DHCP服务器上的DNS选项配成了内网DNS但忘了该DNS的解析策略,或者直接配了公网DNS但出口防火墙封了53端口,就会出现“能上QQ但网页打不开”的典型症状。所以验证阶段不要只看IP,ipconfig /all里的每个字段都要核对。
5.4 摄像头、打印机周期性掉线,十有八九是Inform没转发
这个坑前面提过,再展开说一下。IPC摄像头、网络打印机、部分WiFi AP在开机后除了Discover,还会定期发送DHCP Inform报文,目的是确认自己的IP租约仍然有效。如果中继不转发这类报文,服务器的租约表里该客户端的租约无法正常更新,等租约时间一到,服务器认为客户端已离线,可能回收地址。此时摄像机还在用旧IP通信,一旦地址被分配给其他终端,立刻冲突掉线。
配置了dhcp relay client-inform relay-to-server后,这类报文会被正常转发,整个链路就稳了。项目里遇到摄像头掉线问题,不用纠结摄像头厂商,先在中继设备接口下把这个命令补上,基本能解决一大半。
5.5 跨厂商设备对比:H3C、华为、思科的中继配置差异
如果你在网络环境里会接触到不同厂商的设备,这里做个快速对比:
| 厂商 | 开启全局DHCP服务 | 定义中继组 | 接口引用 |
|---|---|---|---|
| H3C V7 | dhcp enable | dhcp relay server-group 1 ip 10.10.0.10 | dhcp relay server-select 1 |
| H3C V5 | dhcp enable | dhcp relay server-group 1 ip 10.10.0.10 | dhcp select relay+dhcp relay server-select 1 |
| 华为 VRP V5 | dhcp enable | dhcp relay server-group 1 ip 10.10.0.10 | dhcp relay server-select 1 |
| 思科 IOS | service dhcp | ip dhcp relay address 10.10.0.10(旧版) /ip helper-address 10.10.0.10 | 接口下直接配ip helper-address |
可以看到,思科与华系思路差异较大,思科使用ip helper-address,一个命令就完成中继指向,不需要显式定义组。而华系的“组”概念,本质上是为了实现一个接口引用多个DHCP服务器时复用配置,以及按组统一管理后端服务器列表。理解这一点,跨厂商操作时就不会被命令差异搞糊涂。
6. 个人经验:几个让中继配置更稳的小习惯
折腾了这么多年DHCP中继,我总结出几个实际运维中非常实用的习惯。
第一,配置完成不是终点,验证配置保存才是。新设备上线,我会先display current-configuration | include dhcp扫一遍关键配置,确认无误后立刻save,然后让设备重启一次验证配置完全生效。虽然多花几分钟,但能防止“配置没保存、重启即事故”的悲剧。
第二,中继组和地址池的命名要可读。设备上处理一个中继组,如果只是个数字编号,时间久了根本记不清这个组是给哪栋楼用的。H3C V7支持在部分视图下配置组名,如果版本不支持,就在配置注释里写清楚,或者用描述语句标记。服务器侧同理,地址池名称最好带上业务含义,比如Pool-Building1-Floor1,而不是Pool1、Pool2。
第三,上线前先在测试VLAN跑一轮。我在正式项目里,一定先在一个不影响业务的VLAN上把中继配置做完,然后用两台终端分别验证PC和打印机/摄像头场景。确认没问题了,再批量往其余接口上配置。这办法虽然多花点时间,但能避免一次配错全部接口,把所有终端都搞下线。
第四,变更前记得备份配置。display current-configuration输出的内容导出保存,或者直接用backup startup-configuration到FTP服务器。中继配置改起来说简单也简单,说复杂也复杂,尤其涉及接口引用组的调整时,一旦改错,影响面是整片终端的。备份配置就是给你留一条退路。
最后再提一个小技巧:如果想验证中继到底有没有在转发,可以临时在设备上打开DHCP中继的调试开关,但调试输出非常占用CPU,生产环境慎用。一般用display dhcp relay statistics看计数增长就够了。流量高峰时段尽量别开debug,真有需要也建议在业务低峰期快速打开、快速关闭,避免影响核心设备转发性能。
DHCP中继是个基础得不能再基础的功能,但基础功能往往最能拉开运维水平差距。把原理吃透,把配置细节做好,再把常见问题背熟,遇到跨网段IP分配的需求就永远不会慌。这套配置方法在H3C的S7006X、MSR系列等设备上都验证过,普通的三层交换机和路由器完全可以照抄,最多根据版本微调命令。