¿Por qué estás aquí?
Quieres saber la verdadera respuesta a dos preguntas sobre la seguridad de Docker:
¿Es seguro Docker para uso en producción?
Sí y no. Docker utiliza un modelo de seguridad que se basa en espacios de nombres y aislamiento de recursos, haciendo que los procesos internos sean más seguros frente a ataques específicos que ejecutar tus aplicaciones directamente desde una VM en la nube o un sistema bare metal. A pesar de esa capa, todavía hay muchas formas en que los atacantes pueden acceder a tu contenedor, permitiéndoles leer información confidencial, ejecutar ataques de denegación de servicio (DoS) o incluso obtener acceso root al sistema host.
¿Cómo puedo mejorar mi seguridad en Docker (de una manera no demasiado dolorosa)?
Te guiaremos a través de las vulnerabilidades de Docker más comunes y graves, saltándonos las recomendaciones básicas que encontrarás en Google, como usar imágenes oficiales y mantener tu host actualizado. En su lugar, te llevaremos directamente a nuevas opciones de Docker y líneas de Dockerfile que harán que tu nuevo despliegue predeterminado de contenedores Docker sea mucho más seguro que nunca.

La lista de verificación de seguridad de Docker sin rodeos
Hacer que los sistemas de archivos dentro de los contenedores sean de solo lectura
¿Qué obtiene?
Evita que un atacante edite el entorno de ejecución de su contenedor Docker, lo que podría permitirles recopilar información útil sobre su infraestructura, obtener datos de usuario o llevar a cabo un ataque DOS o de ransomware directamente.
¿Cómo lo configuras?
Tiene dos opciones, ya sea en tiempo de ejecución o dentro de su configuración de Docker Compose.
En tiempo de ejecución: docker run --read-only your-app:v1.0.1
En su archivo Docker Compose:
services:
webapp:
image: your-app:v1.0.1read_only: true
...Bloquear la escalada de privilegios
¿Qué obtiene?
Evita que su contenedor Docker —o un atacante que esté manipulando dicho contenedor— habilite nuevos privilegios, incluso a nivel de root, con setuid o setgid. Con un acceso más permisivo a su contenedor, un atacante podría acceder a credenciales en forma de contraseñas o claves de partes conectadas de su despliegue, como una base de datos.
¿Cómo lo configuras?
Una vez más, en tiempo de ejecución o dentro de tu configuración de Docker Compose.
En tiempo de ejecución: docker run --security-opt=no-new-privileges your-app:v1.0.1
En su archivo Docker Compose:
servicios:
webapp:
image: your-app:v1.0.1
security_opt:
- no-new-privileges:true
...Aísle sus redes de contenedor a contenedor
¿Qué obtiene?
Por defecto, Docker permite que todos los contenedores se comuniquen a través de la red docker0, lo que podría permitir a un atacante moverse lateralmente de un contenedor comprometido a otro. Si tienes servicios discretos A y B en contenedores Y y Z, y no necesitan comunicarse directamente, aislar sus redes proporciona la misma experiencia al usuario final al tiempo que previene el movimiento lateral para una mejor seguridad de Docker.
¿Cómo lo configuras?
Puede especificar redes Docker en tiempo de ejecución o dentro de su configuración de Docker Compose. Sin embargo, primero debe crear la red:
docker network create your-isolated-networkEn tiempo de ejecución, añade el --network option: docker run --network your-isolated-network your-app:v1.0.1
O la opción equivalente en tu archivo Docker Compose:
servicios:
webapp:
image: your-app:v1.0.1
networks:
- your-isolated-network
...Establecer un usuario no-root adecuado
¿Qué obtiene?
El usuario por defecto dentro de un contenedor es root, con un uid de 0. Al especificar un usuario distinto, evita que un atacante escale sus privilegios a otro usuario que pueda actuar sin restricciones, como root, lo que anularía cualquier otra medida de seguridad de Docker que se haya esforzado en implementar.
¿Cómo lo configuras?
Crea tu usuario durante el proceso de compilación o en tiempo de ejecución. En tiempo de ejecución, puedes crear el usuario por primera vez o sobrescribir el USUARIO ya configuraste en la compilación.
Durante el proceso de compilación, en su Dockerfile:
...
RUN groupadd -r your-user
RUN useradd -r -g your-user your-user
USER myuser
...En tiempo de ejecución: docker run -u your-user your-app:v1.0.1
Eliminar capacidades del kernel de Linux
¿Qué obtiene?
Por defecto, a los contenedores Docker se les permite usar un conjunto restringido de capacidades del kernel de Linux. Podrías pensar que la gente de Docker creó ese conjunto restringido para ser completamente seguro, pero muchas capacidades existen por compatibilidad y simplicidad. Por ejemplo, los contenedores por defecto pueden cambiar arbitrariamente la propiedad de los archivos, cambiar su directorio raíz, manipular los UIDs de los procesos y leer sockets. Al eliminar algunas o todas estas capacidades, minimizas el número de vectores de ataque.
¿Cómo lo configuras?
Puedes eliminar capacidades y establecer nuevas en tiempo de ejecución. Por ejemplo, podrías eliminar todas las capacidades del kernel y permitir a tu contenedor solo la capacidad de cambiar la propiedad de los archivos existentes.
docker run --cap-drop ALL --cap-add CHOWN your-app:v1.0.1O para Docker Compose:
services:
webapp:
image: your-app:v1
cap_drop
- ALL
cap_add
- CHOWN
...Prevenir bombas fork
¿Qué obtiene?
Las bombas fork son un tipo de ataque DoS que replica infinitamente un proceso existente. En primer lugar, reducen el rendimiento y restringen los recursos, lo que inevitablemente eleva los costes y, en última instancia, puede provocar el fallo de sus contenedores o del sistema anfitrión. Una vez que una bomba fork ha comenzado, no hay forma de detenerla que no sea reiniciando el contenedor o el anfitrión.
¿Cómo lo configuras?
En tiempo de ejecución, puedes limitar el número de procesos (PIDs) que tu contenedor puede crear.
docker run --pids-limit 99 your-app:v1.0.1O con Docker Compose:
services:
webapp:
image: your-app:v1
deploy
limits
pids: 99Mejora la seguridad de Docker monitorizando tus dependencias de código abierto
¿Qué obtiene?
Las aplicaciones que has contenedorizado para su despliegue con Docker probablemente tienen un amplio árbol de dependencias.
¿Cómo lo configuras?
La forma más "sin tonterías" es con el análisis de dependencias de código abierto de Aikido. Nuestra monitorización continua analiza proyectos escritos en más de una docena de idiomas basándose en la presencia de archivos lockfile dentro de tu aplicación y ofrece una visión instantánea de vulnerabilidades y malware. Con un triaje automático que filtra los falsos positivos, Aikido te ofrece consejos de remediación con los que puedes empezar a trabajar de inmediato… y no solo después de leer una docena de otros documentos de referencia y problemas de GitHub.
En Aikido, nos encantan los proyectos de código abierto establecidos como Trivy, Syft y Grype. También sabemos por experiencia que usarlos de forma aislada no ofrece una experiencia de desarrollador particularmente buena. Internamente, Aikido mejora estos proyectos con reglas personalizadas para cubrir lagunas y revelar fallos de seguridad que de otro modo no podrías encontrar. A diferencia de encadenar varias herramientas de código abierto, Aikido te libera de tener que construir un script de escaneo o crear un trabajo personalizado en tu CI/CD.

