Common Misconfiguration
Running containers withprivileged: true grants them nearly all capabilities of the host, effectively breaking container isolation. This allows containers to access host devices, mount filesystems, and potentially compromise the entire system.
Vulnerable Example
Copy
# Vulnerable docker-compose.yml
version: '3.8'
services:
monitoring:
image: monitoring-agent:latest
privileged: true # DANGEROUS - full host access
network_mode: host # Also problematic
pid: host # Access to host processes
volumes:
- /:/host # Mounting entire host filesystem
- /var/run/docker.sock:/var/run/docker.sock
network-tools:
image: network-scanner:latest
privileged: true # Unnecessary for most network operations
cap_add:
- ALL # Adding all capabilities
backup-service:
image: backup:latest
privileged: true
volumes:
- /:/backup-source # Full system access
user: root
Secure Example
Copy
# Secure docker-compose.yml with minimal capabilities
version: '3.8'
services:
monitoring:
image: monitoring-agent:latest
# Use specific capabilities instead of privileged mode
cap_add:
- SYS_PTRACE # Only for process monitoring
- SYS_ADMIN # Only if absolutely necessary
cap_drop:
- ALL # Drop all other capabilities
security_opt:
- no-new-privileges:true
- apparmor:docker-default
- seccomp:default
volumes:
# Mount only necessary paths with read-only where possible
- /proc:/host/proc:ro
- /sys:/host/sys:ro
- monitoring_data:/var/lib/monitoring
read_only: true # Make root filesystem read-only
tmpfs:
- /tmp
- /var/run
user: "1000:1000" # Run as non-root
network-tools:
image: network-scanner:latest
# Only add required network capabilities
cap_add:
- NET_RAW # For packet capture
- NET_ADMIN # For network configuration
cap_drop:
- ALL
security_opt:
- no-new-privileges:true
networks:
- monitoring_net
user: "1001:1001"
backup-service:
image: backup:latest
cap_drop:
- ALL
cap_add:
- DAC_READ_SEARCH # For reading files with different ownership
security_opt:
- no-new-privileges:true
volumes:
# Mount only specific directories needed for backup
- /data/app:/backup-source/app:ro
- /data/database:/backup-source/database:ro
- backup_storage:/backups
user: "1002:1002"
read_only: true
tmpfs:
- /tmp
volumes:
monitoring_data:
driver: local
backup_storage:
driver: local
driver_opts:
type: none
o: bind
device: /secure/backups
networks:
monitoring_net:
driver: bridge
ipam:
config:
- subnet: 172.28.0.0/24
Capability Reference
Copy
# Common capabilities and their secure alternatives
version: '3.8'
services:
# Example: Container needing to bind to privileged ports
web-server:
image: nginx:alpine
cap_drop:
- ALL
cap_add:
- NET_BIND_SERVICE # Bind to ports < 1024
- CHOWN # Change file ownership
- SETUID # Switch user context
- SETGID # Switch group context
ports:
- "80:80"
- "443:443"
# Example: Container needing to modify network settings
vpn-client:
image: vpn-client:latest
cap_drop:
- ALL
cap_add:
- NET_ADMIN # Network administration
- NET_RAW # Raw socket access
devices:
- /dev/net/tun # Only specific device access
sysctls:
- net.ipv4.ip_forward=1
- net.ipv6.conf.all.disable_ipv6=0
# Example: Container needing to monitor system
system-monitor:
image: prometheus-node-exporter:latest
cap_drop:
- ALL
cap_add:
- SYS_PTRACE # Process tracing
pid: host # Only if absolutely necessary
security_opt:
- no-new-privileges:true
volumes:
- /proc:/host/proc:ro
- /sys:/host/sys:ro
command:
- '--path.procfs=/host/proc'
- '--path.sysfs=/host/sys'
- '--collector.filesystem.ignored-mount-points=^/(dev|proc|sys|var/lib/docker/.+)($|/)'
Security Policy Example
Copy
# AppArmor profile for additional security
# Save as: /etc/apparmor.d/docker-custom
profile docker-custom flags=(attach_disconnected,mediate_deleted) {
# Include base abstraction
include <abstractions/base>
# Deny all file writes by default
deny /** w,
# Allow specific read access
/etc/ld.so.cache r,
/lib/** r,
/usr/lib/** r,
/proc/sys/kernel/random/uuid r,
# Allow writing to specific directories
/var/log/app/** w,
/tmp/** rw,
# Network access
network inet tcp,
network inet udp,
# Deny capability usage
deny capability,
}

