Prevent routing of DHCP traffic

First, I'm aware that similar questions to mine have been asked elsewhere (I've read many of those posts!) but I've not been able to figure out a solution to my problem, so I'm asking for help.

My setup

I have two networks on my LAN, 192.168.0.0/24 and 10.11.12.0/24. The former has DHCP running on my WAN router, the latter runs dnsmasq on Ubuntu Server 20.04 on a box that also serves as a router between the two subnets. I've configured dnsmasq to only serve DHCP on the 10.11.12.0/24 network with the no-dhcp-interface=wlp3s0 option, wlp3s0 being the interface on the 192.168.0.0/24 side.

To summarise:

WAN Router (gateway to WAN) is 192.168.0.1/24 Runs DHCP for clients on 192.168.0.0/24
Router (b/w subnets): Ubuntu Server 20.04 with two interfaces wlp3s0: 192.168.0.2/24 (static IP) eno1: 10.11.12.1/24 (static IP)

I've configured iptables to FWD and NAT like so.

iptables -t nat -A POSTROUTING -o wlp3s0 -j MASQUERADE
iptables -A FORWARD -i wlp3s0 -o eno1 -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i eno1 -o wlp3s0 -j ACCEPT

I've allowed DHCP through my firewall with ufw allow 67/udp:

To Action From
-- ------ ----
67/udp ALLOW IN Anywhere

Everything appears to be working fine. However, from experience I know that running two DHCP servers like this can cause conflicts unless they are kept strictly separate. (Clients intended for the 192.168.0.0/24 network wouldn't be all too pleased if DHCP gave them an IP address on the 10.11.12.0/24 network!)

Discovering the problem

So I did the following to test it out. I set up a tcpdump listening on the wlp3s0 interface (192.168.0.2) and used nmap to simulate a DHCP Discover request originating on the eno1 interface (10.11.12.1/24), like so:

sudo tcpdump -i wlp3s0 -n udp port 67 or port 68
sudo nmap --script broadcast-dhcp-discover -e eno1

As expected I get a DHCP offer from dnsmasq running on 10.11.12.1. So far so good!

Some detail omitted from the output for brevity (he said)

Starting Nmap 7.80 ( ) at 2021-12-22 16:19 UTC
Pre-scan script results:
| broadcast-dhcp-discover:
| Response 1 of 1:
| IP Offered: 10.11.12.53
| DHCP Message Type: DHCPOFFER
| Server Identifier: 10.11.12.1
| Broadcast Address: 10.11.12.255
| Subnet Mask: 255.255.255.0
| Domain Name Server: 10.11.12.1
|_ Router: 10.11.12.1

However, tcpdump shows that both DHCP servers respond to the discover request. (In fact, my WAN router sends 2 replies!)

16:19:43.517029 IP 10.11.12.1.68 > 255.255.255.255.67: BOOTP/DHCP, Request from de:ad:c0:de:ca:fe, length 316
16:19:46.486227 IP 10.11.12.1.67 > 255.255.255.255.68: BOOTP/DHCP, Reply, length 321
16:19:46.794207 IP 192.168.0.1.67 > 255.255.255.255.68: BOOTP/DHCP, Reply, length 323
16:19:46.794207 IP 192.168.0.1.67 > 255.255.255.255.68: BOOTP/DHCP, Reply, length 323

It seems the DHCP discover request is forwarded to the 192.168.0.0/24 network via the wlp3s0 interface. Looking at my iptables and firewall rules I see no reason to be surprised by this. However, what I'm really struggling with is figuring out how to prevent it.

What I've tried

I've tried various permutations of rules in both ufw and iptables but to no avail, likely because I don't fully understand either iptables or ufw. A few examples of what I tried:

(All ufw/iptables rules were added at the top of the respective ruleset/chain to ensure they were hit.)

ufw:

# Restrict 67/udp to one interface
ufw allow in on eno1 proto udp from 0.0.0.0/0 to 0.0.0.0/0 port 67
# Deny routing
ufw route deny in on eno1 out on wlp3s0 to 0.0.0.0/0 port 67 proto udp

iptables:

# Prevent forwarding of UDP port 67/68
iptables -I FORWARD 1 -p udp --match multiport --dports 67,68 -j DROP
# Drop outbound UDP port 67
iptables -I OUTPUT 1 -p udp --match multiport --dports 67,68 -o wlp3s0 -j DROP

I must be missing some fundamental understanding of how this works since none of the above prevents the WAN router DHCP from receiving the discover and offering an IP on the 192.168.0.0/24 subnet.

I did read somewhere that DHCP servers may listen on a raw (or packet?) socket, which isn't subject to iptables. That isn't the case with dnsmasq as documented here . I also proved that by deleting the allow 67/udp rule in ufw, after which dnsmasq stops responding to DHCP discover. Perhaps surprisingly (or not), even with the allow rule deleted in ufw my WAN router continues to receive and respond to DHCP discover. Presumably because I have iptables rules configured to forward all traffic, but no equivalent INPUT rule (until I add one using ufw).

What I'd like to achieve

Preferably I'd like to prevent the DHCP discover broadcast on the 10.11.12.0/24 network from even reaching the 192.168.0.0/24 network.

If that proves difficult, I'd be happy to just prevent DHCP offers from my WAN router from reaching the 10.11.12.0/24 network.

Note that I do not have a problem on the 192.168.0.0/24 network since I've configured dnsmasq to not offer DHCP on the wlp3s0 interface (192.168.0.2). That appears to be working and DHCP discover on wlp3s0 (192.168.0.2/24) do not get a reply from dnsmasq.

So what am I missing? Am I going about this entirely wrong or am I just not getting it quite right? Any help is much appreciated.

Happy holidays!

Update

In response to a question in the comments from @sleepyhead, here is my iptables nat setup.

Chain PREROUTING (policy ACCEPT 13452 packets, 4312K bytes) pkts bytes target prot opt in out source destination
Chain INPUT (policy ACCEPT 48 packets, 12715 bytes) pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 87 packets, 10884 bytes) pkts bytes target prot opt in out source destination
Chain POSTROUTING (policy ACCEPT 55 packets, 8622 bytes) pkts bytes target prot opt in out source destination 32 2262 MASQUERADE all -- * wlp3s0 0.0.0.0/0 0.0.0.0/0

Update 2

Is it possible that this is an artefact of how I conduct my test? What makes me suspicious is the source IP of the tcpdump output. Could it be that running DHCP Discover on an interface that already has an IP produces a different result than if it didn't? Anyway, if I can repurpose one of my Raspberry Pis I'll run this test with it as a DHCP client and see if I get the same output, though I suspect I will.

6

1 Answer

All sorted, @sleepyhead was onto something about the routing but the issue was much more mundane (or idiotic!) than bridged interfaces etc. There's a switch on the 10.11.12.0/24 network and it turns out I'd left a cable in it that was connected to one of my mesh routers! So there were in fact two routes out of the box to the 192.168.0.0/24 network, one via the wlp3s0 interface (correctly blocked in iptables) and another out via eno1, which obviously was open. This explains why I kept receiving responses from the WAN router and also, I think, why they were duplicated.

Well, blunders aside I hope this will be helpful to someone given how many questions are asked about DHCP and routing.

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

You Might Also Like