From 6b4c6fc062957ba13ba4cc87101d2849c41d7e7a Mon Sep 17 00:00:00 2001 From: Christian Schwarz Date: Sat, 22 Aug 2020 02:51:09 +0200 Subject: [PATCH] [#357] docs: update quickstart + tls transport to produce keypairs with subject alternative names fixes #357 --- docs/changelog.rst | 8 ++ docs/configuration/transports.rst | 81 ++++++++++++-------- docs/quickstart/continuous_server_backup.rst | 25 +++--- 3 files changed, 70 insertions(+), 44 deletions(-) diff --git a/docs/changelog.rst b/docs/changelog.rst index 410e738..d74ded4 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -44,6 +44,13 @@ This is a big one! Headlining features: We highly recommend studying the updated :ref:`overview section of the configuration chapter ` to understand how replication works. +.. TIP:: + + Go 1.15 changed the default TLS validation policy to **require Subject Alternative Names (SAN) in certificates**. + The openssl commands we provided in the quick-start guides up to and including the zrepl 0.3 docs seem not to work properly. + If you encounter certificate validation errors regarding SAN and wish to continue to use your old certificates, start the zrepl daemon with env var ``GODEBUG=x509ignoreCN=0``. + Alternatively, generate new certificates with SANs (see :ref:`both options int the TLS transport docs ` ). + Quick-start guides: * We have added :ref:`another quick-start guide for a typical workstation use case for zrepl `. @@ -51,6 +58,7 @@ Quick-start guides: Additional changelog: +* |break| Go 1.15 TLS changes mentioned above. * |break| |break_config| **more restrictive job names than in prior zrepl versions** Starting with this version, job names are going to be embedded into ZFS holds and bookmark names (see :ref:`this section for details `). Therefore you might need to adjust your job names. diff --git a/docs/configuration/transports.rst b/docs/configuration/transports.rst index ad1b92d..be88a56 100644 --- a/docs/configuration/transports.rst +++ b/docs/configuration/transports.rst @@ -91,7 +91,8 @@ The ``tls`` transport uses TCP + TLS with client authentication using client cer The client identity is the common name (CN) presented in the client certificate. It is recommended to set up a dedicated CA infrastructure for this transport, e.g. using OpenVPN's `EasyRSA `_. -For a simple 2-machine setup, see the :ref:`instructions below`. +For a simple 2-machine setup, mutual TLS might also be sufficient. +We provide :ref:`copy-pastable instructions to generate the certificates below `. The implementation uses `Go's TLS library `_. Since Go binaries are statically linked, you or your distribution need to recompile zrepl when vulnerabilities in that library are disclosed. @@ -103,6 +104,16 @@ If intermediate CAs are used, the **full chain** must be present in either in th Regardless, the client's certificate must be first in the ``cert`` file, with each following certificate directly certifying the one preceding it (see `TLS's specification `_). This is the common default when using a CA management tool. +.. NOTE:: + + As of Go 1.15 (zrepl 0.3.0 and newer), the Go TLS / x509 library **requrires Subject Alternative Names** + be present in certificates. You might need to re-generate your certificates using one of the :ref:`two alternatives + provided below`. + + Note further that zrepl continues to use the CommonName field to assign client identities. + Hence, we recommend to keep the Subject Alternative Name and the CommonName in sync. + + Serve ~~~~~ @@ -147,45 +158,25 @@ The ``server_cn`` specifies the expected common name (CN) of the server's certif It overrides the hostname specified in ``address``. The connection fails if either do not match. +.. _transport-tcp+tlsclientauth-certgen: + .. _transport-tcp+tlsclientauth-2machineopenssl: -Self-Signed Certificates -~~~~~~~~~~~~~~~~~~~~~~~~ +Mutual-TLS between Two Machines +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Tools like `EasyRSA `_ make it easy to manage CA infrastructure for multiple clients, e.g. a central zrepl backup server (in sink mode). However, for a two-machine setup, self-signed certificates distributed using an out-of-band mechanism will also work just fine: Suppose you have a push-mode setup, with `backups.example.com` running the :ref:`sink job `, and `prod.example.com` running the :ref:`push job `. Run the following OpenSSL commands on each host, substituting HOSTNAME in both filenames and the interactive input prompt by OpenSSL: .. code-block:: bash - :emphasize-lines: 1-5,24 - openssl req -x509 -sha256 -nodes \ - -newkey rsa:4096 \ - -days 365 \ - -keyout HOSTNAME.key \ - -out HOSTNAME.crt - - #Generating a 4096 bit RSA private key - #................++++ - #.++++ - #writing new private key to 'backups.key' - #----- - #You are about to be asked to enter information that will be incorporated - #into your certificate request. - #What you are about to enter is what is called a Distinguished Name or a DN. - #There are quite a few fields but you can leave some blank - #For some fields there will be a default value, - #If you enter '.', the field will be left blank. - #----- - #Country Name (2 letter code) [XX]: - #State or Province Name (full name) []: - #Locality Name (eg, city) [Default City]: - #Organization Name (eg, company) [Default Company Ltd]: - #Organizational Unit Name (eg, section) []: - #Common Name (eg, your name or your server's hostname) []:HOSTNAME - #Email Address []: + (name=HOSTNAME; openssl req -x509 -sha256 -nodes \ + -newkey rsa:4096 \ + -days 365 \ + -keyout $name.key \ + -out $name.crt -addext "subjectAltName = DNS:$name" -subj "/CN=$name") Now copy each machine's ``HOSTNAME.crt`` to the other machine's ``/etc/zrepl/HOSTNAME.crt``, for example using `scp`. The serve & connect configuration will thus look like the following: @@ -216,6 +207,36 @@ The serve & connect configuration will thus look like the following: ... +Certificate Authority using EasyRSA +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +For more than two machines, it might make sense to set up a CA infrastructure. +Tools like `EasyRSA `_ make this very easy: + +:: + + #!/usr/bin/env bash + set -euo pipefail + + HOSTS=(backupserver prod1 prod2 prod3) + + curl -L https://github.com/OpenVPN/easy-rsa/releases/download/v3.0.7/EasyRSA-3.0.7.tgz > EasyRSA-3.0.7.tgz + echo "157d2e8c115c3ad070c1b2641a4c9191e06a32a8e50971847a718251eeb510a8 EasyRSA-3.0.7.tgz" | sha256sum -c + rm -rf EasyRSA-3.0.7 + tar -xf EasyRSA-3.0.7.tgz + cd EasyRSA-3.0.7 + ./easyrsa + ./easyrsa init-pki + ./easyrsa build-ca nopass + + for host in $HOSTS; do + ./easyrsa build-serverClient-full $host nopass + echo cert for host $host available at pki/issued/$host.crt + echo key for host $host available at pki/private/$host.key + done + echo ca cert available at pki/ca.crt + + .. _transport-ssh+stdinserver: ``ssh+stdinserver`` Transport diff --git a/docs/quickstart/continuous_server_backup.rst b/docs/quickstart/continuous_server_backup.rst index f17c119..c19bec3 100644 --- a/docs/quickstart/continuous_server_backup.rst +++ b/docs/quickstart/continuous_server_backup.rst @@ -51,21 +51,18 @@ To get things going quickly, we skip setting up a CA and generate two self-signe For convenience, we generate the key pairs on our local machine and distribute them using ssh: .. code-block:: bash - :emphasize-lines: 6,13 - openssl req -x509 -sha256 -nodes \ - -newkey rsa:4096 \ - -days 365 \ - -keyout backups.key \ - -out backups.crt - # ... and use "backups" as Common Name (CN) + (name=backups; openssl req -x509 -sha256 -nodes \ + -newkey rsa:4096 \ + -days 365 \ + -keyout $name.key \ + -out $name.crt -addext "subjectAltName = DNS:$name" -subj "/CN=$name") - openssl req -x509 -sha256 -nodes \ - -newkey rsa:4096 \ - -days 365 \ - -keyout prod.key \ - -out prod.crt - # ... and use "prod" as Common Name (CN) + (name=prod; openssl req -x509 -sha256 -nodes \ + -newkey rsa:4096 \ + -days 365 \ + -keyout $name.key \ + -out $name.crt -addext "subjectAltName = DNS:$name" -subj "/CN=$name") ssh root@backups "mkdir /etc/zrepl" scp backups.key backups.crt prod.crt root@backups:/etc/zrepl @@ -94,4 +91,4 @@ We define a corresponding **sink job** named ``sink`` in ``/etc/zrepl/zrepl.yml` Go Back To Quickstart Guide --------------------------- -:ref:`Click here ` to go back to the quickstart guide. \ No newline at end of file +:ref:`Click here ` to go back to the quickstart guide.