Recap
In my first article in this series, Let's Encrypt Certificate Authority, I secured my Asterisk server with a Let's Encrypt certificate.
In a subsequent article, Let's Encrypt and NGINX, my StartSSL certificate for my calendar server was due to expire so I used letsencrypt-auto's manual mode again to authenticate control of the domain and to request a new certificate.
Those certificates are now close to expiry so need renewing.
In this article I am going to renew the certificate generated in the first article in a completely manual way. By renewal, I mean issuing exactly the same letsencrypt-auto command used to generate the original certificate.
I will renew the certificate for the calendar server (running on NGINX) by using the webroot method with an SSHFS mount point. I do not use letsencrypt-auto on my servers, I use it on my laptop.
Update letsencrypt-auto
cd /opt/letsencrypt/
git pull
sudo ./letsencrypt-auto --help
Renewing my Asterisk Certificate
As I am not changing the key or anything in the certificate, I will use the CSR I used previously for this certificate. On my laptop:
sudo chmod 670 -R ~/lets-encrypt-data/
cd ~/lets-encrypt-data/
/opt/letsencrypt/letsencrypt-auto -c ~/lets-encrypt-data/config/letsencrypt.conf auth -a manual --csr ~/lets-encrypt-data/csr/sip_johncook_co_uk.csr
- NOTE: The IP of this machine will be publicly logged as having requested this certificate. If you're running letsencrypt in manual mode on a machine that is not your server, please ensure you're okay with that. Are you OK with your IP being logged?
- Yes
Make sure your web server displays the following content at http://sip.johncook.co.uk/.well-known/acme-challenge/JArTCjRdgtiKncO7yiat5sDJpkY1tuBiAeA3TNY6Bnk before continuing: JArTCjRdgtiKncO7yiat5sDJpkY1tuBiAeA3TNY6Bnk.DoF45VJtf5D8xFPlklYLoX5kqLn0w4Ys7uEase57yQs If you don't have HTTP server configured, you can run the following command on the target server (as root): mkdir -p /tmp/letsencrypt/public_html/.well-known/acme-challenge cd /tmp/letsencrypt/public_html printf "%s" JArTCjRdgtiKncO7yiat5sDJpkY1tuBiAeA3TNY6Bnk.DoF45VJtf5D8xFPlklYLoX5kqLn0w4Ys7uEase57yQs > .well-known/acme-challenge/JArTCjRdgtiKncO7yiat5sDJpkY1tuBiAeA3TNY6Bnk # run only once per server: $(command -v python2 || command -v python2.7 || command -v python2.6) -c \ "import BaseHTTPServer, SimpleHTTPServer; \ s = BaseHTTPServer.HTTPServer(('', 80), SimpleHTTPServer.SimpleHTTPRequestHandler); \ s.serve_forever()" Press ENTER to continue
- Create authentication file on home server
echo 'JArTCjRdgtiKncO7yiat5sDJpkY1tuBiAeA3TNY6Bnk.DoF45VJtf5D8xFPlklYLoX5kqLn0w4Ys7uEase57yQs' > /home/www/var/www/acme-challenge/JArTCjRdgtiKncO7yiat5sDJpkY1tuBiAeA3TNY6Bnk
- Press ENTER to continue
- NOTE: The IP of this machine will be publicly logged as having requested this certificate. If you're running letsencrypt in manual mode on a machine that is not your server, please ensure you're okay with that. Are you OK with your IP being logged?
- Yes
Make sure your web server displays the following content at http://sip.thejc.me.uk/.well-known/acme-challenge/dEQcmwz9aDMqE5e3049wrqJAdx47GyWSbMbyhbYCzMw before continuing: dEQcmwz9aDMqE5e3049wrqJAdx47GyWSbMbyhbYCzMw.DoF45VJtf5D8xFPlklYLoX5kqLn0w4Ys7uEase57yQs If you don't have HTTP server configured, you can run the following command on the target server (as root): mkdir -p /tmp/letsencrypt/public_html/.well-known/acme-challenge cd /tmp/letsencrypt/public_html printf "%s" dEQcmwz9aDMqE5e3049wrqJAdx47GyWSbMbyhbYCzMw.DoF45VJtf5D8xFPlklYLoX5kqLn0w4Ys7uEase57yQs > .well-known/acme-challenge/dEQcmwz9aDMqE5e3049wrqJAdx47GyWSbMbyhbYCzMw # run only once per server: $(command -v python2 || command -v python2.7 || command -v python2.6) -c \ "import BaseHTTPServer, SimpleHTTPServer; \ s = BaseHTTPServer.HTTPServer(('', 80), SimpleHTTPServer.SimpleHTTPRequestHandler); \ s.serve_forever()" Press ENTER to continue
- Create authentication file on home server
echo 'dEQcmwz9aDMqE5e3049wrqJAdx47GyWSbMbyhbYCzMw.DoF45VJtf5D8xFPlklYLoX5kqLn0w4Ys7uEase57yQs' > /home/www/var/www/acme-challenge/dEQcmwz9aDMqE5e3049wrqJAdx47GyWSbMbyhbYCzMw
- Press ENTER to continue
IMPORTANT NOTES: - Congratulations! Your certificate and chain have been saved at /home/thejc/lets-encrypt-data/0000_chain.pem. Your cert will expire on 2016-05-15. To obtain a new version of the certificate in the future, simply run Let's Encrypt again. - If you like Let's Encrypt, please consider supporting our work by: Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate Donating to EFF: https://eff.org/donate-le
sudo cp 0000_* sip_johncook_co_uk/
cd sip_johncook_co_uk
cp 0000_chain.pem sip_johncook_co_uk.chained.pem
scp sip_johncook_co_uk.* thejc@home:/etc/ssl/asterisk/
cd ~
And on my home server, start using the new certificates:
sudo /home/thejc/Scripts/ocsp-stapling-cache-now.sh
sudo service asterisk restart
Setting Up Webroot
http://domain.example/.well-known/acme-challenge/ redirects to my home server's NGINX vhost sip.johncook.co.uk for every hostname I need certificates for.
That vhost uses a different location and root for files, which I will need to modify for the webroot method to work.
cd /home/www/var/www/acme-challenge
mkdir -p .well-known/acme-challenge
cd .well-known/acme-challenge
echo -n 'meh' > blah
sudo nano /etc/nginx/sites-enabled/blocked.thejc.me.uk
Old:
location ~* ^/.well-known/acme-challenge/ {
root /home/www/var/www/acme-challenge;
add_header Content-Type text/plain;
rewrite ^/.well-known/acme-challenge/(.*)$ /$1 break;
}
New:
location ~* ^/.well-known/acme-challenge/ {
root /home/www/var/www/acme-challenge;
add_header Content-Type text/plain;
}
sudo service nginx configtest && sudo service nginx reload
lynx http://sip.johncook.co.uk/.well-known/acme-challenge/blah
lynx http://web.johncook.uk/.well-known/acme-challenge/blah
Installing and Configuring SSHFS
Back on my laptop, I need to install SSHFS. Since letsencrypt-auto runs with sudo, I also need to change a default SSHFS configuration option.
cd /mnt
sudo mkdir acme-challenge
sudo chown thejc acme-challenge
sudo chmod 777 acme-challenge
sudo apt-get install sshfs
Edit /etc/fuse.conf and uncomment user_allow_other
.
Renewing My Calendar Certificate
sshfs -o idmap=user -o allow_root thejc@home:/home/www/var/www/acme-challenge /mnt/acme-challenge/
cd ~/lets-encrypt-data/
/opt/letsencrypt/letsencrypt-auto -c ~/lets-encrypt-data/config/letsencrypt.conf auth -a webroot -w /mnt/acme-challenge/ --csr ~/lets-encrypt-data/csr/calendar_johncook_co_uk.csr
Checking for new version... Requesting root privileges to run letsencrypt... sudo /home/thejc/.local/share/letsencrypt/bin/letsencrypt --no-self-upgrade -c /home/thejc/lets-encrypt-data/config/letsencrypt.conf auth -a webroot -w /mnt/acme-challenge/ --csr /home/thejc/lets-encrypt-data/csr/calendar_johncook_co_uk.csr IMPORTANT NOTES: - Congratulations! Your certificate and chain have been saved at /home/thejc/lets-encrypt-data/0001_chain.pem. Your cert will expire on 2016-05-15. To obtain a new version of the certificate in the future, simply run Let's Encrypt again. - If you like Let's Encrypt, please consider supporting our work by: Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate Donating to EFF: https://eff.org/donate-le
sudo cp 0001_* calendar_johncook_co_uk/
cd calendar_johncook_co_uk
cp 0001_chain.pem calendar_johncook_co_uk.chained.pem
scp calendar_johncook_co_uk.* thejc@home:/etc/ssl/calendar.johncook.co.uk/
cd ~
sudo umount /mnt/acme-challenge
Start using the new certificate on my server:
sudo /home/thejc/Scripts/ocsp-stapling-cache-now.sh
Modification to My Draft Expiring Soon Script
#!/bin/sh
cd /home/thejc/lets-encrypt-data
find . -maxdepth 1 -type d -name '*_*' | sed 's,^./,,' > dirs.tmp
while read directory; do
cd $directory
LATEST_CERT=$(find . -maxdepth 1 -type f -name '*.chained.pem' | sed 's,^./,,')
openssl x509 -checkend 1209600 -noout -in "$LATEST_CERT" > /dev/null
if [ ! $? -eq 0 ]; then
echo "--------------------------------------------------------------------------------"
REMOTE_DIR=$(echo "/etc/ssl/$directory" | sed 's,_,.,g;s,sip.johncook.co.uk$,asterisk,')
echo "$LATEST_CERT in $directory expires within a fortnight!"
echo "Remote directory is $REMOTE_DIR/"
fi
cd ..
done < dirs.tmp
echo "--------------------------------------------------------------------------------"
rm dirs.tmp
Conclusion
By switching to using the Webroot method with an SSHFS mount point, I no longer need to manually create the acme-challenge files. Although it saved a little bit of time for renewing a certificate with 2 SANs, it will save a lot of time and hassle when it comes time to renew my certificate with 17 SANs.
Although I am not using a completely automated method, my use of the Webroot method means certificate requests and renewals now take approximately the same amount of effort as they would with other certificate authorities, without having to login to a CA and paste the CSR to a browser tab, waiting for manual approval, or copying the new certificate from a browser tab.
The only change I would need to make in my current process is to my ocsp-stapling-cache-now.sh script. At the moment it uses the Let's Encrypt X1 cross-signed intermediary. Since I am using the bundle file (certificate plus intermediate) generated by letsencrypt-auto I will need to modify my script if Let's Encrypt start to use the intermediate certificate signed by their own root.
The only TLS certificate I currently use that is not issued by Let's Encrypt is the one for my Webmail server. I will be switching to Let's Encrypt for that certificate as well soon.
I have not yet automated renewal reminders, and I still haven't migrated and merged my hostmaster mailbox so don't see the e-mail reminders from Let's Encrypt. Both of those are tasks I will do a later date, but until then there is a chance I will forget to renew a certificate.