I wanted to use letsencrypt keys and stunnel to encrypt sessions with a valid server key. Once setup the system needed to look like a regular https website with a valid certificate. I’ll explain why I did this in a later posting.
I’m not going to go into getting the original key from letsencrypt as there are too many ways to do it and letsencrypt’s certbot is already well documented.
These instructions are also specific to Ubuntu 16.04 but could be modified for other Linux’s. The instructions below will also conflict with any webserver listening on port 443 (https).
Setup stunnel
In all of the instructions and scripts below replace <servername> with your hostname. <servername> also needs to match you letsencrypt hostname.
sudo apt-get install stunnel4
Edit /etc/default/stunnel4 and change ENABLED=1
Now create a new stunnel conf file in /etc/stunnel/ with the contents below
pid = /var/run/stunnel.pid cert = /etc/stunnel/stunnel.pem [ssh] accept = <servername>:443 connect = 127.0.0.1:80
If you want to connect to something other than you local webserver change the “connect = 127.0.0.1:80” line above.
Now because stunnel needs the fullchain.pem and the privkey.pem in the same file we need to combine the letsencrypt files. Here’s a script ( combine_certs.sh ) that will check the md5sums of the letsencrypt file and generate a new stunnel.pem whenever the originals change.
#!/bin/bash # # Copyright (c) 2017 Angus Ainslie # IN_PATH="/etc/letsencrypt/live" CERT_NAME=$1 OUT_PATH=$2 PEM_NAME=$3 CHAIN_SUM=`md5sum ${IN_PATH}/${CERT_NAME}/fullchain.pem` KEY_SUM=`md5sum ${IN_PATH}/${CERT_NAME}/privkey.pem` echo "Chain sum ${CHAIN_SUM}" echo "Key sum ${KEY_SUM}" if [ ! -e ${OUT_PATH}/sums ]; then echo ${CHAIN_SUM} > ${OUT_PATH}/sums echo ${KEY_SUM} >> ${OUT_PATH}/sums fi md5sum --status -c ${OUT_PATH}/sums if [ $? -eq 0 ]; then echo "Keys match" else echo "Keys don't match. re-creating pem file" cat ${IN_PATH}/${CERT_NAME}/fullchain.pem ${IN_PATH}/${CERT_NAME}/privkey.pem > ${OUT_PATH}/${PEM_NAME} echo ${CHAIN_SUM} > ${OUT_PATH}/sums echo ${KEY_SUM} >> ${OUT_PATH}/sums fi
To generate the stunnel.pem file run combine_certs.sh like this
sudo combine_certs.sh <servername> /etc/stunnel stunnel.pem
Because the letsencrypt certificates are short lived their install process adds a cron job that will renew any keys expiring in 30 days or less. So we need to rerun the combine script to keep our stunnel.pem current. Put this crontab in /etc/cron.d
# Copyright (c) 2017 Angus Ainslie <angus at akkea.ca> # SHELL=/bin/bash PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin 5 */12 * * * root test -x /usr/local/bin/combine_certs.sh && combine_certs.sh /etc/stunnel stunnel.pem
Now restart stunnel
systemctl restart stunnel4
You will now have a fully functional stunnel listener that will function as an https server.