// Engineering Log
Desarrollo seguro: Parte 6 — Seguridad de contenedores
Publicado el 22.09.2026
// Ruta rapida
Este articulo pertenece al tema Seguridad y proteccion.
El contenedor aísla la aplicación del host, pero el aislamiento no es absoluto: todos los contenedores usan un mismo kernel. Una vulnerabilidad en la imagen, un proceso con privilegios root o privilegios excesivos convierten un fallo en la aplicación en un problema para todo el servidor. Esta parte trata sobre qué hacer con una imagen ya construida y cómo ejecutarla. La correcta construcción del Dockerfile (caché, build multi-etapa, fijación por digest) se analiza en la parte 5, la verificación de dependencias — en la parte 4.
De dónde vienen los riesgos
La imagen consiste en capas: la imagen base con los paquetes de la distribución, las dependencias de la aplicación, el propio código. Las vulnerabilidades suelen venir no de su código, sino de la imagen base: un python:3.13 completo o node:22 contiene compilador, gestor de paquetes, shell y cientos de librerías que la aplicación en ejecución no necesita. Cada una de ellas es una potencial vulnerabilidad y una herramienta lista para un atacante si llega dentro del contenedor.
El segundo grupo de riesgos son los parámetros de ejecución: proceso como root, escritura en cualquier parte del sistema de archivos, el conjunto completo de capacidades del kernel (capabilities), ausencia de límites de memoria y número de procesos.
Imagen base mínima
Cuanto menos haya en la imagen, menor será la superficie de ataque y menos hallazgos tendrá el escáner.
-slim(python:3.13-slim,node:22-slim) — Debian sin herramientas de compilación ni documentación. Opción razonable por defecto: se mantiene la compatibilidad con glibc y el tamaño es notablemente menor que la imagen completa.- Alpine — imagen muy pequeña sobre musl libc. Adecuada para programas compilados estáticamente; para Python y Node.js con módulos nativos pueden surgir problemas de compatibilidad y tiempo de compilación más largo.
- Distroless de Google — en la imagen solo está el runtime, sin shell ni gestor de paquetes. Las imágenes actuales están basadas en Debian 13:
gcr.io/distroless/static-debian13para binarios estáticos (Go, Rust),gcr.io/distroless/python3-debian13,gcr.io/distroless/nodejs22-debian13y otras. La mayoría tiene la etiqueta:nonroot— el proceso se ejecuta directamente no como root, y la etiqueta:debugincluye un shell busybox para depuración.
No use versiones sin soporte: Python 3.9 y Node.js 18 ya no reciben correcciones de seguridad. Para imágenes nuevas — Python 3.12 o 3.13, Node.js 22 o 24.
La ausencia de shell en una imagen distroless es a la vez protección e inconveniente: docker exec -it … sh no funcionará. Para analizar problemas use la variante :debug en un entorno de pruebas o un contenedor de depuración separado, en lugar de añadir un shell a la imagen de producción.
Ejecutar sin root
Por defecto el proceso en el contenedor corre como root. Si un atacante supera la aplicación, tendrá privilegios máximos dentro del contenedor y, ante una vulnerabilidad en el runtime, la posibilidad de obtener root en el host.
En el Dockerfile cree un usuario y cámbiese a él:
FROM python:3.13-slim
RUN useradd --system --uid 10001 --no-create-home app
WORKDIR /app
COPY --chown=app:app . .
USER app
CMD ["python", "main.py"]Para distroless es suficiente con la etiqueta :nonroot. También se puede especificar el usuario al ejecutar: docker run --user 10001:10001 …. Una aplicación sin root no puede escuchar puertos por debajo de 1024 — use el puerto 8080 y publíquelo según corresponda.
Restricciones al ejecutar
Los parámetros de docker run (en Compose — las claves homónimas del servicio) cierran la mayor parte de las vías típicas de escalada de privilegios:
docker run -d --name app \
--read-only --tmpfs /tmp \
--cap-drop=ALL \
--security-opt no-new-privileges \
--memory 512m --cpus 1 --pids-limit 200 \
--user 10001:10001 \
registry.example.ru/app@sha256:...--read-onlymonta el sistema de archivos raíz en solo lectura: el atacante no podrá sustituir archivos de la aplicación ni escribir herramientas. Los directorios donde la aplicación realmente escribe se montan por separado:--tmpfs /tmpo un volumen para datos.--cap-drop=ALLelimina todas las capacidades del kernel. Si la aplicación necesita algo — por ejemplo,NET_BIND_SERVICEpara el puerto 80 — añada exactamente eso mediante--cap-add.--security-opt no-new-privilegesimpide que los procesos obtengan nuevos privilegios, incluido porsu,sudoy archivos con el bit setuid.--memory,--cpus,--pids-limitlimitan recursos: una fuga de memoria o una fork-bomb en un contenedor no tumbará todo el servidor.
Nunca ejecute contenedores de producción con --privileged ni monte dentro de ellos el socket de Docker (/var/run/docker.sock): el acceso al socket equivale a privilegios root en el host.
Seccomp y modo rootless
Seccomp filtra llamadas al sistema. El perfil por defecto de Docker funciona como una lista de llamadas permitidas y bloquea alrededor de 44 de más de 300 — las que se usan para ataques al kernel y que casi no necesitan las aplicaciones comunes. La documentación de Docker no recomienda cambiarlo; lo principal es no desactivarlo con la opción --security-opt seccomp=unconfined, que a veces se sugiere en instrucciones «para que funcione».
El modo rootless ejecuta no solo los contenedores, sino también el propio demonio Docker como un usuario normal. Incluso al escapar del contenedor, el atacante obtiene los privilegios de ese usuario, no de root. Para la instalación se requieren las utilidades newuidmap y newgidmap (paquete uidmap) y al menos 65 536 identificadores subordinados en /etc/subuid y /etc/subgid; luego, como usuario, se ejecuta dockerd-rootless-setuptool.sh install. El modo rootless restringe algunas capacidades (red, puertos privilegiados), por lo que vale la pena probarlo en su stack antes de migrar.
Escaneo de imágenes
La imagen construida debe verificarse en busca de vulnerabilidades conocidas antes del despliegue y de forma periódica después: se descubren nuevos CVE en paquetes ya publicados. El mismo Trivy que verifica dependencias (ver parte 4) también escanea la imagen entera:
trivy image --severity HIGH,CRITICAL --exit-code 1 registry.example.ru/app:1.4.2Con --exit-code 1 el escaneo hace fallar el pipeline cuando hay hallazgos de alto nivel. Los resultados del escaneo suelen ser un orden de magnitud menores en imágenes -slim o distroless que en la imagen completa: es la forma más barata de reducir la lista de vulnerabilidades.
Firma y verificación de imágenes
La firma garantiza que al servidor llega la imagen que construyó su CI y no una sustituida en el registro. La herramienta estándar es cosign del proyecto Sigstore:
cosign generate-key-pair
cosign sign --key cosign.key registry.example.ru/app@sha256:...
cosign verify --key cosign.pub registry.example.ru/app@sha256:...Se debe firmar y verificar por digest, no por etiqueta: la etiqueta puede apuntar a otra imagen. Cosign también soporta un modo sin claves propias, con confirmación vía un proveedor OIDC. La verificación de la firma tiene sentido solo si está integrada en el despliegue: el script de despliegue o el controlador en Kubernetes rechaza ejecutar una imagen no firmada.
Lista de comprobación
- Imagen base
-slimo distroless, versión del runtime con soporte, fijación por digest. USERno root; puerto de la aplicación por encima de 1024.- Ejecución con
--read-only,--cap-drop=ALL,no-new-privileges, límites de memoria, CPU y procesos. - Nada de
--privileged, socket de Docker dentro del contenedor niseccomp=unconfined. - Escaneo de la imagen en CI y regularmente para imágenes ya desplegadas.
- Firma de la imagen en CI y verificación de la firma en el despliegue.
- Donde sea posible — modo rootless de Docker.
Errores típicos
- «El contenedor es una sandbox». Todos los contenedores comparten el kernel del host; el aislamiento depende de los permisos y límites que usted haya configurado.
- Root por defecto. El hallazgo más común en auditorías —y el más fácil de corregir.
- Seccomp desactivado o
--privilegedusado para depuración, y que queda en la configuración de producción. - Escaneo solo en la compilación. Una imagen construida hace seis meses puede haber acumulado decenas de nuevos CVE.
- Etiqueta
latesten producción. No queda claro qué se está ejecutando y no se puede verificar la firma.
// Tarea parecida
Si estas resolviendo algo parecido
Este articulo pertenece a uno de los temas principales de trabajo. Puedes seguir leyendo sobre el tema, ir a la pagina principal para entender a que me dedico o abrir directamente los servicios.
Tema del articulo
Seguridad y proteccion
SSL, hardening, accesos, proteccion de servicios y configuraciones seguras.
Tareas frecuentes de esta tema
- Configurar SSL, certificados y conexiones seguras
- Restringir accesos y cerrar puntos de entrada innecesarios
- Reforzar la configuracion del servidor y los servicios
// Siguiente paso
Si necesitas ayuda con este tema y no solo otro articulo, es mejor ir directo a la pagina del servicio. La pagina principal y la seleccion de materiales quedan como rutas secundarias.
Abrir servicios// Reviews
Reseñas relacionadas
La experiencia de colaboración dejó una impresión sumamente positiva, principalmente por el profesionalismo y el enfoque para resolver los problemas que surgieron.
La experiencia de colaboración dejó una impresión sumamente positiva, principalmente por el profesionalismo y el enfoque para resolver los problemas que surgieron.
Jitsi Meet: Zoom personal, configuración de Jitsi Meet en Docker y en VPS
11.11.2025 · ★ 5/5
Había que hacer funcionar n8n, Redis y la base de datos. Lo había encargado antes a otro proveedor; todo se rompía constantemente. Se lo encargué a Mijaíl y al día siguiente todo funcionó rápido, ¡como un reloj!
Había que poner en marcha n8n, redis y la base de datos. Contraté antes a otro proveedor, y todo se rompía constantemente. Lo encargué a Mikhail, y al día siguiente ¡todo empezó a funcionar rápido, como un reloj!
Instalación de n8n en su servidor VPS. Configuración de n8n, Docker, IA, Telegram
24.09.2025 · ★ 5/5
Gracias por el trabajo rápido y bien hecho. Todo se hizo de manera ágil y como debía ser!
Gracias por el trabajo rápido y bien hecho. Todo se hizo con prontitud y tal como se necesitaba!
Instalación de n8n en su servidor VPS. Configuración de n8n, Docker, IA, Telegram
06.09.2025 · ★ 5/5
Solución rápida al problema, ¡recomiendo a Mijaíl como profesional a todo el mundo! Intenté montar una configuración similar por mi cuenta y siguiendo consejos de IA, y acabé gastando mucho tiempo y dinero (por el tiempo de inactividad del servidor). Así que mi consejo final: acudan a profesionales, sale más barato =) Gracias a Mijaíl por su profesionalidad.
Solución rápida al problema, ¡recomiendo a Mikhail como profesional! Intenté montar una configuración similar por mi cuenta y siguiendo consejos de redes neuronales, y acabó siendo una pérdida de mucho esfuerzo y dinero …
Instalación de n8n en su servidor VPS. Configuración de n8n, Docker, IA, Telegram
25.08.2025 · ★ 5/5
Mijaíl configuró otro VPS. Rápida y profesionalmente sorteó ciertas limitaciones de los proveedores de hosting.
Mijaíl completó la configuración de otro VPS. De forma rápida y profesional, sorteando ciertas limitaciones impuestas por los proveedores de hosting.
Instalación de N8n en su servidor VPS. Configuración de n8n, Docker, IA, Telegram
12.08.2025 · ★ 5/5
¡Excelente trabajo, gracias! ¡Mijaíl es un profesional, lo recomiendo!
¡Excelente trabajo, gracias! Mikhail es un profesional en lo suyo, ¡lo recomiendo!
Instalación de n8n en su servidor VPS. Configuración de n8n, Docker, IA, Telegram
03.07.2025 · ★ 5/5
// Contact
¿Necesitas ayuda?
Escríbeme y te ayudaré a resolver el problema
Respondo en un día laborable (03:00-13:00 GMT)
Или оставьте заявку здесь:
// Related