LXC 6.0 unprivileged security and container deployment decisions
LXC 6.0 unprivileged containers provide strong security by mapping container UID 0 to a subordinate host user. This release introduces hardening through the removal of stack-based memory allocations and new seccomp features to enhance system-level workload isolation.
Unprivileged runtime security
LXC 6.0 unprivileged containers provide the strongest security boundary for system-level workloads. These containers map the container UID 0 to an unprivileged user on the host. This architecture reduces the impact of file-permission mistakes and container escapes. LXC uses three pieces of setuid code to facilitate this: lxc-user-nic, newuidmap, and newgidmap. While LXC utilizes AppArmor, seccomp, and capabilities, these tools provide only additional layers because the security model relies on the user namespace. You probably know that unprivileged containers require a kernel version of 3.13 or higher to work. Privileged containers remain unsafe because the container UID 0 maps to the host UID 0. LXC 6.0 also introduces significant hardening through the removal of all stack-based memory allocations and the removal of the fgets() function from the codebase. The developers also added support for the LGTM code analysis tool and the coccinelle transformation tool. New seccomp features allow the kernel to forward intercepted syscalls to a dedicated file descriptor via a unix socket. Users can specify a unix socket address via lxc.seccomp.notify.proxy in the format unix:<path>. This lets a privileged userspace process inspect syscall arguments and perform actions. The release also includes the lxc.seccomp.allow_nesting configuration key, which allows seccomp profiles to be stacked. This enables nested containers to load their own seccomp policy on top of the policy that the outer container applied. The release also includes initial support for the pidfd API, using the pidfd_send_signal() syscall and the CLONE_PIDFD flag. This eliminates various race conditions when sending signals or retrieving process information. LXC also uses the /sys/kernel/cgroup/delegate file to determine which cgroups v2 files to delegate to the user. The images.linuxcontainers.org library provides a variety of distributions, releases, and architectures for these containers.
Deployment boundaries for Docker and LXC
Teams choosing between Docker and Podman must evaluate how they manage host resources. Docker allows for a rootless mode where both the daemon and containers run without host-root privileges. This reduces risk when the application supports rootless limitations. However, the Docker socket presents a massive risk. A compromised service with access to /var/run/docker.sock can instruct the host daemon to create containers or mount host paths. This access functions like host administration. If a service requires broad host filesystem access or unrestricted device permissions, neither the Docker nor the LXC model provides a meaningful security boundary once the application gains host-level root powers through a compromise.
| Container Type | Primary Isolation Method | Security Boundary |
|---|---|---|
| Privileged LXC | AppArmor, Seccomp, Capabilities | Host-root identity |
| Unprivileged LXC | User Namespaces | Subordinate user identity |
| Docker (Rootful) | Namespaces, Cgroups | Container user identity |
| Docker (Rootless) | User Namespaces | Subordinate user identity |
Docker containers package applications and dependencies into a single unit, while LXC creates a system container with its own package database and services. Docker manages resource usage through constraints, but the engine allows unrestricted CPU and memory use by default unless a user applies limits. In an LXC deployment, the outer container adds its own limits. A 2025 runc/AppArmor incompatibility demonstrated that runtime security changes can interact with outer container policies, causing failures in descriptor reopening. Proxmox documentation recommends containers inside a QEMU VM for requirements emphasizing isolation and live migration. LXD, which Canonical maintains, provides LTS releases with five years of support. Will the move to newer kernels eliminate the remaining container escape vulnerabilities?
Network and hardware access
Networking and device mapping determine the blast radius of a compromise. LXC 6.0 provides IPVLAN support and layer 2 ARP/NDP proxy mode. The IPVLAN functionality works on older kernels. The router veth mode configures the host machine as a router for the container. This mode uses the host routing table and prevents the container from altering its IP. A container with host networking loses port-level separation.
For device access, LXC can share specific resources like GPIO pins or PCI devices. Users can grant read, write, and mknod permissions to character devices. This allows precise control over what a container uses. However, containers connected to a bridge can transmit any level 2 traffic, which allows MAC or IP spoofing. To mitigate this, administrators should create one bridge per user or group.
| Resource Type | LXC Configuration Method | Network Method |
|---|---|---|
| GPIO | /dev/device node mapping | N/A |
| Network | lxc.net.[i].veth.mode | Bridge or Router |
| Storage | /var/lib/lxc/ path | N/A |
Users can also set static routes via lxc.net.[i].ipv4.gateway or lxc.net.[i].ipv6.gateway using the value dev. This allows for specific device route settings. To secure IPv6, administrators can set the /proc/sys/net/ipv6/conf/default/accept_ra setting to 0. This prevents the LXC host from accepting potentially malicious router advertisements from the containers. If a service requires hardware decoding, a successful decode test after migration remains necessary.