一、DHCP 简介

DHCP是一种对基于TCP/IP协议主机的网络参数进行动态配置和集中管理的协议,可以为网络主机分配IP地址和其它网络参数,如网关地址、DNS服务器地址等。DHCP采用C/S模型,通过DHCP Client和DHCP Server之间交互DHCP消息来实现。DHCP消息封装在UDP报文中,DHCP Server使用端口67来接收DHCP消息,DHCP Client使用端口68来接收DHCP消息。

二、DHCP基本原理

1、发现阶段
DHCP Client以广播方式发送DHCP Discover报文来发现DHCP Server。

2、提供阶段
DHCP Server响应DHCP Discover消息,从DHCP地址池中选择一个合适的IP地址,通过DHCP Offer消息以单播方式发送到DHCP Client

3、请求阶段
DHCP Client接收到DHCP Offer消息后,广播发送DHCP Request消息请求DHCP Offer消息中提供的IP地址。

4、确认阶段
DHCP Server收到DHCP Client发送的DHCP Request报文后,回应DHCP ACK消息分配IP地址给DHCP Client使用。

三、DHCP租约

DHCP Server给DHCP Client分配IP地址时,约定IP地址使用的租约。当租约到期后,DHCP Client不能继续使用IP地址。
1、当在租约期到达50%时,DHCP Client向DHCP Server发送DHCP Request消息,请求更新IP地址租期,如果收到DHCP ACK报文,则更新租期成功;如果收到DHCP NAK报文,则重新发送DHCP Discover报文请求新的IP地址
2、当租期在87.5%时还没收到DHCP ACK消息,则广播发送DHCP Request消息,如果收到DHCP ACK报文,则更新租期成功;如果收到DHCP NAK报文,则重新发送DHCP Discover报文请求新的IP地址
3、如果租期时间到时都没有收到服务器的回应,客户端停止使用此IP地址,重新发送DHCP Discover报文请求新的IP地址。

四、DHCP Relay

当网络规模较大时,DHCP Client和DHCP Server不在一个二层广播域时,而DHCP 消息不能穿越广播域,可以部署DHCP Relay来实现跨越广播域。DHCP Relay与DHCP Client位于同一二层广播域,以广播方式交互DHCP消息;DHCP Relay与DHCP Server可以是在二层广播域也可以不在二层广播域,以单播方式交互DHCP消息。

五、DHCP ***

DHCP***行为分为DHCP饿死***、仿冒DHCP Server***、DHCP中间人***
1、DHCP饿死***
***者持续大量地向DHCP Server请求IP地址,直到耗尽DHCP Server地址池中的IP地址,导致DHCP Server不能对正常用户提供IP地址分配功能

2、仿冒DHCP Server***
***者仿冒DHCP Server,向客户端分配错误的IP地址及提供错误的网关地址等参数,导致客户端无法正常访问网络

3、DHCP中间人***
***者利用ARP机制,使得DHCP Client与DHCP Server之间的IP报文经过***者中转。

六、DHCP Snooping

DHCP Snooping可以用于防止DHCP饿死***、仿冒DHCP Server***和DHCP中间人***
1、防止DHCP饿死***
对DHCP Request报文的源MAC地址与CHADDR进行一致性检查,如果二者相同转发报文,反之丢弃
dhcp snooping check dhcp-chaddr enable

2、防止仿冒DHCP Server***
DHCP Snooping将交换机上的端口分为两种类型:信任端口和非信任端口。与合法的DHCP Server相连的端口配置为信任端口,其它端口配置为非信任端口。
dhcp snooping trusted

3、防止DHCP中间人***
DHCP Snooping根据DHCP消息,收集用户的MAC地址、用户IP地址等消息,将这些消息放在DHCP Snooping绑定表中,交换机收到ARP请求报文,检查ARP请求报文的源IP地址和源MAC地址,匹配DHCP Snooping绑定表,如果不能匹配,丢弃ARP请求报文
arp dhcp-snooping-detect enable

4、DHCP Snooping 结合IPSG
IPSG:IP Source Guard,应对IP原地址欺骗***行为
对进入交换机端口的报文进行DHCP Snooping绑定表匹配检查,如果报文信息和绑定表一致,则允许通过反之丢弃报文
ip source check user-bind enable