From fac578b878af99a809369a3bd8e6b2f95d7f53d0 Mon Sep 17 00:00:00 2001 From: Jef Roosens Date: Mon, 17 May 2021 09:29:18 +0200 Subject: [PATCH] Updated docker-tcp.md --- content/posts/docker-tcp.md | 86 ++++++++++++++++++++++++++++++++++++- 1 file changed, 85 insertions(+), 1 deletion(-) diff --git a/content/posts/docker-tcp.md b/content/posts/docker-tcp.md index 7101d91..e31d3af 100644 --- a/content/posts/docker-tcp.md +++ b/content/posts/docker-tcp.md @@ -65,7 +65,7 @@ In the above snippet, replace `` with the hostname (output of the `hostname` command) of the machine who's API you want to expose. Now we've created `server-key.pem` and `server.csr`. -As a final step, we need to create a file named `extfile.cnf` with the +After this, we need to create a file named `extfile.cnf` with the following content: ``` @@ -75,3 +75,87 @@ extendedKeyUsage = serverAuth Here, we once again replace `` with the machine's hostname, and `` with the machine's public IP. + +This file can now be used to generate the actual signed certificate: + +```shell +openssl x509 -req -days 365 -sha256 -in server.csr -CA ca.pem -CAkey \ + ca-key.pem -CAcreateserial -out server-cert.pem -extfile extfile.cnf +``` + +Here, we can once again change the days argument to the value we want. After +all these steps, we're left with a signed server-side certificate. + +## Client-side + +Now we'll generate the client-side certificates. We start by creating a `csr` +file: + +```shell +openssl genrsa -out key.pem 4096 +openssl req -subj '/CN=client' -new -key key.pem -out client.csr +``` + +After this, we create another `.cnf`, this time to configure the client-side +keys. Add this to a file named `extfile-client.cnf`: + +``` +extendedKeyUsage = clientAuth +``` + +And then, we generate the client-side key: + +``` +openssl x509 -req -days 365 -sha256 -in client.csr -CA ca.pem -CAkey \ + ca-key.pem -CAcreateserial -out cert.pem -extfile extfile-client.cnf +``` + +Once again change the days value to whatever you want. Now we're left with all +the files we need to securely expose the API. + +## Exposing the API + +**Note**: the following steps will restart the Docker engine and all +running containers, so make sure this won't break anything. + +Start by creating a directory on the host that you're not going to delete. In +the following steps, replace `` with the absolute path to this directory. +After this, copy `ca.pem`, `server-cert.pem` and `server-key.pem` to this +directory. + +We're gonna be creating a system config file for the Docker service (this guide +assumes the use of `systemd`). In +`/etc/systemd/docker.service.d/startup_options.conf`, put the following: + +```shell +[Service] +ExecStart= +ExecStart=/usr/bin/dockerd --tlsverify --tlscacert='/ca.pem' --tlscert='/server-cert.pem' --tlskey='/server-key.pem' -H fd:// -H tcp://0.0.0.0:2376 +``` + +Don't forget the replace `` with the path to your actual directory. + +The final step is restarting the Docker engine: + +```shell +systemctl daemon-reload +systemctl restart docker.service +``` + +**Note**: these commands require root. + +After all this, you should have a Docker API that's accessible using an +encrypted connection. Let's test it by adding it to Portainer! + +## Adding engine to Portainer + +Thankfully this is the easy part. In Portainer, add a new endpoint and choose +the "Docker" type. Pick a name for your endpoint, fill in the endpoint URL +including the port number (Docker's default port number is `2375`) and enable +the "TLS" switch. We choose "TLS with server and client verification", as this +is the safest. The files to upload are `ca.pem` for the TLS CA certificate, +`cert.pem` for the TLS certificate and `key.pem` for the TLS key. If all goes +well, you should now connect to the host! + +Now, I know these steps can be quite tedious to repeat, so I've written +[a script](/scripts/docker-tcp.sh) that can automate this process for you.