Image

Docker Security Best Practices

  • Published On: September 01, 2022 Updated On: February 17, 2023

Docker is a software platform that enables the development and deployment of containerized applications and services.It is a Platform as a Service (PaaS) that uses the host OS Kernel instead of hypervisors like VirtualBox.

Docker containers contain all of the dependencies and libraries needed to run an application.As a result, containers eliminate the need to install dependencies manually.

Introduction to Docker security

When running applications in a virtual environment, security is a major issue.As a result, securing Docker containers is critical.It is necessary to secure everything from the host to the network.

Docker Vs Virtual Machine

Docker containers provide your systems with a more secure environment than traditional virtual machines.They enable the division of applications into smaller components.The components are isolated from one another, which aids in the reduction of attacks.Hackers are prevented from exploiting computer systems, making security breaches and attacks more difficult.

It is critical to understand and apply the best practises for protecting containerized applications.The following are some critical tips for securing applications hosted on a container platform.

Best Practices To Be Followed In Docker

image

1. Update the host and Docker daemon frequently

Containers and the host system share the kernel.Any kernel exploits run within the container will have a direct impact on the host kernel.When the Dirty Cow kernel privilege escalation exploit is run within the container, it grants root access to the host.As a result, it is critical to keep the host and Docker engine fully updated.

2. Do not expose the Docker daemon socket

All communications between the Docker client and the Docker daemon take place over the Docker daemon socket, which is a UNIX socket that is typically located at /var/run/docker.sock.

This gives you access to the Docker API.This socket's access is restricted using standard UNIX file permissions.In the default configuration, the socket is owned by the root user.Anyone who gains access to the socket will gain root access to the host.

  • Only the root user and the docker group should have access to the Docker daemon socket.
  • To secure the Docker daemon socket, use SSH.
  • To secure the Docker daemon socket, use TLS (HTTPS).This enables Docker to be safely accessed via HTTP.
  • Unless you're using Docker's encrypted HTTPS socket, which supports authentication, don't make the daemon socket available for remote connections.
  • Docker images should not be run with the option -v /var/run/docker.sock:/var/run/docker.sock, which exposes the socket in the resulting container.Remember that making the socket read-only is not a solution; it simply makes it more difficult to compromise.

In the docker compose file, below is an example how to check if socket are exposed and also to check if you already have a container which is running in such a configuration:

image

3. Run Docker in rootless Mode

It is able to run the Docker daemon as a non-root user, which eliminates potential Docker vulnerabilities.This is known as the "Rootless mode."

While installing Docker or communicating with the Docker API, rootless mode does not require root privileges.

image

The Docker daemon and containers are run within a user namespace and without root privileges by default in rootless mode.

  1. Install uidmap package with sudo privileges:
    apt-get install -y uidmap
  2. Fetch the installation script from Docker’s website and run it:
    curl -fSsL https://get.docker.com/rootless | sh

4. Container Resource Configuration

Control Groups or cgroups is a Linux kernel feature that plays a key role in implementing resource allocation and limiting for containers. Their job is to not only make sure that each container gets its fair share of resources like memory and CPU, but also see to it that a single container cannot bring the system down by exhausting one of these resources.

Limiting resources prevents Denial-of-Service attacks. Following are some CLI flags you can use to limit resources for a container:

  • --memory= — maximum amount of memory
  • --restart=on-failure: — number of restarts
  • --memory-swap — amount of swap memory
  • --cpus= — maximum CPU resources available to a container
  • --ulimit nofile= — maximum number of file descriptors
  • --ulimit nproc= — maximum number of processes

By default, Docker allows the container to use as much RAM and CPU resources that are allowed by the host’s kernel. Therefore it is necessary to set resource constraints to prevent security issues in the container and host.

5. Avoid Privileged Containers

Use the '— privileged' flag infrequently.

Docker includes features that allow a container to run as root on the host.This is accomplished by using the—-privileged flag.A container running in privileged mode has root access to all host devices.

If an attacker compromises a privileged container, they will have easy access to resources on the host.Tampering with system security modules such as SELinux would also be trivial.

As a result, running containers in privileged mode is not recommended at any stage of the development lifecycle.Privileged containers pose a significant security risk.The potential for abuse is limitless.Attackers can use the host's services to find and exploit vulnerabilities.They can also take advantage of container misconfigurations, such as containers with weak or no authentication.Privileged containers grant an attacker root access, allowing malicious code to run.Avoid using them in any situation.

Use the following command to see if the container is running in privileged mode:

—format='.HostConfig.Privileged' docker inspect[container id]

  • True indicates that the container is privileged.
  • false indicates that the container is not privileged

Make use of the 'no-new-privileges' option.

When creating containers, add the no-new-privileges security option to prevent container processes from escalating their privileges using setuid or setgid binaries.This prevents processes within the container from gaining new privileges while running.So, if a programme has the setuid or setgid bit set, any attempt to gain privileges with that programme will be denied.

6. Set Filesystem and Volumes to Read-only

Running containers with a read-only filesystem is a useful security feature in Docker.Because the container's filesystem cannot be tampered with or written to unless it has explicit read-write permissions on its filesystem files and directories, attack vectors are reduced.

The code below makes a Docker container read-only:

  • 'echo "read only" > /tmp' docker run —read-only alpine sh -c 

7.Drop capabilities

The Linux kernel can divide the root user's privileges into distinct units known as capabilities.    Almost all of the Linux root user's special abilities are divided into individual capabilities.

Docker imposes some constraints that make working with capabilities much easier.File capabilities are stored in a file's extended attributes, which are removed when Docker images are built.This means you won't have to worry about file capabilities in containers very often.

As previously stated, do not run containers with the —privileged flag because this adds all Linux kernel capabilities to the container.

The most secure configuration is to drop all capabilities with —cap-drop all and then add only those that are required.

As an example:

—cap-drop all —cap-add docker run Alpine CHOWN

image

8.Set the logging level to at least INFO

Maintaining logging information is important as it helps in troubleshooting any potential issues during runtime. By default, the Docker daemon is configured to have a logging level of info, if this is not the case, it can be set using the --log-level info option. This is a base log level and captures all logs except the debug logs. It is not recommended to use the debug log level, unless required.

To configure the log level in docker-compose:

docker-compose --log-level info up

To Summarize

Securing Docker containers is essential and can be complex as well. With the tips above, you can manage a large and safe platform for containerized applications. The practices above are crucial because they will help you prevent security breaches and attacks in your containerized enviroments.