How to get a Let's Encrypt certificate while using CloudFlare

[Moderator’s note, 2018-10-25: If your site is behind CloudFlare, the best option is to not use Let’s Encrypt at all, but instead to use Cloudflare’s Origin CA: https://blog.cloudflare.com/cloudflare-ca-encryption-origin/]

This seems to have come up a couple of times so here’s how to do it.

It’s not necessary to disable CloudFlare to use Let’s Encrypt.

If you’re configuring Let’s Encrypt for the first time for a site already active on CloudFlare, all that is needed to successfully verify and obtain your certificate and private key pair is to use the webroot method for verification.

Download certbot, the recommended Let’s Encrypt client and change to the download directory:

wget https://dl.eff.org/certbot-auto
chmod a+x certbot-auto

(OS-specific instructions can be found on the certbot homepage.)

Run the script for automatic installation:

./certbot-auto

Using the certbot client with the certonly command and the --webroot flag, we’re able to verify and obtain the cert/key pair using HTTP verification. An example command might look like:

./certbot-auto certonly --webroot --webroot-path /usr/share/nginx/html/ --renew-by-default --email email@host.tld --text --agree-tos -d example.tld -d www.example.tld

where

--webroot-path is the directory on your server where your site is located (nginx used in the example)
--renew-by-default selects renewal by default when domains are a superset of a previously attained cert
--email is the email used for registration and recovery contact.
--text displays text output
--agree-tos agrees to Let’s Encrypt’s Subscriber Agreement
-d specifies hostnames to add to the SAN.

Successful completion of this verification method will show text similar to the following:

IMPORTANT NOTES
- Congratulations! Your certificate and chain have been saved at 
/etc/letsencrypt/live/example.tld/fullchain.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.

As a note, both the cert and key will be saved to /etc/letsencrypt/live/example.tld/ . After both have been obtained, you’ll need to manually update your virtual host to use this key/cert pair.

5 Likes

For what it’s worth I chased my tail with this for a bit… I kept getting an error:
Error: The server could not connect to the client to verify the domain
Turning off CloudFlare SSL support did the trick

I’m running discourse with cloudflare as my cdn. I generated my cert before enabling cloudflare, which was relatively simple. However, now I can’t renew.

Any ideas what to use for the --webroot_path when running discourse? I can’t seem to find a directory or path that discourse is using for nginx.

Hello I followed all steps and made it to the congratulations part. I now have 4 files saved at /etc/letsencrypt/live/DOMAIN/ called: cert.pem, chain.pem, fullchain.pem and privkey.pem.

When looking at my config file at /etc/nginx/sites-available/default I have these 2 lines:
ssl_certificate cert.pem;
ssl_certificate_key cert.key;
I do have the cert.pem file but what about the cert.key? I can’t seem to find it.

Help much appreciated.

Hello @Koyaanis,

As you are using nginx, in ssl_certfile directive you should specify the fullchain.pem file (it includes your domain cert and the intermediate cert). And for ssl_certificate_key directive you should specify the privkey.pem file:

ssl_certificate /etc/letsencrypt/live/HEREYOURDOMAIN/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/HEREYOURDOMAIN/privkey.pem;

Note: Use always the full path to the cert files.

Cheers,
sahsanu

Thanks a lot that worked!

1 Like

You should also suggest to set Cloudflares SSL mode at least to “Full SSL (Strict)” or (better) use keyless SSL. Because all other SSL options of Cloudflare are very flawed and always keep in mind that Cloudflare man-in-the-middles your “secure” connection.

More at @scotthelme’s blog:

2 Likes

Hi,

If we have sites loading from more than 1 web root, how do we specify this in the command? do I have to generate a new cert for every site that loads from a different web root?

Hello @andrewjs18,

Take a look to ./letsencrypt-auto --help webroot and you will see two options to specify a webroot per domain/domains.

Example using -w ( --webroot-path ):

./letsencrypt-auto here_your_options -w /var/www/domain.tld -d domain.tld -d www.domain.tld -w /var/www/otherdomain.tld -d otherdomain.tld -d www.otherdomain.tld

Example using --webroot-map:

./letsencrypt-auto here_your_options --webroot-map '{"domain.tld,www.domain.tld":"/var/www/domain.tld", "otherdomain.tld,www.otherdomain.tld":"/var/www/otherdomain.tld"}'

Cheers,
sahsanu

Thank you. I’ll give it a try tonight.

@sahsanu, not quite sure what I’m doing wrong here. when I run ./letsencrypt-auto, it asks me which sites I’d like to activate HTTPS for, I choose them, then it errors out with a similar error as I’ll post below.

I then moved on to the instructions provided here: How to get a Let's Encrypt certificate while using CloudFlare

after doing so, it errored out, with the following: http://pastebin.com/ARyRQTNe

any help is greatly appreciated!

thanks!!!

again you (according to the error) tried tls authenticatinng (which only works if their is an existing cert)

instead of the previously advised webroot auth method

Hello @andrewjs18,

I recommend to put the options you will use in the command line and use the webroot method.

For example;

./letsencrypt-auto certonly --email youruser@yourdomain.tld --text --renew-by-default --agree-tos --webroot -w /home/site/public_html/ -d mysite.com -d www.mysite.com -w /home/site2/public_html/ -d sub1.mysite.com -w /home/site3/public_html/ -d sub2.site.com -w /home/site4/public_html/ -d sub3.mysite.com --dry-run

Replace your email, your domain names and webroot path with the real ones and execute again the command. If you get no error you could remove the last parameter --dry-run and launch again the command (--dry-run option simulates all the process but doesn’t issue the certificate so you can check that all will work fine once you are ready).

Cheers,
sahsanu

@sahsanu, thanks.

just tried rerunning the command…this time it returned a different error:

Failed authorization procedure. sub.mysite.com (http-01): urn:acme:error:unauthorized :: The client lacks sufficient authorization :: Invalid response from http://sub.mysite.com/.well-known/acme-challenge/ZVeBvGjXcf_uoKZyrGcANNKrBt04l_2--OW8ccT_0yo [104.18.52.40]: 404

IMPORTANT NOTES:

  • If you lose your account credentials, you can recover through
    e-mails sent to email@me.com.

  • The following errors were reported by the server:

    Domain: sub.mysite.com
    Type: unauthorized
    Detail: Invalid response from http://sub.mysite.com/.well-
    known/acme-challenge/ZVeBvGjXcf_uoKZyrGcANNKrBt04l_2–OW8ccT_0yo
    [104.18.52.40]: 404

    To fix these errors, please make sure that your domain name was
    entered correctly and the DNS A record(s) for that domain
    contain(s) the right IP address.

  • Your account credentials have been saved in your Let’s Encrypt
    configuration directory at /etc/letsencrypt. You should make a
    secure backup of this folder now. This configuration directory will
    also contain certificates and private keys obtained by Let’s
    Encrypt so making regular backups of this folder is ideal.

@andrewjs18, the error is clear, the challenge can’t be accessed to verify your domain.

Put a simple test file in /path/to/document/root/for/sub.mysite.com/.well-known/acme-challenge/testfile and try to access it using your web browser http://sub.mysite.com/.well-known/acme-challenge/testfile. If you get the content of testfile all is ok, if you receive a 404 Not found something is wrong in your conf.

Also, re-check that you wrote the correct webroot-path for your sub.mysite.com domain when you executed the letsencrypt-auto command.

Cheers,
sahsanu

1 Like

@sahsanu ah…that’s what it was, a slight directory issue in my command. thanks for all of your help!

I liked seeing this:

IMPORTANT NOTES:

  • The dry run was successful.

@andrewjs18, you are welcome. I’m glad you get it working, now, remove --dry-run and get your certs :wink:

1 Like

@sahsanu, just finished that up.

when I go to automate the renewal of the certs, can I just stuff the same command I ran to get the certs into a file that’s then set up in crontab?

That would work, but letsencrypt renew is a better option since it’s smarter about which options it uses, when it actually renews the certificates, etc.

Just put it in a daily cronjob, test it once, and you should be good to go. :smile:

1 Like