I am trying to create a firewall rule on an Ubuntu 10.04 server running isc-dhcpd. I only want dhcp to be accessible by a single relay host (172.1.1.1). I have iptables set up like so:

# iptables -vnL
Chain INPUT (policy ACCEPT 5325 packets, 523K bytes)
pkts bytes target     prot opt in     out     source               destination         
0     0 ACCEPT     udp  --  *      *       172.1.1.1            0.0.0.0/0           udp dpt:67 
1497  533K DROP    udp  --  *      *       0.0.0.0/0            0.0.0.0/0           udp dpt:67 

This is my attempt to drop all UDP traffic destined to port 67 unless it's coming from 172.1.1.1.

However, with this rule in place, when I start the dhcpd I immediately see DHCP requests start to come in via broadcast (the log says via eth0).

Do I need another firewall rule to catch the broadcast traffic? I've tried adding a rule like

iptables -A INPUT -p udp -d 255.255.255.255 -j DROP

which should drop all UDP broadcast traffic. But again when I start dhcpd I see tons of requests via broadcast.

EDIT: According to this page:

For most operations, DHCP software interfaces to the Linux IP stack at a level below Netfilter. Hence, Netfilter (and therefore Shorewall) cannot be used effectively to police DHCP.

So is there any way to accomplish what I want here?

link|improve this question

75% accept rate
Are you certain the server has accepted any DHCP packets? Your DROP rule seems to have matched a good number of packets (1497), while your ACCEPT rule has zero. – Steven Monday Oct 27 '10 at 1:11
Yes. I see the unwanted dhcp traffic in the dhcpd logs the instant I start the daemon. I wouldn't expect to see bytes from 172.1.1.1 yet, it is only relaying for a single test client at the moment. – Cory J Oct 27 '10 at 1:36
feedback

1 Answer

Since it appears that netfilter (iptables) is not effective for filtering DHCP broadcasts, try using ebtables, the Linux tool for filtering at a lower level, of ethernet frames. I don't have direct, real world experience with ebtables, but a brief perusal of the man page suggests that something like the following may be effective in your case:

ebtables -A INPUT --protocol ipv4 --ip-proto udp --ip-src \! 172.1.1.1 --ip-dport 67 -j DROP

This should cause the Linux kernel to drop all ethernet frames that contain IPv4 UDP packets that are not from 172.1.1.1 and are destined for port 67.

link|improve this answer
Thanks, this looks quite promising! I will give this a try in the next couple of days. – Cory J Oct 27 '10 at 20:17
feedback

Your Answer

 
or
required, but never shown

Not the answer you're looking for? Browse other questions tagged or ask your own question.