Docker Bench for Security for Docker Daemon

Maciej
3 min readMay 11, 2021
Photo by chris panas on Unsplash

Introduction

In continuation to the previous post about Docker Bench for Security, this time we are handle secure the Daemon Docker.

Result of Docker Bench for Security

Let’s start

🚨 2.1 — Ensure network traffic is restricted between containers on the default bridge

  • Edit file /lib/systemd/system/docker.service
  • Change ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock to ExecStart=/usr/bin/dockerd -H fd:// -containerd=/run/containerd/containerd.sock --config-file=/etc/docker/daemon.json
  • Create file /etc/docker/daemon.json with below content
root@vagrant:/home/vagrant# cat /etc/docker/daemon.json
{
"icc": false
}
  • Reload daemon and restart docker service
root@vagrant:/home/vagrant# systemctl daemon-reload
root@vagrant:/home/vagrant# systemctl restart docker

⚠️ Keep in mind that this requires an option to connect the containers to the network

🚨 2.5 — Ensure aufs storage driver is not used

  • Check if aufs storage is not used
root@vagrant:/home/vagrant# sudo docker info | grep Storage
WARNING: No swap limit support
Storage Driver: aufs
  • Update file /etc/docker/daemon.json
root@vagrant:/home/vagrant# cat /etc/docker/daemon.json
{
"icc": false,
"storage-driver": "overlay2"
}
  • Restart docker service
root@vagrant:/home/vagrant# systemctl restart docker

🚨 2.7 — Ensure the default ulimit is configured appropriately

Describe the ulimit parameter here in daemon.json.

  • Update file /etc/docker/daemon.json
root@vagrant:/home/vagrant# cat /etc/docker/daemon.json
{
"icc": false,
"storage-driver": "overlay2",
"default-ulimit": true
}
  • Restart docker service
root@vagrant:/home/vagrant# systemctl restart docker

🚨 2.8 — Enable user namespace support

It is already enabled by default in recent versions, but it is explicitly enabled, to be sure, let’s add an appropriate entry to the daemon.json file.

  • Update file /etc/docker/daemon.json
root@vagrant:/home/vagrant# cat /etc/docker/daemon.json
{
"icc": false,
"storage-driver": "overlay2",
"default-ulimit": true,
"userns-remap": "default"
}
  • Restart docker service
root@vagrant:/home/vagrant# systemctl restart docker

🚨 2.12 — Ensure centralized and remote logging is configured

We should make sure to aggregate the logs output by the container somewhere. In this case we we will use the simplest way to aggregate logs like rsyslog.

  • Update the rsyslogd setting like below
  • Update file /etc/docker/daemon.json
root@vagrant:/home/vagrant# cat /etc/docker/daemon.json
{
"icc": false,
"storage-driver": "overlay2",
"default-ulimit": true,
"userns-remap": "default",
"log-driver": "syslog",
"log-opts": {
"syslog-address": "tcp://127.0.0.1:514"
}

}
  • Restart docker service
root@vagrant:/home/vagrant# systemctl restart docker

🚨 2.13 — Ensure live restore is Enabled

This settings prevents the container from stopping when the docker daemon is stopped. More info we can find in official documentation

  • Update file /etc/docker/daemon.json
root@vagrant:/home/vagrant# cat /etc/docker/daemon.json
{
"icc": false,
"storage-driver": "overlay2",
"default-ulimit": "true",
"userns-remap": "default",
"log-driver": "syslog",
"log-opts": {
"syslog-address": "tcp://127.0.0.1:514"
},
"live-restore": true
}
  • Restart docker service
root@vagrant:/home/vagrant# systemctl restart docker

🚨 2.14 — Ensure Userland Proxy is Disabled

When assigning a container port on the host, by enabling hairpin NAT, communication is performed using iptables rules instead of a user space proxy using a loopback address.

  • Update file /etc/docker/daemon.json
root@vagrant:/home/vagrant# cat /etc/docker/daemon.json
{
"icc": false,
"storage-driver": "overlay2",
"default-ulimit": true,
"userns-remap": "default"
"log-driver": "syslog",
"log-opts": {
"syslog-address": "tcp://127.0.0.1:514"
},
"live-restore": true,
"userland-proxy": false
}
  • Restart docker service
root@vagrant:/home/vagrant# systemctl restart docker

🚨 2.17 — Ensure containers are restricted from acquiring new privileges

Prevents you from adding privileges to the container process. If we check the material in the docker documentation , it seems to guarantee that the process we forked or cloned from the parent process cannot grant new privileges .

  • Update file /etc/docker/daemon.json
root@vagrant:/home/vagrant# cat /etc/docker/daemon.json
{
"icc": false,
"storage-driver": "overlay2",
"default-ulimit": true,
"userns-remap": "default"
"log-driver": "syslog",
"log-opts": {
"syslog-address": "tcp://127.0.0.1:514"
},
"live-restore": true,
"userland-proxy": false,
"no-new-privileges": true
}
  • Restart docker service
root@vagrant:/home/vagrant# systemctl restart docker

Full /etc/docker/daemon.json file:

Conclusion

We have described how to realize a more secure container execution environment by setting the docker daemon . I think that the settings we have introduced here can significantly affect the actual usability of the docker, and will certainly improve the security of our containerization system.

Source: https://giphy.com

--

--

Maciej

DevOps Consultant. I’m strongly focused on automation, security, and reliability.