3

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?

3
  • 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. Oct 27, 2010 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, 2010 at 1:36
  • read this unix.stackexchange.com/a/659709/266428
    – acgbox
    Jul 24, 2021 at 14:26

2 Answers 2

2

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.

1
  • Thanks, this looks quite promising! I will give this a try in the next couple of days.
    – Cory J
    Oct 27, 2010 at 20:17
2

It doesn't work on pure IP-level, one needs to know how DHCP does work:

  • At first, the DHCP client does send a packet (DHCPDISCOVER) from 0.0.0.0 to 255.255.255.255 (the local broadcast address).

  • The DHCP server will offer an IP address (DHCPOFFER); in terms of iptables, this will be a packet from the DHCP server's address and also targeted at the local broadcast address 255.255.255.255. The ethernet frame is addressed at the MAC address of the DHCP client.

  • The DHCP client chooses from any offers sent at their ethernet MAC address and sends a DHCPREQUEST to the DHCP server; for iptables, this is yet another packet from 0.0.0.0 and still targeted at local broadcast address 255.255.255.255.

  • The DHCP server acknowledges the IP address assignment (DHCPACK). The resulting IP packet is from the DHCP server's IP address, the destination IP address is one more time 255.255.255.255, the ethernet frame address will be addressed at the DHCP client's MAC address.

  • When a DHCP client wants to renew its DHCP lease, it does send another DHCPREQUEST from 0.0.0.0 to 255.255.255.255 and request the current IP address. It'll do this until the DHCP lease has expired, from where it'll start with DHCPDISCOVER again.

So more likely, you're looking for something like this:

iptables -A INPUT -m mac --mac-source xx:xx:xx:xx:xx:xx -p udp --dport 67 -j ACCEPT iptables -A INPUT -p udp --dport 67 -j DROP

This will drop any dhcp requests aimed at your server who don't originate at the listed MAC.

The issue may also be solved at a different level: remove the IP address pool from the DHCP server and do only assign static mappings for your respective MAC addresses. This way, the DHCP server won't answer to anyone listed and will only assign IPs to known hosts.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .