{"id":15551,"date":"2023-03-01T00:10:00","date_gmt":"2023-02-28T21:10:00","guid":{"rendered":"https:\/\/kifarunix.com\/?p=15551"},"modified":"2024-03-10T08:47:54","modified_gmt":"2024-03-10T05:47:54","slug":"configure-docker-daemon-for-remote-connections","status":"publish","type":"post","link":"https:\/\/kifarunix.com\/configure-docker-daemon-for-remote-connections\/","title":{"rendered":"Configure Docker Daemon for Remote Connections"},"content":{"rendered":"\n
Is it possible to connect Docker daemon running on remote host from local Docker client? Yes, this tutorial will take you through how to configure Docker daemon for remote connections. Docker daemon listens on Unix socket on a localhost by default. It can as well be configured to listen on an IP address and port to allow remote clients to connect to it.<\/p>\n\n\n\n As already mentioned, Docker daemon can listens on non-networked unix socket by default. It can however be configured to listen on both an IP and port as well as on usual unix socket.<\/p>\n\n\n\n There are two ways in which you can configure Docker daemon to allow remote connections (You can only use one method and not both at the same time on the same system).<\/p>\n\n\n\n For systems that uses systemd and have Docker engine installed, then you can edit the Docker daemon service unit file, Create a systemd drop-in directory for the Configure the overide file to look like;<\/p>\n\n\n\n Port 2375\/TCP is the default port used for the Docker daemon to listen on for API requests.<\/p>\n\n\n\n Above configures Docker daemon to listen on specific IP address only. You can use 0.0.0.0 to listen on all interfaces.<\/p>\n\n\n\n You might be wondering why an extra ExecStart line without a value? Well, Reload the Restart Docker.<\/p>\n\n\n\n Verify that it is now listening on both Unix socket and IP\/port;<\/p>\n\n\n\n You can edit this file, if it is already existing and configure it as follows to enable Docker daemon for remote connections;<\/p>\n\n\n\n If the file already exists, add that line and ensure that the file remains a valid json file.<\/p>\n\n\n\n Save and exit the file.<\/p>\n\n\n\n Restart Docker daemon;<\/p>\n\n\n\n If docker service fails with the error;<\/p>\n\n\n\n Then solve by removing the Restart Docker again;<\/p>\n\n\n\n Allowing remote access to Docker daemon is a security risk. Ensure that you implement firewall rules to allow access from specific systems only.<\/p>\n\n\n\n For example, the command below can be used to allow access to Docker daemon from specific host;<\/p>\n\n\n\n If using iptables;<\/p>\n\n\n\n There are also two methods in which you can configure secured access to remote Docker deamon;<\/p>\n\n\n\n To begin with, on the Docker host, where you have configured Docker daemon for remote access, create a user and add the user to Docker group. The name can be anything!<\/p>\n\n\n\n Set the user password;<\/p>\n\n\n\n If the user already exists, add it to Docker group;<\/p>\n\n\n\n On the client host that you want to use to connect to remote Docker daemon, generate SSH keys from your user account;<\/p>\n\n\n\n Next, update the remote Docker daemon DNS details on your hosts file if there is no local DNS;<\/p>\n\n\n\n Copy the SSH keys into the Docker server, replace connection details appropriately;<\/p>\n\n\n\n You can now access remote Docker daemon as follows;<\/p>\n\n\n\n For example, to get info about remote Docker daemon;<\/p>\n\n\n\n You can also update the DOCKER_HOST environment variable with SSH connection command;<\/p>\n\n\n\n e.g;<\/p>\n\n\n\n With this done, then you can ran your docker commands against the remote host as you would when logged in to that server;<\/p>\n\n\n\n If you are running Docker engine on the client node you are using to access remote Docker daemon, you can create Docker contexts<\/a> that enables you to switch between the local and remote Docker daemon.<\/p>\n\n\n\n By default, the local Docker context that defines the local Docker daemon socket, You can create another Docker context to define remote Docker daemon endpoint;<\/p>\n\n\n\n E.g to create a Docker context for our remote Docker daemon;<\/p>\n\n\n\n You can list contexts again;<\/p>\n\n\n\n To connect to a remote Docker daemon using Docker contexts, simply use the specific Docker context. e.g;<\/p>\n\n\n\n If you list contexts again, you will see that current context is the remote context;<\/p>\n\n\n\n You can then run Docker commands against remote Docker host as usual;<\/p>\n\n\n\n e.g<\/p>\n\n\n\n This list Docker containers running on the remote Docker node;<\/p>\n\n\n\n And that is on how you can use SSH to connect to remote Docker daemon.<\/p>\n\n\n\n Docker over TLS should run on TCP port 2376.<\/p>\n\n\n\n Thus, similarly, you can enable HTTPS connection to your remote Docker daemon. To be able to use HTTPS connection to remote Docker container, you need SSL\/TLS certificates.<\/p>\n\n\n\n To make this process easy and cost effective, you can setup your own CA server that enables you to generate and sign your own SSL\/TLS certificates;<\/p>\n\n\n\n How to Setup a Local CA Server on Ubuntu<\/a><\/p>\n\n\n\n Thus, on your CA server, generate SSL\/TLS certificates to be installed on the remote Docker server node and clients connecting to it to develop trust among them.<\/p>\n\n\n\n Generate Docker SSL\/TLS certificates and keys (you can follow the guide above to generate and sign your own ssl certificates);<\/p>\n\n\n\n Put the certificates and keys on a single directory for easy access.<\/p>\n\n\n\n For example, we have the following;<\/p>\n\n\n\n You will need to copy these same files into Docker client.<\/p>\n\n\n\n For this, you can use either To use daemon.json, update it such that it may look like in below, ensuring that the file remains a valid JSON file<\/strong>.<\/p>\n\n\n\n Restart Docker daemon;<\/p>\n\n\n\n Check the port;<\/p>\n\n\n\n Also check logs if need be;<\/p>\n\n\n\n Open port 2376\/tcp on firewall;<\/p>\n\n\n\n To configure Docker daemon for SSL\/TLS connection using systemd unit file;<\/p>\n\n\n\n Reload the Restart Docker.<\/p>\n\n\n\n Next, copy the CA, CRT and KEY files into the client into your users Docker directory, On Docker Client, we have already copied the files;<\/p>\n\n\n\n You can now connect to remote Docker node using the command;<\/p>\n\n\n\n e.g<\/p>\n\n\n\n We used FQDN since we generated a wildcard SSL\/TLS certificate.<\/p>\n\n\n\n You can now access remote Docker host as usual;<\/p>\n\n\n\n And that is all on how to configure Docker daemon for remote connections.<\/p>\n\n\n\n Remote access for Docker daemon<\/a><\/p>\n\n\n\n How to Install Docker Desktop on Kali Linux<\/a><\/p>\n\n\n\n<\/figure>\n\n\n\n
Configuring Docker Daemon for Remote Connections<\/h3>\n\n\n\n
\n
Use Systemd Service Unit File to enable Docker Daemon Remote Connections<\/h3>\n\n\n\n
docker.service<\/code><\/strong>, and configure it to listen on an IP and port.<\/p>\n\n\n\n
docker<\/code> service:<\/p>\n\n\n\n
sudo mkdir -p \/etc\/systemd\/system\/docker.service.d<\/code><\/pre>\n\n\n\n
sudo tee \/etc\/systemd\/system\/docker.service.d\/override.conf << 'EOL' \n[Service]\nExecStart=\nExecStart=\/usr\/bin\/dockerd -H fd:\/\/ --containerd=\/run\/containerd\/containerd.sock -H tcp:\/\/192.168.59.48:2375\nEOL<\/code><\/pre>\n\n\n\n
ExecStart=<\/code> with no value is typically used to clear any previously defined
ExecStart<\/code> commands from the original service file. It ensures that the original
ExecStart<\/code> command is cleared before adding your new command with
ExecStart=\/new\/value<\/code>.<\/p>\n\n\n\n
systemctl<\/code> configuration.<\/p>\n\n\n\n
sudo systemctl daemon-reload<\/code><\/pre>\n\n\n\n
sudo systemctl restart docker<\/code><\/pre>\n\n\n\n
ss -altnp | grep :2375<\/code><\/pre>\n\n\n\n
LISTEN 0 4096 192.168.59.48:2375 0.0.0.0:* users:((\"dockerd\",pid=3344,fd=3))<\/code><\/pre>\n\n\n\n
Enable Docker Remote Connections via daemon.json file<\/h3>\n\n\n\n
daemon.json<\/code> is a configuration file for the Docker daemon used to set various options and settings for the Docker daemon, such as network settings, storage drivers, logging options, and more.<\/p>\n\n\n\n
sudo vim \/etc\/docker\/daemon.json<\/code><\/pre>\n\n\n\n
{\n \"hosts\": [\"unix:\/\/\/var\/run\/docker.sock\", \"tcp:\/\/192.168.59.48:2375\"]\n}<\/code><\/pre>\n\n\n\n
sudo systemctl restart docker<\/code><\/pre>\n\n\n\n
unable to configure the Docker daemon with file \/etc\/docker\/daemon.json: the following directives are specified both as a flag and in the configuration file: hosts: (from flag: [fd:\/\/], from file: [unix:\/\/\/var\/run\/docker.sock tcp:\/\/192.168.59.48:2375])<\/code><\/pre>\n\n\n\n
-H fd:\/\/<\/code> option from the systemd unit file it as follows;<\/p>\n\n\n\n
[[ -d \/etc\/systemd\/system\/docker.service.d ]] || sudo mkdir -p \/etc\/systemd\/system\/docker.service.d<\/code><\/pre>\n\n\n\n
sudo tee \/etc\/systemd\/system\/docker.service.d\/override.conf << 'EOL' \n[Service]\nExecStart=\nExecStart=\/usr\/bin\/dockerd --containerd=\/run\/containerd\/containerd.sock\nEOL<\/code><\/pre>\n\n\n\n
sudo systemctl restart docker<\/code><\/pre>\n\n\n\n
Control Docker Daemon Remote Access on Firewall<\/h3>\n\n\n\n
sudo ufw allow from 192.168.59.46 to any port 2375 proto tcp comment \"Allow access from johndoes system\"<\/code><\/pre>\n\n\n\n
sudo iptables -A INPUT -p tcp --dport 2375 -s 192.168.59.100\/32 -m comment --comment \"Allow from johndoes system\" -j ACCEPT<\/code><\/pre>\n\n\n\n
sudo cp \/etc\/iptables\/rules.v4{,.bak}<\/code><\/pre>\n\n\n\n
iptables-save > \/etc\/iptables\/rules.v4<\/code><\/pre>\n\n\n\n
Configure Secured Access to Remote Docker Daemon<\/h3>\n\n\n\n
\n
Access Docker Daemon via SSH<\/h4>\n\n\n\n
sudo useradd -m -G docker -s \/bin\/bash kifarunix<\/code><\/pre>\n\n\n\n
sudo passwd kifarunix<\/code><\/pre>\n\n\n\n
sudo usermod -aG docker kifarunix<\/code><\/pre>\n\n\n\n
ssh-keygen<\/code><\/pre>\n\n\n\n
sudo tee -a \"192.168.59.48 docker01.kifarunix.com docker01\" >> \/etc\/hosts<\/code><\/pre>\n\n\n\n
ssh-copy-id kifarunix@docker01<\/code><\/pre>\n\n\n\n
docker -H ssh:\/\/username@remote-docker-hostname <docker command options><\/code><\/pre>\n\n\n\n
docker -H ssh:\/\/kifarunix@docker01 info<\/code><\/pre>\n\n\n\n
export DOCKER_HOST=ssh:\/\/username@remote-docker-hostname<\/code><\/pre>\n\n\n\n
export DOCKER_HOST=ssh:\/\/kifarunix@docker01<\/code><\/pre>\n\n\n\n
docker ps<\/code><\/pre>\n\n\n\n
unix:\/\/\/var\/run\/docker.sock<\/code>, is created;<\/p>\n\n\n\n
docker context ls<\/code><\/pre>\n\n\n\n
NAME DESCRIPTION DOCKER ENDPOINT KUBERNETES ENDPOINT ORCHESTRATOR\ndefault * Current DOCKER_HOST based configuration unix:\/\/\/var\/run\/docker.sock swarm<\/code><\/pre>\n\n\n\n
docker context create \\\n--docker host=ssh:\/\/docker-user@hostname \\\n--description=\"Description\" \\\ncontext-name<\/code><\/pre>\n\n\n\n
docker context create \\\n--docker host=ssh:\/\/kifarunix@docker01 \\\n--description=\"Remote DOCKER_HOST docker01 configuration\" \\\ndocker01<\/code><\/pre>\n\n\n\n
docker context ls<\/code><\/pre>\n\n\n\n
NAME DESCRIPTION DOCKER ENDPOINT KUBERNETES ENDPOINT ORCHESTRATOR\ndefault * Current DOCKER_HOST based configuration unix:\/\/\/var\/run\/docker.sock swarm\ndocker01 Remote DOCKER_HOST docker01 configuration ssh:\/\/kifarunix@docker01<\/strong><\/code><\/pre>\n\n\n\n
docker context use docker01<\/code><\/pre>\n\n\n\n
docker context ls<\/code><\/pre>\n\n\n\n
NAME DESCRIPTION DOCKER ENDPOINT KUBERNETES ENDPOINT ORCHESTRATOR\ndefault Current DOCKER_HOST based configuration unix:\/\/\/var\/run\/docker.sock swarm\ndocker01 * Remote DOCKER_HOST docker01 configuration ssh:\/\/kifarunix@docker01<\/strong><\/code><\/pre>\n\n\n\n
docker ps<\/code><\/pre>\n\n\n\n
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES\n950a8a3f3bb6 grafana\/grafana-oss \"\/run.sh\" 2 weeks ago Up 2 hours 0.0.0.0:3000->3000\/tcp, :::3000->3000\/tcp grafana\nce3eb465e820 prom\/prometheus \"\/bin\/prometheus --c\u2026\" 2 weeks ago Up 2 hours 0.0.0.0:9090->9090\/tcp, :::9090->9090\/tcp prometheus\n567d549c4768 gcr.io\/cadvisor\/cadvisor \"\/usr\/bin\/cadvisor -\u2026\" 2 weeks ago Up 2 hours (healthy) 0.0.0.0:9080->8080\/tcp, :::9080->8080\/tcp cadvisor\n8d2a1aac1384 mariadb \"docker-entrypoint.s\u2026\" 4 weeks ago Up 2 hours 3306\/tcp wp-mariadb\nb46dce1fc33c amir20\/dozzle:latest \"\/dozzle\" 6 weeks ago Up 3 hours 0.0.0.0:8888->8080\/tcp, :::8888->8080\/tcp dozzle\n1421e6e27733 nagios-core:4.4.9 \"\/start.sh\" 6 weeks ago Up 2 hours 0.0.0.0:80->80\/tcp, :::80->80\/tcp nagios-core-4.4.9\n<\/code><\/pre>\n\n\n\n
Connect to Docker Daemon using via TLS (HTTPS)<\/h4>\n\n\n\n
ls \/etc\/ssl\/docker\/<\/code><\/pre>\n\n\n\n
cacert.pem\ndocker01.crt\ndocker01.key<\/code><\/pre>\n\n\n\n
Configure Daemon for Remote SSL\/TLS connection;<\/h4>\n\n\n\n
daemon.json<\/code><\/strong> file or
systemd unit file<\/code><\/strong> for Docker daemon.<\/p>\n\n\n\n
sudo vim \/etc\/docker\/daemon.json<\/code><\/pre>\n\n\n\n
{\n \"hosts\": [\"unix:\/\/\/var\/run\/docker.sock\", \"tcp:\/\/192.168.59.48:2376\"],\n \"tlsverify\": true,\n \"tlscacert\": \"\/etc\/ssl\/docker\/cacert.pem\",\n \"tlscert\": \"\/etc\/ssl\/docker\/docker01.crt\",\n \"tlskey\": \"\/etc\/ssl\/docker\/docker01.key\"\n}\n<\/code><\/pre>\n\n\n\n
sudo systemctl restart docker<\/code><\/pre>\n\n\n\n
ss -altnp | grep 2376<\/code><\/pre>\n\n\n\n
journalctl -xeu docker.service<\/code><\/pre>\n\n\n\n
iptables -A INPUT -p tcp --dport 2376 -s 192.168.59.100\/32 -m comment --comment \"Allow from johndoes system\" -j ACCEPT<\/code><\/pre>\n\n\n\n
\nsudo tee \/etc\/systemd\/system\/docker.service.d\/override.conf << 'EOL' \n[Service]\nExecStart=\nExecStart=\/usr\/bin\/dockerd -H fd:\/\/ --containerd=\/run\/containerd\/containerd.sock -H tcp:\/\/192.168.59.48:2376 \\\n --tlsverify --tlscacert=\/etc\/ssl\/docker\/cacert.pem \\\n --tlscert=\/etc\/ssl\/docker\/docker01.crt \\\n --tlskey=\/etc\/ssl\/docker\/docker01.key\nEOL\n<\/code><\/pre>\n\n\n\n
systemctl<\/code> configuration.<\/p>\n\n\n\n
sudo systemctl daemon-reload<\/code><\/pre>\n\n\n\n
sudo systemctl restart docker<\/code><\/pre>\n\n\n\n
~\/.docker<\/code><\/strong> and rename them as
ca.pem, key.pem, cert.pem<\/code><\/strong>.<\/p>\n\n\n\n
ls -1 ~\/.docker\/<\/code><\/pre>\n\n\n\n
ca.pem\nconfig.json\ncontexts\ncert.pem\nkey.pem<\/code><\/pre>\n\n\n\n
export DOCKER_HOST=tcp:\/\/$HOST:2376 DOCKER_TLS_VERIFY=1<\/code><\/pre>\n\n\n\n
export DOCKER_HOST=tcp:\/\/docker01.kifarunix.com:2376 DOCKER_TLS_VERIFY=1<\/code><\/pre>\n\n\n\n
docker ps<\/code><\/pre>\n\n\n\n
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES\n950a8a3f3bb6 grafana\/grafana-oss \"\/run.sh\" 2 weeks ago Up 16 minutes 0.0.0.0:3000->3000\/tcp, :::3000->3000\/tcp grafana\nce3eb465e820 prom\/prometheus \"\/bin\/prometheus --c\u2026\" 2 weeks ago Up 16 minutes 0.0.0.0:9090->9090\/tcp, :::9090->9090\/tcp prometheus\n8d2a1aac1384 mariadb \"docker-entrypoint.s\u2026\" 4 weeks ago Up 16 minutes 3306\/tcp wp-mariadb\nb46dce1fc33c amir20\/dozzle:latest \"\/dozzle\" 6 weeks ago Up 16 minutes 0.0.0.0:8888->8080\/tcp, :::8888->8080\/tcp dozzle\n1421e6e27733 nagios-core:4.4.9 \"\/start.sh\" 6 weeks ago Up 16 minutes 0.0.0.0:80->80\/tcp, :::80->80\/tcp nagios-core-4.4.9\n<\/code><\/pre>\n\n\n\n
Reference<\/h3>\n\n\n\n
Other Tutorials<\/h3>\n\n\n\n