Free Wildcard Certificates using Cloudflare, Let’s Encrypt and acme.sh

     

Table of Contents

Preface

I already covered Azure DNS, it’s time to cover Cloudflare, too.

If you haven’t done so yet, sign up to Cloudflare (it’s free), and move your domain name to Cloudflare.

Note: Cloudflare can (and in fact does, by default) proxy your website and generate SSL certificates for you automatically (which you can disable by pausing your website), but in this case you still do need SSL certificates on your server for full security.

acme.sh

acme.sh is one of the many Let’s Encrypt clients. It has built-in support for Cloudflare DNS, and it is written in pure Bash, so it’s very portable. Most importantly, it supports ACME v2, which allows for wildcard certificates.

Setup

To obtain acme.sh:

git clone https://github.com/Neilpang/acme.sh.git /opt/acme.sh

Obtain your Cloudflare Global API Key, then set up your credentials on the server:

export CF_Key="***"
export CF_Email="[email protected]"

Don’t worry, you only need to set these once, then acme.sh will save those in its config folder. Now acquire a staging cert for foobar.com and all its subdomains:

/opt/acme.sh/acme.sh --issue --dns dns_cf --dnssleep 20 --force -d foobar.com -d *.foobar.com --staging

If it works, you can try doing the same for a production cert:

/opt/acme.sh/acme.sh --issue --dns dns_cf --dnssleep 20 --force -d foobar.com -d *.foobar.com

Since the certificates are stored under /root/.acme.sh, you need to tell SELinux to treat these files as certs:

yum install setools-console checkpolicy policycoreutils policycoreutils-python
semanage fcontext --add -t cert_t "/root/.acme.sh(/.*)?"
restorecon -rv /root/.acme.sh

Renewal

A cronjob like this should suffice:

00 07 1 * * root /opt/acme.sh/acme.sh "--renew" "--dns" "dns_cf" "--dnssleep" "20" "--force" "-d" "foobar.com" "-d" "*.foobar.com" >> /var/log/acme.sh 2>&1
05 07 1 * * root /sbin/nginx -s reload

Cheers!