1080*80 ad

Enabling Remote Access to the Docker Daemon

A Practical Guide to Securely Accessing Your Docker Daemon Remotely

By default, the Docker daemon listens on a local Unix socket (/var/run/docker.sock) to protect it from unauthorized remote access. This is a sensible and secure default, as direct access to the Docker API is equivalent to having root access on the host machine. However, there are legitimate reasons for enabling remote access, such as managing a remote Docker host, integrating with CI/CD pipelines, or using graphical Docker clients.

This guide will walk you through the proper, secure method for enabling remote access to your Docker daemon using TLS encryption. We’ll also cover why the common insecure method should be avoided at all costs.

A Critical Security Warning: Avoid Unencrypted Remote Access

You may find tutorials suggesting you expose the Docker daemon by simply adding a -H tcp://0.0.0.0:2375 flag. This configures the daemon to listen on TCP port 2375 without any encryption or authentication.

Exposing the Docker daemon over an unencrypted TCP port is extremely dangerous. Anyone who can connect to that port on your machine can execute any Docker command, which includes running containers with privileged access and mounting sensitive directories from the host. This effectively gives them root access to your server. This method should only ever be considered in a completely isolated and trusted network, and even then, it is not recommended.

The industry-standard and only truly secure method is to use Transport Layer Security (TLS) to encrypt and authenticate the connection.

The Secure Solution: Using TLS for Remote Docker Access

To protect the Docker daemon socket with TLS, we need to create a set of certificates that allow the Docker client and daemon to verify each other’s identity before establishing a connection. This process involves three key components:

  1. Certificate Authority (CA): A trusted, private root authority that will sign both the server and client certificates.
  2. Server Certificate: Used by the Docker daemon to prove its identity to the client.
  3. Client Certificate: Used by the Docker client to prove its identity to the daemon.

Step-by-Step Guide to Enabling Secure Remote Access

Here’s how to generate the necessary certificates and configure your Docker host. These commands should be run on your Docker host machine.

Step 1: Generate the Certificate Authority (CA)

First, create a directory to store your certificates and generate the private key for your CA.

mkdir ~/docker-certs
cd ~/docker-certs

# Generate CA private key
openssl genrsa -aes256 -out ca-key.pem 4096

# Generate CA public key (certificate)
openssl req -new -x509 -days 365 -key ca-key.pem -sha256 -out ca.pem

You will be prompted for a passphrase for the CA key and information for the certificate (Country Name, Organization, etc.).

Step 2: Generate the Server Certificate

Now, we’ll create a server key and a certificate signing request (CSR). The “Common Name” (CN) for this certificate must match the hostname or IP address of your Docker server that clients will use to connect.

# Generate server private key
openssl genrsa -out server-key.pem 4096

# Create a certificate signing request (CSR)
# IMPORTANT: Use your server's DNS name or IP for the Common Name (CN)
openssl req -subj "/CN=your.server.hostname.com" -sha256 -new -key server-key.pem -out server.csr

Next, sign the server certificate with your CA.

# Sign the public key with our CA
openssl x509 -req -days 365 -sha256 -in server.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out server-cert.pem

Step 3: Generate the Client Certificate

The process for the client certificate is similar. This certificate will be used to authenticate your client machine.

# Generate client private key
openssl genrsa -out key.pem 4096

# Create a client certificate signing request (CSR)
openssl req -subj "/CN=client" -new -key key.pem -out client.csr

# To make the key suitable for client authentication, create an extensions config file
echo "extendedKeyUsage = clientAuth" > extfile.cnf

# Sign the client public key with our CA
openssl x509 -req -days 365 -sha256 -in client.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out cert.pem -extfile extfile.cnf

After these steps, you should have several files. The critical ones are:

  • ca.pem (CA public key)
  • server-cert.pem (Server public key)
  • server-key.pem (Server private key)
  • cert.pem (Client public key)
  • key.pem (Client private key)

Clean up the unnecessary signing request files:

rm -v client.csr server.csr extfile.cnf ca.srl

Step 4: Configure the Docker Daemon

The modern and recommended way to configure the Docker daemon is by using the /etc/docker/daemon.json file. This file persists across Docker updates.

Create or edit /etc/docker/daemon.json and add the following configuration. Remember to replace the file paths with the correct location of your certificates.

{
  "tls": true,
  "tlscacert": "/home/youruser/docker-certs/ca.pem",
  "tlscert": "/home/youruser/docker-certs/server-cert.pem",
  "tlskey": "/home/youruser/docker-certs/server-key.pem",
  "hosts": ["unix:///var/run/docker.sock", "tcp://0.0.0.0:2376"]
}

This configuration tells Docker to:

  • Enable TLS ("tls": true).
  • Verify clients against your CA.
  • Present its server certificate and key.
  • Listen on both the local Unix socket and the secure TCP port 2376.

After saving the file, restart the Docker daemon to apply the changes.

sudo systemctl daemon-reload
sudo systemctl restart docker

Step 5: Harden Your Firewall

Do not expose port 2376 to the entire internet. You must configure your firewall to only allow connections from specific, trusted IP addresses (like your work office or home IP).

Here is an example using ufw on Ubuntu. Replace <your_client_ip> with the public IP address of the machine you will be connecting from.

# Allow connections on port 2376 only from a specific IP
sudo ufw allow from <your_client_ip> to any port 2376

# Make sure to enable the firewall if it's not already
sudo ufw enable

Connecting from a Remote Docker Client

To connect from your remote machine, you need to securely copy the client certificates (ca.pem, cert.pem, and key.pem) to it.

A common practice is to place them in a .docker directory in your home folder.

# On your client machine
mkdir -p ~/.docker
# Securely copy ca.pem, cert.pem, and key.pem into ~/.docker/

You can now connect to your remote Docker daemon by specifying the host and the TLS certificates with every command:

docker --tlsverify \
  --tlscacert=~/.docker/ca.pem \
  --tlscert=~/.docker/cert.pem \
  --tlskey=~/.docker/key.pem \
  -H=tcp://your.server.hostname.com:2376 \
  version

To avoid typing this every time, you can set environment variables in your shell profile (~/.bashrc, ~/.zshrc, etc.):

export DOCKER_HOST=tcp://your.server.hostname.com:2376
export DOCKER_TLS_VERIFY=1
export DOCKER_CERT_PATH=~/.docker/

After setting these variables and reloading your shell, you can use docker commands as you normally would, and they will automatically and securely connect to your remote daemon.

By following these steps, you can harness the power of remote Docker management without compromising the security of your host system. Remember, security is not optional when exposing a service as powerful as the Docker daemon.

Source: https://kifarunix.com/configure-docker-daemon-for-remote-connections/

900*80 ad

      1080*80 ad