Background
I have a Debian server hosted on UpCloud (because they are fast) with a Nginx Web Server, My Domain name is purchased through https://porkbun.com, DNS and SSL certificates are managed by https://cloudflare.com
Cloudflare are cool, for a number of reasons






Cloudflare handle my HTTPS certificate that the public receive. This costs me $5 a month and I don’t need to manage renewals.

https://dev.ssllabs.com/ reports that the site is Certificate is OK.

Cloudflare do allow you to create a free Cloudflare certificate to use on your website but I am happy with Lets Encrypt.

Maybe one day I will try out the Cloudflare certificate on my website behind the scenes

I awoke today with news that Let’s Encrypt to revoke 3 million certificates on March 4 due to software bug. I will need to update my Lets Encrypt certificate on my server but the catch is because Cloudflare handle the HTTS certificate any attempt to renew my HTTPS certificate will be blocked by Cloudflare.
Acme.sh
This is where a handy Open Source script called (acme.sh) on Github comes in, it will renew my Let’s Encrypt Certificate from the command line and verify my server with Let’s Encrypt via DNS records. To do this it will use the Cloudflare API and create a DNS records to verify my server with Let’s Encrypt. Nice.
Go to https://github.com/acmesh-official/acme.sh and read how you can install acme.sh
e.g
curl https://get.acme.sh | sh
or
wget -O - https://get.acme.sh | sh
or
git clone https://github.com/acmesh-official/acme.sh.git
cd ./acme.sh
./acme.sh --install
Now you can login to Cloudflare and generate an API Token
Once you have a Cloudflare API Token you can edit the acme.sh file
nano acme.sh
Add the following to the top of you acme.sh after the “VER=” line.
CF_Key="#########your#cloudflare-api-key##########"
CF_Email="your-clou[email protected]"
CF_Api="https://api.cloudflare.com/client/v4"
Review these values
_SUB_FOLDER_NOTIFY="notify"
_SUB_FOLDER_DNSAPI="dnsapi"
_SUB_FOLDER_DEPLOY="deploy"
VTYPE_HTTP="http-01"
VTYPE_DNS="dns-01"
VTYPE_ALPN="tls-alpn-01"
LOCAL_ANY_ADDRESS="0.0.0.0"
DEFAULT_RENEW=60
DEFAULT_DNS_SLEEP=120
NGINX="nginx:"
You can renew a Certificate via the Cloudflare API by running this command
sudo /root/.acme.sh/acme.sh --cron --home /root/.acme.sh --force
The output of the command will look like this
sudo bash /parentfolder/.acme.sh/acme.sh --cron --home /parentfolder/.acme.sh --force
[Wed Mar 4 18:20:59 AEDT 2020] ===Starting cron===
[Wed Mar 4 18:20:59 AEDT 2020] Renew: 'fearby.com'
[Wed Mar 4 18:20:59 AEDT 2020] Multi domain='DNS:fearby.com,DNS:www.fearby.com'
[Wed Mar 4 18:20:59 AEDT 2020] Getting domain auth token for each domain
[Wed Mar 4 18:21:00 AEDT 2020] Getting webroot for domain='fearby.com'
[Wed Mar 4 18:21:00 AEDT 2020] Getting webroot for domain='www.fearby.com'
[Wed Mar 4 18:21:00 AEDT 2020] fearby.com is already verified, skip dns-01.
[Wed Mar 4 18:21:00 AEDT 2020] www.fearby.com is already verified, skip dns-01.
[Wed Mar 4 18:21:00 AEDT 2020] Verify finished, start to sign.
[Wed Mar 4 18:21:00 AEDT 2020] Lets finalize the order, Le_OrderFinalize: https://acme-v02.api.letsencrypt.org/acme/finalize/###############/############
[Wed Mar 4 18:21:02 AEDT 2020] Download cert, Le_LinkCert: https://acme-v02.api.letsencrypt.org/acme/cert/############################
[Wed Mar 4 18:21:02 AEDT 2020] Cert success.
-----BEGIN CERTIFICATE-----
**************************************************************
**************************************************************
**************************************************************
**************************************************************
**************************************************************
**************************************************************
**************************************************************
**************************************************************
**************************************************************
**************************************************************
**************************************************************
**************************************************************
**************************************************************
**************************************************************
**************************************************************
**************************************************************
**************************************************************
**************************************************************
**************************************************************
**************************************************************
**************************************************************
**************************************************************
**************************************************************
**************************************************************
-----END CERTIFICATE-----
[Wed Mar 4 18:21:02 AEDT 2020] Your cert is in /parentfolder/.acme.sh/fearby.com/fearby.com.cer
[Wed Mar 4 18:21:02 AEDT 2020] Your cert key is in /parentfolder/.acme.sh/fearby.com/fearby.com.key
[Wed Mar 4 18:21:02 AEDT 2020] The intermediate CA cert is in /parentfolder/.acme.sh/fearby.com/ca.cer
[Wed Mar 4 18:21:02 AEDT 2020] And the full chain certs is there: /parentfolder/.acme.sh/fearby.com/fullchain.cer
[Wed Mar 4 18:21:02 AEDT 2020] ===End cron===
Open the Crontab
crontab -e
Add this line to your crontab and save it.
0 0 1 */2 * /theparentfolder/.acme.sh/acme.sh --cron --home /root/.acme.sh --force
Conclusion
I can now update my websites behind the scenes HTTPS certificate that Cloudflare will use via the command line.
Related Guides:
Securing an Ubuntu VM with a free LetsEncrypt SSL certificate in 1 Minute
Troubleshooting
Read the acme.sh documentation here: https://github.com/acmesh-official/acme.sh