Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Setting up GH-pages with custom domain, strict (end-to-end) SSL with CloudFlare DNS & CDN

Custom domains, GH-pages, Cloudflare and strict SSL end-to-end encryption

Why I wrote this

Before Github supported SSL encryption for github pages sites, many people were using CloudFlare (CF) as their DNS provider and CDN proxy. CF allowed users to enable SSL encryption from the CDN end points/proxies to the end user. This was great and it allowed visitors to your website to connect with a secure connection between their browser and the cloudflare CDN box that was serving your content. However, with this setup one (significant) link in the chain remained unencrypted and exposed: The link between your published github pages site and the CF servers. So, in a sense, the warm cozy feeling users were having from seeing https:// and that nice padlock icon in their browser URL bar was disingenuous--Their connection to your original content was not completely encrypted and protected.

Fast forward to today: Github has enabled https for custom domains through provisioning Letsencrypt SSL certificates for Github pages sites. Now you can even pair this functionality with custom domains! In addition, since the CF functionality of providing SSL encrypted connections between their CDN/proxy servers and end users was first introduced, Github has also changed some of the details that one must consider when setting up custom domains. E.g., DNS A records need to point to different IP addresses for reaching GH's GH-pages servers than they used to.

Great, let's try full (strict) end-to-end encryption for GH pages and my personal website! Well, unfortunately, for a long time I could never get the settings page of my personal website (https://izaakbeekman.com) to allow me to check the checkbox to enable https. What's more, every time I googled the issue, the top posts were all about setting up this psuedo https/ssl encryption before GH supported SSL with custom domains, how frustrating! Some hits started to appear on the GH community forms for issues where https/ssl was never being provisioned and the checkbox would remain disabled, however, these issues did not specifically mention CF and the resolution was "contact GH support".

Full end-to-end (strict) encryption with GH pages, custom domains and CF!

Ultimately, I was in touch with GH support for an unrelated GH pages issue, and asked them why I could never get GH to provision a certificate for my GH-pages hosted site, and they gave me the solution. What's more, is that it seems to work!

  1. Create your GH-pages repository and setup gh-pages hosting for a user, org, or project level repository following the standard GH instructions.
  2. Procure a domain name from a registrar.
  3. Set the custom domain name in the GH-pages setting of your repository, this will create a file named CNAME with your registered domain.
  4. Only after you have created your repository & registered your domain name should you register your domain with CF and setup DNS records.
  5. If you want a top level domain, and a www subdomain, you should use A records with CF to point to GH's servers and then a CNAME record for the www subdomain to point to the top level domain.
  6. Ensure that the CF CDN/proxy is OFF for now; this is critical to get GH pages to provision an SSL cert for you.
  7. Once you have your custom domain entered in the GH pages settings menu, and you have CF setup to point to GH's servers as per GH's instructions, only then should you point your registrar to CF's nameservers. If these steps are done in a different order, someone can hijack your domain.
  8. Now you should be able to navigate to your domain (http) and see your GH pages website. At this point, the use https portion of your GH settings page should have some message about provisioning an SSL certificate, if the https checkbox is still greyed out. If not, you may have to wait for DNS records to propagate more. If it's been a day or longer, you should try removing the custom domain CNAME record in the GH pages setting, then adding it back. Eventually you will be able to click the "enable https" checkbox.
  9. Only once you have had an SSL certificate provisioned for your site, and you have checked the "enable https" box in the github pages settings should you back over to CF and enable the CF CDN/Proxy (click the grey cloud icons next to DNS records so that they become orange) and then navigate to the "encryption" tab and enable https/ssl strict (full)

After you follow these steps, your website should be available at the https:// url and have end-to-end SSL encryption from the GH servers hosting your static website, to the CF servers, to the CF CDN/proxy servers, to the user.

If you have questions leave them here or reach out on twitter; I'm @zbeekman there too.

@milancurcic

This comment has been minimized.

Copy link

@milancurcic milancurcic commented Oct 9, 2018

Nice write-up! I found the 2nd paragraph confusing: Github has supported HTTPS for Github Pages for a while now. What's really new here (as of May this year) is HTTPS for custom domains. Just a nit pick. I'm set up without Cloudflare so that step is optional.

@zbeekman

This comment has been minimized.

