場景:linux
內網環境須要開啓多個DHCP服務器,分別給不一樣的設備進行PXE安裝。服務器
存在的問題:網絡
多個DHCP的狀況下,設備在啓動時隨機從一個DHCP服務器獲取IP(哪一個DHCP服務器先響應就從哪一個獲取)並從那個服務器讀取配置進行引導安裝。tcp
若是提供IP的DHCP服務器不是指望的那個,就沒法獲得正確的配置文件,也就沒法進行正常引導安裝。spa
初步解決方法:code
DHCP服務提供配置能夠對響應進行限制,僅給某些設備(設備的MAC)分配IP,對其它設備的請求則不予響應。cli
/etc/dhcpd.conf配置大體以下:sed
subnet 128.128.0.0 netmask 255.255.0.0 {配置
......file
filename "pxelinux.0";
}
deny unknown-clients;
host <hostname1> { hardware ethernet <XX:XX:XX:XX:XX:XX>;}
host <hostname2> { hardware ethernet <XX:XX:XX:XX:XX:YY>;}
這樣配置之後,DHCP服務器僅會對<XX:XX:XX:XX:XX:XX> <XX:XX:XX:XX:XX:YY>這些MAC進行響應。
依然存在的問題:
若是每一個DHCP服務器都作了限制,僅給指定MAC分配IP,而且沒有兩個DHCP服務器同時配置了同一MAC,那麼每一個MAC可以獲得響應的DHCP服務器就是惟一肯定的。
但不可避免,有些DHCP服務器並無或者忘記設置,依然致使DHCP響應氾濫,設備仍是可能從不指望的DHCP服務器獲取響應。
進一步的解決方法:
要求每一個使用的DHCP服務器在/etc/dhcpd.conf指定具體的MAC。對於那些氾濫響應的DHCP服務器,使用Dhcpstarv將其提供的IP(DHCP 響應)消耗掉。Dhcpstarv的執行方式就是不斷僞造一些MAC地址進行DHCP請求,把DHCP服務器可以響應的IP地址都消耗掉。
具體操做:
當你想啓動DHCP服務,給某臺設備進行PXE安裝,可是發現同一網絡中還存在另外一個DHCP服務器也在提供DHCP服務,那麼就可使用Dhcpstarv了。
命令使用(ethX就是鏈接到要消耗的網絡的網卡,不要指定錯了):
# ./dhcpstarv -v -i ethX
相似下面的輸出就說明dhcpstarv正在消耗DHCP響應
14:54:20 01/10/14: got address 128.128.18.199 for 00:16:36:4c:d7:48 from 128.128.18.5
14:54:20 01/10/14: got address 128.128.18.200 for 00:16:36:06:98:de from 128.128.18.5
等再也不有相似的輸出結果,說明DHCP的響應被消耗差很少了。讓dhcpstarv程序繼續運行,啓動你本身的DHCP服務器。
恢復方法:
若是DHCP服務器未進行限制MAC配置,不幸被Dhcpstarv消耗完,能夠經過如下方法恢復「被攻擊」DHCP服務器:
1. 修改配置文件/etc/dhcpd.conf,增長限制MAC的配置:
deny unknown-clients;
host <hostname1> { hardware ethernet <XX:XX:XX:XX:XX:XX>;}
host <hostname2> { hardware ethernet <XX:XX:XX:XX:XX:YY>;}
2. 刪除文件 /var/lib/dhcp/db/dhcpd.leases
3. 重啓DHCP服務
如何定位攻擊來源:
Dhcpstarv在發送的DHCP請求包中僞造隨機的源MAC,其僞造方式是:固定前3個字節硬件設備「製造商」爲「001636」,後3個字節隨機生成。源代碼位置:
dhcpstarv-0.2.1/src/main.c:130行
unsigned char vendor_mac_prefix[] = { 0x00, 0x16, 0x36 };
可是,以太網幀的源MAC仍是發送數據幀的網卡的真實MAC,所以爲了定位Dhcpstarv僞造的DHCP請求包的來源,能夠經過抓包,根據以太網幀中的源MAC肯定Dhcpstarv的位置。
DHCP請求包是封裝在UDP數據報,UDP數據報偏移36字節的位置便是DHCP請求包的源MAC,過濾UDP數據報的前3個字節爲「001636」,就能夠獲得Dhcpstarv僞造的DHCP請求包。命令以下:
# tcpdump -i bond0 -ne src port 68 and udp[36:2]=0x0016 and udp[38]=0x36
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on bond0, link-type EN10MB (Ethernet), capture size 96 bytes
13:51:31.254469 00:18:82:b0:7e:22 > ff:ff:ff:ff:ff:ff, ethertype IPv4 (0x0800), length 286: 0.0.0.0.68 > 255.255.255.255.67: BOOTP/DHCP, Request from 00:16:36:81:30:15, length 244
13:51:32.000714 00:18:82:b0:7e:22 > ff:ff:ff:ff:ff:ff, ethertype IPv4 (0x0800), length 304: 0.0.0.0.68 > 255.255.255.255.67: BOOTP/DHCP, Request from 00:16:36:81:30:15, length 262