From fdf49d2b6d61308ade36fc7e0dacf78688843181 Mon Sep 17 00:00:00 2001 From: Joao Morais Date: Mon, 4 Sep 2017 20:30:17 -0300 Subject: [PATCH] docs of 0.8 --- README.md | 166 ++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 125 insertions(+), 41 deletions(-) diff --git a/README.md b/README.md index 2ce70fb..a372d8a 100644 --- a/README.md +++ b/README.md @@ -8,66 +8,148 @@ A very simple automated Certificate Authority. Such CA is useful on auto provisi Run the CA: - docker run -d -p 80:8080 -p 443:8443 quay.io/jcmoraisjr/simple-ca +``` +docker run -d -p 80:8080 -p 443:8443 quay.io/jcmoraisjr/simple-ca +``` Create a private key and certificate request: - openssl req -new -newkey rsa:2048 -keyout host-key.pem -nodes -out host.csr -subj "/" +``` +openssl req -new -newkey rsa:2048 -keyout host-key.pem -nodes -out host.csr -subj "/" +``` Sign the certificate -- change `localhost` to the IP if Docker Server is on a VM - eg Docker Machine: - curl -fk --data-binary @host.csr -o host.pem "https://localhost/sign?cn=my-host&ns=my-host.localdomain" +``` +curl -fk --data-binary @host.csr -o host.pem "https://localhost/sign?cn=my-host&ns=my-host.localdomain" +``` Check the certificate: - openssl x509 -noout -text -in host.pem +``` +openssl x509 -noout -text -in host.pem +``` Using `dn` instead `cn`: - curl -fk --data-binary @host.csr -o host.pem "https://localhost/sign?dn=/CN=my-host&ns=my-host.localdomain" +``` +curl -fk --data-binary @host.csr -o host.pem "https://localhost/sign?dn=/CN=my-host&ns=my-host.localdomain" +``` Shortcut to organizationName and `dn` syntax - Note that `ca.cnf` changed on `0.7`, you should update or remove `/ssl/ca/ca.cnf` before restart `simple-ca`: - curl -fk --data-binary @host.csr -o host.pem "https://localhost/sign?cn=my-host&o=company&ns=my-host.localdomain" - curl -fk --data-binary @host.csr -o host.pem "https://localhost/sign?dn=/CN=my-host/O=company&ns=my-host.localdomain" +``` +curl -fk --data-binary @host.csr -o host.pem "https://localhost/sign?cn=my-host&o=company&ns=my-host.localdomain" +curl -fk --data-binary @host.csr -o host.pem "https://localhost/sign?dn=/CN=my-host/O=company&ns=my-host.localdomain" +``` One liner key and cert: - openssl req -new -newkey rsa:2048 -keyout host-key.pem -nodes -subj "/" | \ - curl -fk --data-binary @- -o host.pem "https://localhost/sign?cn=my-host&ns=my-host.localdomain" +``` +openssl req -new -newkey rsa:2048 -keyout host-key.pem -nodes -subj "/" | \ + curl -fk --data-binary @- -o host.pem "https://localhost/sign?cn=my-host&ns=my-host.localdomain" +``` Using subject from the request - `cn` is optional since `0.7`: - openssl req -new -newkey rsa:2048 -keyout host-key.pem -nodes -subj "/CN=my-host" | \ - curl -fk --data-binary @- -o host.pem "https://localhost/sign?ns=my-host.localdomain" +``` +openssl req -new -newkey rsa:2048 -keyout host-key.pem -nodes -subj "/CN=my-host" | \ + curl -fk --data-binary @- -o host.pem "https://localhost/sign?ns=my-host.localdomain" +``` Using alternative IP, NS or both: **Note:** If neither IP nor NS is provided, a client certificate would be generated. Always provide IP, NS or both for server certificates. - curl -fk --data-binary @host.csr -o host.pem "https://localhost/sign?cn=my-host&ip=10.0.0.1" - curl -fk --data-binary @host.csr -o host.pem "https://localhost/sign?cn=my-host&ip=10.0.0.1,192.168.0.1" - curl -fk --data-binary @host.csr -o host.pem "https://localhost/sign?cn=my-host&ns=localhost,my-host.localdomain" - curl -fk --data-binary @host.csr -o host.pem "https://localhost/sign?cn=my-host&ip=10.0.0.1&ns=my-host.localdomain" +``` +curl -fk --data-binary @host.csr -o host.pem "https://localhost/sign?cn=my-host&ip=10.0.0.1" +curl -fk --data-binary @host.csr -o host.pem "https://localhost/sign?cn=my-host&ip=10.0.0.1,192.168.0.1" +curl -fk --data-binary @host.csr -o host.pem "https://localhost/sign?cn=my-host&ns=localhost,my-host.localdomain" +curl -fk --data-binary @host.csr -o host.pem "https://localhost/sign?cn=my-host&ip=10.0.0.1&ns=my-host.localdomain" +``` Using alternative number of days: - curl -fk --data-binary @host.csr -o host.pem "https://localhost/sign?cn=my-host&days=30" +``` +curl -fk --data-binary @host.csr -o host.pem "https://localhost/sign?cn=my-host&days=30" +``` + +The signing of certificates can also be protected with a token: + +``` +echo -n "mysupersecret" | md5sum +docker run -d -p 80:8080 -p 443:8443 \ + -e TOKEN=md5:6dc90cbae61d22f5cd1ca3f4025c47a3 \ + quay.io/jcmoraisjr/simple-ca +``` + +Now `/sign` method must provide `&token=mysupersecret` param, otherwise the certificate won't be signed. If using echo to generate the hash, remember to use `-n` so echo won't add a line break into your secret. + +# Multi Certificate Authority + +Since 0.8 simple-ca has support for multiple certificate authorities: + +``` +docker run -d -p 80:8080 -p 443:8443 \ + -e CA_LIST=servers,etcd,kube \ + -e CA_CN_servers="CA for servers" \ + -e CA_CN_etcd="Etcd CA" \ + -e CA_CN_kube="Kubernetes CA" \ + quay.io/jcmoraisjr/simple-ca +openssl req -new -newkey rsa:2048 -keyout kube-etcd-key.pem -nodes -subj "/" | \ + curl -fk --data-binary @- -o kube-etcd.pem "https://localhost/sign/etcd?cn=kube" +openssl req -new -newkey rsa:2048 -keyout kube-admin-key.pem -nodes -subj "/" | \ + curl -fk --data-binary @- -o kube-admin.pem "https://localhost/sign/kube?cn=admin&o=system:masters" +``` + +When running 0.8 the first time on a schema of an old version, simple-ca will update to the new schema creating the CA `default`. All new certificate authorities are created as sub-directories of `/ssl/ca`. + +Both syntax are still valid: `/sign` and `/ca` using `default` certificate authority, and the new `/sign/` and `/ca/`. The ID of the certificate authority of the first syntax can be changed declaring `CA_DEFAULT` environment variable. + +If TLS certificate for https isn't provided, the CA which will sign the certificate will be chosen in the following order: + +* Certificate authority declared with `CA_DEFAULT`, which defaults to `default` +* If the above certificate authority ID does not exist, the first certificate authority declared on `CA_LIST` will be used + +New certificate authorities can be included updating `CA_LIST` environment variable. The next start of simple-ca will update the schema. + +Note that removing CAs from the `CA_LIST` will deny the access from `/sign` and `/ca` methods but won't remove it from the schema. If the CA is reincluded to the list, the same CA cert and private key will continue to sign certificates. + +# Parameters + +The following parameters can be used in the query string of the `/sign` method: + +* `dn`: Distinguished name in the following format: `/O=.../OU=.../.../CN=...` +* `cn`: Common name of the certificate - do not use the `/CN=` prefix +* `o`: Comma separated list of organizationName - do not use the `/O=` prefix +* `ip`: Comma separated list of IPs of server certificate +* `ns`: Comma separated list of name servers of server certificate. Either `ip` or `ns` must be provided for server certificates, otherwise a client certificate will be generated +* `days`: The number of days to certify the signed certificate +* `token`: Security token, should be provided when signing certificates if the server was started with `TOKEN` envvar # Options The following optional environment variables may be defined: -* `CRT_DAYS`: default number of days to certify signed certificates, defaults to 365, can be changed per signed certificate -* `CA_DAYS`: number of days to certify the CA certificate, defaults to 3652 (10 years) -* `CA_DIR`: path to `ca.pem` and `private/ca-key.pem` used to sign certificates, defaults to `/ssl/ca`. A new cert and key will be created if not found -* `CA_CN`: Aa self generated CA will use `CA_CN` as its common name, defaults to `my-ca` +* `TOKEN`: hash of the secret token. If defined the `&token=` is mandatory and must match the value. The token has the following format: `:`. The currently supported algorithms are `md5`, `sha1`, `sha256` and `sha512` +* `CRT_DAYS`: default number of days to certify signed certificates, defaults to 365, can be changed per signed certificate with `&days=` +* `CA_DAYS`: number of days to certify the auto generated CA certificate, defaults to 3652 (10 years) +* `CA_DIR`: path to directory of all certificate authorities. A new cert and key will be created for any CA if not found +* `CA_CN`: A self generated CA will use `CA_CN` as its common name, defaults to `my-ca` * `CERT_TLS`: TLS certificate and key file used by web server to provide https, defaults to `/ssl/www/localhost.pem`. If not found, CA itself will sign a certificate * `CERT_TLS_DNS`: name server of the CA server, used on auto generated TLS certificate. At least one of `CERT_TLS_DNS` or `CERT_TLS_IP` should be provided * `CERT_TLS_IP`: public IP of the CA server, used on auto generated TLS certificate. At least one of `CERT_TLS_DNS` or `CERT_TLS_IP` should be provided * `CERT_TLS_DAYS`: number of days to certify the CA server cert, used on auto generated TLS certificate, defaults to 365 days +When using multi certificate authority, the following environment variables might also be defined: + +* `CA_LIST`: comma separated list of IDs of CAs. IDs must match `[a-z0-9_]`. The default value is one certificate authority: `default` +* `CA_DEFAULT`: ID of the certificate authority that should be used on `/sign` and `/ca` methods. `default` is used if not provided. Note that if `CA_LIST` doesn't include `default` and `CA_DEFAULT` isn't provided, `/sign` and `/ca` methods will issue `404 Not Found`. +* `CRT_DAYS_`: override default `CRT_DAYS` +* `CA_DAYS_`: override default `CA_DAYS` +* `CA_CN_`: override default `CA_CN` + # Deploy * Mount the `/ssl` directory to ensure that nothing will be lost if the container is recreated @@ -75,24 +157,26 @@ The following optional environment variables may be defined: This systemd unit has the most common configuration: - [Unit] - Description=Simple CA - After=docker.service - Requires=docker.service - [Service] - ExecStartPre=-/usr/bin/docker stop simple-ca - ExecStartPre=-/usr/bin/docker rm simple-ca - ExecStartPre=/usr/bin/mkdir -p /var/lib/simple-ca/ssl - ExecStartPre=/bin/bash -c 'chown $(docker run --rm quay.io/jcmoraisjr/simple-ca id -u lighttpd) /var/lib/simple-ca/ssl' - ExecStart=/usr/bin/docker run \ - --name simple-ca \ - -p 80:8080 \ - -p 443:8443 \ - -e CERT_TLS_DNS=ca.mycompany.com \ - -e CA_CN=MyCompany-CA \ - -v /var/lib/simple-ca/ssl:/ssl \ - quay.io/jcmoraisjr/simple-ca:latest - RestartSec=10s - Restart=always - [Install] - WantedBy=multi-user.target +``` +[Unit] +Description=Simple CA +After=docker.service +Requires=docker.service +[Service] +ExecStartPre=-/usr/bin/docker stop simple-ca +ExecStartPre=-/usr/bin/docker rm simple-ca +ExecStartPre=/usr/bin/mkdir -p /var/lib/simple-ca/ssl +ExecStartPre=/bin/bash -c 'chown $(docker run --rm quay.io/jcmoraisjr/simple-ca id -u lighttpd) /var/lib/simple-ca/ssl' +ExecStart=/usr/bin/docker run \ + --name simple-ca \ + -p 80:8080 \ + -p 443:8443 \ + -e CERT_TLS_DNS=ca.mycompany.com \ + -e CA_CN=MyCompany-CA \ + -v /var/lib/simple-ca/ssl:/ssl \ + quay.io/jcmoraisjr/simple-ca:latest +RestartSec=10s +Restart=always +[Install] +WantedBy=multi-user.target +```