// Introduction
Deploying Docker containers often brings a sense of ease, but it’s crucial to recognize that the default configurations are not always secure. Here’s a rundown of key security settings you should adjust before your containers hit production.
// Running as Root
By default, Docker containers run as the root user. This is a significant security risk, especially when a container is compromised, as the attacker gains root access to the host system.
Solution
Create a non-root user in your Dockerfile:
FROM ubuntu:latest
RUN useradd -m myuser
USER myuserThis ensures that your application runs with limited permissions.
// Unrestricted Network Access
Docker containers are launched with unrestricted network access by default. This can lead to unwanted exposure and potential attacks from malicious actors within the same network.
Solution
Use user-defined bridge networks to isolate your containers:
docker network create my_bridgeThen, run your containers on this network:
docker run --network my_bridge my_imageThis limits the containers' ability to communicate with the outside world unless explicitly allowed.
// Insecure Docker Socket
The Docker socket (/var/run/docker.sock) allows anyone with access to it to control Docker, potentially giving an attacker full control over the host. Exposing this socket in the container can lead to container escape.
Solution
Avoid mounting the Docker socket into your containers unless absolutely necessary. If you must, restrict access:
docker run -v /var/run/docker.sock:/var/run/docker.sock:ro my_imageThis mounts the socket as read-only.
// Resource Constraints
Containers can consume excessive resources if not limited, affecting other services running on the host. By default, there are no limits on memory or CPU usage.
Solution
Set resource limits in your docker run command:
docker run --memory=512m --cpus=1 my_imageThis command restricts the container to 512MB of memory and one CPU. Adjust these values based on your needs.
// Seccomp Profiles
Docker comes with a default seccomp profile that allows a large number of system calls. A more restrictive seccomp profile can prevent many common attacks.
Solution
Use a custom seccomp profile with your containers. Create a profile file, seccomp-profile.json:
{
"defaultAction": "SCMP_ACT_ALLOW",
"syscalls": [
{
"names": ["execve"],
"action": "SCMP_ACT_ERRNO"
}
]
}Then run your container with the seccomp flag:
docker run --security-opt seccomp=seccomp-profile.json my_image// Docker API Security
The Docker API is exposed over TCP by default and can be accessed unencrypted, leading to possible unauthorized access.
Solution
If you need to expose the Docker API, ensure it's secured with TLS and only accessible to trusted users. This can be done by creating certificates and configuring the Docker daemon accordingly:
Edit your /etc/docker/daemon.json:
{
"tls": true,
"tlscert": "/etc/docker/certs/server-cert.pem",
"tlskey": "/etc/docker/certs/server-key.pem",
"hosts": ["tcp://0.0.0.0:2376", "unix:///var/run/docker.sock"]
}And restart Docker:
sudo systemctl restart docker// Checklist for Docker Security Hardening
- [ ] Run containers as non-root users.
- [ ] Use user-defined networks.
- [ ] Avoid mounting the Docker socket into containers.
- [ ] Set resource limits on containers.
- [ ] Implement a restrictive seccomp profile.
- [ ] Secure the Docker API with TLS.
// Conclusion
Docker provides a powerful platform for containerization, but default settings often expose vulnerabilities. By adjusting these configurations, you significantly enhance the security of your deployments. Always remember to conduct these practices in a controlled environment you own, ideally with a disposable range for experimentation. For further learning and hands-on practices, DaemonCore Academy offers a comprehensive, free curriculum to help you improve your skills.