Revision: 259 http://svn.sv.gnu.org/viewvc/?view=rev&root=administration&revision=259 Author: rwp Date: 2016-10-15 20:55:10 +0000 (Sat, 15 Oct 2016) Log Message: ----------- https: Review, edit, update EFF Certbot instructions
Many thanks for Assaf's most excellent documentation. Modified Paths: -------------- trunk/sviki/https.mdwn Modified: trunk/sviki/https.mdwn =================================================================== --- trunk/sviki/https.mdwn 2016-10-15 20:55:02 UTC (rev 258) +++ trunk/sviki/https.mdwn 2016-10-15 20:55:10 UTC (rev 259) @@ -1,19 +1,19 @@ -HTTPS Certificates -=================== +HTTPS Certificates +================== -This page describes the HTTPS configuration for savannah's -new servers (e.g. `frontend0`, `vcs0`). +This page describes the HTTPS configuration for Savannah's +new servers (e.g. `download0`, `frontend0`, `vcs0`, `mgt0`). The current ('old') servers use a wildcard SSL certificate from GANDI.net. -The new servers use [Let's Encrypt](https://letsencrypt.org) certificates. +The new servers use [Let's Encrypt](https://letsencrypt.org/) certificates. -Further reading about savannah's server: +Further reading about Savannah's server: * [[SavannahArchitecture]] - overview of the current ('old') setup (i.e. vcs, mgt, frontend, internal, vcs, download). * [[SavannahHosts]] - Configuration of the new servers (i.e. mgt0, vcs0, frontend0, internal0, download0). -Further reading about savannah's frontend: +Further reading about Savannah's frontend: * [[FrontEnd]] - Notes about the current frontend setup (git,cvs). * [[FrontEndDevelopmentSite]] - Setting up development sites for savannah. @@ -22,234 +22,63 @@ EFF's CertBot ------------- -[EFF's CertBot](https://certbot.eff.org) is a python-based package that -registers and renews "Let's Encrypt" certificates (it is the successor of -`letencrypt-auto` - the old name of the package, before EFF took over its -maintenance). +[EFF's CertBot](https://certbot.eff.org/) is a program that registers +and renews "Let's Encrypt" certificates. -Savannah's configuration uses `webroot` method (aka `certonly`), -in which the webserver (apache2) exposes a specific directory -over HTTP, certbot writes the authentication files to this directory -and comminucates with "Let's Encrypt"'s certificate authority -to register/renew certificates. For details, see +Savannah's configuration uses the `webroot` method (aka `certonly`) in +which the web server exposes a specific directory over HTTP. Certbot +writes the authentication files to this directory and communicates +with the "Let's Encrypt" certificate authority to register/renew +certificates. For details, see <https://certbot.eff.org/docs/using.html#webroot>. -Savannah uses a non-standard `certbot` configuration, which allows it -to operate without requiring `root` access to the server. By default, -`certbot` requires root access to register/renew certificates (as the -certificate's private-key need to be securely stored, and accesible -only by the webserver). Details of this non-standard setup are +Savannah uses a custom `certbot` configuration which allows it to +operate without requiring `root` access to the server. The client in +default operation requires root superuser access in order to make +modifications to the operating system configuration as an agent for +the system administrator. The system modification is only needed +during the initial installation. After that point it provides a +vulnerable surface for attackers to aim at breaking through. By +operating `certbot` without root privilege it removes that vulnerable +security layer. Removing this vulnerable security attack service is +worth the effort of doing the system administrator doing the manual +configuration setup once. Details of this non-standard setup are described below. -Typical Certbot/webroot setup ------------------------------ +Savannah's non-root certbot installation +---------------------------------------- -*NOTE*: Savannah uses a modified setup which does not require running -`certbot` as root. This section gives a general overview of `certbot ---webroot` setup (to help understand savannah's customization, -below). +Bob Proulx developed and installed a modified `certbot` recipe which +allows `certbot-auto` to operate as a non-root user, isolated in its +own directory. This setup is used on `frontend0`, `vcs0`, and `mgt0`. -Install `certbot` by downloading the prebuilt package for your OS here: -<https://certbot.eff.org/> or by following detailed instructions here -<https://certbot.eff.org/docs/using.html#getting-certbot>. +### Web Server Configuration, Part 1 +In the Apache configuration file, expose this directory with a pre-set URL: -### Web-server configuration, part 1 - -Create a directory where certbot will write the authentication files: - - $ sudo mkdir /var/www/certbot - -In the apache configuration file, expose this directory with a pre-set URL: - - Alias /.well-known /var/www/certbot/.well-known - <Directory "/var/www/certbot/"> + Alias /.well-known /home/certbot/www/certbot/.well-known + <Directory "/home/certbot/www/"> AllowOverride None Require all granted </Directory> -If using nginx, use the following (savannah does not yet use nginx): +If using Nginx, use the following: (frontend0 does not yet use Nginx +however mgt0 and vcs0 do.) location /.well-known { - root /var/www/certbot/ ; + root /home/certbot/www/ ; } -Test the setup by create a file and downloading it -(the `.well-known` subdirectory is needed for testing, otherwise -it will be automatically created by `certbot` on one the first run): +Reload Apache or Nginx. - $ sudo mkdir /var/www/certbot/.well-known - $ sudo touch /var/www/certbot/.well-known/foo - $ wget http://frontend0.sv.gnu.org/.well-known/foo + # service nginx reload + # service apache2 reload +Install `fakeroot`: + # apt-get install fakeroot -### First-time domain registration - -Run `certbot` for the first time, registaring the required domain names. -Multiple domains can be specified, and they will be included in the same -certificate. "Let's Encrypt" does not support wildcard certificates, so -all needed domains need to be specified. -The first listed domain will determine the output file names. - - ./certbot-auto certonly \ - --email savannah-hackers-priv...@gnu.org \ - --agree-tos \ - --keep-until-expiring - --webroot \ - --configdir /etc/letsencrypt/ \ - -w /var/www/certbot/ \ - -d frontend0.savannah.gnu.org \ - -d frontend0.savannah.nongnu.org \ - -d frontend0.sv.gnu.org \ - -d frontend0.sv.nongnu.org \ - -d jsmith.frontend0.savannah.gnu.org \ - -d jsmith.frontend0.savannah.nongnu.org \ - -d jsmith.frontend0.sv.gnu.org \ - -d jsmith.frontend0.sv.nongnu.org \ - ... - -If the registration succeeded, the following files and directories -will be created (these are the certificates and keys): - - /etc/letsencrypt - |-- accounts - | `-- acme-v01.api.letsencrypt.org - | `-- directory - | `-- xxxxxxxxxxxxxxxxxxxxxxxxxxx - | |-- meta.json - | |-- private_key.json - | `-- regr.json - |-- archive - | `-- frontend0.savannah.gnu.org - | |-- cert1.pem - | |-- chain1.pem - | |-- fullchain1.pem - | `-- privkey1.pem - |-- csr - | `-- 0000_csr-certbot.pem - |-- keys - | `-- 0000_key-certbot.pem - |-- live - | `-- frontend0.savannah.gnu.org - | |-- cert.pem -> ../../archive/frontend0.savannah.gnu.org/cert1.pem - | |-- chain.pem -> ../../archive/frontend0.savannah.gnu.org/chain1.pem - | |-- fullchain.pem -> ../../archive/frontend0.savannah.gnu.org/fullchain1.pem - | `-- privkey.pem -> ../../archive/frontend0.savannah.gnu.org/privkey1.pem - `-- renewal - `-- frontend0.savannah.gnu.org.conf - - -### Web-server configuration, part 2 (SSL) - -The Apache SSL configuration will be: - - <VirtualHost *:443> - SSLEngine on - - SSLCertificateFile /etc/letsencrypt/live/frontend0.savannah.gnu.org/cert.pem - SSLCertificateKeyFile /etc/letsencrypt/live/frontend0.savannah.gnu.org/privkey.pem - SSLCertificateChainFile /etc/letsencrypt/live/frontend0.savannah.gnu.org/chain.pem - - # Many more SSL-specific configuration (ciphers, protocols, etc.) - </VirtualHost> - -If using nginx, the configuration is: - - server { - listen 443 ssl; - ssl on; - ssl_certificate /etc/letsencrypt/live/frontend0.savannah.gnu.org/fullchain.pem; - ssl_certificate_key /etc/letsencrypt/live/frontend0.savannah.gnu.org/privkey.pem; - - # Many more SSL-specific configuration (ciphers, protocols, etc.) - } - - -Restart the web-server to load the certificates (check server logs to -ensure loading suceeded). - - -### SSL certificate testing - - -Use `wget` or `curl` to test if the certificates `just works`: - - $ wget -O- https://frontend0.savannah.gnu.org/ - --2016-09-07 00:27:08-- https://frontend0.savannah.gnu.org/ - Resolving frontend0.savannah.gnu.org (frontend0.savannah.gnu.org)... 208.118.235.79 - Connecting to frontend0.savannah.gnu.org (frontend0.savannah.gnu.org)|208.118.235.79|:443... connected. - ... - - - $ curl https://frontend0.savannah.gnu.org/ - ... - - -Or use `openssl` to troubleshoot the connection: - - $ openssl s_client -servername frontend0.savannah.gnu.org \ - -host frontend0.savannah.gnu.org \ - -port 443 -CApath /etc/ssl/certs -showcerts </dev/null - ...lots of details omitted for brevity... - Verify return code: 0 (ok) - - - -### Certificate renewal - -"Let's Encrypt"'s certificate expire after 90 days, and must be routinely -renewed. It is recommended to run the `renew` command once a month (e.g. in -`/etc/cron.monthly` to avoid service disruptions). - - certbot-auto --no-self-upgrade \ - --email savannah-hackers-priv...@gnu.org \ - --agree-tos \ - renew \ - --text \ - --webroot \ - --config-dir /etc/letsencrypt \ - -w /var/www/certbot/ - -If all worked well, the output will resemble: - - ------------------------------------------------------------------------------- - Processing /etc/letsencrypt/renewal/frontend0.savannah.gnu.org.conf - ------------------------------------------------------------------------------- - - The following certs are not due for renewal yet: - /etc/letsencrypt/live/frontend0.savannah.gnu.org/fullchain.pem (skipped) - No renewals were attempted. - - -### Adding subdomains - -"Let's Encrypt" certificates do not support wildcard subdomains (e.g. -`*.frontend.savannah.gnu.org`). Each domain must be explicitly registered. - -One method is to register multiple domains in a single certificate (and a single -`certbot-auto` invocation) - they will be stored (and visible) in the -"Certificate Subject Alternative Name" field of the published certificate. -To add domains, simply add more `-d MY.SUB.DOMAIN.ORG` parameters to the -`certbot-auto` command. Make sure to add them *last* and leave the name -of the first domain unchanged, as the name of the first domain (the -first `-d` parameter) detemintes the output file names in `/etc/letsencrypt`). - -Another method is to create a separate certificate file for each subdomain, -and run `certbot-auto` separately for each domain. Each certificate will -have a separate subdirectory under `/etc/letsencrypt/live`. (This is the -method savannah currently uses). - - - -Savannah's non-root certbot installation ----------------------------------------- - -Bob Proulx developed and installed a modfied configuration which -allows `certbot-auto` to operate as a non-root user, isolated in its -own directory. This setup is used on `frontend0`. - Create a dedicated non-root user: # adduser --disabled-password --gecos Certbot certbot @@ -260,6 +89,16 @@ $ cd /home/certbot $ mkdir -p bin etc www log tmp +Test the web setup by create a file and downloading it +(the `.well-known` subdirectory is needed for testing, otherwise +it will be automatically created by `certbot` on one the first run): + + $ mkdir /home/certbot/www/.well-known + $ echo "this is a test file" /home/certbot/certbot/.well-known/foo.txt + $ wget -O- http://frontend0.sv.gnu.org/.well-known/foo.txt + this is a test file + $ rm /home/certbot/certbot/.well-known/foo.txt # clean up + Create two fake root programs (to simulate root environment for the `certbot-auto` program): @@ -271,25 +110,45 @@ $ printf '#!/bin/sh\nfakeroot env "$@"' > sudo $ chmod a+x sudo -Install the certbot program into `/home/certbot/src`. -FIXME: Fill-in exact commands. + $ wget https://dl.eff.org/certbot-auto + chmod a+x certbot-auto -When `certbot-auto` is run the first time (as the non-root `certbot` -user), it will try to install some packages automatically (by calling -`apt-get`). With the fake `apt-get` in place, the names of the -required packages will be printed to the screen instead of being -installed. Install the printed packages as root. The list of pacakges -will be likely similar to this: +Verify that `PATH` is correctly set to process `$HOME/bin` prior to +other directories. This ensures that the local copies will be called +instead of the system ones and will override them. If this is not +correct then fix the PATH setting in the `$HOME/.profile` file. - # apt-get install -y --no-install-recommends python python-dev \ - python-virtualenv gcc dialog libaugeas0 augeas-lenses \ - libssl-dev libffi-dev ca-certificates + $ type apt-get + apt-get is /home/certbot/bin/apt-get -Run `certbot-auto` as `certbot` user with `-d` parameter to register a -new domain: +Run the `certbot-auto` command the first time using the +`--os-packages-only` option. This will instruct it to call `apt-get` +in order to install any dependencies that it requires. This will call +our local fake `apt-get` which will simply print out the operation that +it is attempting. Here is an example. + $ certbot-auto --no-self-upgrade --os-packages-only + Bootstrapping dependencies for Debian-based OSes... + fakeroot sudo apt-get update + fake apt-get update + fakeroot sudo apt-get install --no-install-recommends python python-dev virtualenv python-virtualenv gcc dialog libaugeas0 augeas-lenses libssl-dev libffi-dev ca-certificates + fake apt-get install --no-install-recommends python python-dev virtualenv python-virtualenv gcc dialog libaugeas0 augeas-lenses libssl-dev libffi-dev ca-certificates + Failed to install a working "virtualenv" command, exiting + +The failure is expected since we are preventing it from being able to +perform this root superuser operation. Note the `apt-get` command +that it is trying to run. Perform that task as root yourself. In +this case the example here is the following. The list of packages is +system dependent and your list may very well be different from this +example. + + # apt-get install --no-install-recommends python python-dev ... use the list of packages from your output not this example + +Run `certbot-auto` as `certbot` user with `-d` parameters to register +new domains: + # su -l certbot - $ XDG_DATA_HOME=src \ + $ env XDG_DATA_HOME=src \ certbot-auto --no-self-upgrade \ --email savannah-reports-priv...@gnu.org \ --agree-tos \ @@ -299,45 +158,94 @@ --logs-dir ~/log \ -w ~/www \ -d frontend0.savannah.gnu.org \ - -d frontend0.savannah.nongnu.org + -d frontend0.savannah.nongnu.org \ + -d frontend0.sv.gnu.org \ + -d frontend0.sv.nongnu.org -FIXME: Bob's examples in `/home/certbot/README` show a slightly more complicated -invocation. Validate above command or fix it. +Create the renew script. -The content of `/home/certbot` should look like this: + $ printf '#!/bin/sh\nenv XDG_DATA_HOME=src certbot-auto --no-self-upgrade --email savannah-reports-priv...@gnu.org --agree-tos renew --text --webroot --config-dir ~/etc --work-dir ~/tmp --logs-dir ~/log -w ~/www\n' > $HOME/bin/renew-ssl-certificate + $ chmod a+x $HOME/bin/renew-ssl-certificate +Install the /etc/cron.daily/renew-ssl-certificate-cron script. FIXME: +Provide a network location to download this small script. It is a +little large for an inline copy here. However the main part of it is +simply `echo renew-ssl-certificate | su - certbot` wrapped to log +output and email root upon errors and significant changes. + +The content of `/home/certbot` will look like this: + /home/certbot |-- bin | |-- apt-get | |-- certbot-auto | |-- renew-ssl-certificate - | |-- renew-ssl-certificate-cron | `-- sudo | - |-- etc [*** equivalent to /etc/letsencrypt in the previous section, ***] - | [*** certificates and private keys in PEM format are stored here ***] - | |-- accounts + |-- etc [*** certificates and private keys in PEM format are stored here ***] | |-- archive - | |-- csr | |-- keys - | |-- live - | `-- renewal + | |-- live [*** certificates path ***] + | [...] | |-- log [*** renewal logs will be saved here ***] | - |-- src [*** the installed 'certbot-auto' program ***] + |-- src [*** the installed python virtualenv and 'certbot' program ***] | `-- letsencrypt | `-- bin | [...] | |-- tmp + | `-- www - `-- .well-known [*** This directory should be exposed by the webserver ***] + `-- .well-known [*** domain validation directory exposed to web ***] +### Web Server Configuration, Part 2 +#### Forward Secrecy & Diffie Hellman Ephemeral Parameters + +Both Apache and Nginx rely upon OpenSSL for the Diffie-Hellman which +defaults to 1024 bits. Create a stronger 2048 parameter for the DH +key exchange. + + # cd /etc/ssl + # openssl dhparam -out dhparam.pem 2048 + + +#### For Apache + + <VirtualHost *:443> + SSLEngine on + SSLCertificateFile /home/certbot/etc/live/frontend0.savannah.gnu.org/cert.pem + SSLCertificateKeyFile /home/certbot/etc/live/frontend0.savannah.gnu.org/privkey.pem + SSLCertificateChainFile /home/certbot/etc/live/frontend0.savannah.gnu.org/chain.pem + SSLOpenSSLConfCmd DHParameters "/etc/ssl/dhparams.pem" + SSLHonorCipherOrder On + SSLCipherSuite ... use current accepted values + SSLProtocol ... use current accepted values + include ssl_params.local; + # Many more SSL-specific configuration items + +#### For Nginx + + server { + listen 443 ssl; + listen [::]:443 ssl; + ssl_certificate /home/certbot/etc/live/frontend0.savannah.gnu.org/fullchain.pem; + ssl_certificate_key /home/certbot/etc/live/frontend0.savannah.gnu.org/privkey.pem; + ssl_dhparam /etc/ssl/dhparam.pem; + ssl_prefer_server_ciphers On; + ssl_ciphers ... use current accepted values + ssl_protocols ... use current accepted values + ssl_session_cache shared:SSL:10m; + ssl_session_timeout 10m; + include ssl_params.local; + # Many more SSL-specific configuration + + ### Frontend0's apache configuration -The majority of the apache's configurations are in +The majority of the Apache's configurations are in `/etc/apache2/sites-available/sv.inc`. However this file does *not* contain SSL configuration - as it is included twice in other files (once for gnu, once for nongnu). @@ -367,32 +275,14 @@ virtual hosts). -### Manual Renewal - -The script `/home/certbot/bin/renew-ssl-certificate` contains: - - #!/bin/sh - - # Conditionally renew the certificate. - - env XDG_DATA_HOME=src certbot-auto --no-self-upgrade --email savannah-reports-priv...@gnu.org --agree-tos renew --text --webroot --config-dir ~/etc --work-dir ~/tmp --logs-dir ~/log -w ~/www - - -### Automatic Renewal (cron) - -FIXME: document `/home/certbot/bin/renew-ssl-certificate-cron` once -the setup is stable. - -FIXME: is it symlinked in `/etc/cron.monthly` ? - - ### Registering additional sub-domains Additional subdomains can be used for [[FrontEndDevelopmentSite]]. -The current recommendation is to register new subdomains in a new, -separate certificate file (as opposed to adding more subdomains to the -existing certficiate). +The recommendation is to register new subdomains in a new, separate +certificate file as opposed to adding more subdomains to the existing +certficiate. This way development certificates are not exposed +through the main production certificate information. # su - certbot $ env XDG_DATA_HOME=src \