Eliminación de Capacidades de los Contenedores Docker
En este paso, aprenderemos a eliminar capacidades de los contenedores Docker utilizando la bandera --cap-drop. Esta es una práctica de seguridad importante que sigue el principio del mínimo privilegio: los contenedores solo deben tener las capacidades que absolutamente necesitan.
Sintaxis básica para eliminar capacidades
La sintaxis básica para eliminar una capacidad de un contenedor Docker es:
docker run --cap-drop=<CAPABILITY> <IMAGE> <COMMAND>
Intentemos eliminar la capacidad CHOWN, que permite cambiar la propiedad de los archivos:
docker run --rm -it --cap-drop=CHOWN ubuntu:22.04 capsh --print
En la salida, notará que cap_chown ya no aparece entre las capacidades:
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
Eliminación de múltiples capacidades
Puede eliminar múltiples capacidades especificando la bandera --cap-drop varias veces:
docker run --rm -it --cap-drop=CHOWN --cap-drop=NET_RAW ubuntu:22.04 capsh --print
Este comando elimina las capacidades CHOWN y NET_RAW del contenedor.
Ejemplo práctico: Prueba de restricciones de capacidad
Creemos un contenedor con la capacidad CHOWN eliminada e intentemos cambiar la propiedad del archivo:
docker run --rm -it --cap-drop=CHOWN ubuntu:22.04 /bin/bash
Dentro del contenedor, creemos un archivo de prueba e intentemos cambiar su propiedad:
touch test_file
ls -l test_file
chown nobody:nogroup test_file
Debería ver un mensaje de error que indica que la operación no está permitida:
chown: changing ownership of 'test_file': Operation not permitted
Esto demuestra que la eliminación de la capacidad CHOWN impide que el contenedor cambie la propiedad del archivo, aunque el contenedor se esté ejecutando como root. Escriba exit para salir del contenedor.
Uso de --cap-add y --cap-drop
Puede usar las banderas --cap-add y --cap-drop en el mismo comando para controlar con precisión las capacidades de su contenedor:
docker run --rm -it --cap-add=NET_ADMIN --cap-drop=CHOWN ubuntu:22.04 capsh --print
Este comando agrega la capacidad NET_ADMIN mientras elimina la capacidad CHOWN.
Eliminación de todas las capacidades y adición de capacidades específicas
Para una máxima seguridad, puede eliminar todas las capacidades y luego agregar solo las específicas que su aplicación necesita:
docker run --rm -it --cap-drop=ALL --cap-add=NET_BIND_SERVICE ubuntu:22.04 capsh --print
Este comando crea un contenedor con solo la capacidad NET_BIND_SERVICE, que permite la vinculación a puertos privilegiados (por debajo de 1024).
Prueba de un contenedor con todas las capacidades eliminadas
Creemos un contenedor con todas las capacidades eliminadas y observemos las restricciones:
docker run -d --name no-caps --cap-drop=ALL ubuntu:22.04 sleep 3600
Ahora, adjuntemos al contenedor e intentemos realizar varias operaciones:
docker exec -it no-caps /bin/bash
Dentro del contenedor, intente hacer ping a un host externo:
apt-get update && apt-get install -y iputils-ping
ping -c 1 google.com
Probablemente verá un error porque el contenedor no tiene las capacidades necesarias para crear sockets de red sin formato requeridos para ping.
Salga del contenedor escribiendo exit y luego limpie:
docker stop no-caps
docker rm no-caps
Al comprender cómo eliminar capacidades de los contenedores Docker, puede mejorar significativamente la seguridad de sus aplicaciones en contenedores al limitar estrictamente lo que cada contenedor puede hacer.