DHCP协议及报文
动态主机配置协议(DHCP)是一种基于UDP协议且仅限于在局域网内部使用的网络协议,目的就是为了减轻TCP/IP网络的规划、管理和维护的负担,为局域网内部的设备分配IP地址、子网掩码、网关、DNS地址等网络信息。 DHCP功能分为两个部份:一个是服务器端,端口号67 ,而另一个是客户端,端口号68
DHCP的8种报文:
①:DHCP DISCOVER:这是 DHCP 客户端首次登录网络时进行 DHCP 过程的第一个报文,用来寻找 DHCP 服务器。 ②:DHCP OFFER:DHCP服务器用来响应DHCP,DISCOVER报文,此报文携带了各种配置信息。 ③:DHCP REQUEST:客户端初始化后,发送广播的 DHCP REQUEST 报文来回应服务器的 DHCP OFFER 报文。客户端重启初始化后,发送广播的 DHCP REQUEST 报文来确认先前被分配的 IP 地址等配置信息。当客户端已经和某个 IP 地址绑定后,发送 DHCP REQUEST 报文来延长 IP 地址的租期。 ④:DHCP ACK:服务器对客户端的 DHCP REQUEST 报文的确认响应报文,客户端收到此报文后,才真正获得了 IP 地址和相关的配置信息。 ⑤:DHCP NAK:服务器对客户端的 DHCP REQUEST 报文的拒绝响应报文,比如服务器对客户端分配的 IP 地址已超过使用租借期限或者由于某些原因无法正常分配 IP 地址,则发送 DHCP NAK 报文作为应答。 ⑥:DHCP DECLINE:当客户端发现服务器分配给它的 IP 地址发生冲突时会通过发送此报文来通知服务器,并且会重新向服务器申请地址。 ⑦:DHCP RELEASE:客户端可通过发送此报文主动释放服务器分配给它的 IP 地址,当服务器收到此报文后,可将这个 IP 地址分配给其它的客户端。 ⑧:DHCP INFORM:客户端已经获得了 IP 地址,发送此报文的目的是为了从服务器获得其他的一些网络配置信息,比如网关地址、DNS 服务器地址等。
DHCP分配过程
1、DHCP客户端通过广播方式发送DHCP DISCOVER请求报文来寻找网络中的DHCP服务器,源端口68,目的端口67。 2、DHCP服务端会Ping即将分配的ip地址 3、DHCP服务器收到DHCP DISCOVER请求报文后,会从自己的地址池中选择一个合适的IP地址,把IP地址,子网掩码,网关,DNS,租约相关的内容还有客户端的MAC地址封装在DHCP OFFER报文中,通过广播方式发送给客户端,网络内的所有客户端根据封装在DHCP OFFER报文中的MAC地址来决定是否接收此报文。源端口67,目的端口68 4、DHCP客户端收到DHCP OFFER报文后,会再通过广播方式发送一个DHCP REQUEST报文,但是在requested address字段包含了OFFER应答报文中分配的IP地址,DHCP服务器地址和DHCP服务器名。源端口68,目的端口67。 5、DHCP服务器在收到客户端的REQUEST报文后,确认将此IP地址分配给客户端,会以广播方式返回一个DHCP ACK确认报文,确认不能把此IP地址分配给客户端则返回一个DHCP NAK确认报文。源端口67,目的端口68 6、DHCP客户端在收到服务器的ACK确认报文后,会以广播方式发送免费的ARP报文,该报文中源IP和目的IP都是本机的IP地址,源MAC是本机的MAC,目的MAC是广播MAC,探测网络内是否有主机使用服务器分给自己的IP地址,如果在规定时间内没有收到回应,则正是使用该地址,否则,客户端会继续发送DHCP DECLINE报文给DHCP服务器,重新申请IP地址
DHCP是单播还是组播
从DHCP Server回复的报文是单播还是广播由DHCP Client决定,有些IP协议栈在完成IP地址的配置前,是不会接收任何单播IP报文的,只会接收广播IP报文,即Dst IP = 255.255.255.255,会在DHCP Discovery / Request报文的Flags里明确告知服务器,通过设置“BROADCAST flag = 1” 如果协议栈在初始化时,可以接收单播IP报文,请在DHCP Discovery / Request报文的Flags里明确告知服务器,通过设置“BROADCAST flag = 0”,那么服务器就使用单播来和客户端通信。
搭建环境验证DHCP获取IP和释放IP
ip netns add ns100
ip l a veth0 type veth peer name ovs-veth0
ip l s veth0 netns ns100
ovs-vsctl add-br br-int
ovs-vsctl add-port br-int ovs-veth0
ip l s ovs-veth0 up
ovs-vsctl add-port br-int dhcp1 -- set interface dhcp1 type=internal
ifconfig dhcp1 192.168.1.1
dnsmasq --bind-interfaces --except-interface=lo --interface dhcp1 --dhcp-range 192.168.1.2,192.168.1.10
ovs-ofctl add-flow br-int "table=0,priority=100,udp,nw_dst=255.255.255.255,tp_src=68,tp_dst=67,actions=output:dhcp1"
ovs-ofctl add-flow br-int "table=0,priority=100,udp,nw_dst=192.168.1.1,tp_src=68,tp_dst=67,actions=output:dhcp1"
ovs-ofctl add-flow br-int "table=0,priority=100,udp,nw_src=192.168.1.1,tp_src=67,tp_dst=68,actions=output:ovs-veth0"
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
11: veth0@if10: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
link/ether 6e:e8:3d:79:44:4b brd ff:ff:ff:ff:ff:ff link-netnsid 0
$ ip netns exec ns100 dhclient veth0
10:05:40.525512 6e:e8:3d:79:44:4b > ff:ff:ff:ff:ff:ff, ethertype IPv4 (0x0800), length 342: (tos 0x10, ttl 128, id 0, offset 0, flags [none], proto UDP (17), length 328)
0.0.0.0.68 > 255.255.255.255.67: [udp sum ok] BOOTP/DHCP, Request from 6e:e8:3d:79:44:4b, length 300, xid 0x4ed34737, Flags [none] (0x0000)
Client-Ethernet-Address 6e:e8:3d:79:44:4b
Vendor-rfc1048 Extensions
Magic Cookie 0x63825363
DHCP-Message Option 53, length 1: Discover
Requested-IP Option 50, length 4: 192.168.1.8
Hostname Option 12, length 6: "ubuntu"
Parameter-Request Option 55, length 13:
Subnet-Mask, BR, Time-Zone, Default-Gateway
Domain-Name, Domain-Name-Server, Option 119, Hostname
Netbios-Name-Server, Netbios-Scope, MTU, Classless-Static-Route
NTP
10:05:40.525669 d6:bd:3e:83:49:f9 > 6e:e8:3d:79:44:4b, ethertype IPv4 (0x0800), length 62: (tos 0x0, ttl 64, id 25589, offset 0, flags [DF], proto ICMP (1), length 48)
192.168.1.1 > 192.168.1.8: ICMP echo request, id 56407, seq 0, length 28
10:05:43.529494 d6:bd:3e:83:49:f9 > 6e:e8:3d:79:44:4b, ethertype IPv4 (0x0800), length 342: (tos 0xc0, ttl 64, id 43770, offset 0, flags [none], proto UDP (17), length 328)
192.168.1.1.67 > 192.168.1.8.68: [bad udp cksum 0x849f -> 0x4b80!] BOOTP/DHCP, Reply, length 300, xid 0x4ed34737, Flags [none] (0x0000)
Your-IP 192.168.1.8
Server-IP 192.168.1.1
Client-Ethernet-Address 6e:e8:3d:79:44:4b
Vendor-rfc1048 Extensions
Magic Cookie 0x63825363
DHCP-Message Option 53, length 1: Offer
Server-ID Option 54, length 4: 192.168.1.1
Lease-Time Option 51, length 4: 3600
RN Option 58, length 4: 1800
RB Option 59, length 4: 3150
Subnet-Mask Option 1, length 4: 255.255.255.0
BR Option 28, length 4: 192.168.1.255
Default-Gateway Option 3, length 4: 192.168.1.1
Domain-Name-Server Option 6, length 4: 192.168.1.1
10:05:43.529846 6e:e8:3d:79:44:4b > ff:ff:ff:ff:ff:ff, ethertype IPv4 (0x0800), length 342: (tos 0x10, ttl 128, id 0, offset 0, flags [none], proto UDP (17), length 328)
0.0.0.0.68 > 255.255.255.255.67: [udp sum ok] BOOTP/DHCP, Request from 6e:e8:3d:79:44:4b, length 300, xid 0x4ed34737, secs 3, Flags [none] (0x0000)
Client-Ethernet-Address 6e:e8:3d:79:44:4b
Vendor-rfc1048 Extensions
Magic Cookie 0x63825363
DHCP-Message Option 53, length 1: Request
Server-ID Option 54, length 4: 192.168.1.1
Requested-IP Option 50, length 4: 192.168.1.8
Hostname Option 12, length 6: "ubuntu"
Parameter-Request Option 55, length 13:
Subnet-Mask, BR, Time-Zone, Default-Gateway
Domain-Name, Domain-Name-Server, Option 119, Hostname
Netbios-Name-Server, Netbios-Scope, MTU, Classless-Static-Route
NTP
10:05:43.532087 d6:bd:3e:83:49:f9 > 6e:e8:3d:79:44:4b, ethertype IPv4 (0x0800), length 342: (tos 0xc0, ttl 64, id 43772, offset 0, flags [none], proto UDP (17), length 328)
192.168.1.1.67 > 192.168.1.8.68: [bad udp cksum 0x849f -> 0xfc11!] BOOTP/DHCP, Reply, length 300, xid 0x4ed34737, secs 3, Flags [none] (0x0000)
Your-IP 192.168.1.8
Server-IP 192.168.1.1
Client-Ethernet-Address 6e:e8:3d:79:44:4b
Vendor-rfc1048 Extensions
Magic Cookie 0x63825363
DHCP-Message Option 53, length 1: ACK
Server-ID Option 54, length 4: 192.168.1.1
Lease-Time Option 51, length 4: 3600
RN Option 58, length 4: 1800
RB Option 59, length 4: 3150
Subnet-Mask Option 1, length 4: 255.255.255.0
BR Option 28, length 4: 192.168.1.255
Default-Gateway Option 3, length 4: 192.168.1.1
Domain-Name-Server Option 6, length 4: 192.168.1.1
Hostname Option 12, length 6: "ubuntu"
10:05:48.669095 d6:bd:3e:83:49:f9 > 6e:e8:3d:79:44:4b, ethertype ARP (0x0806), length 42: Ethernet (len 6), IPv4 (len 4), Request who-has 192.168.1.8 tell 192.168.1.1, length 28
10:05:48.669388 6e:e8:3d:79:44:4b > d6:bd:3e:83:49:f9, ethertype ARP (0x0806), length 42: Ethernet (len 6), IPv4 (len 4), Reply 192.168.1.8 is-at 6e:e8:3d:79:44:4b, length 28
$ ip netns exec ns100 ip a
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
11: veth0@if10: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether 6e:e8:3d:79:44:4b brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 192.168.1.8/24 brd 192.168.1.255 scope global dynamic veth0
valid_lft 3594sec preferred_lft 3594sec
inet6 fe80::6ce8:3dff:fe79:444b/64 scope link
valid_lft forever preferred_lft forever
ip netns exec ns100 dhclient -r
Killed old client process
tcpdump -i dhcp1 -nn -vv -e
tcpdump: listening on dhcp1, link-type EN10MB (Ethernet), capture size 262144 bytes
10:04:05.215678 6e:e8:3d:79:44:4b > d6:bd:3e:83:49:f9, ethertype IPv4 (0x0800), length 342: (tos 0x0, ttl 64, id 57498, offset 0, flags [DF], proto UDP (17), length 328)
192.168.1.8.68 > 192.168.1.1.67: [udp sum ok] BOOTP/DHCP, Request from 6e:e8:3d:79:44:4b, length 300, xid 0x78cfc423, Flags [none] (0x0000)
Client-IP 192.168.1.8
Client-Ethernet-Address 6e:e8:3d:79:44:4b
Vendor-rfc1048 Extensions
Magic Cookie 0x63825363
DHCP-Message Option 53, length 1: Release
Server-ID Option 54, length 4: 192.168.1.1
Hostname Option 12, length 6: "ubuntu"
DHCP Client请求IP
通过抓包可以发现,DHCP Server在收到discovery报文后会发送免费arp进行冲突检测,检测要分配的ip是否被其他主机占用,之后会发送icmp包检测DHCP Client是否占用,之后单播回复,因为client在discovery报文里已设置支持单播,而client发送request报文是当网络中有多个DHCP Server时,会同时给client发送IP,而client选择其中一个后会发reuest通知所有DHCP Server自己使用某个DHCP Server,只有被选择的DHCP Server会回复client
DHCP Client释放IP
当dhcp租约到期时client主动单播发送release报文给server
|