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.
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.
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:
and edit the line:
http01_port = 54000
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.