Started writing Docker TCP post
continuous-integration/drone the build was successful
Details
continuous-integration/drone the build was successful
Details
parent
282e5f3824
commit
be5b5ba3b1
|
@ -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=<HOST>" -sha256 -new -key server-key.pem -out server.csr
|
||||
```
|
||||
|
||||
In the above snippet, replace `<HOST>` 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:<HOST>,IP:<IP>,IP:127.0.0.1 >> extfile.cnf
|
||||
extendedKeyUsage = serverAuth
|
||||
```
|
||||
|
||||
Here, we once again replace `<HOST>` with the machine's hostname, and `<IP>`
|
||||
with the machine's public IP.
|
|
@ -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.
|
||||
|
||||
|
Reference in New Issue