Docker Focus Areas
Docker Engine
Component |
Description |
Do not run dockerd on any networked socket |
- If anyone can reach the networked socket that Docker is listening on, they potentially have access to Docker (which runs as root)
- The default docker behavior today is the safest assumption, which is to listen on a unix socket
- Example:
- Not recommended:
$ dockerd -H "tcp://1.2.3.4:8080" - Recommended:
$ dockerd -H "unix:///var/run/docker.sock"
|
Do not mount the Docker socket (/var/run/docker.sock) into containers |
- An attacker can execute any command that the docker service can run (gives access to the whole host system since dockerd runs as root)
- Example:
$ docker run -it -v /var/run/docker.sock:/var/run/docker.sock ubuntu /bin/bash
|
Monitor dangerous mountpoints |
- Do not mount:
/var/run/docker.sock , /proc , /dev - Set container FS to RO:
docker run --read-only <image> - Set volumes to RO:
docker run -v $(pwd):/secrets:ro
|
Harden Kernel
Component |
Description |
Set cgroups |
- Control groups (
cgroups ) are a feature of the Linux kernel that allow you to control how much resources a process can use - Can prevent DoS via system resource exhaustion
- Examples:
- CPU:
docker run -it --rm --cpuset-cpus 0 --cpu-shares 768 ... --cpu-shares defines a share between 0-768- if a container defines a share of 768, while another defines a share of 256
- the first container will have 50% share with the other having 25% of the available share total
- Memory:
docker run -it --rm --memory 128m ... - Storage:
docker -d --storage-opt dm.basesize=5G - Disk I/O:
--device-read-iops , --device-write-iops
|
Enforce MAC (Mandatory Access Control) |
- Enforce MAC to prevent undesired operations (both on host and on containers) at the kernel level (Seccomp, AppArmor, SELinux)
- MAC can confine processes to a limited set of system resources or privileges:
- Enable
- In container:
setenforce 1 - For dockerd:
--selinux-enabled
- Policies:
--security-opt="label:user:USER" --security-opt="label:role:ROLE" --security-opt="label:type:TYPE" --security-opt="label:level:LEVEL" --security-opt="apparmor:PROFILE"
- Example:
docker run --security-opt=label:level:s0:c100,c200 -i -t centos bash
|
Drop Capabilities |
- Capabilities turn the binary "root/non-root" dichotomy into a fine-grained access control system
- Drop capabilities that are not required (Docker - Capabilities)
- Default capabilities:
chown, dac_override, fowner kill, setgid, setuid, setpcap net_bind_service, net_raw sys_chroot, mknod, setfcap, audit_write
- When launching a container (
--cap-add=[] or --cap-drop=[] ):$ docker run --cap-add SYS_PTRACE ubuntu $ docker run --cap-drop setuid --cap-drop setgid <container_name> /bin/sh
- Do not use
--privileged - Allows the container to access all devices on the host
- Provides the container with a LSM (i.e SELinux or AppArmor) configuration that would give it the same level of access as processes running on the host
|
Enforce User Namespaces |
- Namespaces limit the maximum privileges of the containers over the host
- Allows the Docker daemon to run as an unprivileged user on the host but appear as running as root within containers
- Processes running within a container cannot see processes running in another container, or in the host system
- Each container also gets its own network stack: all containers on a given Docker host are sitting on bridge interfaces
- Do not run containers as root users:
- NO (runtime):
$ docker run -d ubuntu sleep infinity
$ ps aux | grep sleep
root ... sleep infinity - YES (runtime):
$ docker run -d -u 1000 ubuntu sleep infinity
$ ps aux | grep sleep
1000 ... sleep infinity - YES (BUILD):
FROM ubuntu:latest
USER 1000
|