update readme and tests

master
Andy 6 years ago
parent c17a7b98b6
commit b6ee6d3ce2
Signed by: arno
GPG Key ID: 9076D5E6B31AE99C

@ -5,6 +5,18 @@ self-signed CA.
## Purpose
The whole idea is to run the ``gencert.sh`` script right before starting the
service and then, making sure the reverse proxy updates its main CA bundle
right before starting.
Some services require the certificate on their backend and would not be
satisfied with the TLS termination elsewhere.
For example, one of such services is Minio. It [requires](https://github.com/minio/minio/issues/6093) its certificate in order
to enable SSE-C (Server Side Encryption with Customer provided keys).
## How does this script work
This script will always produce a self-signed x509 certificate with the IP
addresses embedded to x509's SAN.
@ -14,121 +26,75 @@ which may need to authenticate against this self-signed certificate.
The authentication works in a way that a public CA certificate will be
used by the client in order to validate the server's certificate.
## Application
### Backend requiring x509 running behind reverse proxy
This script has been created in order to ease the Minio's SSE-C
(Server Side Encryption - Customer provided keys) enablement when
Minio server is running as a backend behind a reverse proxy like Traefik.
Minio server enables SSE-C only when it detects the x509 certificates.
Traefik (running with docker service provider or similar) is talking to the
backend using the IP address rather than a hostname.
Usually, the IP address is not static, hence this script comes handy.
## Script logic
- generate CA certificate if does not find any
- always generate server certificate on startup to ensure all IP addresses
are in x509 SAN
- warn if the CA certificate is about to expire (<30 days till expiration)
- regenerate the CA certificate if it finds it has expired
## Notes
> - The CA certificate will be valid for 3650 days (10 years)
> - The server certifcate will be valid for 365 days (1 year)
> - The x509 certs are ECDSA with prime256v1 curve and SHA256 signatures
- The CA certificate will be valid for 3650 days (10 years)
- The server certifcate will be valid for 365 days (1 year)
- The x509 certs are ECDSA with prime256v1 curve and SHA256 signatures
## Testing
I have added a simplistic script [testme.sh](testme.sh) that helps to test this
script in the following Linux distributions:
- Alpine 3.7
- Ubuntu Bionic
- Debian Stretch
- CentOS 7
## Examples
## Usage example
### Minio and Docker Registry services with Traefik reverse proxy
### Minio server with Traefik example
- docker-compose.yml
1. Replace ``minio server`` command with the following one:
``cd /root/.minio/certs && ./gencert.sh --cn minio.example.com && minio server /data``
2. Copy the CA certificate ``ca.crt`` file to ``/usr/local/share/ca-certificates/`` and
run ``update-ca-certificates`` command which will update
``/etc/ssl/certs/ca-certificates.crt`` file;
3. Restart Traefik.
With the Step 1. Minio server will get the certificate it needs, hence SSE-C
will be enabled.
Steps 2. and 3. will need to be repeated each time you get a new CA
certificate.
These steps can be automated this way:
Start Traefik with this command:
``sh -c "update-ca-certificates && traefik"``
while ``/usr/local/share/ca-certificates`` container path is mounted from the
host with the CA certificate produced by this script.
I am using Alpine Traefik image, the correct ca certificates path is
``/usr/local/share/ca-certificates/``, otherwise one of these
https://golang.org/src/crypto/x509/root_linux.go
- ``docker-compose.yml`` example with the gencert script:
> I intentionally left only the gencert-related lines.
>
> If you are using Alpine based image, the correct CA certificates path is
> ``/usr/local/share/ca-certificates/``, otherwise one of these
> https://golang.org/src/crypto/x509/root_linux.go
```
version: '3'
networks:
oasis: {}
services:
minio:
restart: unless-stopped
image: minio/minio
networks:
- oasis
volumes:
- /srv/data/minio:/data
- /srv/data/minio/start/gencert.sh:/gencert.sh:ro
- /srv/data/minio/certs:/root/.minio/certs
- /srv/services/gencert/gencert.sh:/gencert.sh:ro
entrypoint: sh -c "cd /root/.minio/certs && /gencert.sh --cn minio.example.com && minio server /data"
environment:
- "MINIO_ACCESS_KEY=redacted"
- "MINIO_SECRET_KEY=redacted"
labels:
- "traefik.enable=true"
- "traefik.frontend.rule=Host: minio.example.com"
- "traefik.frontend.passHostHeader=true"
- "traefik.port=9000"
registry:
image: registry:2.6.2
volumes:
- /srv/services/gencert/gencert.sh:/gencert.sh:ro
- /srv/data/registry/certs:/certs
entrypoint: sh -c "cd /certs && /gencert.sh --cn registry.example.com && registry serve /etc/docker/registry/config.yml"
environment:
REGISTRY_HTTP_TLS_CERTIFICATE: '/certs/public.crt'
REGISTRY_HTTP_TLS_KEY: '/certs/private.key'
traefik:
restart: unless-stopped
image: traefik:1.6-alpine
volumes:
- /srv/data/traefik/acme:/etc/traefik/acme
- /srv/data/traefik/traefik.toml:/etc/traefik/traefik.toml:ro
- /var/run/docker.sock:/var/run/docker.sock:ro # listen to the Docker events.
- /srv/data/traefik/ca-certs:/usr/local/share/ca-certificates:ro
- /srv/data/minio/certs/ca.crt:/usr/local/share/ca-certificates/minio_ca.crt:ro
- /srv/data/registry/certs/ca.crt:/usr/local/share/ca-certificates/registry_ca.crt:ro
command: sh -c "update-ca-certificates && traefik"
networks:
- oasis
ports:
- "127.0.0.1:8080:8080"
- "80:80"
- "443:443"
depends_on:
- minio
- registry
```
### Drawbacks
## Testing
I have added a simplistic script [testme.sh](testme.sh) that helps to test this
script in the following Linux distributions:
- Alpine 3.4
- Alpine 3.7
- Ubuntu Bionic
- Debian Stretch
- CentOS 7
> Alpine 3.4 - as it has old getent which [misses](https://git.alpinelinux.org/cgit/aports/commit/?id=2e4493888fff74afc6a6ef6257aeea469df32af5) ahostsv4
## Drawbacks
- [operational] it requires self-signed CA certs shared when running multiple
Minio (or any other) servers;
- [operational] every X years it requires updating the CA certificate in the
Traefik's (or any other reverse proxy) container;
- [security] the CA key will have to be spread all over the environment.
Theoretically, this could be solved by HashiCorp's Vault, but that won't be
nice & small way of running things;

@ -5,7 +5,7 @@ TMPDIR="$(mktemp -d)"
cp -v gencert.sh "${TMPDIR}/"
pushd "${TMPDIR}"
for DISTRO in alpine:3.7 ubuntu:bionic debian:stretch centos:7; do
for DISTRO in alpine:3.4 alpine:3.7 ubuntu:bionic debian:stretch centos:7; do
printf "\n\n\nTesting the script with ${DISTRO} ...\n\n\n"
rm -vf openssl.cnf private.key public.crt ca.crt ca.key ca.srl
docker run --rm -ti -v ${PWD}:/w -w /w ${DISTRO} sh gencert.sh --cn test.example.com

Loading…
Cancel
Save