DHCP client issue when Host Firewall is enabled

Hey guys, I have an Ubuntu VM running on a RHEL 9 host, and I am seeing weird behavior that I don’t know enough about DHCP in order to track down some more. So when my host machine’s firewalld is running, the VM is unable to receive a DHCP lease from it (using the default NAT network provided by libvirt). Here is the relevant Firewalld zone:

sudo firewall-cmd --zone libvirt --list-all
libvirt (active)
  target: ACCEPT
  icmp-block-inversion: no
  interfaces: virbr0 virbr1
  sources: 192.168.100.0/28 192.168.122.0/28
  services: dhcp dhcpv6 dns postgresql tftp
  ports: 
  protocols: icmp ipv6-icmp
  forward: no
  masquerade: no
  forward-ports: 
  source-ports: 
  icmp-blocks: 
  rich rules: 
        rule priority="32767" reject

And the output from this dhclient test is the result of me beginning the test when the firewall is up, and subsequently stoppling the firewalld service on the host. It got the lease immediately after the firewall went down:

linuxdragon@build-runner-vm:~$ sudo dhclient -v -r enp7s0 && sudo dhclient -v enp7s0
Internet Systems Consortium DHCP Client 4.4.1
Copyright 2004-2018 Internet Systems Consortium.
All rights reserved.
For info, please visit https://www.isc.org/software/dhcp/

Listening on LPF/enp7s0/52:54:00:53:88:4a
Sending on   LPF/enp7s0/52:54:00:53:88:4a
Sending on   Socket/fallback
DHCPRELEASE of 192.168.122.52 on enp7s0 to 192.168.122.1 port 67 (xid=0x4207101b)
Internet Systems Consortium DHCP Client 4.4.1
Copyright 2004-2018 Internet Systems Consortium.
All rights reserved.
For info, please visit https://www.isc.org/software/dhcp/

Listening on LPF/enp7s0/52:54:00:53:88:4a
Sending on   LPF/enp7s0/52:54:00:53:88:4a
Sending on   Socket/fallback
DHCPDISCOVER on enp7s0 to 255.255.255.255 port 67 interval 3 (xid=0x22241a21)
DHCPDISCOVER on enp7s0 to 255.255.255.255 port 67 interval 8 (xid=0x22241a21)
^[[CDHCPDISCOVER on enp7s0 to 255.255.255.255 port 67 interval 8 (xid=0x22241a21)
DHCPDISCOVER on enp7s0 to 255.255.255.255 port 67 interval 14 (xid=0x22241a21)
DHCPDISCOVER on enp7s0 to 255.255.255.255 port 67 interval 20 (xid=0x22241a21)
DHCPDISCOVER on enp7s0 to 255.255.255.255 port 67 interval 15 (xid=0x22241a21)
DHCPDISCOVER on enp7s0 to 255.255.255.255 port 67 interval 14 (xid=0x22241a21)
DHCPDISCOVER on enp7s0 to 255.255.255.255 port 67 interval 20 (xid=0x22241a21)
DHCPOFFER of 192.168.122.52 from 192.168.122.1
DHCPREQUEST for 192.168.122.52 on enp7s0 to 255.255.255.255 port 67 (xid=0x211a2422)
DHCPACK of 192.168.122.52 from 192.168.122.1 (xid=0x22241a21)
bound to 192.168.122.52 -- renewal in 1682 seconds.

I’ve also done an additional test once before wherein I ran the DHCP client command on the VM while the host firewall is running. Simultaneously, I used tcpdump on the host to capture UDP packets on port 67. So the Host is at least seeing the DHCP request from the VM when the firewall is up.

P.S. I could easily solve this issue by putting this VM on a bridge to my LAN; but that’s a lot of work, and this VM doesn’t need that. Plus, I only have a limited number of physical network connections left on my PFSense box without additional hardware.

1 Like

Is it assigning to downstream real machines and just having problems with the VM?

1 Like

I don’t use it for real machines. It’s just the libvirt network stack. From what I can tell, The firewall allows the host to request DHCP leases from libvirt and that traffic flows. It’s just after the host responds, something else must be getting blocked by the host’s firewall.

Thoughts on debugging:

tcpdump is ever handy, with the firewall disabled to see what’s supposed to happen, then enabled to see what doesn’t happen.

Afraid I don’t know anything about firewall-cmd, though it looks like a frontend to nftables.

With nftables rules you can mark rules with “counter” and/or turn on nftrace.

I’ve been using counter for debugging, knowing what rule a packet matched has been enough so far for me to fix my problems :slight_smile:

The pretend intelligence tells me that firewall-cmd doesn’t support those. One way around that would be to dump your nftables rules, add counter keywords, flush the rules, then load the rules with nft.

1 Like

Consider the following:

  1. You are using an IP whitelist to restrict access to your machine

  2. You are running a local dhcp server

What happens before a machine contacts the DHCP server? The machine does not have an IP on the local subnet. Which means presumably all requests to the DHCP server are being dropped by your firewall configuration. It’s probably easiest to just open the ports for DHCP to all traffic.

1 Like

Yeah. I tried that, actually, as that was my thought exactly. It wouldn’t let me add 0.0.0.0/0 to that zone because I already have that on my “public” zone. I would rather not have restrictive sources altogether, but when I remove them, traffic from my VMs gets blocked. At least this is the case for one VM that uses a macvtap bridge along with a libvirt isolated network. I was able to add 0.0.0.0 to that zone though. I’ll see if it lets DHCP work. I can’t see me needing to provide DHCP to anything other than VMs, either, so I don’t think it’s too specific. Several months ago, I tried to use Firewalld as a port-forwarder to one of my VMs, and I feel like I messed up the Linux distribution maintainer’s (RHEL) default settings for that package.

I think this has actually fixed the issue. I was able to add 0.0.0.0 as a source address rather than the entire subnet, and now all DHCP issues are fixed - including what I was thinking was DNS.

2 Likes

Ah something else I may have learned, though it would require more discovery, is that Firewalld may apply filter priority to zones. That could be the something that’s preventing my libvirt zone from working unless I explictly add IP ranges. Anyway, this works and I won’t need DHCP on other zones; so I’ll investigate that later.

1 Like