Merge branch 'develop' of code.greenhost.net:open/certbot-haproxy into develop
This commit is contained in:
commit
1a5737f1b3
276
README.rst
276
README.rst
|
@ -1,7 +1,277 @@
|
|||
HAProxy plugin for Certbot
|
||||
==========================
|
||||
|
||||
Getting started (development)
|
||||
Installing: Requirements
|
||||
------------------------
|
||||
|
||||
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+
|
||||
|
||||
Installing: Getting started
|
||||
---------------------------
|
||||
|
||||
The installation below assumes you are running Debian Jessie but it should be
|
||||
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.
|
||||
|
||||
```
|
||||
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
|
||||
|
||||
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
|
||||
```
|
||||
|
||||
.. 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
|
||||
```
|
||||
|
||||
If you want to run Certbot in an unprivileged mode, keep reading, otherwise,
|
||||
skip to the installation of Certbot.
|
||||
|
||||
Certbot normally requires access to the ``/etc/`` directory, which is owned by
|
||||
root and therefore, Certbot needs to run as root. However, we don't like it
|
||||
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.
|
||||
|
||||
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
|
||||
```
|
||||
|
||||
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]
|
||||
```
|
||||
|
||||
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``.
|
||||
|
||||
Besides the working directory.
|
||||
|
||||
```
|
||||
mkdir -p $HOME/.config/letsencrypt
|
||||
cat <<EOF > $HOME/.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.
|
||||
|
||||
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 ./
|
||||
```
|
||||
|
||||
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
|
||||
configured our plugin to open port ``8000`` to verify control over the domain
|
||||
instead. Therefore we need to forward verification requests on port 80 to port
|
||||
8000 internally.
|
||||
|
||||
The sample below contains all that is required for a working load-balancing
|
||||
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 <<EOF > /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
|
||||
|
||||
# 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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
# 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
|
||||
|
||||
backend certbot
|
||||
log global
|
||||
mode http
|
||||
server certbot 127.0.0.1:8000
|
||||
|
||||
# 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 }
|
||||
|
||||
# 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]
|
||||
|
||||
# The default backend is a cluster of 4 Apache servers that you need to
|
||||
# host.
|
||||
default_backend nodes
|
||||
|
||||
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
|
||||
```
|
||||
|
||||
If you want your ``certbot`` to always use our Installer and Authenticator, you
|
||||
can add this to your configuration file:
|
||||
|
||||
```
|
||||
cat <<EOF >> $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.
|
||||
|
||||
.. _TOS: https://letsencrypt.org/documents/LE-SA-v1.1.1-August-1-2016.pdf
|
||||
|
||||
After you run certbot successfully once, there will be 2 certificate files in
|
||||
the certificate directory.
|
||||
|
||||
Development: Getting started
|
||||
-----------------------------
|
||||
|
||||
In order to run tests against the Let's Encrypt API we will run a Boulder
|
||||
|
@ -11,8 +281,8 @@ components and dependencies from cluttering up your computer there is also a
|
|||
client Virtual Box instance. Both of these machines can be setup and started by
|
||||
running the `dev_start.sh` script.
|
||||
|
||||
Running locally without sudo
|
||||
----------------------------
|
||||
Development: Running locally without sudo
|
||||
-----------------------------------------
|
||||
|
||||
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
|
||||
|
|
|
@ -73,7 +73,7 @@ CLI_DEFAULTS_DEBIAN_BASED_SYSTEMD_OS = dict(
|
|||
conftest_cmd=['/usr/sbin/haproxy', '-c', '-f'],
|
||||
haproxy_config='/etc/haproxy/haproxy.cfg',
|
||||
# Needs to be writeable by the user that will run certbot
|
||||
crt_directory='/etc/ssl/crt/',
|
||||
crt_directory='/opt/cerbot/haproxy_fullchains',
|
||||
)
|
||||
|
||||
CLI_DEFAULTS_DEBIAN_BASED_PRE_SYSTEMD_OS = dict(
|
||||
|
@ -84,7 +84,7 @@ CLI_DEFAULTS_DEBIAN_BASED_PRE_SYSTEMD_OS = dict(
|
|||
conftest_cmd=['/usr/sbin/haproxy', '-c', '-f'],
|
||||
haproxy_config='/etc/haproxy/haproxy.cfg',
|
||||
# Needs to be writeable by the user that will run certbot
|
||||
crt_directory='/etc/ssl/crt/',
|
||||
crt_directory='/opt/cerbot/haproxy_fullchains',
|
||||
)
|
||||
|
||||
CLI_DEFAULTS = {
|
||||
|
|
|
@ -31,8 +31,8 @@ import os
|
|||
import glob
|
||||
import subprocess
|
||||
import re
|
||||
from OpenSSL import crypto
|
||||
from distutils.version import StrictVersion
|
||||
from OpenSSL import crypto
|
||||
|
||||
import zope.component
|
||||
import zope.interface
|
||||
|
@ -81,6 +81,8 @@ class HAProxyInstaller(common.Plugin):
|
|||
#: Dict of supported enhancement functions:
|
||||
self._enhance_func = {}
|
||||
|
||||
print self.get_all_certs_keys()
|
||||
|
||||
@classmethod
|
||||
def add_parser_arguments(cls, add):
|
||||
"""
|
||||
|
|
|
@ -2,7 +2,8 @@
|
|||
echo "$PROJECT_TZ" > /etc/timezone
|
||||
dpkg-reconfigure -f noninteractive tzdata
|
||||
export DEBIAN_FRONTEND="noninteractive"
|
||||
echo "deb http://ftp.debian.org/debian jessie-backports main" >> /etc/apt/sources.list
|
||||
echo "deb http://ftp.debian.org/debian jessie-backports main" >> \
|
||||
/etc/apt/sources.list.d/jessie-backports.list
|
||||
apt-get update
|
||||
apt-get upgrade -y
|
||||
apt-get install -y \
|
||||
|
@ -12,9 +13,9 @@ apt-get install -y \
|
|||
|
||||
apt-get install -y -t jessie-backports certbot
|
||||
|
||||
easy_install pip
|
||||
pip install --upgrade setuptools
|
||||
|
||||
easy_install pip
|
||||
pip install virtualenv
|
||||
|
||||
ufw allow ssh
|
||||
|
@ -81,32 +82,28 @@ EOF
|
|||
# TODO: Does this even work with the `chroot` directive?
|
||||
usermod -a -G vagrant haproxy
|
||||
|
||||
mkdir /etc/ssl/crt
|
||||
mkdir -p /opt/cerbot/haproxy_fullchains
|
||||
|
||||
cat <<EOF > /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
|
||||
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
|
||||
|
||||
# Default SSL material locations
|
||||
# ca-base /etc/ssl/certs
|
||||
# crt-base /etc/ssl/private
|
||||
|
||||
# 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
|
||||
# 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
|
||||
|
||||
defaults
|
||||
log global
|
||||
|
@ -125,27 +122,38 @@ defaults
|
|||
errorfile 504 /etc/haproxy/errors/504.http
|
||||
|
||||
frontend http-in
|
||||
# Listen on port 80
|
||||
bind *:80
|
||||
mode http
|
||||
# LE HAProxy installer should combine certs and place them here..
|
||||
# Uncomment when ready.. Needs ACL to work per site.
|
||||
# bind *:443 ssl crt /etc/ssl/crt
|
||||
# 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
|
||||
|
||||
# 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 redirect is to be used, uncomment the next line
|
||||
# redirect scheme https if !{ ssl_fc } and testsite.nl
|
||||
default_backend nodes
|
||||
|
||||
acl is_cerbot path_beg -i /.well-known/acme-challenge
|
||||
use_backend certbot if is_cerbot
|
||||
|
||||
backend certbot
|
||||
log global
|
||||
mode http
|
||||
server certbot 127.0.0.1:8000
|
||||
|
||||
# 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 }
|
||||
|
||||
# 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]
|
||||
|
||||
# The default backend is a cluster of 4 Apache servers that you need to
|
||||
# host.
|
||||
default_backend nodes
|
||||
|
||||
backend nodes
|
||||
log global
|
||||
mode http
|
||||
|
@ -162,6 +170,7 @@ frontend http-in
|
|||
server node3 127.0.0.1:8080 check
|
||||
server node4 127.0.0.1:8080 check
|
||||
EOF
|
||||
|
||||
cat <<EOF > /etc/apache2/sites-enabled/000-default.conf
|
||||
<VirtualHost testsite.nl:8080>
|
||||
ServerName testsite.nl
|
||||
|
|
Reference in New Issue