How to Configure User Namespace Remapping (userns-remap) in Docker

Docker tutorial - IT technology blog
Docker tutorial - IT technology blog

Introduction: The Illusion of Container Security

Imagine renting out a small spare room in your house. You hand the tenant a key to their room, only to realize that very same key also unlocks the front door and your master bedroom. If the tenant turns hostile or an intruder compromises them, your entire home is essentially forfeit.

By default in Docker, this scenario plays out every single day without most developers realizing it. Unless you explicitly define a non-root user when starting a container, its processes default to running under root (UID 0). The core issue lies within the Linux kernel: containers share the host kernel. Root inside the container is identical to root on the host machine.

The consequences are devastating. If a web app suffers from an RCE or a container escape exploit via a kernel vulnerability (such as CVE-2024-21626 in runc), attackers instantly gain full control over the host. They can wipe disks, spin up cryptominers, or exfiltrate databases with just a handful of commands.

Core Concept: What Is User Namespace Remapping?

Linux provides User Namespaces to remap user identities across two isolated security contexts.

When you enable userns-remap in Docker:

  • Inside the container, the process still believes it is running as root (UID 0). Services and package managers operate smoothly without throwing Permission Denied errors.
  • On the host machine, the kernel treats that process as an unprivileged regular user with zero administrative privileges—such as UID 165536.

Even if an attacker breaks out of the container, they remain trapped as an unprivileged, nameless user. They cannot tamper with config files in /etc, cannot read shadow passwords, and cannot interfere with system processes.

Step-by-Step Practical Guide: Enabling userns-remap

During a recent audit of 12 internal servers running Ubuntu 22.04, despite having solid firewall rules in place, I decided to enable userns-remap to completely eliminate container breakout vectors. The entire process takes less than 5 minutes:

Step 1: Verify Subordinate UID/GID Ranges on Your System

Linux uses two files, /etc/subuid and /etc/subgid, to allocate subordinate ID ranges for users. First, check if these files exist:

cat /etc/subuid
cat /etc/subgid

If these files do not exist or are empty, configure them for the dockremap user:

echo "dockremap:165536:65536" | sudo tee -a /etc/subuid
echo "dockremap:165536:65536" | sudo tee -a /etc/subgid

This entry grants dockremap a range of 65,536 subordinate IDs, from 165536 through 231071. Now, UID 0 inside the container directly maps to UID 165536 on the host.

Step 2: Configure the Docker Daemon

Open /etc/docker/daemon.json (create it if it doesn’t already exist):

{
  "userns-remap": "default"
}

The "default" setting instructs Docker to automatically bind to the system user dockremap created in Step 1.

Step 3: Restart the Docker Daemon

Apply your configuration changes by restarting the service:

sudo systemctl restart docker

Important note: Docker will relocate its image storage to a dedicated directory segregated by UID mapping (for example, /var/lib/docker/165536.165536/). Containers running prior to this change will not appear in docker ps. Don’t panic—you simply need to pull or rebuild your images within this new namespace.

Step 4: Verify the Configuration

Run an Alpine test container in the background:

docker run -d --name test-remap alpine sleep 3600

Check the active user inside the container:

docker exec -it test-remap id

The output inside the container confirms root privileges:

uid=0(root) gid=0(root) groups=0(root)

Now, inspect the process from the host machine using grep:

ps aux | grep "sleep 3600"

The host displays the following result:

165536   18924  0.0  0.0   1596     4 ?        Ss   10:15   0:00 sleep 3600

The process on the host is flagged under UID 165536 rather than root. Complete container isolation has been successfully achieved.

Conclusion

User Namespace Remapping downgrades container root privileges to a standard unprivileged user on the host without breaking application workflows. With just a 5-minute configuration tweak, you establish a solid defense-in-depth layer across your entire infrastructure.

Share: