Servers‎ > ‎

Letsencrypt & haproxy - no down time

posted Jan 11, 2016, 6:59 AM by Chris Franklin
So letsencrypt requires port 80 and 443 access in order to generate or renew certs. This can be an issue if your server already uses port 80, 443, if you need a cert for a appliance can can't run letsencrypt on that device, or you just can't afford the down time. All the above is a BS attempt at stopping non-admins from generating certs (this is a BS as you can still "get" letsencrypt to give you a cert using the webroot feature and a non-root user, but that's a topic for another time).

My solution is simple, let a "proxy" look at the inbound url and forward *allletsencrypt connections to the letsencrypt standalone service. This way matter what sub(s) or domain(s) needed or used one copy of letsencrypt can answer ALL the requests. This means you only ever need 1 copy of letsencrypt for all the servers BEHIND the load balancer and you never need to take down or in anyway modify your existing server or website.

What you need to for all this
  1. letsencrypt
  2. apache (if on the same machine) configured to only listen on any ip other than the one web traffic is being sent to from the wan (internet). In my example (
  3. letsencrypt set to listen on 8080 (or any other none 80 (**IF** it's on the same server/ip as haproxy). 
    1. If letsencrypt ever decide to make it so you can't change the listening/bind port just setup a virtual nic and have it only bind to that ip.

Heres my haproxy config  

Haproxy config

        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
        # Default SSL material locations
        ca-base /etc/ssl/certs
        crt-base /etc/ssl/private
        # Default ciphers to use on SSL-enabled listening sockets.
        # For more information, see ciphers(1SSL). This list is from:
        ssl-default-bind-options no-sslv3

        log     global
        mode tcp
        option tcplog
        #mode   http
        #option httplog
        option  dontlognull
        timeout connect 500
        timeout client  100
        timeout server  500
        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

listen stats
    bind       #Listen on all IP's on port 9000
    mode http
    timeout client 5000
    timeout connect 4000
    timeout server 30000
    #This is the virtual URL to access the stats page
    stats uri /haproxy_stats
    #Authentication realm. This can be set to anything. Escape space characters with a backslash.
    stats realm HAProxy\ Statistics
    #The user/pass you want to use. Change this password!
    stats auth ******:*****
    #This allows you to take down and bring up back end servers.
    #This will produce an error on older versions of HAProxy.
    stats admin if TRUE

#Application Setup
frontend ContentSwitching
  bind ssl crt /etc/haproxy/ssl/
  mode http
  option httplog
  acl letsencrypt_remote_host path_beg /.well-known/acme-challenge/
  use_backend letsencrypt_nodes if letsencrypt_remote_host
  default_backend linux_www_node

backend letsencrypt_nodes
  mode http
  server letsencrypt

backend linux_www_node
  mode http
  compression algo gzip
  compression type text/html text/plain text/css text/js
  balance roundrobin
  stick-table type ip size 200k expire 30m
  stick on src
  server node1 check

And now and example of the letsencrypt cli

letsencrypt cli

/usr/bin/letsencrypt  --agree-tos --renew-by-default --standalone --standalone-supported-challenges http-01 --http-01-port 8080 certonly -d -d -d