apparmor denies dhclient socket

n0x0n

Active Member
Jan 20, 2022
40
4
28
Updated from PVE 8-latest to PVE 9.1.1 yesterday, kernel 6.17.2-1-pve. Starting immediately after the upgrade, I get lots of apparmor messages denying dhclient access to a socket:
Code:
2025-11-22T09:54:12+01:00 pve2 kernel: audit: type=1400 audit(1763801652.257:138): apparmor="DENIED" operation="create" class="net" info="failed protocol match" error=-13 profile="/{,usr/}sbin/dhclient" pid=1060 comm="dhclient" family="unix" sock_type="dgram" protocol=0 requested="create" denied="create" addr=none
2025-11-22T09:54:12+01:00 pve2 kernel: audit: type=1400 audit(1763801652.257:139): apparmor="DENIED" operation="create" class="net" info="failed protocol match" error=-13 profile="/{,usr/}sbin/dhclient" pid=1060 comm="dhclient" family="unix" sock_type="dgram" protocol=0 requested="create" denied="create" addr=none
2025-11-22T09:54:12+01:00 pve2 kernel: audit: type=1400 audit(1763801652.291:140): apparmor="DENIED" operation="create" class="net" info="failed protocol match" error=-13 profile="/{,usr/}sbin/dhclient" pid=1060 comm="dhclient" family="unix" sock_type="dgram" protocol=0 requested="create" denied="create" addr=none

System seems to work fine, but I think this shouldn't happen.
 
Temporary workaround to get rid of the noise: Add the following to /etc/apparmor.d/local/usr.sbin.dhclient
Code:
# local addition for dhclient
# permits creation and usage of UNIX domain datagram sockets
network unix dgram,
Don't forget to systemctl reload apparmor afterwards.

You probably should not do this on a production system.
 
Last edited:
Did you put a comma after, i.e. abi <abi/3.0>, (edited now in the original) and reload systemctl restart apparmor.service?
 
Did you put a comma after, i.e. abi <abi/3.0>, (edited now in the original) and reload systemctl restart apparmor.service?
Same on my freshly updated PVE host. /etc/apparmor.d/local/usr.sbin.dhclient consists of the abi declaration only, apparmor service was reloaded. I got a kernel update, the reboot is still pending. Might that have some impact on this too?
 
Did you put a comma after, i.e. abi <abi/3.0>, (edited now in the original) and reload systemctl restart apparmor.service?
Yes I did. It did quiet down the number of dhclient messages. They only generate about once every 8hrs versus fairly regularly.
 
Yes I did. It did quiet down the number of dhclient messages. They only generate about once every 8hrs versus fairly regularly.
So your /etc/apparmor.d/local/usr.sbin.dhclient also consists of the abi line only? Unfortunately on my side the messages still occur every ~100 seconds.
 
So your /etc/apparmor.d/local/usr.sbin.dhclient also consists of the abi line only? Unfortunately on my side the messages still occur every ~100 seconds.
Yes, the only line in that file is
Code:
abi <abi/3.0>,
You can reload apparmor, but I would reboot if it seems to not be doing anything. Not sure what you are using for a router, but you may have a short lease time set which is causing proxmox to request more often. I use OPNsense and default lease time is 86400 seconds (24hrs), but a client will typically request about halfway through the lease time.
 
Last edited:
You can reload apparmor, but I would reboot if it seems to not be doing anything. Not sure what you are using for a router, but you may have a short lease time set which is causing proxmox to request more often. I use OPNsense and default lease time is 86400 seconds (24hrs), but a client will typically request about halfway through the lease time.
I tried both, reloading first, then rebooting. Had always the same result :/ The lease time for this network is set to 30 minutes, which indeed is low for a servers only network, but not low enough to explain this level of spamming. I'm on a Mikrotik Router for this net, would be really surprised if that indeed plays part.
 
Spent a while chasing this on a fresh PVE 9 host and wanted to share what actually worked, since the `abi <abi/3.0>,` advice gave me "mixed results" at first too — and I think I finally understand why.

The key thing: **the `abi <abi/3.0>,` line only works if it's in the profile *preamble*** (the top of `/etc/apparmor.d/usr.sbin.dhclient`, before the `/{,usr/}sbin/dhclient {` block). If you put it in `/etc/apparmor.d/local/usr.sbin.dhclient`, it gets `#include`d *inside* the profile block, where the abi declaration is parsed but silently ignored — so the denials keep coming. That placement difference is, I think, why some people report it working and others don't.

What fixed it for me, permanently:
1. Add to the **top** of `/etc/apparmor.d/usr.sbin.dhclient`, before `#include <tunables/global>`:
```
abi <abi/3.0>,
```
2. Add to `/etc/apparmor.d/local/usr.sbin.dhclient`:
```
network unix dgram,
```
3. Reload:
```
apparmor_parser -r /etc/apparmor.d/usr.sbin.dhclient
```
Both parts are needed: the abi pin makes the profile compile against the older ABI where `AF_UNIX` is mediated by the coarse network class, and the `network unix dgram,` line is the grant that class understands. The fine-grained `unix (...)` rules don't help here because this kernel mediates `AF_UNIX` through the network class (`/sys/kernel/security/apparmor/features/network_v9/af_unix` is `yes`, and there's no `features/unix` dir).
A tip for verifying without waiting on lease renewals — the denials are bursty, so a quiet minute or two doesn't mean it's fixed. This tests it deterministically:
```
aa-exec -p "/{,usr/}sbin/dhclient" -- python3 -c "import socket; socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM); print('OK')"
```
`Permission denied` = still broken, `OK` = fixed.
One caveat: editing `/etc/apparmor.d/usr.sbin.dhclient` touches a dpkg-managed file, so an `apparmor-profiles` upgrade may revert the preamble line (the `local/` override survives). I automate re-applying it, but worth knowing if you do it by hand.