UFW/IPTABLES not blocking DHCP UDP port 67

dhcpiptablesufw

I am running ubuntu 16.04. I have ufw installed and enabled. I also have isc-dhcp-server installed. I have not opened up UDP port 67, yet DHCP clients still seem to be able to obtain DHCP leases from the server. Why is this? I have reviewed the IPTABLES that ufw creates, and it does have UDP port 68 opened for a DHCP client, but not UDP port 67 (as far as I can understand). It also does not appear to me as though ufw has configured IPTABLES to accept broadcast traffic. Is ufw supposed to allow or block broadcast traffic?

Does IPTABLES have some kind of special exception for UDP port 67 traffic?

Does a DHCP client fall back to broadcasting on UDP port 68 if it doesn't first get a response from broadcasting on UDP port 67? If so, this could make sense that the DHCP requests are making their way to the server, because then the UFW rule for allowing outgoing DHCP client requests would then allow incoming DHCP client requests.

The status of ufw status verbose is

Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), disabled (routed)
New profiles: skip

To                         Action      From
--                         ------      ----
22/tcp                     ALLOW IN    Anywhere                  

Best Answer

I was too dump to open up the proper ports on my firewall before I started testing out my shiny new DHCP server, and it took a moment to dawn on me that it shouldn't work yet. I never opened port 67 on my server's firewall.

...

The simple answer is that DHCP is indeed special. To quote what a stranger quoted,

Per Mark Andrews of isc.org:

"DHCP uses packet filters and these tie into the IP stack before the firewall."

http://thr3ads.net/netfilter-buglog/2011/07/1961358-Bug-730-New-DHCP-request-and-other-traffic-bypasses-iptables-netfilter

-- https://www.centos.org/forums/viewtopic.php?t=8728


It's often stated that this is because the DHCP server uses raw sockets. I think this phrasing is quite confusing. Some official ISC docs for their DHCP server use "raw sockets" as a broad term, because it can run on a number of different platforms where it must use a number of different interfaces. On Linux, there is more than one type that you might hear referred to as raw sockets. Some are affected by Linux iptables, and some are not affected by Linux iptables.

I'm confident that Linux' TCP/IP stack imposes some restrictions when sending packets with PF_INET+SOCK_RAW. My vague memory was that DHCP on Linux does not necessarily work with that type of socket, and might need to use "packet sockets" instead. Packet sockets work at a lower level. I'm confident that packet sockets are not affected by iptables.

PF_PACKET sockets bypass the TCP/IP stack.

PF_INET/SOCK_RAW sockets still travers the TCP/IP stack.

-- https://lists.netfilter.org/pipermail/netfilter-devel/2003-March/010845.html

This quote was written in the context of receiving packets. There is also evidence that this applies to sending packets, as you might expect.


It seems that iptables is one of the restrictions that applies to the TCP/IP stack, including to sending with PF_INET+SOCK_RAW.

If I have a an IP datagram in userspace and I send it via a raw socket created with socket(PF_INET, SOCK_RAW, IPPROTO_RAW) using the send() system call, will this packet traverse the netfilter chains?

...

looks like good news:

ipt_hook: happy cracking.
ipt_hook: happy cracking.
ipt_hook: happy cracking.
ipt_tcpmss_target: bad length (10 bytes)

So your packets will traverse iptables.

https://lists.netfilter.org/pipermail/netfilter-devel/2003-March/010829.html

And the evidence for the receive direction:

It turns out that using raw sockets gives me the packets post-NAT so the IP addresses are back in the private range (10.x.x.x in my example). Maybe this is common knowledge but I've struggled to find it documented. If I use libpcap/tcpdump I get packets pre-NAT

[NAT is performed by iptables]

-- https://lists.gt.net/iptables/user/62529#62529


Bonus griping: I think the term "packet filter" in my initial quote is a straight out abuse, albeit a long-standing one. Berkeley Packet Filter is a mechanism used to install a filter on a raw socket, e.g. so that it only receives packets on the DHCP port. I think ISC at times refer to "Linux Packet Filter" as if it was a type of raw socket itself. It's not, and you can actually use BPF on normal UDP or TCP sockets.

Related Question