Let's Encrypt and NGINX

With my TLS certificate for my calendar server expiring in a few days I need a new certificate. I'm going to use Let's Encrypt as CA.

Recap

In my previous article, Let's Encrypt Certificate Authority, I secured my Asterisk server with a Let's Encrypt certificate.

My StartSSL certificate for my calendar server expires in a few days. I'm going to use letsencrypt-auto's manual mode again to authenticate control of the domain and to request a new certificate.

The Calendar Server

The calendar server uses the port Apple devices assumes is the TLS port of a CalDAV server (port 8443).

As part of my transition to using johncook.co.uk rather than thejc.me.uk for my infrastructure (sub-)domains, my CSR will, as with my CSR for my Asterisk server, include two SANs (calendar.johncook.co.uk and calendar.thejc.me.uk).

My domain johncook.co.uk already has SRV records for caldavs and carddavs, I will just replace calendar.thejc.me.uk with calendar.johncook.co.uk.

I will also need to delegate calendar.johncook.co.uk to Hurricane Electric, as I use their DNS for my DDNS records.

With that said, Let's Encrypt my calendar server.

Manual Mode

Like in my last article, I am going to be using manual mode as I want to do things myself.

So, on my laptop, I need to create two keys (one for backup) and a CSR.

cd /etc/ssl
sudo mkdir calendar.johncook.co.uk
sudo chgrp thejc calendar.johncook.co.uk
cd calendar.johncook.co.uk
sudo chmod g+w .
openssl genrsa -out calendar_johncook_co_uk.key1 4096
openssl genrsa -aes256 -out calendar_johncook_co_uk.key2 4096
openssl req -new -sha256 -key /etc/ssl/calendar.johncook.co.uk/calendar_johncook_co_uk.key1 -subj "/C=GB/ST=Hertfordshire/L=Watford/O=John Cook/CN=calendar.johncook.co.uk/emailAddress=hostmaster@johncook.co.uk" -reqexts SAN -config <(cat /etc/ssl/openssl.cnf <(printf "[SAN]\nsubjectAltName=DNS:calendar.johncook.co.uk,DNS:calendar.thejc.me.uk\nbasicConstraints=CA:FALSE\nkeyUsage=digitalSignature,keyEncipherment,keyAgreement\nextendedKeyUsage=serverAuth,clientAuth\nsubjectKeyIdentifier=hash\n")) -text

Double-check that the CSR looks OK, and if it does swap -text with -out calendar_johncook_co_uk.csr -outform DER:

openssl req -new -sha256 -key /etc/ssl/calendar.johncook.co.uk/calendar_johncook_co_uk.key1 -subj "/C=GB/ST=Hertfordshire/L=Watford/O=John Cook/CN=calendar.johncook.co.uk/emailAddress=hostmaster@johncook.co.uk" -reqexts SAN -config <(cat /etc/ssl/openssl.cnf <(printf "[SAN]\nsubjectAltName=DNS:calendar.johncook.co.uk,DNS:calendar.thejc.me.uk\nbasicConstraints=CA:FALSE\nkeyUsage=digitalSignature,keyEncipherment,keyAgreement\nextendedKeyUsage=serverAuth,clientAuth\nsubjectKeyIdentifier=hash\n")) -out calendar_johncook_co_uk.csr -outform DER

Double-check the CSR again:

openssl req -text -in calendar_johncook_co_uk.csr -inform DER

Widen permissions on ~/lets-encrypt-data/ and copy the CSR:

sudo chmod 670 -R ~/lets-encrypt-data/
cd ~/lets-encrypt-data/
sudo -k
mkdir calendar_johncook_co_uk
cp /etc/ssl/calendar.johncook.co.uk/calendar_johncook_co_uk.csr csr/

In another open shell, SSH to my home server and change directory to where I'll be storing the files:

cd /home/www/var/www/acme-challenge/

Update DNS

Double-check that the NS records for calendar_johncook_co_uk have reached the slave nameservers. They have reached the Esgob secondaries, but not the Hurricane Electric secondaries.

