My plans to automate most of the Let's Encrypt SSL certificate renewal process are getting closer.
Earlier this year I wrote about installing a Let’s Encrypt SSL certificate on Blacknight Solutions hosting where I have this and a number of other sites. This is working quite well – I get a few renewal reminder emails from Let’s Encrypt and I run a command line script to do the renewal but one of the manual steps annoys me.
Simulation & failure
The annoying manual step is the creation of a challenge file in the /.well-known/acme-challenge directory. I have to open my text editor to create a file and then open my FTP client to upload it, then press Enter at the command prompt. There must be a way to automate it.
I use LE64.EXE, the portable ZeroSSL client to generate the SSL certificate. To get sample testing data I copied the output produced when I was renewing a cert. I converted the output into a C file (just multiple printf() calls and getchar() calls to wait for Enter) and created an executable. I used this to aid development.
It was going great. I had a config file listing the domains and FTP information and I used the Net::FTP module to be able to upload (and delete) the challenge files. My regex was working perfectly, extracting the challenge filename and contents and uploading them (and deleting them afterwards).
Then I switched out my test executable and ran the LE64.EXE file. My code failed. It seemed that piping its output into my script wasn’t working – my code wasn’t receiving it and therefore the regex couldn’t parse it to get the challenge file information. Back to the drawing board.
As I read the docs for LE64 I found that it has a -handle-with parameter that allows for an external perl module to handle the challenge file process. It seems that LE64 is a perl script compiled into an executable.
I copied portions of the Crypt-LE/Simple moule and put my Net::FTP code into it. It does quite well but the SSL certificate file was not created. I wasn’t able to recreate the issue because the certificate was issued and could not be renewed.
I am getting closer to a solution. I am sure that I’ve made a small mistake and it will all come together when I fix that.
Here is the code that will read a config file and call the LE64 exectuable.
This is the module that handles creating and uploading the challenge files. I need to copy some of the code that reads the config file into this module so that I don’t have to hard code the FTP information.