Implementing Rootless Podman with User Namespace Mapping
Learn how to configure rootless Podman using User Namespaces to eliminate root-privileged daemons and enhance host security through subuid and subgid mapping.
19 Aug 2025, 03:59 UTC

The Security Risk of Rooted Daemons
Running container engines as a root-privileged daemon creates a significant attack surface: if a container escapes its isolation, the attacker inherits root privileges on the host. Rootless Podman solves this by utilizing User Namespaces (userns), a Linux kernel feature that maps a range of non-privileged User IDs (UIDs) and Group IDs (GIDs) from the host to a different set of IDs inside the container.
The primary takeaway is that rootless mode allows a standard user to act as the root user inside the container while remaining a powerless, non-privileged user outside on the host system.
Prerequisites
- A Linux distribution with a kernel supporting user namespaces (most modern kernels 4.18+).
- Podman installed (Version 4.0+ recommended).
- A non-root system user account with sudo privileges for the initial configuration of subordinate IDs.
- The
slirp4netnsorpastapackage installed for rootless networking.
Configuring Subordinate IDs
For Podman to map the container's root user to your host user, the system must define a range of subordinate IDs that the user is allowed to use. These are stored in /etc/subuid and /etc/subgid.
Run the following commands as a user with sudo permissions to assign a range of 65,536 IDs to your user (replace username with your actual account name):
# Assign a range of subordinate UIDs
sudo usermod --add-subuids 100000-165535 username
# Assign a range of subordinate GIDs
sudo usermod --add-subgids 100000-165535 username
Expected Check: Verify the entries exist by running grep username /etc/subuid. You should see a line like username:100000:65536.
Running the Rootless Container
Once the subordinate IDs are mapped, you can launch containers without sudo. Because rootless containers cannot bind to privileged ports (those below 1024), you must map your service to a higher port.
Run this command as the non-privileged user:
# Run an Nginx container mapping host port 8080 to container port 80
podman run -d --name rootless-web -p 8080:80 nginx
Managing Volume Permissions with podman unshare
A common point of failure in rootless mode is permission denied errors on mounted volumes. This happens because the files on the host are owned by your user, but the process inside the container expects them to be owned by the container's root (which is mapped to a subordinate ID).
To fix this, use podman unshare. This command executes a process in the same user namespace as the containers, allowing you to modify permissions as if you were the container's root user:
# Change ownership of a host directory to the container's root user
podman unshare chown -R 0:0 /home/username/my-data-volume
Verification and Diagnostics
To confirm the environment is correctly configured as rootless, perform these three checks:
- System Info: Run
podman info | grep rootless. The output must berootless: true. - Identity Mapping: Run
podman run --rm alpine whoami. The output should beroot. Then, on the host, runps -ef | grep alpine. The process owner should be your non-privileged username, not root. - Connectivity: Run
curl -I localhost:8080. A successful HTTP response confirms the user-mode network stack is functioning.
Operational Limitations
| Constraint | Impact | Workaround |
|---|---|---|
| Privileged Ports | Cannot bind to ports < 1024 | Use ports 1024+ or modify net.ipv4.ip_unprivileged_port_start via sysctl. |
| Network I/O | Higher latency due to slirp4netns | Use pasta for improved performance in newer Podman versions. |
| Kernel Capabilities | CAP_SYS_ADMIN is restricted | Avoid containers requiring deep kernel modifications or raw socket access. |
Rollback and Reset
If you modify /etc/subuid or /etc/subgid after you have already created containers, the existing storage configuration will be mismatched, leading to permission errors.
To reset the rootless storage and apply the new ID mappings, run the following as the non-privileged user:
# Reset rootless storage configuration
podman system migrate
Risk: This command resets the internal mapping but does not delete your images; however, it may require you to re-verify volume permissions using podman unshare.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.