github pages secure with cloudflare

[ Update October 2018: I no longer use this setup. I migrated to gitlab (mostly because gitlab can easily build my website with hugo. Gitlab provides straightforward instructions on securing your site with Cloudflare. This would be my recommended setup now. ]

Do you see a little green icon in your browser bar? This website is now served using TLS (a secure connection also known as SSL) thanks to Cloudflare’s new free Universal SSL1. Combined with Github Pages hosting this website securely costs me nothing. Here I explain how to connect these services together so you can get your own green icon. I’ll assume you’re already familiar with Github Pages and how to publish your site using it.

As a bonus, in addition to making the web slightly better for everyone2, your site will probably resolve and load faster (Cloudflare caches your site at edge locations around the world and supports a new faster protocol called SPDY) and comes with IPv6 support.

On the other hand, be aware this free solution has some limitations and is not appropriate for if your site deals with sensitive or personal information. In particular:

  • If you use your own custom domain (like I do) the connection between Cloudflare servers and Github is not secured at all. This connection is generally going to be over high-speed backhaul connections that are much harder for an attacker to get at (compared with the wifi link in the coffee shop) but its certainly not safe against state level or sophisticated attackers. This limitation is because Github does not currently support secure connections for custom domains.

  • [Update August 2017. The fraction of users that still have this issue is now tiny. Unless you have a very particular market in mind, this is a non-concern for most people.] Older browsers will not be able to access your site securely (and if you force all connections to be secure, as I do, they will not be able to access your site at all). Primarily, this affects users of Internet Explorer on Windows XP and old Android phones. If this is an issue for you can you use a paid plan to support them (essentially, the only way for Cloudflare to support old browsers is to provide a dedicated IP address for your site which they can’t economically provide to everyone for free - see their blog post for more details).

  • [Update August 2017. This is no longer true, HSTS is easily enabled under the Cloudflare Crypto tab]. Cloudflare doesn’t currently support adding HSTS headers (telling the user’s browser to always use a secure connection for your website) so, again, this setup is not appropriate for a website dealing with sensitive information.

Setup

I was pleasantly surprised how straightforward it was to set this. I’ve outlined the steps below:

  • Setup an account at Cloudflare

  • Click through and follow the steps to setup Cloudflare for your domain. The defaults are pretty much ok.

  • As instructed you will need to point your DNS nameservers to Cloudflare. You then use Cloudflare to manage DNS for your domain. For Github Pages you should have a CNAME entry pointing to your github pages (e.g. for this site I have a CNAME @ aliased to jjh42.github.io). Make sure any other DNS settings are correct (i.e. for subdomains or MX fields).

  • (Optionally) I lowered the security profile since I’m not a likely target for attacks and I didn’t want any users (for example on Tor) to be forced to solve CAPTCHAs. This is Settings -> Security Profile. You may also want to enable CDN + Basic Optimizations which may help your website load a bit faster.

  • Enable SSL by selecting Flexible SSL in settings (if you are not using a custom domain then I believe you should be able to choose Full (Strict) for a more secure setup but I have not tried this). You may have to be patient at this point as you wait up to 24 hours for DNS settings to propogate and for Cloudflare to generate an SSL certificate for your domain.

  • Now your site should be available via Cloudflare in both secure and insecure versions. Try visiting https://yourwebsite (note the s) and check that it works.

  • Check in Google Chrome (I’m not sure about other browsers) for mixed content errors. Chrome will refuse to load resources on your page that have insecure URLs (since this could be easily used to compromise the integrity of the page) and will show the user a yellow warning icon. Usually, this can be easily fixed by replacing the resource with a secure or protocol agnostic form. For example, I used MathJAX which referred to a resource at http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS_HTML which Chrome wasn’t happy with. By editing the URL to be //cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS_HTML everything works fine and the browser will connect securely when on a secure page.

  • Setup a redirect so that visitors are always sent to the secure version of your website. From the Cloudflare console choose Page Rules and add a URL pattern http://yourwebsite/* and select Always use HTTPS and then Add Rule. Now check that when you go to the insecure version of your website you are redirected to the secure version.

  • Relax, knowing that you’ve made the web a slightly better place.

I hope that’s helpful. Feel free to ask questions or provide additional information in the comments below (I can’t promise I’ll have time to respond promptly though).

Be aware that due to Cloudflare’s caching changes to your website might not show up right away. You can always go to the Cloudflare console and put it in developer mode (which will temporarily disable caching so changes show up right away).


  1. Somewhat oddly, Cloudflare’s blog itself is not served over a secure connection. ^
  2. Even if your site, like mine, is not particularly sensitive, the more connections are secured even for trivial sites the more difficult it becomes for bad actors to snoop or censor. ^
comments powered by Disqus