Let's Encrypt Manual Renewal

Two of my Let's Encrypt certificates will expire in a little over two weeks. Time to renew them.

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
  1. Create authentication file on home server
    echo 'JArTCjRdgtiKncO7yiat5sDJpkY1tuBiAeA3TNY6Bnk.DoF45VJtf5D8xFPlklYLoX5kqLn0w4Ys7uEase57yQs' > /home/www/var/www/acme-challenge/JArTCjRdgtiKncO7yiat5sDJpkY1tuBiAeA3TNY6Bnk
  2. 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
  1. Create authentication file on home server
    echo 'dEQcmwz9aDMqE5e3049wrqJAdx47GyWSbMbyhbYCzMw.DoF45VJtf5D8xFPlklYLoX5kqLn0w4Ys7uEase57yQs' > /home/www/var/www/acme-challenge/dEQcmwz9aDMqE5e3049wrqJAdx47GyWSbMbyhbYCzMw
  2. 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.