Utiliza solo imágenes de confianza para la seguridad de Docker.
¿Qué obtiene?
Docker Content Trust (DCT) es un sistema para firmar y validar el contenido y la integridad de las imágenes oficiales que extrae de los registros de Docker como Docker Hub. Extraer solo imágenes firmadas por el autor le da más seguridad de que no han sido manipuladas para crear vulnerabilidades en su despliegue.
¿Cómo lo configuras?
La forma más sencilla es establecer la variable de entorno en su shell, lo que le impide a usted o a cualquier otra persona trabajar con imágenes no confiables.
export DOCKER_CONTENT_TRUST=1
docker run ...O bien, puedes establecer la variable de entorno cada vez que ejecutes Docker:
DOCKER_CONTENT_TRUST=1 docker run …Actualizar entornos de ejecución (EOL) al final de su vida útil
¿Qué obtiene?
Una recomendación común para la seguridad de contenedores Docker es fijar las imágenes y dependencias a una versión específica en lugar de latest. En teoría, eso evita que utilices imágenes nuevas sin saberlo, incluso aquellas que hayan sido manipuladas, y que puedan introducir nuevas vulnerabilidades.
¿Cómo lo configuras?
Tiene algunos proyectos de código abierto disponibles para ayudarle a descubrir los EOLs y prepararse de la mejor manera. El proyecto endoflife.date (repositorio de GitHub) rastrea más de 300 productos agregando datos de múltiples fuentes y poniéndolos a disposición a través de una API pública. Tiene varias opciones con endoflife.date y proyectos similares:
- Verifica manualmente el proyecto en busca de actualizaciones de las dependencias de las que dependen tus aplicaciones y crea tickets o incidencias para las actualizaciones requeridas.
- Escribe un script (Bash, Python, etc.) para obtener las fechas EOL de las dependencias de la API y ejecútalo regularmente, como un cron job.
- Incorpore la API pública, o ese script personalizado, en su plataforma de CI para que fallen las compilaciones que utilizan un proyecto que se acerca o ha alcanzado el fin de vida útil (EOL).
Como desarrolladores, entendemos que su tiempo es valioso y a menudo limitado. Aquí es donde Aikido puede proporcionar una sensación de seguridad: nuestra funcionalidad de escaneo de EOL rastrea su código y sus contenedores, priorizando los runtimes con mayor impacto y exposición, como Node.js o un servidor web Nginx. Como es habitual, no solo automatizamos la recopilación de información, sino que también entregamos alertas con la severidad adecuada para informarle, no para abrumarle.