Copy link
Owner Author

@zbeekman zbeekman commented Oct 17, 2018

@milancurcic: Did my slight edit clarify your issue with the second paragraph?

I'm set up without Cloudflare so that step is optional.

Ah, yes I see. Cloudflare provides CDN proxies, and you were able to kinda-sorta have https before GH enabled support for custom domains. However, this was done by serving your site from their CDN Proxies. CF still has to fetch your website from the GH servers. Before GH enabled HTTPS with custom domains end-to-end HTTPS was impossible---traffic, i.e. the website you're serving, would travel unencrypted from GH's servers where it's hosted to the CF CDN proxies, where it's cached and served to visitors. Only this last step, serving the cached version to visitors from the CDN/proxy, could be encrypted before GH enabled this feature.

GH changed its recommended DNS setup either before or after enabling HTTPS for custom domains. Previously, I could never get the Full (Strict) (i.e., GH to CF, CF to CDN, CDN to visitor) SSL encryption to work because GH wasn't provisioning the SSL cert to me. I had my website setup to have www.website.com redirect to website.com via CF DNS. The old recommended way, AFAICT, on GH was to use CNAME records. However, now, switching to A records for the top level domain and a CNAME record for www fixes this.

@zbeekman

This comment has been minimized.

Copy link
Owner Author

@zbeekman zbeekman commented Jan 21, 2019

It seems that Github has attempted to re-provision an SSL cert for me, and it is now failing. Using SLL: Full (Strict) on cloudflare now causes my site to be unreachable. The GitHub SSL cert provisioning is back in that limbo status of waiting to provision the certificate. I suspect that I can turn of the cloudflare caching/routing let the cert get provisioned and then re-enable it. It would be nice if there were a way to have better control over the GitHub SSL provisioning process. (Or if we could bring our own Let's Encrypt certs somehow.)

@supposedly

This comment has been minimized.

Copy link

@supposedly supposedly commented Sep 16, 2020

Thanks so much for putting this up!! Can't believe GH doesn't have this list on an official help page somewhere. Fingers crossed I don't end up having the same problem with Full (Strict).

@Jip-Hop

This comment has been minimized.

Copy link

@Jip-Hop Jip-Hop commented Oct 27, 2020

Did anyone find a way to make GitHub renew it's SSL certificates automatically? I don't want to disable the Cloudflare proxy manually each time the cert needs to be renewed. Maybe a custom page rule that would bypass the proxy?

@Jxck-S

This comment has been minimized.

Copy link

@Jxck-S Jxck-S commented Feb 14, 2021

Yeah GitHub wont get a cert when the proxy is on, the site will work when SSL on Cloudflare is on Full non strict but not on strict, What i did was create a page rule for just the GitHub page to be full non strict. This way you don't need to work about the github ssl and you still have ssl from cloudflare.

@galaxy4public

This comment has been minimized.

Copy link

@galaxy4public galaxy4public commented Sep 8, 2021

I think that to enable the renewal for the GH Pages custom domain certificate with CloudFlare with the strict SSL, one just need to create a page rule that allows traffic to reach /.well-known/acme-challenge/* with Browser Integrity Check: Off (to allow the dumb Let's Encrypt agent to pass through), Cache Level: Bypass (not to engage caching for tokens), and Automatic HTTPS Rewrites: Off (to allow Let's Encrypt to talk via HTTP, since the check is performed on port 80). I threw in a bit more like disabled security and performance, made SSL flexible, and switched off "Allways Online", however I think these are unnecessary.

@alfonmga

This comment has been minimized.

Copy link

@alfonmga alfonmga commented Sep 18, 2021

I think that to enable the renewal for the GH Pages custom domain certificate with CloudFlare with the strict SSL, one just need to create a page rule that allows traffic to reach /.well-known/acme-challenge/* with Browser Integrity Check: Off (to allow the dumb Let's Encrypt agent to pass through), Cache Level: Bypass (not to engage caching for tokens), and Automatic HTTPS Rewrites: Off (to allow Let's Encrypt to talk via HTTP, since the check is performed on port 80). I threw in a bit more like disabled security and performance, made SSL flexible, and switched off "Allways Online", however I think these are unnecessary.

Damm this makes sense, it finally worked for me. Thanks a lot for your comment.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment