1. 初识DHCP
1.1 DHCP的作用
在网络通信中,每一个设备需要与另外一方通信的前提是,它得有个IP地址,无论这个设备是PC、服务器还是路由器、交换机、防火墙。
正常来讲,我们可以给这些设备每个都手动配置一个IP地址,也就是我们所说的静态IP,所有的这些设备都支持静态IP。但需要一个一个得给这么多设备配置IP,那岂不是很麻烦,而且还容易出错。
这时候就该谈到我们的DHCP了,它是一个实时动态给设备分配IP地址的协议。需要获取IP的设备,叫DHCP客户端,比如Window、Linux等等。提供IP的设备我们称之为DHCP服务器,比如Window Server、Linux等等。
1.2 DHCP的发展
其实最早提供IP地址的协议是叫bootp,在v2.x.x的wireshark中,抓包过滤DHCP的包还是以bootp为关键字。后来由于bootp的一些问题,才重新设计了DHCP协议,而这主要是针对IPv4的,所有称之为DHCPv4协议。随着IPv4往IPv6发展,我们的DHCP协议,也有个新版本,即DHCPv6协议。
本文先讲DHCPv4协议,DHCPv6另一篇文档再讲。
1.3 DHCPv4与OSI模型
DHCPv4协议在OSI模型中属于应用层协议,底层是传输层UDP。 它占用了UDP的两个知名端口,客户端使用68/udp,服务器使用67/udp,这一点与其他应用层协议不一样。如下图,以DHCPv4 Discover报文为例。
1.4 DHCPv4的报文头部结构
从上图可知,DHCPv4的报文头部结构比较复杂,可以分成两个部分去理解。第一部分时固定头部,第二部分是option,这部分也是DHCPv4的精华部分。
具体每个字段的意思可以从图中看出,这里不过多解释,后面用到再说。
2. 正常情况下的DHCPv4报文交互
如下图所示,我在DHCPv4服务器上配置的租期为120s,然后接入一台新的客户端到该服务器所在的网络(VLAN),抓包得到以下数据。
2.1 客户端初次获取IP地址的报文交换--DORA
从NO.1--NO.4号报文可知,客户端要拿到服务器给的IP地址,需要经历DHCP的四个报文交互,Discover、Offer、Request、ACK。
(1)Client --> Server:Discover报文
A、客户端由于没有IP地址,故用0.0.0.0来代替;源端口采用固定的68,而不是临时端口。原因为何?留个悬念。
B、由于不知道该VLAN的DHCP服务器地址,故用255.255.255.255(广播地址)代替;目的端口为67。
C、Discover报文里面,包含了客户端的MAC地址、主机名等信息,当然一般有参数请求列表信息。
(2)Server --> Client:Offer报文
A、服务器都会有自己的静态IP地址,比如本例中的100.101.0.254,当这不一定是服务器的IP,也有可能是中继的IP。
B、该报文的目的地址也是255.255.255.255,因为此时客户端没有IP(还在本报文内部,没给到客户端),只能广播。
C、Offer报文内部,包含了服务器给客户端分配的IP地址以及子网掩码,或者还请其他信息。
(3)Client --> Server:Request报文
A、客户端源地址仍然为0.0.0.0,为何不用服务器通过Offer报文提供的地址?
因为可能在发送Offer与Request报文间隙时,服务器可能把IP给了其他IP。
B、Request报文存在的意义是,客户端告诉同一VLAN内其他客户端和服务器,自己将使用指定的服务器提供的指定IP,
其他客户端不能使用,其他服务器也不能再分配该IP给其他人。因此不难理解该报文的目的IP是广播地址。
(4)Server --> Client:ACK报文
A、Offer报文存在的意义类似于Request报文,服务器告诉同一VLAN内其他客户端和服务器,自己将IP分配给该客户端。
2.2 客户端拿到的IP后,需要做地址重复检查--DAD
当客户端通过Offer报文拿到服务器给的IP后,客户端需要考虑该IP是否被其他设备使用呢?虽然服务器在提供Offer时自己检测过,但可能在发送Offer瞬间之后,有设备配置了静态IP,刚好与这Offer提供的IP相同。
因此从客户端的角度考虑,在使用该IP前,需要做地址重复检测,而这个功能是通过 gratutios ARP来是实现的。如上图中NO.5号报文。
服务器给客户端提供的IP为100.101.0.229,客户端把该地址放入ARP报文的Sender IP Address和Target MAC Address,然后广播出去,收到该广播的设备,会检查自己的IP地址是否是100.101.0.229,如果是则回复此ARP,否则不响应。
如果客户端收到有设备回复的响应时,可以判断该地址已经被人使用。如果在指定时间内没有设备回复,就可以判断没有人使用该地址。
2.2 客户端定时向服务器续约--ReqAck
服务器向客户端提供的IP地址,一般不是永久的,这样也好理解,如果给客户端分配永久的IP,当该客户端离开此VLAN,不再接入时,岂不是浪费了此IP。所有服务器给客户端的IP一般是带了期限的,也就是DHCP租期。
当租期快到了时,客户端需要向服务器续约,通过Request/ACK报文来完成,如上图中的NO.6--11号报文。由于服务器端配置的租期为120s,当时间到了60s(NO.6号报文时间)、120s(NO.9号报文时间),客户端再发送Request报文,服务器回复ACK报文。
可以发现此时的Request/ACK报文的目的地址不是广播地址了,而是接收者的单播地址。另外由于客户端经过前面的DORA,已经拿到服务器分配的地址,续约的时候,Request报文源地址直接使用即可。
3. 特殊情况下的DHCPv4报文交互
3.1 客户端释放申请的IP
当客户端不想再使用该IP时,客户端就会通过DHCP Release报文告诉服务器,回收此IP。一般出现在客户端获取IP方式从动态切换到静态、恢复出厂设置时。
3.2 客户端检测到地址冲突
前面我们提到,当客户端拿到服务器分配的地址后,在使用之前是需要做地址重复检测的。如果检测到地址重复呢,客户端会主动向服务器发起Decline报文,如下图所示。
=============DHCPv4 Decline 占位===================
3.3 服务器拒绝客户端请求
通常情况下,客户端来的请求,服务器都会响应,要么给Offer,要么给ACK,但有些情况服务器会回复NACK。这些情况有:地址分配完毕,没有可用的地址;。。。。
=============DHCPv4 NACK 占位===================
4 客户端和服务器不在一个VLAN怎么办?
上文中,我们说的情况都是DHCP客户端和服务器都在一个网络(VLAN)内部,但实际情况中,这很难满足,基本上客户端和服务器都处在不同的VLAN。
由于DHCPv4采用了广播地址,而广播被局限在一个VLAN内部。为了解决这个问题,DHCP引进了中继这个角色。
原来客户端与服务器的报文交互,全部替换成客户端和中继的交互。中继只是负责DHCP报文的转发,当客户端请求时,中继把报文转给真正的服务器,服务器响应的报文也是先给到中继,中继再转发给客户端。客户端与中继直接还是该广播就广播、单播就单播,而中继与服务器中继一定是单播。一般中继都是由一个VLAN的网关来担任。
由于引入了中继,因此整个DHCP环境有所变化。DHCP客户端和服务器,无需任何改变。主要是DHCP中继,对于中继需要满足以下三个要求。
(1)需要配置一个静态地址,用于做DHCP响应报文的源地址;
(2)需要指定服务器的地址,用于转发请求到服务器;
(3)需要有到服务器的路由,中继的地址和服务器地址处于不同的网段(VLAN)。