Letsencrypt on raspberry pi using haproxy

Letsencrypt is a free service to get SSL certificates. Currently the certbot tool is not included in the raspberry pi repository, and I could not find any guide for using this in the combination of raspberry pi and haproxy - so this is my notes about how I did it.


Haproxy is a load balancer and reverse proxy. You can use it if you want to host multiple domains on the same IP or want to have more computers on the same ip - either as load balancing or if you want to split the functionality to different computers. It is very useful, and if anyone would like i can make a seperate post about how i use haproxy.

Download cerbot-auto

Certbot is the application you normally use to handle the certificates from letsencrypt. Certbot-auto is a shell script implementing the same functionality and you can get it here:

chmod a+x certbot-auto

Get your certificate

Make sure you do not have anything else running on port 80. If you have already setup haproxy stop it by doing:

service haproxy stop

Certbot will create a server on port 80 to verify the certificate. If you raspberry pi is not on a public ip, setup a port 80 forward from you router to the raspberry pi. Now get the certificate:

sudo ./certbot-auto certonly--standalone --preferred-challenges http --http-01-port 80 -d -d

You can add more domains using additional -d xxxx parameters

Combine keys to haproxy

Make sure you already have the folder ‘/etc/haproxy/certs’ otherwise create it and then do:

/etc/letsencrypt/live/ /etc/letsencrypt/live/ > /etc/haproxy/certs/'

to combine fullchain.pem and privkey.pem into one file.

Renew certificate

certbot renew

After renew you must combine the fullchain and private key again - so make a sh file to do it - and run it in a cronjob.

Setting up haproxy

Port 443 should be forwarded from your router to do https. In /etc/haproxy/haproxy.cfg setup a binding to 443 and include a path the the combined certificate.

frontend http-in
    bind \*:80
    acl letsencrypt-acl path\_beg /.well-knwon/acme-challenge/
    use\_backend letsencrypt\_backend if letsencrypt\_acl
    default\_backend www
frontend https-in
    bind \*:443 ssl crt /etc/haproxy/certs/
    default\_backend www
backend www
    server www localhost:1234
backend letsencrypt\_backend
    server letsencrypt localhost:54000

Here the www server is running on port 1234. Whenever the url path match /.well-known…. we will pass it to localhost:54000 - so now we need to setup certbot to use port 54000 to verify. Open the file:


and edit the line:

http01\_port = 54000

Haproxy Authenticating

To add basic authentication to haproxy add this:

backend www
    server www localhost:1234
    acl auth\_ok http\_auth(wwwusers)
    http-request auth realm wwwusers if !auth\_ok
userlist wwwusers
    user myname insecure-password mypassword

Note 1: here the password is in clear text in the configuration. It is possible to encrypt the password if you want to make more secure (you can find that elsewhere) Note 2: You should never use basic authentication without ssl, because without ssl, the password will be send in clear text.

(c) 2010-2023