Configure Cloudflare and Heroku over HTTPS

Heroku is a cloud platform as a service which supports several programming languages, meaning you do not have to worry about any infrastructure, and can instead focus on your application.

This article describes how to configure Cloudflare and Heroku to serve your traffic over HTTPS. For the purpose of this article we will assume that you already have an active domain on Cloudflare, as well as have a running Heroku app.

 

Adding a custom domain to your Heroku app

NOTE: Heroku requires a credit card on file before adding a domain.

  1. Log in to Heroku, select your app, and go to 'Settings'
  2. Scroll down to ‘Domains’ and click ‘Edit’.
  3. Type in your (sub) domain and click ‘Save’.
  4. You're done!

If you are managing your Heroku app via CLI you can also add a domain by running the following command:

heroku domain:add [yourdomain]


Configuring your Cloudflare DNS
Heroku uses multiple IP addresses for their app servers so choosing to bind to a single IP address using an 'A record' could impact the availability of your app. Instead we'll be using the CNAME flattening functionality to dynamically resolve requests for the root domain.

Root domain
To start, log in to your Cloudflare account and navigate to the DNS app.

Add a new ‘CNAME’ record for your root domain that points at your Heroku app URL (example: cf-app-test.herokuapp.com).

At this point CNAME flattening will automatically take effect, and your domain will resolve to Heroku’s servers.

Subdomain
If your website relies on any subdomains you will want to make sure those were added accordingly as well.

Please note that by default CNAME flattening is only enabled for your root domain. You may request CNAME flattening to be enabled across your entire zone by contacting our Support team.

 

Confirming that your domain is routed through Cloudflare
The easiest way to confirm that Cloudflare is working for your domain is to use cURL.

╰─➤  curl -I martijn.cf
HTTP/1.1 200 OK
Date: Wed, 24 Jun 2015 02:46:16 GMT
Content-Type: text/html; charset=utf-8
Connection: keep-alive
Set-Cookie: __cfduid=d981b13a67668bc3dba1f4cf901450cf21435113976; expires=Thu, 23-Jun-16 02:46:16 GMT; path=/; domain=.martijn.cf; HttpOnly
X-Frame-Options: SAMEORIGIN
Via: 1.1 vegur
Server: cloudflare-nginx
CF-RAY: 1fb519efe503119b-SJC

You can identify Cloudflare-proxied requests by either the ‘__cfuid’ cookie or the ‘CF-Ray’ response header. If either of these two are present, your requests are being proxied by Cloudflare accordingly.

You can repeat the above cURL command for any of your sub domains that you have configured within your DNS settings.

 

Configuring your domain for SSL
Cloudflare provides a SANs wildcard certificate with all paid plans, and a SNI wildcard certificate with the Free plan. Full details on our SSL offering can be found here.

Utilizing SSL through Cloudflare is very simple. To start, navigate to the Crypto app within your Cloudflare Dashboard.

 

SSL

Cloudflare provides three different SSL options that you can benefit from.

SSL options on Heroku:

  • For Hobby dynos, Heroku offers a wildcard SSL certificate which only covers ‘*.herokuapp.com’. You should use the "Full" SSL mode on Cloudflare, which does not require that the SAN contains your FQDN, but does require that the certificate is publicly valid and has not expired.
  • Paid Heroku users can use Heroku's Automated Certificate Management service to provision a certificate in your name automatically, however this may conflict with Cloudflare's proxy due to the required DNS (re)-validation.
  • Heroku also offers an SSL endpoint add-on for uploading your own custom certificates.

Forcing all traffic over HTTPS
To force all traffic over HTTPS we’ll be using the Page Rules functionality found in the Cloudflare Dashboard. You can also do this via the application directly. However, any request that is made at the edge will be faster than if it had to reach the application first.

Once you've navigated to the Page Rules app you can start adding a new rule that covers your entire domain.

Type in your Page Rule according (i.e. 'http://*yourdomain.com/*) and click 'Add Rule'. We can then use a similar cURL command as before to verify that all requests are being forced over HTTPS.

╰─➤  curl -I -L martijn.cf
HTTP/1.1 301 Moved Permanently
Date: Wed, 24 Jun 2015 04:06:00 GMT
Connection: keep-alive
Set-Cookie: __cfduid=d37122464f26484c74e2359938310ac611435118760; expires=Thu, 23-Jun-16 04:06:00 GMT; path=/; domain=.martijn.cf; HttpOnly
Location: https://martijn.cf/
Server: cloudflare-nginx
CF-RAY: 1fb58ebf219111b9-SJC
HTTP/1.1 200 OK
Server: cloudflare-nginx
Date: Wed, 24 Jun 2015 04:06:01 GMT
Content-Type: text/html; charset=utf-8
Connection: keep-alive
Set-Cookie: __cfduid=dacb13cbfbc6415248b68d3c51e03a8001435118761; expires=Thu, 23-Jun-16 04:06:01 GMT; path=/; domain=.martijn.cf; HttpOnly
X-Frame-Options: SAMEORIGIN
Via: 1.1 vegur
CF-RAY: 1fb58ec130851213-SJC

If SSL was not working for your domain (e.g. your SSL certificate has not yet been issued), you would see a 525 or 526 HTTP response after following the redirect.

Please note that the issuing of a Universal SSL certificate typically takes up to 24 hours. Our paid SSL certificates issue within 10-15 minutes. 

Still not finding what you need?

The CloudFlare team is here to help. 95% of questions can be answered using the search tool, but if you can’t find what you need, submit a support request.

Powered by Zendesk