All the standard security practices still apply You're only as secure as your weakest link. • Attack vectors (anything involved in your SDLC) • Who are you protecting against?
Official images != secure Over 30% of Official Images in Docker Hub Contain High Priority Security Vulnerabilities (https://banyanops.com/blog/analyzing-docker-hub/)
/sbin/nologin -u 10000 -D passenger USER passenger Even in images from scratch: FROM scratch COPY testRoot_linux_amd64 / USER 123 ENTRYPOINT ["/testRoot_linux_amd64"]
--selinux-enabled • /etc/selinux/targeted/contexts/lxc_contexts --security-opt="label=user:USER" : Set the label user for the container --security-opt="label=role:ROLE" : Set the label role for the container --security-opt="label=type:TYPE" : Set the label type for the container --security-opt="label=level:LEVEL" : Set the label level for the container --security-opt="label=disable" : Turn off label confinement for the container
capabilities to the container (cca. 38 currently) • also lifts all the limitations enforced by the device cgroup controller --cap-add: Add Linux capabilities --cap-drop: Drop Linux capabilities --privileged=false: Give extended privileges to this container --device=[]: Allows you to run devices inside the container without the --privileged flag.
7 2014 /bin/ping $ docker run -it --rm test -u nobody ping google.com PING google.com (216.58.206.110): 56 data bytes 64 bytes from 216.58.206.110: seq=0 ttl=37 time=4.147 ms 64 bytes from 216.58.206.110: seq=1 ttl=37 time=6.385 ms $ docker run -it --rm --cap-drop ALL test ping google.com PING google.com (216.58.206.110): 56 data bytes ping: permission denied (are you root?)
and Kernel enabled • By default disables around 44 system calls out of 300+ $ docker run --rm -it \ --security-opt seccomp=/path/to/seccomp/profile.json \ hello-world
relative, by default 1024 • --cpus=2 - number of CPUs to limit container to • Memory • -m, --memory="300M" - memory limit for process • IO • r/w iops/bps per device or relative
mhart/alpine-node:latest Error: remote trust data does not exist for docker.io/mhart/alpine-node: notary.docker.io does not have trust data for docker.io/mhart/alpine-node $ DOCKER_CONTENT_TRUST=1 docker pull alpine:3.6 Pull (1 of 1): alpine:3.6@sha256:d6bfc3baf615dc9618209a8d607ba2a8103d9c8a405b3bd8741d88b4bef36478 sha256:d6bfc3baf615dc9618209a8d607ba2a8103d9c8a405b3bd8741d88b4bef36478: Pulling from library/alpine Digest: sha256:d6bfc3baf615dc9618209a8d607ba2a8103d9c8a405b3bd8741d88b4bef36478 Status: Image is up to date for alpine@sha256:d6bfc3baf615dc9618209a8d607ba2a8103d9c8a405b3bd8741d88b4bef36478 Tagging alpine@sha256:d6bfc3baf615dc9618209a8d607ba2a8103d9c8a405b3bd8741d88b4bef36478 as alpine:3.6
For example: • A shell is run inside a container container.id != host and proc.name = bash • Non-authorized container namespace change syscall.type = setns and not proc.name in (docker, sysdig)