Login to Hurricane Electric DNS and force an AXFR (manage the zone, click the validate button). Wait a few minutes and have another look. Look's like Hurricane Electric are being slow at processing changes today, so I'm going to have to wait longer.

Until that happens I cannot create a zone for calendar.johncook.co.uk at HE DNS nor can I create a DDNS A record.

It took a few hours for HE DNS to process the AXFR, but with the zone delegated and DDNS setup, I can now move on to domain authentication and certificate creation.

Create Certificate

Back on my laptop, use the CSR to request a certificate:

/opt/letsencrypt/letsencrypt-auto -c ~/lets-encrypt-data/config/letsencrypt.conf auth -a manual --csr ~/lets-encrypt-data/csr/calendar_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://calendar.johncook.co.uk/.well-known/acme-challenge/qmPz-qjVBInp-k8xIr34HupzhHEE8CPnL9H3rsndi-Q before continuing:

qmPz-qjVBInp-k8xIr34HupzhHEE8CPnL9H3rsndi-Q.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" qmPz-qjVBInp-k8xIr34HupzhHEE8CPnL9H3rsndi-Q.DoF45VJtf5D8xFPlklYLoX5kqLn0w4Ys7uEase57yQs > .well-known/acme-challenge/qmPz-qjVBInp-k8xIr34HupzhHEE8CPnL9H3rsndi-Q
# 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 'qmPz-qjVBInp-k8xIr34HupzhHEE8CPnL9H3rsndi-Q.DoF45VJtf5D8xFPlklYLoX5kqLn0w4Ys7uEase57yQs' > /home/www/var/www/acme-challenge/qmPz-qjVBInp-k8xIr34HupzhHEE8CPnL9H3rsndi-Q
  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://calendar.thejc.me.uk/.well-known/acme-challenge/ZMLih0TfHclbXCU_TMUWIN9on025h5dwXjPmQXWWcF8 before continuing:

ZMLih0TfHclbXCU_TMUWIN9on025h5dwXjPmQXWWcF8.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" ZMLih0TfHclbXCU_TMUWIN9on025h5dwXjPmQXWWcF8.DoF45VJtf5D8xFPlklYLoX5kqLn0w4Ys7uEase57yQs > .well-known/acme-challenge/ZMLih0TfHclbXCU_TMUWIN9on025h5dwXjPmQXWWcF8
# 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 'ZMLih0TfHclbXCU_TMUWIN9on025h5dwXjPmQXWWcF8.DoF45VJtf5D8xFPlklYLoX5kqLn0w4Ys7uEase57yQs' > /home/www/var/www/acme-challenge/ZMLih0TfHclbXCU_TMUWIN9on025h5dwXjPmQXWWcF8
  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-03-03. To obtain a new version of the certificate in the
   future, simply run Let's Encrypt again.
 - If 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

Creating Chained Certificate for NGINX

NGINX needs the server certificate to be concatenated with the intermediary certificate. Although the root certificate can also be concatenated, it is not only unnecessary but increases the size of what is sent to a client on connection, potentially increasing the number of round trips to setup a connection.

mkdir calendar_johncook_co_uk
mv 0000* calendar_johncook_co_uk
cat calendar_johncook_co_uk/0000_certs ca/lets-encrypt-x1-cross-signed.pem > calendar_johncook_co_uk/calendar_johncook_co_uk.chained.pem

Install New Certificate and Key

cp /etc/ssl/calendar.johncook.co.uk/calendar_johncook_co_uk.key1 calendar_johncook_co_uk/

Over on my home server:

rm /home/www/var/www/acme-challenge/*
cd /etc/ssl/
sudo mkdir calendar.johncook.co.uk
sudo chgrp thejc calendar.johncook.co.uk
sudo chmod 775 calendar.johncook.co.uk

Back on laptop, copy files across and secure permissions:

scp calendar_johncook_co_uk/calendar_johncook_co_uk.* thejc@home:/etc/ssl/calendar.johncook.co.uk/
rm calendar_johncook_co_uk/calendar_johncook_co_uk.key1
sudo chmod 600 -R /home/thejc/lets-encrypt-data
sudo chmod 400 -R /etc/ssl/calendar.johncook.co.uk

Back on home server, edit NGINX configuration to add new hostname and swap to new certificate and key:

sudo nano /etc/nginx/sites-enabled/calendar_thejc_me_uk
…
	server_name calendar.johncook.co.uk calendar.thejc.me.uk;
	ssl_certificate         /etc/ssl/calendar.johncook.co.uk/calendar_johncook_co_uk.chained.pem;
	ssl_certificate_key     /etc/ssl/calendar.johncook.co.uk/calendar_johncook_co_uk.key1;
…
sudo service nginx configtest && sudo service nginx reload
openssl s_client -connect calendar.johncook.co.uk:8443 -CAfile /etc/ssl/certs/ca-certificates.crt

The new key and certificate are installed and being used for new connections.

Add OCSP Stapling

On my VPS I already have a script I wrote that deals with OCSP stapling files.

cd ~/Scripts
nano ocsp-stapling.sh
#!/bin/sh

ISSUER_CER=$1
SERVER_CER=$2
CA_FILE=$3
CACHED_OCSP=$4

URL=$(openssl x509 -in "$SERVER_CER"  -text | grep "OCSP - URI:" | cut -d: -f2,3)
HOST=$(echo "$URL" | awk -F/ '{print $3}')

echo "ISSUER=$ISSUER_CER"
echo "SERVER=$SERVER_CER"
echo "CA=$CA_FILE"
echo "OCSP_CACHE=$CACHED_OCSP"
echo "URL=$URL"
echo "HOST=$HOST"

openssl ocsp -no_nonce -respout "$CACHED_OCSP" -issuer "$ISSUER_CER" -cert "$SERVER_CER" -url "$URL" -header HOST "$HOST" -CAfile "$CA_FILE" -VAfile "$CA_FILE"

Add the necessary files:

sudo mkdir /etc/ssl/LetsEncrypt/
cd /etc/ssl/LetsEncrypt/
sudo chgrp thejc .
sudo chmod 770 .
sudo update-ca-certificates
sudo dpkg-reconfigure ca-certificates

Add all the new certificates to the trust store.

Download the intermediate certificates:

wget --trust-server-names 'https://letsencrypt.org/certs/lets-encrypt-x1-cross-signed.pem'
wget --trust-server-names 'https://letsencrypt.org/certs/letsencryptauthorityx1.pem'
wget --trust-server-names 'https://letsencrypt.org/certs/lets-encrypt-x2-cross-signed.pem'
wget --trust-server-names 'https://letsencrypt.org/certs/letsencryptauthorityx2.pem'

The ISRG Root X1 certificate is not currently in the trusted certificate store in Debian, so I need to download it.

wget --trust-server-names 'https://letsencrypt.org/certs/isrgrootx1.pem'

Concatenate the ISRG Root X1 Certificate with the DST Root CA X3 certificate and the intermediate certificate:

cat isrg* lets* ../certs/DST_Root_CA_X3.pem > ca-bundle.pem

Create the OCSP stapling file:

chmod +x /home/thejc/Scripts/ocsp-stapling.sh
/home/thejc/Scripts/ocsp-stapling.sh /etc/ssl/LetsEncrypt/lets-encrypt-x1-cross-signed.pem /etc/ssl/calendar.johncook.co.uk/calendar_johncook_co_uk.chained.pem /etc/ssl/LetsEncrypt/ca-bundle.pem /etc/ssl/calendar.johncook.co.uk/ocsp_cache.resp
ISSUER=/etc/ssl/LetsEncrypt/lets-encrypt-x1-cross-signed.pem
SERVER=/etc/ssl/calendar.johncook.co.uk/calendar_johncook_co_uk.chained.pem
CA=/etc/ssl/LetsEncrypt/ca-bundle.pem
OCSP_CACHE=/etc/ssl/calendar.johncook.co.uk/ocsp_cache.resp
URL=http://ocsp.int-x1.letsencrypt.org/
HOST=ocsp.int-x1.letsencrypt.org
Error loading file /etc/ssl/LetsEncrypt/ca-bundle.pem
140357445670544:error:0906D066:PEM routines:PEM_read_bio:bad end line:pem_lib.c:802:
140357445670544:error:0B084009:x509 certificate routines:X509_load_cert_crl_file:PEM lib:by_file.c:280:

One of the files didn't end on a newline. Open the offending file in a text editor that automatically adds a newline to the end of a file, and then save it.

nano letsencryptauthorityx2.pem

You can use the -L option with nano to tell it not to automatically end files with a newline, if you want to manually add the newline. Alternatively, just opening it (without -L) and saving will add a newline.

Now we need to create ca-bundle again:

rm ca-bundle.pem
cat isrg* lets* ../certs/DST_Root_CA_X3.pem > ca-bundle.pem

And create the OCSP stapling file:

/home/thejc/Scripts/ocsp-stapling.sh /etc/ssl/LetsEncrypt/lets-encrypt-x1-cross-signed.pem /etc/ssl/calendar.johncook.co.uk/calendar_johncook_co_uk.chained.pem /etc/ssl/LetsEncrypt/ca-bundle.pem /etc/ssl/calendar.johncook.co.uk/ocsp_cache.resp
ISSUER=/etc/ssl/LetsEncrypt/lets-encrypt-x1-cross-signed.pem
SERVER=/etc/ssl/calendar.johncook.co.uk/calendar_johncook_co_uk.chained.pem
CA=/etc/ssl/LetsEncrypt/ca-bundle.pem
OCSP_CACHE=/etc/ssl/calendar.johncook.co.uk/ocsp_cache.resp
URL=http://ocsp.int-x1.letsencrypt.org/
HOST=ocsp.int-x1.letsencrypt.org
Response verify OK
/etc/ssl/calendar.johncook.co.uk/calendar_johncook_co_uk.chained.pem: good
	This Update: Dec  4 14:00:00 2015 GMT
	Next Update: Dec 11 14:00:00 2015 GMT

Now I need to tell NGINX about it.

To copy my VPS set-up, I have 2 include files:

  1. nginx.ssl-stapling
  2. nginx.ssl-stapling-startssl
sudo nano /etc/nginx/includes/nginx.ssl-stapling

This file already exists, and contains the following:

	ssl_stapling		on;
	ssl_stapling_verify		on;
	resolver		[fdf4:90db:f24c:72ca:df4d:b9ee:be0b:c37d] [2001:470:1f09:38d::fcf4:53] [
2001:470:20::2] 74.82.42.42 8.8.8.8;
ln -s isrgrootx1.pem ca.pem
sudo nano /etc/nginx/includes/nginx.ssl-stapling-letsencrypt
	include /etc/nginx/includes/nginx.ssl-stapling;
	ssl_trusted_certificate /etc/ssl/LetsEncrypt/ca.pem;

Add the OCSP cache file and the Let's Encrypt OCSP stapling include to the calendar.johncook.co.uk vhost:

	include /etc/nginx/includes/nginx.ssl-stapling-letsencrypt;
	ssl_stapling_file /etc/ssl/calendar.johncook.co.uk/ocsp_cache.resp

Finally, test the config, reload nginx, and check OCSP stapling is working:

sudo service nginx configtest && sudo service nginx reload
openssl s_client -connect calendar.thejc.me.uk:8443 -CAfile /etc/ssl/certs/ca-certificates.crt -status
CONNECTED(00000003)
depth=2 O = Digital Signature Trust Co., CN = DST Root CA X3
verify return:1
depth=1 C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X1
verify return:1
depth=0 CN = calendar.johncook.co.uk
verify return:1
OCSP response: 
======================================
OCSP Response Data:
    OCSP Response Status: successful (0x0)
    Response Type: Basic OCSP Response
    Version: 1 (0x0)
    Responder Id: C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X1
    Produced At: Dec  4 14:43:00 2015 GMT
    Responses:
    Certificate ID:
      Hash Algorithm: sha1
      Issuer Name Hash: BC5772E2797C56E39994598D75A4A3D24C4C85C5
      Issuer Key Hash: A84A6A63047DDDBAE6D139B7A64565EFF3A8ECA1
      Serial Number: 0140DCF3591635E85090C4497CBCBEEE3042
    Cert Status: good
    This Update: Dec  4 14:00:00 2015 GMT
    Next Update: Dec 11 14:00:00 2015 GMT

    Signature Algorithm: sha256WithRSAEncryption
         94:63:b9:cb:6b:df:ce:84:3a:12:50:5c:33:48:7c:be:49:00:
         6a:c0:b6:dc:58:a2:d7:cb:92:ab:36:c3:41:f8:b5:d9:8a:7a:
         c0:d0:16:84:f3:30:7d:98:53:fb:4e:d3:f3:e0:29:e1:6e:16:
         da:ee:74:b2:01:8a:94:ca:cd:31:3a:8d:7f:5b:02:fc:51:1d:
         db:aa:f3:54:25:a2:83:7d:a1:07:5b:10:48:98:f5:cd:b1:a5:
         e2:35:fe:8d:04:54:c5:f8:9a:33:2d:23:aa:b8:a6:b8:07:88:
         8d:68:1b:68:67:a0:c0:a2:a3:09:cb:84:4b:17:8c:98:f0:b1:
         25:3d:d3:72:8b:63:63:79:a5:e5:ab:a7:89:a6:a6:8b:fc:08:
         23:59:46:c7:57:4c:89:55:ed:32:eb:13:a7:9a:e8:c6:49:81:
         be:7f:e7:f0:c1:d8:57:3e:64:e8:57:72:b5:e2:bd:84:c8:81:
         37:cb:ef:24:4c:66:aa:e4:19:cc:5d:69:5e:83:2b:e6:d0:f2:
         1e:09:04:4c:38:eb:80:0d:91:cd:f9:92:ea:3b:e4:50:bc:59:
         de:9c:db:bd:ad:a2:95:80:ec:5a:80:d2:fc:ac:a4:90:a8:2c:
         02:2b:fd:01:da:44:45:83:29:ee:7f:2d:52:63:0c:14:9a:84:
         3c:c5:e9:3e
======================================
…

In future OCSP cache files will be updated using root's cron, so I can now tighten up permissions:

sudo chown root -R /etc/ssl/calendar.johncook.co.uk
sudo chmod 464 /etc/ssl/calendar.johncook.co.uk/calendar_johncook_co_uk.chained.pem
sudo chmod 420 /etc/ssl/calendar.johncook.co.uk/calendar_johncook_co_uk.key1
sudo chmod 644 /etc/ssl/calendar.johncook.co.uk/ocsp_cache.resp

Updating OCSP Cache

This is going to be simple. I am going to create a script and add the script to root's crontab.

nano ~/Scripts/ocsp-stapling-cache-now.sh
#!/bin/sh

/home/thejc/Scripts/ocsp-stapling.sh /etc/ssl/LetsEncrypt/lets-encrypt-x1-cross-signed.pem /etc/ssl/asterisk/sip_johncook_co_uk.chained.pem /etc/ssl/LetsEncrypt/ca-bundle.pem /etc/ssl/asterisk/ocsp_cache.resp
/home/thejc/Scripts/ocsp-stapling.sh /etc/ssl/LetsEncrypt/lets-encrypt-x1-cross-signed.pem /etc/ssl/calendar.johncook.co.uk/calendar_johncook_co_uk.chained.pem /etc/ssl/LetsEncrypt/ca-bundle.pem /etc/ssl/calendar.johncook.co.uk/ocsp_cache.resp

/usr/sbin/service nginx configtest && /usr/sbin/service nginx reload
chmod +x ~/Scripts/ocsp-stapling-cache-now.sh
sudo crontab -e
# Update OCSP caches
02 2 * * Mon,Wed,Fri,Sat /home/thejc/Scripts/ocsp-stapling-cache-now.sh

For subsequent domains and certificates, I will just do the initial stapling and then add the command to ocsp-stapling-cache-now.sh.

The reason the cron job is run 4 times a week is because it is the closest way of running it every 48 hours.

Renewing the Certificate

Let's Encrypt states the following about renewals:

To renew a certificate, simply run letsencrypt again providing the same values when prompted. Let’s Encrypt is working hard to fully automate this process and we apologize for the inconvenience until this functionality is ready.

Let's Encrypt. Renewing a Certificate. In How it Works

What I think that basically means is when you want to renew a certificate you just run letsencrypt-auto again feeding it exactly the same options/answers it was fed when the certificate was created.

So, in the case of the certificate created in this article:

/opt/letsencrypt/letsencrypt-auto -c ~/lets-encrypt-data/config/letsencrypt.conf auth -a manual --csr ~/lets-encrypt-data/csr/calendar_johncook_co_uk.csr

Since some of the options in my configuration file don't seem to work, that will dump the new certificate (and the chain files) into the current directory.

My directory naming structure means that a certificate is found in the directory below ~/lets-encrypt-data/ with the directory and files having the same name as the Common Name in the certificate, with the dots replaced with underscores.

Likewise, on my home server the certificates are found in the directory below /etc/ssl/ with the directory name of the Common Name in the certificate, and the files have the dots replaced with underscores. With the exception of my asterisk certificates, which are stored in /etc/ssl/asterisk/.

I don't yet know if I need to authenticate and prove I have control over a domain when renewing or not.

While I cannot completely script the entire renewal process until I have seen it in action a few times, I can do some scripting.

Programitcally Determining What Certificates Need Renewing

As long as I keep to my directory and file naming convention, this should be simple.

First, I need a list of directories:

cd /home/thejc/lets-encrypt-data/
find . -maxdepth 1 -type d -name '*_*' | sed 's,^./,,'
calendar_johncook_co_uk
sip_johncook_co_uk

With those, I can then check if a certificate expires in the next 1,209,600 seconds (14 days). For example:

find calendar_johncook_co_uk -maxdepth 1 -type f -name '*_certs' | sort | tail -n 1 | xargs openssl x509 -checkend 1209600 -noout -in
if [ ! $? -eq 0 ]; then echo Expiring Soon; fi

For a simple script, I will need one loop:

#!/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 '*_certs' | sort | tail -n 1 | 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

Obviously the echo lines will need replacing with the certificate renewing, bundling, and transferring, and I'll also need a way to tell NGINX on my home server to reload.

One way of getting NGINX to reload would be a cron job on my Web servers that calls a script that runs a configtest and reload. I would have to add a safeguard in case I'm editing NGINX files though, which I could probably do using find with the -newermt option.

Once I start using certificates on my VPS, I'll also need to add case statements so the files are sent to the right server(s). I'll need 3 cases:

  1. Certificates only used on home.
  2. Certificates only used on vps3.
  3. Certificates used on both home and vps3.

Client Version

I am not sure if letsencrypt-auto updates itself or not when it does the dependency checking.

If it doesn't, then the possible reason the filenames don't match those elsewhere is because I cloned the git repository before the public beta opened.

The next time I request a new certificate (or request a renewal) I will have a pull the latest changes from the repo before running the commands and seeing what happens. It might just be a side-effect of running in manual mode, or my configuration file might have an error I can't see.

I think I have grasped the basics of how the client works, the next question is whether I need to create acme-challenge files on renewals.

If I do, then complete automation with manual mode is probably out of the question. I may well decide to write a C client at a later date, but that will likely have to wait until I have done some more work on my EPP client.