This Gist documents how to obtain a Let's Encrypt certificate for use with CloudFlare origin servers. For background please see my article on CloudFlare and Origin Servers for the Rightfully Paranoid.
I'm assuming OpenSSL is installed on your machine. You're also going to need
Node.js 5.6.0 or above. We'll be using
wilee to obtain the certificate from
Let's Encrypt.
First generate the private key for your Let's Encrypt account:
openssl genrsa -out account.pem 4096Then generate the private key for the certificate you want issued:
openssl genrsa -out privkey.pem 2048You'll have to create a certificate signing request that gets sent to Let's
Encrypt. Most likely you'll want the certificate to work for your main domain
and the www subdomain. Here's the approach that worked for me.
First copy the openssl.cnf file to a new location. On OS X it should be under
/System/Library/OpenSSL/openssl.cnf, on Linux it's probably under
/etc/ssl/openssl.cnf. Add the following at the end:
[ req ]
req_extensions = v3_req
[ v3_req ]
# Extensions to add to a certificate request
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = @alt_names
[alt_names]
Then under alt_names list the DNS names, like:
DNS.1=example.com
DNS.2=www.example.com
Substitute example.com for your domain name. You can add more domains, e.g.
DNS.3=admin.example.com, DNS.4=beta.example.com.
Create the request like this:
openssl req -new -sha256 -key privkey.pem -outform der -out csr.der -config openssl.cnfPlease see this Google Developers tutorial on how to answer the CSR questions.
Next install wilee:
npm install -g wileeRate limits
apply
when you use Let's Encrypt. It's best to go through this flow using their
staging
server
first. This is the default when you use wilee so let's push on.
Run the following to register an account with Let's Encrypt:
wilee --account account.pem new-reg [email protected]Please use your actual email address. Note that MX records must exist. You'll
have to agree to the terms of service as well.
Your account needs to be authorized for each domain you've included in the
certificate signing request. Run the following to authorize your account for
example.com:
wilee --account account.pem new-authz example.comThis will prompt you to create a TXT record for _acme-challenge.example.com
with a specific value. You can create this record using CloudFlare's dashboard.
Make sure to use the smallest possible TTL value.
wilee will poll DNS until the record exists, then it'll ask Let's Encrypt to
verify.
Repeat for your other domain names, e.g.:
wilee --account account.pem new-authz www.example.comThis will prompt you to create a TXT record for
_acme-challenge.www.example.com with a different value.
Once you've authorized all domain names you can request the certificate:
wilee --account account.pem new-cert csr.der --out cert.derAssuming all this worked you can repeat the process using Let's Encrypt's production server. You'll be making a new account and you'll have to authorize your domains again.
To register:
wilee --account account.pem --directory https://acme-v01.api.letsencrypt.org/directory new-reg [email protected]To authorize a domain:
wilee --account account.pem --directory https://acme-v01.api.letsencrypt.org/directory new-authz example.comTo request the certificate:
wilee --account account.pem --directory https://acme-v01.api.letsencrypt.org/directory new-cert csr.der --out cert.derCloudFlare won't accept the certificate by itself. It needs the intermediate certificates.
Personally I like creating a .p12 file which combines the private key and
certificates. Node.js accepts these files when you create an HTTPS server using
the pfx
option.
First convert the cert.der file:
openssl x509 -inform der -in cert.der -out chain.pemAppend the content of
https://letsencrypt.org/certs/lets-encrypt-x3-cross-signed.pem.txt to
chain.pem:
curl https://letsencrypt.org/certs/lets-encrypt-x3-cross-signed.pem.txt >> chain.pemThen to create the .p12 file:
openssl pkcs12 -export -passout pass: -inkey privkey.pem -in chain.pem -out cert.p12Configure your server to use cert.p12 and CloudFlare should accept it.
Let's Encrypt certificates expire after 90 days. The process described in this Gist is manual, so you'll have to repeat it before your certificate has expired. It's recommended to do this in the last 30 days that your certificate is still valid.
You can use your existing Let's Encrypt account, provided you haven't lost the
account key. You should be able to use your existing certificate signing request
as well. Simply request the new certificate and follow the steps to create a new
.p12 file:
wilee --account account.pem --directory https://acme-v01.api.letsencrypt.org/directory new-cert csr.der --out cert.derDomain authorizations expire after 10 months. You'll have to reauthorize domains at that point.
Error 'rsa routines:RSA_sign:digest too big for rsa key:rsa_sign.c:122'
I regenerated privkey.pem using
openssl genrsa -out privkey.pem 4096andopenssl req -new -sha512...