Despliegue Seguro con Docker Compose + Ubuntu
En las startups del Silicon Valley, Docker Compose es una de las herramientas preferidas para desplegar y gestionar rápidamente aplicaciones contenerizadas. Sin embargo, la comodidad a menudo viene acompañada de riesgos de seguridad. Como Ingeniero de Fiabilidad del Sitio (SRE), soy plenamente consciente de que las vulnerabilidades de seguridad pueden provocar consecuencias catastróficas. Este artículo compartirá las mejores prácticas de seguridad que he resumido en mi trabajo real combinando Docker Compose con sistemas Ubuntu, ayudándote a disfrutar de la comodidad de Docker Compose mientras garantizas la seguridad del sistema.
I. Reforzando la Seguridad del Sistema Ubuntu
Antes de desplegar contenedores, es crucial asegurar la seguridad del host Ubuntu en sí. Aquí hay algunos pasos clave:
1. Actualizar Ubuntu y Docker regularmente
Asegúrate de que tanto el sistema como Docker estén actualizados para corregir vulnerabilidades conocidas:
sudo apt update && sudo apt upgrade -y
sudo apt install docker-ce docker-compose-plugin
2. Restringir los permisos de gestión de Docker
Controla estrictamente los permisos de gestión de Docker para prevenir ataques de escalada de privilegios:
sudo usermod -aG docker deployuser
# Prevent regular users from easily obtaining docker management permissions
3. Configurar el firewall de Ubuntu (UFW)
Restringe razonablemente el acceso a la red para prevenir accesos no autorizados:
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
sudo ufw status verbose
4. Configurar correctamente la interacción entre Docker y UFW
Por defecto, Docker elude UFW para configurar iptables, por lo que se recomienda un control manual:
Modificar el archivo de configuración de Docker:
sudo nano /etc/docker/daemon.json
Agregar el siguiente contenido:
{
"iptables": false,
"ip-forward": true,
"userland-proxy": false
}
Reiniciar el servicio Docker:
sudo systemctl restart docker
Vincula explícitamente direcciones en Docker Compose:
services:
webapp:
ports:
- "127.0.0.1:8080:8080"
II. Mejores Prácticas de Seguridad en Docker Compose
Las siguientes configuraciones se aplican a Docker Compose v2.4 y superiores. Observa las diferencias entre los modos no Swarm y Swarm.
1. Restringir los permisos de los contenedores
Los contenedores que se ejecutan como root por defecto representan altos riesgos; cámbialos a usuarios no root:
services:
app:
image: your-app:v1.2.3
user: "1000:1000" # Non-root user
read_only: true # Read-only filesystem
volumes:
- /tmp/app:/tmp # Mount specific directories if write access is needed
cap_drop:
- ALL
cap_add:
- NET_BIND_SERVICE
- Un sistema de archivos de solo lectura evita la manipulación dentro del contenedor.
- Asegúrate de que los volúmenes montados estén limitados a los directorios necesarios.
2. Aislamiento de red y gestión de puertos
Divide de manera precisa las redes internas y externas para evitar exponer servicios sensibles al público:
networks:
frontend:
internal: false
backend:
internal: true
services:
nginx:
networks: [frontend, backend]
database:
networks:
- backend
- Red frontal: Puede estar abierta al público.
- Red trasera: Estrictamente restringida, solo comunicación interna.
3. Gestión segura de secretos
Los datos sensibles nunca deben colocarse directamente en los archivos Compose:
En modo de máquina única:
services:
webapp:
environment:
- DB_PASSWORD_FILE=/run/secrets/db_password
volumes:
- ./secrets/db_password.txt:/run/secrets/db_password:ro
En modo Swarm:
services:
webapp:
secrets:
- db_password
environment:
DB_PASSWORD_FILE: /run/secrets/db_password
secrets:
db_password:
external: true # Managed through Swarm's built-in management
- Los secretos nativos de Swarm de Docker no pueden usar directamente herramientas externas como Vault o AWS Secrets Manager.
- Si se necesita almacenamiento externo de secretos, integra tú mismo el proceso de lectura.
4. Limitación de recursos (adaptar a la versión de Docker Compose)
Los límites de recursos de los contenedores evitan que un solo contenedor agote los recursos del host.
Docker Compose modo de máquina única (v2.4 recomendado):
version: "2.4"
services:
api:
image: your-image:1.4.0
mem_limit: 512m
cpus: 0.5
Docker Compose modo Swarm (v3 y superior):
services:
api:
deploy:
resources:
limits:
cpus: "0.5"
memory: 512M
reservations:
cpus: "0.25"
memory: 256M
Nota: En entornos no Swarm, los límites de recursos de la sección
deployno tienen efecto, asegúrate de prestar atención a la versión del archivo Compose.
5. Comprobaciones de salud de los contenedores
Configura comprobaciones de salud para detectar proactivamente problemas y reducir el tiempo de inactividad del servicio:
services:
webapp:
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 20s
6. Evitar usar la etiqueta latest
Evita la incertidumbre que trae la etiqueta latest en entornos de producción, impón versiones específicas de imágenes:
services:
api:
image: your-image:1.4.0