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
Copy link

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
Copy link
Author

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
Copy link
Author

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
Copy link

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
Copy link

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
Copy link

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
Copy link

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
Copy link

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.

@Jip-Hop
Copy link

Jip-Hop commented Nov 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.

I set this up a month or so ago with these page rules:
Screenshot 2021-11-18 at 19 10 49

GitHub Pages had a valid certificate when I enabled the Cloudflare proxy with SSL full (not strict). Put in my calendar to check today if GitHub Pages would be able to renew the certificate and was surprised to see I was ubable to access my website due to Error code: SSL_ERROR_NO_CYPHER_OVERLAP.
Screenshot 2021-11-18 at 19 18 44

Turns out the certificate renewal is pending (seems like it's failing):

Screenshot 2021-11-18 at 19 13 42

And in the mean time it's not using an SSL certificate at all... so the website is effectivly down xD

Anyone got this working? If so, how? 🙂

@DavidBuchanan314
Copy link

DavidBuchanan314 commented Jan 9, 2022

In order to get this to work, I had to disable SSL/TLS > Edge Certificates > Always Use HTTPS
image

Then, I used a second page rule to re-enable it for all non-acme pages:
image

I'm still not 100% sure this is going to work, because I'm waiting for github to retry provisioning the cert.

@EdenCrow
Copy link

EdenCrow commented Feb 14, 2022

Hi @DavidBuchanan314 - just checking this worked for you?

@DavidBuchanan314
Copy link

DavidBuchanan314 commented Feb 14, 2022

It did not. (I should've added an update, oops)

Github has some config on their end that will only attempt to provision the cert if it detects that the DNS is pointing at them.

My "solution" was to temporarily point my DNS directly at github (bypassing cloudflare) so that the cert could be reprovisioned. Then, I was able to turn cloudflare back on again.

I expect to have to repeat this process next time the cert expires (although maybe it will renew successfully then? time will tell)

Perhaps as a workaround, I could create a custom DNS server, which gives one answer to github, and a different answer to everyone else...

@felipecrs
Copy link

felipecrs commented Apr 25, 2022

image

I think you should update point number 5 to suggest pointing strictly to <user>.github.io.

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