Limitar el uso de recursos del contenedor
¿Qué obtiene?
Por defecto, los contenedores no tienen restricciones de recursos y utilizarán tanta memoria o CPU como el planificador del host. Limitar el uso de recursos de un contenedor específico puede minimizar el impacto de un ataque DoS. En lugar de que tu contenedor o sistema host se bloquee debido a una excepción de Out of Memory, el ataque DoS en curso “solo” afectará negativamente la experiencia del usuario final.
¿Cómo lo configuras?
En tiempo de ejecución, puedes usar el --memory y --cpus opción para establecer límites de uso de memoria y CPU, respectivamente. La opción de memoria acepta números con g para gigabytes y m para megabytes, mientras que la opción de CPU refleja el límite de CPUs dedicadas disponibles para el contenedor y sus procesos.
docker run --memory="1g" --cpus="2" your-app:v1.0.1Esto también funciona con Docker Compose:
services:
webapp:
image: your-app:v1.0.1
deploy:
limits:
cpus: '2'
memory: 1G
...Tu comando final y opciones de Compose para la seguridad de Docker
A estas alturas, ya habrá visto bastantes consejos de seguridad para Docker y las opciones de CLI o configuraciones relevantes que los acompañan, lo que significa que o bien está bastante entusiasmado por implementarlos o abrumado por cómo unirlos todos. A continuación, hemos recopilado todas las recomendaciones en una única plantilla de comando o configuración, lo que le ayudará a empezar a desplegar contenedores Docker más seguros de inmediato.
Obviamente, querrá cambiar algunas de las opciones —como el nombre de usuario no-root, las capacidades del kernel, los límites de recursos— según las necesidades de su aplicación.
export DOCKER_CONTENT_TRUST=1
docker run \
--read-only \
--security-opt=no-new-privileges \
--network your-isolated-network \
--cap-drop ALL
--cap-add CHOWN \
--pids-limit 99 \
--memory="1g" --cpus="2" \
--user=your-user \
... # OTRAS OPCIONES AQUÍ
your-app:v1.0.1Incluso podría querer crear un alias drun con el shell de su host que pueda invocar sin tener que recordar todos esos detalles.
function drun {
docker run \
--read-only \
--security-opt=no-new-privileges \
--network your-isolated-network \
--cap-drop ALL
--cap-add CHOWN \
--pids-limit 99 \
--memory="1g" --cpus="2" \
--user=your-user \
$1 \
$2
}Luego, ejecuta tu alias de esta manera, con tus opciones y el nombre de la imagen: drun -it your-app:v1.0.1
Si es de los que usa Docker Compose, puede adaptar todas las mismas opciones en una nueva plantilla base de Docker Compose a partir de la cual podrá trabajar en el futuro:
services:
webapp:
image: your-app:v1.0.1
read_only: true
security_opt:
- no-new-privileges:true
networks:
- your-isolated-network
cap_drop:
- ALL
cap_add:
- CHOWN
deploy:
limits:
pids: 9
cpus: '2'
memory: 1G
... # OTRAS OPCIONES AQUÍBonus: Ejecuta Docker con contenedores sin root
Cuando instalas Docker en cualquier sistema, su demonio opera con privilegios de nivel root. Incluso si habilitas todas las opciones anteriores y evitas la escalada de privilegios dentro de un contenedor Docker, el resto del tiempo de ejecución del contenedor en tu sistema anfitrión sigue teniendo privilegios de root. Esto, inevitablemente, amplía tu superficie de ataque.
La solución son los contenedores sin root, que un usuario sin privilegios puede crear y gestionar. No involucrar privilegios de root significa muchos menos problemas de seguridad para tu sistema anfitrión.
Nos gustaría poder ayudarte a usar contenedores sin root con una sola opción o comando, pero no es tan sencillo. Puedes encontrar instrucciones detalladas en el sitio web de Rootless Containers, incluyendo una guía práctica para Docker.
¿Qué sigue para la seguridad de tu Docker?
Si has aprendido algo de esta experiencia, es que la seguridad de contenedores es una operación de cola larga. Siempre hay más listas de verificación de endurecimiento y artículos de análisis profundo que leer sobre cómo asegurar tus contenedores en Docker o su primo más antiguo y a menudo incomprendido, Kubernetes. No puedes aspirar a una seguridad de contenedores impecable; dedicar tiempo en tu apretada agenda de desarrollo para abordar la seguridad y luego realizar mejoras incrementales basadas en el impacto y la gravedad, dará sus frutos a largo plazo.
Para ayudarte a maximizar ese proceso continuo y priorizar las correcciones que mejorarán significativamente la seguridad de tu aplicación, está Aikido. Acabamos de cerrar una ronda de financiación Serie A de 17 millones de dólares para nuestra plataforma de seguridad para desarrolladores "sin tonterías", y nos encantaría que te unieras a nosotros.
Protege tu software ahora.



.avif)
