From be5b5ba3b1a3a64b89cf3c7fdb73e009650ce921 Mon Sep 17 00:00:00 2001 From: Jef Roosens Date: Sun, 16 May 2021 22:37:43 +0200 Subject: [PATCH] Started writing Docker TCP post --- content/posts/docker-tcp.md | 77 +++++++++++++++++++++++++++++++++++++ static/docker-tcp.sh | 6 +++ 2 files changed, 83 insertions(+) create mode 100644 content/posts/docker-tcp.md create mode 100755 static/docker-tcp.sh diff --git a/content/posts/docker-tcp.md b/content/posts/docker-tcp.md new file mode 100644 index 0000000..4f337c1 --- /dev/null +++ b/content/posts/docker-tcp.md @@ -0,0 +1,77 @@ +--- +draft: true +title: "Encrypting a Docker API for Remote Access Using Portainer" +date: "2021-05-16" +--- + +tl;dr [This script](/docker-tcp.sh) has everything you need, just run +`./docker-tcp.sh -h` (after making it executable) for any help. + +## Introduction + +To manage my little army of servers, I use +[Portainer CE](https://www.portainer.io/). It's an open-source management tool +for controlling Dockerized applications across multiple hosts. It can handle +regular Docker containers, compose stacks, Kubernetes clusters or Docker swarm +mode. It's a really useful tool to keep track of everything, and nowadays, I +really can't miss it. + +Before we can add a host to Portainer, its Docker API has to be exposed to the +public, and in order to do this, we need to protect it using encryption (unless +of course you like random people controlling your server). This post will +explain how this can be done, and I've also written a script that can automate +the "heavy" lifting. + +**Note**: This tutorial is only for Linux. I have no experience with managing a +Windows server and therefore can't confirm these steps will also work on a +Windows machine. + +I recommend running these commands on your local Linux machine and just copying +the certificates to the server later, as you'll need all the files in order to +add the host to Portainer later. + +## Server-side + +To make the connection as secure as possible, we'll use both a server- & a +client-side certificate. This first section describes how to generate the +former: + +```shell +openssl genrsa -aes256 -out ca-key.pem 4096 +openssl req -new -x509 -days 365 -key ca-key.pem -sha256 -out ca.pem +``` + +These first two commands generate the +[CA](https://en.wikipedia.org/wiki/Certificate_authority) key. You'll be asked +for some basic information, e.g. your country, state, city, organization, etc. +The most important one is the password. Keep this one safe, as you'll be asked +for it later when creating the client key. + +One thing to note here is the `-days 365` flag. This defines after how many +days this certificate will expire (but only when the `-x509` flag is +specified). By default, its value is set at 30 days, but I find this to be +rather short. After this time, you'll have to repeat these steps and generate a +new certificate. You'll have to figure out for yourself how long you'd like +your certificate to be valid for. + +Now we can generate the server key: + +```shell +openssl genrsa -out server-key.pem 4096 +openssl req -subj "/CN=" -sha256 -new -key server-key.pem -out server.csr +``` + +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 +following content: + +``` +subjectAltName = DNS:,IP:,IP:127.0.0.1 >> extfile.cnf +extendedKeyUsage = serverAuth +``` + +Here, we once again replace `` with the machine's hostname, and `` +with the machine's public IP. diff --git a/static/docker-tcp.sh b/static/docker-tcp.sh new file mode 100755 index 0000000..4141187 --- /dev/null +++ b/static/docker-tcp.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env sh + +# This script generates an openSSL key pair which can be used to expose a +# Docker API over the internet. + +