Skip to content

Instantly share code, notes, and snippets.

@haproxytechblog
Created July 10, 2023 19:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save haproxytechblog/609e6f970d9e0079ac06135bfd968c8d to your computer and use it in GitHub Desktop.
Save haproxytechblog/609e6f970d9e0079ac06135bfd968c8d to your computer and use it in GitHub Desktop.
HAProxy and Let’s Encrypt: Improved Support in acme.sh
$ sudo adduser \
--system \
--disabled-password \
--disabled-login \
--home /var/lib/acme \
--quiet \
--force-badname \
--group \
acme
$ sudo adduser acme haproxy
$ sudo mkdir /usr/local/share/acme.sh/
$ git clone https://github.com/acmesh-official/acme.sh.git
$ cd acme.sh/
$ sudo ./acme.sh \
--install \
--no-cron \
--no-profile \
--home /usr/local/share/acme.sh
$ sudo ln -s /usr/local/share/acme.sh/acme.sh /usr/local/bin/
$ sudo chmod 755 /usr/local/share/acme.sh/
$ curl https://raw.githubusercontent.com/haproxy/haproxy/master/admin/acme.sh/haproxy.sh | sudo tee /usr/local/share/acme.sh/deploy/haproxy.sh
$ sudo -u acme -s
$ acme.sh --register-account \
--server letsencrypt_test \
-m youremail@example.com
[Mon Apr 24 01:28:14 PM UTC 2023] Create account key ok.
[Mon Apr 24 01:28:14 PM UTC 2023] Registering account: https://acme-staging-v02.api.letsencrypt.org/directory
[Mon Apr 24 01:28:14 PM UTC 2023] Registered
[Mon Apr 24 01:28:14 PM UTC 2023] ACCOUNT_THUMBPRINT='lCufto4sDRTHdmWL0EugFywGV54hBCuTTXvwifi65R4'
$ exit
$ sudo mkdir /etc/haproxy/certs
$ sudo chown haproxy:haproxy /etc/haproxy/certs
$ sudo chmod 770 /etc/haproxy/certs
global
stats socket /var/run/haproxy/admin.sock level admin mode 660
setenv ACCOUNT_THUMBPRINT 'lCufto4sDRTHdmWL0EugFywGV54hBCuTTXvwifi65R4'
frontend web
bind :80
bind :443 ssl crt /etc/haproxy/certs/ strict-sni
http-request return status 200 content-type text/plain lf-string "%[path,field(-1,/)].${ACCOUNT_THUMBPRINT}\n" if { path_beg '/.well-known/acme-challenge/' }
$ sudo systemctl restart haproxy
$ sudo -u acme -s
$ acme.sh --issue \
-d example.com \
--stateless \
--server letsencrypt_test
[Mon Apr 24 01:36:03 PM UTC 2023] Using CA: https://acme-staging-v02.api.letsencrypt.org/directory
[Mon Apr 24 01:36:03 PM UTC 2023] Single domain=example.com'
[Mon Apr 24 01:36:03 PM UTC 2023] Getting domain auth token for each domain
[Mon Apr 24 01:36:04 PM UTC 2023] Getting webroot for domain='example.com'
[Mon Apr 24 01:36:04 PM UTC 2023] Verifying: example.com
[Mon Apr 24 01:36:04 PM UTC 2023] Stateless mode for domain:example.com
[Mon Apr 24 01:36:06 PM UTC 2023] Success
[Mon Apr 24 01:36:06 PM UTC 2023] Verify finished, start to sign.
[Mon Apr 24 01:36:06 PM UTC 2023] Lets finalize the order.
[Mon Apr 24 01:36:06 PM UTC 2023] Le_OrderFinalize='https://acme-staging-v02.api.letsencrypt.org/acme/finalize/12345'
[Mon Apr 24 01:36:06 PM UTC 2023] Downloading cert.
[Mon Apr 24 01:36:06 PM UTC 2023] Le_LinkCert='https://acme-staging-v02.api.letsencrypt.org/acme/cert/abc12345'
[Mon Apr 24 01:36:06 PM UTC 2023] Cert success.
-----BEGIN CERTIFICATE-----
[...]
-----END CERTIFICATE-----
[Mon Apr 24 01:36:06 PM UTC 2023] Your cert is in: /var/lib/acme/.acme.sh/example.com_ecc/example.cer
[Mon Apr 24 01:36:06 PM UTC 2023] Your cert key is in: /var/lib/acme/.acme.sh/example.com_ecc/example.key
[Mon Apr 24 01:36:06 PM UTC 2023] The intermediate CA cert is in: /var/lib/acme/.acme.sh/example.com_ecc/ca.cer
[Mon Apr 24 01:36:06 PM UTC 2023] And the full chain certs is there: /var/lib/acme/.acme.sh/example.com_ecc/fullchain.cer
$ sudo -u acme -s
$ DEPLOY_HAPROXY_HOT_UPDATE=yes \
DEPLOY_HAPROXY_STATS_SOCKET=/var/run/haproxy/admin.sock \
DEPLOY_HAPROXY_PEM_PATH=/etc/haproxy/certs \
acme.sh --deploy -d example.com --deploy-hook haproxy
[Mon Apr 24 02:17:31 PM UTC 2023] The domain 'example.com' seems to have a ECC cert already, lets use ecc cert.
[Mon Apr 24 02:17:31 PM UTC 2023] Deploying PEM file
[Mon Apr 24 02:17:31 PM UTC 2023] Moving new certificate into place
[Mon Apr 24 02:17:31 PM UTC 2023] Creating new certificate '/etc/haproxy/certs/example.com.pem' over HAProxy stats socket.
[Mon Apr 24 02:17:31 PM UTC 2023] Success
$ echo "show ssl cert /etc/haproxy/certs/example.com.pem" |\
socat /var/run/haproxy/admin.sock -
Filename: /etc/haproxy/certs/example.com.pem
Status: Used
Serial: 6C058BA29A03DF58BFA9CF0ABD0C0AB8
notBefore: Apr 24 13:35:04 2023 GMT
notAfter: Apr 25 13:36:04 2023 GMT
Subject Alternative Name: DNS:example.com
Algorithm: EC256
SHA1 FingerPrint: 7A6A64B2D3BB1E548DBF383FDB3A7CA8434B3F5A
[...]
$ curl https://example.com
$ sudo -u acme -s
$ crontab -e
$ acme.sh --install-cronjob
[Unit]
Description=Renew Let's Encrypt certificates using acme.sh
After=network-online.target
[Service]
Type=oneshot
# --home's argument should be where the acme.sh script resides.
ExecStart=/usr/local/bin/acme.sh --cron
User=acme
Group=acme
SuccessExitStatus=0 2
$ systemctl daemon-reload
$ systemctl start acme_letsencrypt
[Unit]
Description=Daily renewal of Let's Encrypt's certificates
[Timer]
OnCalendar=daily
RandomizedDelaySec=1h
Persistent=true
[Install]
WantedBy=timers.target
$ systemctl start acme_letsencrypt.timer
$ systemctl enable acme_letsencrypt.timer
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment