You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

135 lines
4.3 KiB

6 years ago
# gencert
6 years ago
This script generates x509 server certificate (with all IPs in SAN) signed by a
self-signed CA.
6 years ago
## Purpose
6 years ago
This script will always produce a self-signed x509 certificate with the IP
addresses embedded to x509's SAN.
It will also produce a CA certificate and can be used by other services
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.
6 years ago
## Application
6 years ago
6 years ago
### Backend requiring x509 running behind reverse proxy
6 years ago
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.
6 years ago
Traefik (running with docker service provider or similar) is talking to the
6 years ago
backend using the IP address rather than a hostname.
6 years ago
Usually, the IP address is not static, hence this script comes handy.
6 years ago
6 years ago
## 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
## 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
## Usage example
6 years ago
6 years ago
### Minio server with Traefik example
6 years ago
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.
6 years ago
6 years ago
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:
```
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
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"
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
command: sh -c "update-ca-certificates && traefik"
networks:
- oasis
ports:
- "127.0.0.1:8080:8080"
- "80:80"
- "443:443"
```
6 years ago
6 years ago
### Drawbacks
- [operational] it requires self-signed CA certs shared when running multiple
6 years ago
Minio (or any other) servers;
6 years ago
- [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;