From cf0d62696f36e1b11afe06b5c3dc4a6d32cd91c6 Mon Sep 17 00:00:00 2001 From: beatzaplenty Date: Mon, 27 Jul 2026 05:23:22 +1000 Subject: [PATCH] fix(lxc-pxe-boot): make privileged so NFS mounts work MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The kernel's NFS client (FS_USERNS_MOUNT not set) rejects NFS mounts from inside any unprivileged container's user namespace with EPERM — AppArmor's mount=nfs feature only whitelists the AppArmor layer; the VFS-level rejection happens before AppArmor is consulted. lxc-pxe-boot mounts server.sweet.home:/tank/pxe-boot/images at /mnt/pxe-images so nginx can serve large ISOs without filling the container's root disk. Same pattern as lxc-docker (already privileged for the same reason since it also mounts several NFS shares). Operator action required: VMID 103 must be recreated as a privileged container (the UID mapping on disk differs between privileged and unprivileged; changing it in-place with pct set is unsafe). Rebuild the tarball and use create-proxmox-resource.sh to replace it. Co-Authored-By: Claude Sonnet 4.6 --- modules/platforms/lxc.nix | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/modules/platforms/lxc.nix b/modules/platforms/lxc.nix index d9c37a7..fb73b4f 100644 --- a/modules/platforms/lxc.nix +++ b/modules/platforms/lxc.nix @@ -63,9 +63,9 @@ in # back to decide `pct create`'s --unprivileged flag, so the two stay # in sync). # - # lxc-docker is the one exception: the kernel's NFS client doesn't set - # FS_USERNS_MOUNT, so mounting NFS from inside *any* non-init user - # namespace -- which is exactly what an unprivileged container's + # lxc-docker and lxc-pxe-boot are the exceptions: the kernel's NFS client + # doesn't set FS_USERNS_MOUNT, so mounting NFS from inside *any* non-init + # user namespace -- which is exactly what an unprivileged container's # UID-mapped root runs in -- is rejected at the VFS layer with EPERM, # no matter what Proxmox's own `mount=nfs;nfs4` container feature # allows at the AppArmor layer (confirmed live: TCP to the NFS server @@ -73,13 +73,15 @@ in # `mount.nfs: Operation not permitted` still fires immediately with no # corresponding denial anywhere in the server's logs -- a kernel-level # rejection, not a network or export-permission one). Keying off - # hostName rather than something docker-build-type-specific because - # modules/build-types/docker.nix is also composed for linode-docker/ - # proxmox-docker, which don't import proxmox-lxc.nix at all --setting - # this option there would break their eval with "option does not - # exist" regardless of any mkIf guard, since mkIf only makes a value - # conditional, not whether the option needs to exist somewhere. - privileged = config.networking.hostName == "docker"; + # hostName rather than something build-type-specific because + # modules/build-types/{docker,pxe-boot}.nix are also composed for + # linode-docker/proxmox-docker/proxmox-pxe-boot, which don't import + # proxmox-lxc.nix at all -- setting this option there would break their + # eval with "option does not exist" regardless of any mkIf guard, since + # mkIf only makes a value conditional, not whether the option needs to + # exist somewhere. + privileged = config.networking.hostName == "docker" + || config.networking.hostName == "pxe-boot"; }; boot.loader = {