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

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:

wget https://dl.eff.org/certbot-auto
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 mydomain.com -d www.mydomain.com

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/mydomain.com/fullchain.pem /etc/letsencrypt/live/mydomain.com/privkey.pem > /etc/haproxy/certs/mydomnain.com.pem'

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/mydomain.com.pem
    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:

/etc/letsencrypt/renewal/mydomain.com.conf

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.

Leave a Reply

Your email address will not be published. Required fields are marked *