From 6a779e7a84f19c86e381effb0d7a9e97909b1d92 Mon Sep 17 00:00:00 2001 From: Maarten de Waard Date: Mon, 22 Aug 2016 12:42:24 +0200 Subject: [PATCH] README is now valid rst --- README.rst | 408 +++++++++++++++++++++++++++-------------------------- 1 file changed, 208 insertions(+), 200 deletions(-) diff --git a/README.rst b/README.rst index 2c603eb..daafa8f 100644 --- a/README.rst +++ b/README.rst @@ -8,11 +8,11 @@ Currently this plugin has been tested on Debian Jessie, but it will most likely work on Ubuntu 14.04+ too. If you are running Debian Wheezy, you may need to take additional steps during the installation. - - Debian Jessie (or higher) or Ubuntu Trusty (or higher). - - Python 2.7 (2.6 is supported by certbot and our goal is to be compatible but - it has not been tested yet). - - HAProxy 1.5+ (we will configure SNI, which is not strictly required) - - Certbot 0.8+ +- Debian Jessie (or higher) or Ubuntu Trusty (or higher). +- Python 2.7 (2.6 is supported by certbot and our goal is to be compatible but + it has not been tested yet). +- HAProxy 1.5+ (we will configure SNI, which is not strictly required) +- Certbot 0.8+ Installing: Getting started --------------------------- @@ -22,57 +22,62 @@ almost entirely the same process on Ubuntu. First add the backports repo for Jessie to your apt sources. -.. note: This will not work for Ubuntu, you will need to use another source, - check which version comes with your version of Ubuntu, if it is a version - below 0.8, you need to find a back port PPA or download certbot from source. +.. note:: -``` -echo "deb http://ftp.debian.org/debian jessie-backports main" >> \ + This will not work for Ubuntu, you will need to use another source, + check which version comes with your version of Ubuntu, if it is a version + below 0.8, you need to find a back port PPA or download certbot from source. + +.. code:: bash + + echo "deb http://ftp.debian.org/debian jessie-backports main" >> \ /etc/apt/sources.list.d/jessie-backports.list -``` Now update, upgrade and install some requirements: - - **Some utilities:** sudo tcpdump ufw git curl wget - - **OpenSSL and CA certificates:** openssl ca-certificates - - **Build dependencies:** build-essential libffi-dev libssl-dev python-dev - - **Python and related:** python python-setuptools - - **HAProxy:** haproxy - - pip -``` -apt-get update -apt-get upgrade -y -apt-get install -y \ - sudo tcpdump ufw git curl wget \ - openssl ca-certificates \ - build-essential libffi-dev libssl-dev python-dev \ - python python-setuptools \ - haproxy +- **Some utilities:** sudo tcpdump ufw git curl wget +- **OpenSSL and CA certificates:** openssl ca-certificates +- **Build dependencies:** build-essential libffi-dev libssl-dev python-dev +- **Python and related:** python python-setuptools +- **HAProxy:** haproxy +- **Python dependency managing:** pip -easy_install pip -pip install --upgrade setuptools -``` +.. code:: bash + + apt-get update + apt-get upgrade -y + apt-get install -y \ + sudo tcpdump ufw git curl wget \ + openssl ca-certificates \ + build-essential libffi-dev libssl-dev python-dev \ + python python-setuptools \ + haproxy + + easy_install pip + pip install --upgrade setuptools We also installed a simple firewall above, but it is not yet configured, let's do that now: -``` -ufw allow ssh -ufw allow http -ufw allow https -ufw default deny incoming -ufw --force enable -``` +.. code:: bash -.. warning: You probably want a little more protection for a production proxy - than just this simple firewall, but it's out of the scope of this readme. + ufw allow ssh + ufw allow http + ufw allow https + ufw default deny incoming + ufw --force enable + +.. warning:: + + You probably want a little more protection for a production proxy + than just this simple firewall, but it's out of the scope of this readme. Now set a hostname. -``` -echo "[INSERT YOUR HOSTNAME HERE]" > /etc/hostname -hostname -F /etc/hostname -``` +.. code:: bash + + echo "[INSERT YOUR HOSTNAME HERE]" > /etc/hostname + hostname -F /etc/hostname If you want to run Certbot in an unprivileged mode, keep reading, otherwise, skip to the installation of Certbot. @@ -83,49 +88,50 @@ when processes run as root, most especially when they are opening ports on a public network interface.. In order to let Certbot run as an unprivileged user, we will: - - Create a ``certbot`` user with a home directory on the system so the - automatic renewal of certificates can be run by this user. - - Tell Certbot that the working directories are located in ``certbot``'s home - directory. - - Optionally: add your own user account to the Cerbot user's group so you can - run Certbot manually. - - Allow HAProxy to access the certificates that are generated by Certbot. + +- Create a ``certbot`` user with a home directory on the system so the + automatic renewal of certificates can be run by this user. +- Tell Certbot that the working directories are located in ``certbot``'s home + directory. +- Optionally: add your own user account to the Cerbot user's group so you can + run Certbot manually. +- Allow HAProxy to access the certificates that are generated by Certbot. Lastly, to do automatic renewal of certificates, we will create a systemd timer and a service to start at every boot and every 12 hours, at a random time off the day, in order to not collectively DDOS Let's Encrypts service. -``` -useradd -s /bin/bash -m -d /opt/certbot certbot -usermod -a -G certbot haproxy # Allow HAProxy access to the certbot certs -mkdir -p /opt/certbot/logs -mkdir -p /opt/certbot/config -mkdir -p /opt/certbot/.config/letsencrypt -``` +.. code:: bash + + useradd -s /bin/bash -m -d /opt/certbot certbot + usermod -a -G certbot haproxy # Allow HAProxy access to the certbot certs + mkdir -p /opt/certbot/logs + mkdir -p /opt/certbot/config + mkdir -p /opt/certbot/.config/letsencrypt If you need to use Certbot from your user account, or if you have a daemon running on your proxy server, that configures domains on your proxy, e.g.: in a web hosting environment - you can add those users to the ``certbot`` group. -``` -usermod -a -G certbot [ADD YOUR USER HERE] -``` +.. code:: bash + + usermod -a -G certbot [ADD YOUR USER HERE] You will also need to tell your user what the working directory of your Cerbot setup is (/opt/certbot/). Certbot allows you to create a configuration file with default settings in the users' home dir: -``$HOME/.config/letsencrypt/cli.ini``. +``opt/certbot/.config/letsencrypt/cli.ini``. Besides the working directory. -``` -mkdir -p $HOME/.config/letsencrypt -cat < $HOME/.config/letsencrypt/cli.ini -work-dir=/opt/certbot/ -logs-dir=/opt/certbot/logs/ -config-dir=/opt/certbot/config -EOF -``` +.. code:: bash + + mkdir -p /opt/certbot/.config/letsencrypt + cat < /opt/certbot/.config/letsencrypt/cli.ini + work-dir=/opt/certbot/ + logs-dir=/opt/certbot/logs/ + config-dir=/opt/certbot/config + EOF Next time you run Certbot, it will use our new working directory. @@ -133,11 +139,12 @@ Now we haven't done one very essential thing yet, install ``certbot-haproxy``. Since our plugin is in an alpha stage, we did not package it yet. You will need to get it from our Gitlab server. -``` -git clone https://code.greenhost.net/open/certbot-haproxy.git -cd ./certbot-haproxy/ -sudo pip install ./ -``` +.. code:: bash + + git clone https://code.greenhost.net/open/certbot-haproxy.git + cd ./certbot-haproxy/ + sudo pip install ./ + Let's Encrypt's CA server will try to contact your proxy on port 80, which is most likely in use for your and/or your customers' websites. So we have @@ -150,121 +157,122 @@ HAProxy setup that also forwards these verification requests. But it is probably not "copy-paste compatible" with your setup. So you need to piece together a configuration that works for you. -``` -cat < /etc/haproxy/haproxy.cfg -global - log /dev/log local0 - log /dev/log local1 notice - chroot /var/lib/haproxy - stats socket /run/haproxy/admin.sock mode 660 level admin - stats timeout 30s - user haproxy - group haproxy - daemon +.. code:: - # Default ciphers to use on SSL-enabled listening sockets. - # Cipher suites chosen by following logic: - # - Bits of security 128>256 (weighing performance vs added security) - # - Key exchange: EECDH>DHE (faster first) - # - Mode: GCM>CBC (streaming cipher over block cipher) - # - Ephemeral: All use ephemeral key exchanges - # - Explicitly disable weak ciphers and SSLv3 - ssl-default-bind-ciphers AES128+AESGCM+EECDH:AES128+EECDH:AES128+AESGCM+DHE:AES128+EDH:AES256+AESGCM+EECDH:AES256+EECDH:AES256+AESGCM+EDH:AES256+EDH:!SHA:!MD5:!RC4:!DES:!DSS - ssl-default-bind-options no-sslv3 + cat < /etc/haproxy/haproxy.cfg + global + log /dev/log local0 + log /dev/log local1 notice + chroot /var/lib/haproxy + stats socket /run/haproxy/admin.sock mode 660 level admin + stats timeout 30s + user haproxy + group haproxy + daemon -defaults - log global - mode http - option httplog - option dontlognull - timeout connect 5000 - timeout client 50000 - timeout server 50000 - errorfile 400 /etc/haproxy/errors/400.http - errorfile 403 /etc/haproxy/errors/403.http - errorfile 408 /etc/haproxy/errors/408.http - errorfile 500 /etc/haproxy/errors/500.http - errorfile 502 /etc/haproxy/errors/502.http - errorfile 503 /etc/haproxy/errors/503.http - errorfile 504 /etc/haproxy/errors/504.http + # Default ciphers to use on SSL-enabled listening sockets. + # Cipher suites chosen by following logic: + # - Bits of security 128>256 (weighing performance vs added security) + # - Key exchange: EECDH>DHE (faster first) + # - Mode: GCM>CBC (streaming cipher over block cipher) + # - Ephemeral: All use ephemeral key exchanges + # - Explicitly disable weak ciphers and SSLv3 + ssl-default-bind-ciphers AES128+AESGCM+EECDH:AES128+EECDH:AES128+AESGCM+DHE:AES128+EDH:AES256+AESGCM+EECDH:AES256+EECDH:AES256+AESGCM+EDH:AES256+EDH:!SHA:!MD5:!RC4:!DES:!DSS + ssl-default-bind-options no-sslv3 -frontend http-in - # Listen on port 80 - bind *:80 - mode http - # Listen on port 443 - # Uncomment after running certbot for the first time, a certificate - # needs to be installed *before* HAProxy will be able to start when this - # directive is not commented. - # - ## bind *:443 ssl crt /opt/cerbot/haproxy_fullchains + defaults + log global + mode http + option httplog + option dontlognull + timeout connect 5000 + timeout client 50000 + timeout server 50000 + errorfile 400 /etc/haproxy/errors/400.http + errorfile 403 /etc/haproxy/errors/403.http + errorfile 408 /etc/haproxy/errors/408.http + errorfile 500 /etc/haproxy/errors/500.http + errorfile 502 /etc/haproxy/errors/502.http + errorfile 503 /etc/haproxy/errors/503.http + errorfile 504 /etc/haproxy/errors/504.http - # Forward Cerbot verification requests to the certbot-haproxy plugin - acl is_certbot path_beg -i /.well-known/acme-challenge - use_backend certbot if is_certbot + frontend http-in + # Listen on port 80 + bind \*:80 + mode http + # Listen on port 443 + # Uncomment after running certbot for the first time, a certificate + # needs to be installed *before* HAProxy will be able to start when this + # directive is not commented. + # + ## bind \*:443 ssl crt /opt/cerbot/haproxy_fullchains - backend certbot - log global - mode http - server certbot 127.0.0.1:8000 + # Forward Cerbot verification requests to the certbot-haproxy plugin + acl is_certbot path_beg -i /.well-known/acme-challenge + use_backend certbot if is_certbot - # If redirection from port 80 to 443 is to be forced, uncomment the next - # line. Keep in mind that the bind *:443 line should be uncommented and a - # certificate should be present for all domains - # redirect scheme https if !{ ssl_fc } + backend certbot + log global + mode http + server certbot 127.0.0.1:8000 - # You can also configure separate domains to force a redirect from port 80 - # to 443 like this: - # redirect scheme https if !{ ssl_fc } and [PUT YOUR DOMAIN NAME HERE] + # If redirection from port 80 to 443 is to be forced, uncomment the next + # line. Keep in mind that the bind \*:443 line should be uncommented and a + # certificate should be present for all domains + # redirect scheme https if !{ ssl_fc } - # The default backend is a cluster of 4 Apache servers that you need to - # host. - default_backend nodes + # You can also configure separate domains to force a redirect from port 80 + # to 443 like this: + # redirect scheme https if !{ ssl_fc } and [PUT YOUR DOMAIN NAME HERE] - backend nodes - log global - mode http - option tcplog - balance roundrobin - option forwardfor - option http-server-close - option httpclose - http-request set-header X-Forwarded-Port %[dst_port] - http-request add-header X-Forwarded-Proto https if { ssl_fc } - option httpchk HEAD / HTTP/1.1\r\nHost:localhost - server node2 hn222.greenhost.nl:80 check - server node1 hn227.greenhost.nl:80 check -EOF + # The default backend is a cluster of 4 Apache servers that you need to + # host. + default_backend nodes -systemctl restart haproxy -``` + backend nodes + log global + mode http + option tcplog + balance roundrobin + option forwardfor + option http-server-close + option httpclose + http-request set-header X-Forwarded-Port %[dst_port] + http-request add-header X-Forwarded-Proto https if { ssl_fc } + option httpchk HEAD / HTTP/1.1\r\nHost:localhost + server node2 hn222.greenhost.nl:80 check + server node1 hn227.greenhost.nl:80 check + EOF + + systemctl restart haproxy Now you can try to run Certbot with the plugin as the Authenticator and Installer, if you already have websites configured in your HAProxy setup, you may try to install a certificate now. -``` -certbot run -``` +.. code:: bash + + certbot run --authenticator certbot-haproxy:haproxy-authenticator \ + --installer certbot-haproxy:haproxy-installer If you want your ``certbot`` to always use our Installer and Authenticator, you can add this to your configuration file: -``` -cat <> $HOME/.config/letsencrypt/cli.ini -authenticator certbot-haproxy:haproxy-authenticator -installer certbot-haproxy:haproxy-installer -EOF -``` +.. code:: bash + + cat <> $HOME/.config/letsencrypt/cli.ini + authenticator certbot-haproxy:haproxy-authenticator + installer certbot-haproxy:haproxy-installer + EOF If you need to run in unattended mode, there are a bunch of arguments you need to set in order for Certbot to generate a certificate for you. - - ``--domain [DOMAIN NAME]`` The domain name you want SSL to be enabled for. - - ``--agree-tos`` Tell Certbot you agree with its `TOS`_ - - ``--email [EMAIL ADDRESS]`` An e-mail address where issues with certificates - can be sent to, as well as changes in the `TOS`_. Or you could supply - ``--register-unsafely-without-email`` but this is not recommended. +- ``--domain [DOMAIN NAME]`` The domain name you want SSL to be enabled for. +- ``--agree-tos`` Tell Certbot you agree with its `TOS`_ +- ``--email [EMAIL ADDRESS]`` An e-mail address where issues with certificates + can be sent to, as well as changes in the `TOS`_. Or you could supply + ``--register-unsafely-without-email`` but this is not recommended. .. _TOS: https://letsencrypt.org/documents/LE-SA-v1.1.1-August-1-2016.pdf @@ -288,16 +296,16 @@ You can't run certbot without root privileges because it needs to access `/etc/letsencrypt`, however you can tell it not to use `/etc/` and use some other path in your home directory. -``` -mkdir ~/projects/cerbot-haproxy/working -mkdir ~/projects/cerbot-haproxy/working/config -mkdir ~/projects/cerbot-haproxy/working/logs -cat <> ~/.config/letsencrypt/cli.ini -work-dir=~/projects/certbot-haproxy/working/ -logs-dir=~/projects/certbot-haproxy/working/logs/ -config-dir=~/projects/certbot-haproxy/working/config -EOF -``` +.. code:: bash + + mkdir ~/projects/cerbot-haproxy/working + mkdir ~/projects/cerbot-haproxy/working/config + mkdir ~/projects/cerbot-haproxy/working/logs + cat <> ~/.config/letsencrypt/cli.ini + work-dir=~/projects/certbot-haproxy/working/ + logs-dir=~/projects/certbot-haproxy/working/logs/ + config-dir=~/projects/certbot-haproxy/working/config + EOF Now you can run cerbot without root privileges. @@ -306,30 +314,30 @@ Further time savers during development.. The following options can be saved in the `cli.ini` file for the following reasons. - - `agree-tos`: During each request for a certificate you need to agree to the - terms of service of Let's Encrypt, automatically accept them every time. - - `no-self-upgrade`: Tell LE to not upgrade itself. Could be very annoying - when stuff starts to suddenly break, that worked just fine before. - - `register-unsafely-without-email`: Tell LE that you don't want to be - notified by e-mail when certificates are about to expire or when the TOS - changes, if you don't you will need to enter a valid e-mail address for - every test run. - - `text`: Disable the curses UI, and use the plain CLI version instead. - - `domain example.org`: Enter a default domain name to request a certificate - for, so you don't have to specify it every time. - - `configurator certbot-haproxy:haproxy`: Test with the HAProxy plugin every - time. +- `agree-tos`: During each request for a certificate you need to agree to the + terms of service of Let's Encrypt, automatically accept them every time. +- `no-self-upgrade`: Tell LE to not upgrade itself. Could be very annoying + when stuff starts to suddenly break, that worked just fine before. +- `register-unsafely-without-email`: Tell LE that you don't want to be + notified by e-mail when certificates are about to expire or when the TOS + changes, if you don't you will need to enter a valid e-mail address for + every test run. +- `text`: Disable the curses UI, and use the plain CLI version instead. +- `domain example.org`: Enter a default domain name to request a certificate + for, so you don't have to specify it every time. +- `configurator certbot-haproxy:haproxy`: Test with the HAProxy plugin every + time. +.. code:: bash - -cat <> ~/.config/letsencrypt/cli.ini -agree-tos -no-self-upgrade -register-unsafely-without-email -text -domain example.org -configurator certbot-haproxy:haproxy -EOF + cat <> ~/.config/letsencrypt/cli.ini + agree-tos + no-self-upgrade + register-unsafely-without-email + text + domain example.org + configurator certbot-haproxy:haproxy + EOF Setuptools version conflict @@ -338,9 +346,9 @@ Setuptools version conflict Most likely the `python-setuptools` version in your os's repositories is quite outdated. You will need to install a newer version, to do this you can run: -``` -pip install --upgrade setuptools -``` +.. code:: bash + + pip install --upgrade setuptools Since pip is part of `python-setuptools`, you need to have it installed before you can update.