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.