Adventures in blocking a DHCP server with IPFW..
I have a simple local area network where my router is also the DHCP server. It's IP address is 192.168.2.1.
For testing purposes I've been playing with a second DHCP server on the same network running inside VirtualBox - that machine is set to 192.168.2.99
However my DHCP server would never assign an IP address to my test instance - the router would always be the one assigning it - my guess is because it's responding much faster than the VirtualBox.
I tried blocking this with IPFW by blocking all UDP rules.. this is the ruleset I set:
#!/bin/csh
ipfw -f flush
cat /dev/null > /var/log/security
ipfw add 100 deny log udp from any to any
ipfw add 101 deny log tcp from any to any
Of course the above will block everything (both TCP and UDP) and also log everything in /var/log/security. Surprise surprise..... On one window I run
tail -f /var/log/security
On the other one I tried to get a new IP:
service netif restart; dhclient em0
This is what I got in the logs....
Mar 20 18:25:19 freebsd10 kernel: ipfw: 100 Deny UDP 192.168.2.100:68 192.168.2.99:67 out via em0
Mar 20 18:25:28 freebsd10 kernel: ipfw: 100 Deny UDP 192.168.2.1:67 255.255.255.255:68 in via em0
Mar 20 18:25:28 freebsd10 kernel: ipfw: 100 Deny UDP 192.168.2.99:67 192.168.2.100:68 in via em0
So the packets are clearly caught by IPFW ... why am I still getting an IP address? It looks like the ISC DHCP server does not use UDP - it uses "Internet Socket of protocol Raw instead of TCP or UDP" -- Sources here and here. Instead you can edit the /etc/dhclient.conf and add lines like these:
interface "em0"
{
reject 192.168.2.1;
}
Try getting a new IP again: [quote]service netif restart; dhclient em0[/quote] Output: (trimmed)
DHCPREQUEST on em0 to 255.255.255.255 port 67
DHCPNACK from 192.168.2.1 rejected.
DHCPACK from 192.168.2.99
bound to 192.168.2.100 -- renewal in 300 seconds.
Nice. If you need to load your ruleset automatically you can do it by having the following lines in /etc/rc.conf:
firewall_enable="YES"
firewall_logging="YES"
firewall_script="/root/ipfw.sh"