# Trying to use Let's Encrypt + Cloudflare

**URL:** https://meta.discourse.org/t/trying-to-use-lets-encrypt-cloudflare/108031
**Category:** Support
**Created:** [January 31, 2019, 3:52pm UTC](https://meta.discourse.org/t/trying-to-use-lets-encrypt-cloudflare/108031 "2019-01-31T15:52:12Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![cean](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/cean/32/121477_2.png) [@cean](https://meta.discourse.org/u/cean)
#### Post date: [January 31, 2019, 3:52pm UTC](https://meta.discourse.org/t/trying-to-use-lets-encrypt-cloudflare/108031/1 "2019-01-31T15:52:12Z")

</div>

So, my website is behind Cloudflare. I am trying to make it https.

I tried using Cloudflare SSL (Full (strict)) but no, it did not work. I tried using Let’s Encrypt’s SSL which would not work because it is behind such proxy stuff as stated in official tutorial. What I encounter is Error 521.

**What I am trying to achieve is:**  
Public \> Cloudflare SSL \> Origin \> Let’s Encrypt SSL \> Host  
Or just Let’s Encrypt or Cloudflare in the middle. It does not matter, actually.

> **app.yml**
>
> ```
> templates:
> - "templates/postgres.template.yml"
> - "templates/redis.template.yml"
> - "templates/web.template.yml"
> - "templates/web.ratelimited.template.yml"
> - "templates/web.ssl.template.yml"
> - "templates/web.letsencrypt.ssl.template.yml"
> 
> expose:
> - "80:80" # http
> - "443:443" # https
> 
> params:
> db_default_text_search_config: "pg_catalog.english"
> db_shared_buffers: "128MB"
> 
> env:
> LANG: en_US.UTF-8
> UNICORN_WORKERS: 2
> DISCOURSE_HOSTNAME: censored.com
> DISCOURSE_DEVELOPER_EMAILS: 'censored@gmail.com'
> DISCOURSE_SMTP_ADDRESS: smtp.sendgrid.net
> DISCOURSE_SMTP_PORT: 465
> DISCOURSE_SMTP_USER_NAME: apikey
> DISCOURSE_SMTP_PASSWORD: "censored"
> DISCOURSE_SMTP_ENABLE_START_TLS: true
> LETSENCRYPT_ACCOUNT_EMAIL: censored@gmail.com
> 
> volumes:
> - volume:
> host: /var/discourse/shared/standalone
> guest: /shared
> - volume:
> host: /var/discourse/shared/standalone/log/var-log
> guest: /var/log
> 
> hooks:
> after_code:
> - exec:
> cd: $home/plugins
> cmd:
> - git clone https://github.com/discourse/docker_manager.git
> after_web_config:
> - replace:
> filename: /etc/nginx/nginx.conf
> from: /sendfile.+on;/
> to: |
> server_names_hash_bucket_size 64;
> sendfile on;
> - file:
> path: /etc/nginx/conf.d/discourse_redirect_1.conf
> contents: |
> server {
> listen 80 default_server;
> server_name _;
> return 301 $scheme://censored.com$request_uri;
> }
> - file:
> path: /etc/nginx/conf.d/discourse_redirect_2.conf
> contents: |
> server {
> listen 443 ssl default_server;
> server_name _;
> return 301 $scheme://censored.com$request_uri;
> }
> 
> run:
> - exec: echo "Beginning of custom commands"
> - exec: echo "End of custom commands"
> 
> ```

---

<div class="post-metadata">

### Author: ![itsbhanusharma](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/itsbhanusharma/32/180717_2.png) [@itsbhanusharma](https://meta.discourse.org/u/itsbhanusharma)
#### Post date: [January 31, 2019, 4:04pm UTC](https://meta.discourse.org/t/trying-to-use-lets-encrypt-cloudflare/108031/2 "2019-01-31T16:04:15Z")

</div>

Easiest will be to disable ssl on discourse side and let cloudflare manage ssl for you but that’s not okay at all times.

What I’ve done in my case is that I run discourse behind an nginx reverse proxy with letsencrypt ssl (in dns-01 with cloudflare dns plugin) and that makes it so that:  
discourse (sockets) \> nginx (ssl) \> Cloudflare (ssl) \> Public

---

<div class="post-metadata">

### Author: ![Umashankar\_Ankuri](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/umashankar_ankuri/32/150996_2.png) [@Umashankar\_Ankuri](https://meta.discourse.org/u/Umashankar_Ankuri)
#### Post date: [January 31, 2019, 4:38pm UTC](https://meta.discourse.org/t/trying-to-use-lets-encrypt-cloudflare/108031/3 "2019-01-31T16:38:15Z")

</div>

Hi,

I have added cloudflare.template to app.yml and enabled SSL as Full (not Full Strict) in cloudflare crypto settings  
Also disabled rocket loader which is working fine for me.

---

<div class="post-metadata">

### Author: ![Stephen](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/stephen/32/95011_2.png) [@Stephen](https://meta.discourse.org/u/Stephen)
#### Post date: [January 31, 2019, 8:11pm UTC](https://meta.discourse.org/t/trying-to-use-lets-encrypt-cloudflare/108031/4 "2019-01-31T20:11:55Z")

</div>

> [@cean](#):
>
> So, my website is behind Cloudflare. I am trying to make it https.
> 
> I tried using Cloudflare SSL (Full (strict)) but no, it did not work. I tried using Let’s Encrypt’s SSL which would not work because it is behind such proxy stuff as stated in official tutorial.

Ok, step one to do this involves temporarily unchecking the orange cloud and bypassing Cloudflare entirely. To issue the initial certificate Let’s Encrypt needs direct communication with your server.

Ensure that in your app.yml the following lines are uncommented:

- “templates/web.ssl.template.yml”
- “templates/web.letsencrypt.ssl.template.yml”

and add this one:

- “templates/cloudflare.template.yml”

There’s little to no risk in doing this, so click on the orange cloud to disable CloudFlare, configure Let’s Encrypt. When your site is working again under HTTPS you also need to make a change within Discourse enabling the `force_https` setting under /admin.

Once your server is communicating via HTTPS you can change one more setting at Cloudflare if there are no other sites or applications under the same domain. Visit the ‘Crypto’ tab at Cloudflare and swap SSL from ‘Flexible’ to ‘Full (Strict)’.

Note that certain CloudFlare features are incompatible with Discourse, you’re going to need to create the following page rule:

 ![](https://global.discourse-cdn.com/meta/original/3X/1/3/13bc9663ffd3e069a6b6fb91a888ecc72a9b932b.png)

And disable Brotli, which is under the ‘Speed’ tab of your domain:

 ![18%20PM](https://global.discourse-cdn.com/meta/original/3X/8/2/822756e5a85c6655fb8eecbd526180a089fceea2.png)

> [@itsbhanusharma](#):
>
> Easiest will be to disable ssl on discourse side and let cloudflare manage ssl for you but that’s not okay at all times.

This is neither easy, not a good idea. It’s easy to secure Discourse using Let’s Encrypt once you allow Let’s Encrypt to enrol the certificate. Troubleshooting the mixed scenario is much more hassle.

---

<div class="post-metadata">

### Author: ![itsbhanusharma](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/itsbhanusharma/32/180717_2.png) [@itsbhanusharma](https://meta.discourse.org/u/itsbhanusharma)
#### Post date: [January 31, 2019, 8:25pm UTC](https://meta.discourse.org/t/trying-to-use-lets-encrypt-cloudflare/108031/5 "2019-01-31T20:25:05Z")

</div>

> [@Stephen](#):
>
> This is neither easy, not a good idea

I don’t understand how is it not easy?  
If someone is just starting out, not filling in the letsencrypt email disables ssl  
And once You’ve got cloudflare proxying everything and managing ssl, pretty much all that’s left is to create a page rule and disable performance.

---

<div class="post-metadata">

### Author: ![Stephen](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/stephen/32/95011_2.png) [@Stephen](https://meta.discourse.org/u/Stephen)
#### Post date: [January 31, 2019, 8:30pm UTC](https://meta.discourse.org/t/trying-to-use-lets-encrypt-cloudflare/108031/6 "2019-01-31T20:30:13Z")

</div>

Because it doesn’t make the system any _simpler_.

Whether you encapsulate the traffic in SSL at Discourse, a reverse proxy, or via Cloudflare, Force\_HTTPS needs to be enabled. In the scenario where the server talks to CF over :80 that means that any time you access the server directly (and bypass cloudflare) you’re using Discourse with Force\_HTTPS enabled while HTTPS isn’t present.

Enabling HTTPs is easy, the only thing which defeats the process for CloudFlare users is the need for direct server communication during enrollment for the challenge to go through, which is also easy. It leaves the server in a consistent state whether the CF proxy is enabled, or not. There’s no inconsistency in behavior - which your suggestion would create.

And adding a reverse proxy is many orders of magnitude more complex.

---

<div class="post-metadata">

### Author: ![itsbhanusharma](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/itsbhanusharma/32/180717_2.png) [@itsbhanusharma](https://meta.discourse.org/u/itsbhanusharma)
#### Post date: [January 31, 2019, 8:35pm UTC](https://meta.discourse.org/t/trying-to-use-lets-encrypt-cloudflare/108031/7 "2019-01-31T20:35:08Z")

</div>

> [@Stephen](#):
>
> it doesn’t make the system any _simpler_ .

Nobody would be here wanting to deploy cloudflare for the sake of simplicity. General implication is to increase the security bit or to use cloudflare on the rest of the website while still being able to host discourse on a subdomain (however in this case, gray cloud is the best) But there are the fanboys and you absolutely totally gotta do something for the fanboys.

---

<div class="post-metadata">

### Author: ![Stephen](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/stephen/32/95011_2.png) [@Stephen](https://meta.discourse.org/u/Stephen)
#### Post date: [January 31, 2019, 8:39pm UTC](https://meta.discourse.org/t/trying-to-use-lets-encrypt-cloudflare/108031/8 "2019-01-31T20:39:12Z")

</div>

> [@itsbhanusharma](#):
>
> Nobody would be here wanting to deploy cloudflare for the sake of simplicity.

Again, I disagree, CloudFlare is oft misunderstood and sold as a magic bullet for server security, which is why I see so many customer deployments with Cloudflare present and not a shred of hardening done to the local server. The perception is that you turn on CloudFlare and the rest is taken care of.

So in that case simple both describes perception of the product, and also those making the decision :D.

---

<div class="post-metadata">

### Author: ![itsbhanusharma](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/itsbhanusharma/32/180717_2.png) [@itsbhanusharma](https://meta.discourse.org/u/itsbhanusharma)
#### Post date: [January 31, 2019, 8:42pm UTC](https://meta.discourse.org/t/trying-to-use-lets-encrypt-cloudflare/108031/9 "2019-01-31T20:42:16Z")

</div>

I had my own horror stories with trying to use cloudflare on Discourse so I just keep them totally unrelated. Managing your own server puts you into a very different perception than that of the end user who is scared of ssh.

You’re right. Thanks for enlightenment.

---

<div class="post-metadata">

### Author: ![Gulshan\_Kumar](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/gulshan_kumar/32/119562_2.png) [@Gulshan\_Kumar](https://meta.discourse.org/u/Gulshan_Kumar)
#### Post date: [January 31, 2019, 10:01pm UTC](https://meta.discourse.org/t/trying-to-use-lets-encrypt-cloudflare/108031/10 "2019-01-31T22:01:58Z")

</div>

> [@Stephen](#):
>
> Visit the ‘Crypto’ tab at Cloudflare and swap SSL from ‘Flexible’ to ‘Full (Strict)’.

Will Let’s Encrypt continue to renew automatically within 90 days?

I am afraid [Cloudflare says](https://support.cloudflare.com/hc/en-us/articles/200170416-What-do-the-SSL-options-mean-), Full Strict mode requires a valid SSL certificate from the trusted authority. If renew fail by chance, Full Strict Mode will throw Invalid SSL error to the visitors.

Where, Let’s Encrypt requires direct HTTP connection to the server IP.

* * *

Guess, this may be resolved via DNS auth way. But, how to enable for Discourse, Any idea?

In future, if Discourse add an option

Cloudflare email \_\_\_\_\_\_\_\_\_  
Global API key \_\_\_\_\_\_\_\_\_\_\_\_\_

Submit

_We will use this information to manage your DNS for Let’s Encrypt renewal._

This would be great!

---

<div class="post-metadata">

### Author: ![cean](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/cean/32/121477_2.png) [@cean](https://meta.discourse.org/u/cean)
#### Post date: [January 31, 2019, 10:30pm UTC](https://meta.discourse.org/t/trying-to-use-lets-encrypt-cloudflare/108031/11 "2019-01-31T22:30:12Z")

</div>

> [@Gulshan\_Kumar](#):
>
> Will Let’s Encrypt continue to renew automatically within 90 days?

Yes. It should do. Cerbot does that. I do not think Discourse dev team would have skipped that feature.

Edit:

> [@Set up HTTPS support with Let's Encrypt](https://meta.discourse.org/t/set-up-https-support-with-lets-encrypt/40709/1):
>
> Installs the cert into the right directory that `nginx` expects. At the same time, **it adds a cron job that runs a daily cert renewal check**. This will automatically renew your cert. Nothing happens if cert has not expired. If the certificate does expire, you’ll get an email about it from Let’s Encrypt at the email address you provided during setup.

---

<div class="post-metadata">

### Author: ![Gulshan\_Kumar](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/gulshan_kumar/32/119562_2.png) [@Gulshan\_Kumar](https://meta.discourse.org/u/Gulshan_Kumar)
#### Post date: [January 31, 2019, 10:36pm UTC](https://meta.discourse.org/t/trying-to-use-lets-encrypt-cloudflare/108031/12 "2019-01-31T22:36:54Z")

</div>

![image](https://global.discourse-cdn.com/meta/original/3X/5/1/51b28f9853b2f044ab7fc21fa6a82dc6dc34b4b8.png)

I think, It may work with Full, but not with “Full Strict”. For now, I would prefer to avoid CF for Discourse.

---

<div class="post-metadata">

### Author: ![Stephen](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/stephen/32/95011_2.png) [@Stephen](https://meta.discourse.org/u/Stephen)
#### Post date: [January 31, 2019, 10:54pm UTC](https://meta.discourse.org/t/trying-to-use-lets-encrypt-cloudflare/108031/13 "2019-01-31T22:54:12Z")

</div>

It works with Full (Strict).

---

<div class="post-metadata">

### Author: ![Gulshan\_Kumar](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/gulshan_kumar/32/119562_2.png) [@Gulshan\_Kumar](https://meta.discourse.org/u/Gulshan_Kumar)
#### Post date: [January 31, 2019, 11:04pm UTC](https://meta.discourse.org/t/trying-to-use-lets-encrypt-cloudflare/108031/14 "2019-01-31T23:04:32Z")

</div>

But how actually Let’s Encrypt validate for renewal?

---

<div class="post-metadata">

### Author: ![itsbhanusharma](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/itsbhanusharma/32/180717_2.png) [@itsbhanusharma](https://meta.discourse.org/u/itsbhanusharma)
#### Post date: [February 1, 2019, 6:20am UTC](https://meta.discourse.org/t/trying-to-use-lets-encrypt-cloudflare/108031/15 "2019-02-01T06:20:04Z")

</div>

Through http-01 challenge

---

<div class="post-metadata">

### Author: ![Gulshan\_Kumar](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/gulshan_kumar/32/119562_2.png) [@Gulshan\_Kumar](https://meta.discourse.org/u/Gulshan_Kumar)
#### Post date: [February 2, 2019, 11:14am UTC](https://meta.discourse.org/t/trying-to-use-lets-encrypt-cloudflare/108031/16 "2019-02-02T11:14:43Z")

</div>

Let’s Encrypt will connect to Cloudflare IP, not directly to origin IP. Will it work?

---

<div class="post-metadata">

### Author: ![itsbhanusharma](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/itsbhanusharma/32/180717_2.png) [@itsbhanusharma](https://meta.discourse.org/u/itsbhanusharma)
#### Post date: [February 2, 2019, 11:16am UTC](https://meta.discourse.org/t/trying-to-use-lets-encrypt-cloudflare/108031/17 "2019-02-02T11:16:34Z")

</div>

As far as I know it looks for a secret in the .well-known folder.

---

<div class="post-metadata">

### Author: ![Gulshan\_Kumar](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/gulshan_kumar/32/119562_2.png) [@Gulshan\_Kumar](https://meta.discourse.org/u/Gulshan_Kumar)
#### Post date: [February 2, 2019, 11:19am UTC](https://meta.discourse.org/t/trying-to-use-lets-encrypt-cloudflare/108031/18 "2019-02-02T11:19:28Z")

</div>

In http-01 challenge: I doubt this whole thing because let’s encrypt cannot be installed when Cloudflare is active, so it is highly unlikely they may renew without looking up real IP.

---

<div class="post-metadata">

### Author: ![itsbhanusharma](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/itsbhanusharma/32/180717_2.png) [@itsbhanusharma](https://meta.discourse.org/u/itsbhanusharma)
#### Post date: [February 2, 2019, 11:22am UTC](https://meta.discourse.org/t/trying-to-use-lets-encrypt-cloudflare/108031/19 "2019-02-02T11:22:21Z")

</div>

Per

> **[Automatic Certificate Management Environment (ACME)](https://datatracker.ietf.org/doc/html/draft-ietf-acme-acme-07)**
>
> Certificates in PKI using X.509 (PKIX) are used for a number of purposes, the most significant of which is the authentication of domain names. Thus, certificate authorities in the Web PKI are trusted to verify that an applicant for a certificate...

There is no mention of looking up for IP as long as the .well-known directory returns the correct token for validation, the certificate should be issued without any problems.

---

<div class="post-metadata">

### Author: ![Stephen](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/stephen/32/95011_2.png) [@Stephen](https://meta.discourse.org/u/Stephen)
#### Post date: [February 2, 2019, 1:30pm UTC](https://meta.discourse.org/t/trying-to-use-lets-encrypt-cloudflare/108031/20 "2019-02-02T13:30:17Z")

</div>

Correct, renewal works.

[Next page](https://meta.discourse.org/t/trying-to-use-lets-encrypt-cloudflare/108031.md?page=2)
