Removing Capabilities from Docker Containers
In this step, we will learn how to remove capabilities from Docker containers using the --cap-drop
flag. This is an important security practice that follows the principle of least privilege - containers should only have the capabilities they absolutely need.
Basic Syntax for Removing Capabilities
The basic syntax for removing a capability from a Docker container is:
docker run --cap-drop=<CAPABILITY> <IMAGE> <COMMAND>
Let us try removing the CHOWN
capability, which allows changing file ownership:
docker run --rm -it --cap-drop=CHOWN ubuntu:22.04 capsh --print
In the output, you will notice that cap_chown
is no longer listed among the capabilities:
Current: cap_dac_override,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_net_raw,cap_sys_chroot,cap_mknod,cap_audit_write,cap_setfcap=ep
Removing Multiple Capabilities
You can remove multiple capabilities by specifying the --cap-drop
flag multiple times:
docker run --rm -it --cap-drop=CHOWN --cap-drop=NET_RAW ubuntu:22.04 capsh --print
This command removes both the CHOWN
and NET_RAW
capabilities from the container.
Practical Example: Testing Capability Restrictions
Let us create a container with the CHOWN
capability dropped and attempt to change file ownership:
docker run --rm -it --cap-drop=CHOWN ubuntu:22.04 /bin/bash
Inside the container, let us create a test file and try to change its ownership:
touch test_file
ls -l test_file
chown nobody:nogroup test_file
You should see an error message indicating that the operation is not permitted:
chown: changing ownership of 'test_file': Operation not permitted
This demonstrates that removing the CHOWN
capability prevents the container from changing file ownership, even though the container is running as root. Type exit
to leave the container.
Using Both --cap-add and --cap-drop
You can use both --cap-add
and --cap-drop
flags in the same command to precisely control the capabilities of your container:
docker run --rm -it --cap-add=NET_ADMIN --cap-drop=CHOWN ubuntu:22.04 capsh --print
This command adds the NET_ADMIN
capability while removing the CHOWN
capability.
Dropping All Capabilities and Adding Specific Ones
For maximum security, you can drop all capabilities and then add only the specific ones your application needs:
docker run --rm -it --cap-drop=ALL --cap-add=NET_BIND_SERVICE ubuntu:22.04 capsh --print
This command creates a container with only the NET_BIND_SERVICE
capability, which allows binding to privileged ports (below 1024).
Testing a Container with All Capabilities Dropped
Let us create a container with all capabilities dropped and observe the restrictions:
docker run -d --name no-caps --cap-drop=ALL ubuntu:22.04 sleep 3600
Now, let us attach to the container and try to perform various operations:
docker exec -it no-caps /bin/bash
Inside the container, try to ping an external host:
apt-get update && apt-get install -y iputils-ping
ping -c 1 google.com
You will likely see an error because the container does not have the necessary capabilities to create raw network sockets required for ping.
Exit the container by typing exit
, and then clean up:
docker stop no-caps
docker rm no-caps
By understanding how to remove capabilities from Docker containers, you can significantly enhance the security of your containerized applications by strictly limiting what each container can do.