Skip to content

Instantly share code, notes, and snippets.

@brwyatt
Last active April 9, 2025 03:58
Show Gist options
  • Save brwyatt/2c5107e6245c7abcf0d7988682693529 to your computer and use it in GitHub Desktop.
Save brwyatt/2c5107e6245c7abcf0d7988682693529 to your computer and use it in GitHub Desktop.

Installing HAProxy with Certbot

Largely taken from this tutorial, which was hilariously out of date

Install HA Proxy

sudo apt install haproxy

Install Certbot

sudo apt install python3-certbot python3-certbot-dns-route53

Set AWS Creds

sudo mkdir /root/.aws
sudo vim /root/.aws/config

File Content:

[default]
aws_access_key_id={{KEYHERE}}
aws_secret_access_key={{KEYHERE}}

Register with ACME

sudo certbot certonly --non-interactive --agree-tos -m '<<EMAIL>>' --dns-route53 -d {{HOSTNAMEHERE}}
sudo certbot renew --dry-run

Renew hook script

sudo mkdir -p /etc/haproxy/certs/
sudo vim /etc/letsencrypt/renewal-hooks/deploy/haproxy.sh

File Content:

#!/bin/sh

SITE={{HOSTNAMEHERE}}

# move to the correct let's encrypt directory
cd /etc/letsencrypt/live/$SITE

# cat files to make combined .pem for haproxy
cat fullchain.pem privkey.pem > /etc/haproxy/certs/$SITE.pem

# reload haproxy
service haproxy reload
sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/haproxy.sh

Config HA Proxy

sudo vim /etc/haproxy/haproxy.cfg

File Content:

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

	maxconn 2048
	
	stats socket :9000 mode 660 level admin

	# Default SSL material locations
	ca-base /etc/ssl/certs
	crt-base /etc/ssl/private

	# See: https://ssl-config.mozilla.org/#server=haproxy&server-version=2.0.3&config=intermediate
        ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
        ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
        ssl-default-bind-options ssl-min-ver TLSv1.2 no-tls-tickets

	tune.ssl.default-dh-param 2048

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

	option forwardfor
	option http-server-close

resolvers localdns
	nameserver dns1 127.0.0.53:53
	accepted_payload_size 8192

frontend stats
    bind :8404
    stats enable
    stats uri /
    stats refresh 5s

frontend www-http
	bind :80
	http-request redirect scheme https code 301

frontend www-https
	bind :443 ssl crt /etc/haproxy/certs/{{HOSTNAMEHERE}}.pem
	http-request set-header X-Forwarded-Proto https
	default_backend backend-hosts

backend backend-hosts
	balance leastconn

	cookie SERVER insert indirect nocache dynamic
	dynamic-cookie-key RANDOMSECRET

	default-server check check-ssl ssl ca-file /etc/ssl/certs/ca-certificates.crt
	server-template web 1-5 _{{SERVICENAME}}._tcp.{{DOMAINNAME}} resolvers localdns init-addr none

Run renew script

(this fixes the HA Proxy certs and restarts HA)

/etc/letsencrypt/renewal-hooks/deploy/haproxy.sh
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment