Finalized first version of docker-tcp post
continuous-integration/drone the build was successful
Details
continuous-integration/drone the build was successful
Details
parent
87c5b2eca9
commit
9e22b69ecb
|
@ -1,7 +1,6 @@
|
||||||
---
|
---
|
||||||
draft: true
|
|
||||||
title: "Encrypting a Docker API for Remote Access Using Portainer"
|
title: "Encrypting a Docker API for Remote Access Using Portainer"
|
||||||
date: "2021-05-16"
|
date: "2021-05-17"
|
||||||
---
|
---
|
||||||
|
|
||||||
tl;dr [This script](/scripts/docker-tcp.sh) has everything you need, just run
|
tl;dr [This script](/scripts/docker-tcp.sh) has everything you need, just run
|
||||||
|
@ -12,23 +11,23 @@ tl;dr [This script](/scripts/docker-tcp.sh) has everything you need, just run
|
||||||
To manage my little army of servers, I use
|
To manage my little army of servers, I use
|
||||||
[Portainer CE](https://www.portainer.io/). It's an open-source management tool
|
[Portainer CE](https://www.portainer.io/). It's an open-source management tool
|
||||||
for controlling Dockerized applications across multiple hosts. It can handle
|
for controlling Dockerized applications across multiple hosts. It can handle
|
||||||
regular Docker containers, compose stacks, Kubernetes clusters or Docker swarm
|
regular Docker containers, compose stacks, Kubernetes clusters and Docker swarm
|
||||||
mode. It's a really useful tool to keep track of everything, and nowadays, I
|
mode. It's a really useful tool to keep track of everything, and nowadays, I
|
||||||
really can't miss it.
|
really can't miss it.
|
||||||
|
|
||||||
Before we can add a host to Portainer, its Docker API has to be exposed to the
|
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
|
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
|
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
|
explain how this can be done, and I've also written
|
||||||
the "heavy" lifting.
|
[a script](/scripts/docker-tcp.sh) that can automate the "heavy" lifting.
|
||||||
|
|
||||||
**Note**: This tutorial is only for Linux. I have no experience with managing a
|
**Note**: This tutorial is only for Linux distributions that use systemctl. I
|
||||||
Windows server and therefore can't confirm these steps will also work on a
|
have no experience with managing a Windows server and therefore can't confirm
|
||||||
Windows machine.
|
these steps will also work on a Windows machine, or using another init system.
|
||||||
|
|
||||||
I recommend running these commands on your local Linux machine and just copying
|
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
|
the certificates to the server later, as you'll need the files in order to add
|
||||||
add the host to Portainer later.
|
the host to Portainer later.
|
||||||
|
|
||||||
## Server-side
|
## Server-side
|
||||||
|
|
||||||
|
@ -45,32 +44,33 @@ These first two commands generate the
|
||||||
[CA](https://en.wikipedia.org/wiki/Certificate_authority) key. You'll be asked
|
[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.
|
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
|
The most important one is the password. Keep this one safe, as you'll be asked
|
||||||
for it later when creating the client key.
|
for it multiple times when generating the other keys.
|
||||||
|
|
||||||
One thing to note here is the `-days 365` flag. This defines after how many
|
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
|
days the 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
|
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
|
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
|
new certificate. You'll have to figure out for yourself how long you'd like
|
||||||
your certificate to be valid for.
|
your certificate to be valid for. It's a trade-off between convenience and
|
||||||
|
security.
|
||||||
|
|
||||||
Now we can generate the server key:
|
Now we can generate the server key:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
openssl genrsa -out server-key.pem 4096
|
openssl genrsa -out server-key.pem 4096
|
||||||
openssl req -subj "/CN=<HOST>" -sha256 -new -key server-key.pem -out server.csr
|
openssl req -subj '/CN=<HOST>' -sha256 -new -key server-key.pem -out server.csr
|
||||||
```
|
```
|
||||||
|
|
||||||
In the above snippet, replace `<HOST>` with the hostname of the machine who's
|
In the above snippet, replace `<HOST>` with the domain name of the machine
|
||||||
API you want to expose. With hostname, I mean the domain from which your server
|
who's API you want to expose. With domain name, I mean the domain from which
|
||||||
is accessible, e.g. `server.example.com`. Now we've created `server-key.pem`
|
your server is accessible, e.g. `server.example.com`. Now we've created
|
||||||
and `server.csr`.
|
`server-key.pem` and `server.csr`.
|
||||||
|
|
||||||
After this, 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:
|
following content:
|
||||||
|
|
||||||
```
|
```
|
||||||
subjectAltName = DNS:<HOST>,IP:<IP>,IP:127.0.0.1 >> extfile.cnf
|
subjectAltName = DNS:<HOST>,IP:<IP>,IP:127.0.0.1
|
||||||
extendedKeyUsage = serverAuth
|
extendedKeyUsage = serverAuth
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -134,7 +134,7 @@ ExecStart=
|
||||||
ExecStart=/usr/sbin/dockerd --tlsverify --tlscacert='<DIR>/ca.pem' --tlscert='<DIR>/server-cert.pem' --tlskey='<DIR>/server-key.pem' -H fd:// -H tcp://0.0.0.0:2376
|
ExecStart=/usr/sbin/dockerd --tlsverify --tlscacert='<DIR>/ca.pem' --tlscert='<DIR>/server-cert.pem' --tlskey='<DIR>/server-key.pem' -H fd:// -H tcp://0.0.0.0:2376
|
||||||
```
|
```
|
||||||
|
|
||||||
Don't forget the replace `<PATH>` with the path to your actual directory.
|
Don't forget to replace `<DIR>` with the path to your actual directory.
|
||||||
|
|
||||||
The final step is restarting the Docker engine:
|
The final step is restarting the Docker engine:
|
||||||
|
|
||||||
|
|
Reference in New Issue