Securing Docker Containers

I made a guide on how to secure docker. I’ve split it up into 3 categories. Feedback is appreciated as this is more a compilation of other resources than anything else and I did not verify everything.

  • Steps to be taken in the host OS when interacting with Docker

  • Instructions specific to the build configuration file and the creation of containers

  • Security functionality that can integrate with Docker Enterprise specific features.

This guide was compiled from various other resources, many of which are linked below. It is not comprehensive, but it should cover all of the basics. What it does not cover can likely be found in the CIS benchmark linked at the end of this guide, as well as in the Docker documentation

Docker Security Benchmark
The script linked here ( is an automated script that checks for many common Docker best practices. The benchmark script should be considered a good heuristic test of your security, but not as a comprehensive analysis tool.

Host OS
It follows that a Docker container cannot be secured if the host OS is not secure. Therefore you must follow normal security best practices on the host OS, and it would be prudent to run some vulnerability scans against it in addition to implementing the following suggestions.

Audit Rules
Create and use audit rules for Docker-related files using auditctl. An example would be appending “-w /usr/bin/dockerd -k docker” to /etc/audit.rules and then restarting the audit service

Enabling FIPS mode forces cryptographic tools to implement their algorithms in a way that complies with federal and industry security standards and regulations. If your host OS supports FIPS Mode, you can enable it by doing the following:

sed -i 's/GRUB_CMDLINE_LINUX="/GRUB_CMDLINE_LINUX="fips=1 /g' /etc/default/grub
grub2-mkconfig -o /boot/grub2/grub.cfg && reboot

Also enable FIPS on the Docker Engine with the command below

mkdir -p /etc/systemd/system/docker.service.d 2>&1; echo -e "[Service]\n  Environment=\"DOCKER_FIPS=1\"" > /etc/systemd/system/docker.service.d/fips-module.conf; systemctl daemon-reload; systemctl restart docker

For further reading, see and

Docker Secrets
Sensitive data should be stored as Docker secrets with the Docker service create command. An
example is shown below:

docker service create --label com.docker.ucp.access.label=/prod --name nginx --publish 443 --secret,target=ca.pem nginx

The Docker Config File
The following settings can be added to the configuration file located at /etc/docker/daemon.json


This Disables inter-container communication to avoid unnecessary information leakage.

“log-level: “info” 

This Captures all non-debug logs

  "log-driver": "syslog",
  "log-opts": {
    "syslog-address": "udp://"

This enables remote logging, sends logs to listed address. Only works if syslog daemon is running. TCP and UDP are accepted as options. Can also be done on a container-by container basis as a parameter when running Docker (–log-opt syslog-address=ADRESS)

“userns-remap”: “Your_User”

This prevents privilege escalation attempts by isolating the namespace to a specific user

Transport Layer Security
Restrict connections to the Docker daemon (if remote access must be allowed) to users with access to the TLS client credentials.

Authorization Plugins
Determine which commands should be granted to which users, and create an authorization plugin for Docker accordingly. Then when you run the Docker daemon, add the plugin like so:

dockerd --authorization-plugin=PLUGIN_ID

To learn about creating authorization plugins, see this documentation:

Daemon Parameters
The Docker daemon runs with a set of default parameters


Enables daemonless containers to maximize available after system shutdown or reboot. This makes it easier to patch and update with minimal downtime


When hairpin NATs are available or in-use, the userland proxy becomes a redundant service that only increases your attack surface.


Stops containers from acquiring additional privileges via suid or sguid

--seccomp-profile /path/to/profile

If you have a custom seccomp profile you can apply it with this parameter. Learn more about Seccomp and Docker here

Container & Build File Configurations

User Creation
Ensure a user is created for your container, and run the container as that user (do NOT run a container as root).

Remote Access
Do not allow remote access to the daemon, and if you absolutely must do so anyway, secure that access with certificates.

Isolate The User Namespace
It’s especially important to ensure that the user namespace is isolated in Docker, as it’s shared with the host namespace by default. This can be abused in some cases to gain privilege escalation, or even escape the container. You can isolate the user namespace by editing the config file as mentioned in the above section “The Docker Config File”. This is mentioned redundantly here to emphasize the importance of doing so.

Healthcheck is a powerful tool you can use to verify the integrity of a container, and can be configured in your dockerfile. You should implement healthchecks to ensure your container is functioning properly. The example healthcheck below exits with a 0 if the server is up, and a 1 if it is down.

HEALTHCHECK CMD curl --fail http://localhost || exit 1

If SELinux is supported by your host OS, create or import a SELinux policy and start Docker in daemon mode with SELinux enabled.

docker daemon --selinux-enable

Then you can start Docker containers with your security options like so:

docker run --interactive --tty --security-opt label=level:TopSecret centos /bin/bash 

Network Interfaces
By default, Docker listens on every network interface. Since in most cases traffic is only expected on one interface, this increases the attack surface unduly. Therefore, when starting a
Docker container you can bind container ports to specific interfaces on the host as shown below

docker run --detach --publish nginx

Cached Image Versions
When you pull images, make sure the local cache matches what’s in the repository. Otherwise, you could end up extracting an outdated cached version of an image which contains vulnerabilities.

Network Bridge
The default network model, docker0, is vulnerable to ARP spoofing and MAC flooding. In order to resolve this, make a user-defined bridge network to your specifications as described here:

Docker Socket Warning
Never run the Docker socket inside a container. Doing so enables that container to execute Docker commands, and consequently communicate with and control the host OS. So don’t do that.

Enterprise Configurations

Docker Trust
Use the Docker trust tool to generate keys that can be used to verify the cryptographic integrity of your images. Docker trust keys can be used to sign Docker images with private keys, which can be verified with public keys on a Notary Server. More information at To focus on enabling Docker Trust in the Enterprise Engine, skip to this section

Vulnerability Scanning
Docker Enterprise has a built in vulnerability scanning feature, which includes the option to download a database of CVE’s to run offline vuln scans against Docker images. Scanning images on a regular basis will help make them more secure by alerting you to vulnerabilities they possess. Learn more on how to do this here:

LDAP Integration With UCP
The Universal Control Plane can integrate with LDAP for a streamlined authentication system that avoids unnecessary redundancy. Read more about this process here:

Further Reading
For further reading on Docker security best practices, in addition to the resource linked throughout this guide, please also see the Center for Internet Security benchmarks for Docker that can be downloaded here: