Skip to content

Instantly share code, notes, and snippets.

@zbeekman
Last active March 8, 2024 18:12
Show Gist options
  • Star 64 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save zbeekman/ac6eeb41ea7980f410959b13416d74c9 to your computer and use it in GitHub Desktop.
Save zbeekman/ac6eeb41ea7980f410959b13416d74c9 to your computer and use it in GitHub Desktop.
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.

@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

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

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

Hi @DavidBuchanan314 - just checking this worked for you?

@DavidBuchanan314
Copy link

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

image

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

@ARGYROU-MINAS
Copy link

@latenitefilms
Copy link

I'd also love to know if anyone's found a solution to this, or if using CloudFlare Pages to actually host the web content is just an easier/better solution?

@arjunsrinivasan1997
Copy link

arjunsrinivasan1997 commented Nov 5, 2023

@latenitefilms I also had this issue, the only why I was able to fix it was to use CloudFlare Pages. This allowed me to have Proxied DNS and Full(Strict) encryption

@fanmingming
Copy link

I have encountered the same issue as well. Every time there is an SSL error, I have to manually enable and disable only DNS.

@latenitefilms
Copy link

FWIW - I switched from GitHub Pages to CloudFlare Pages.

@lawvs
Copy link

lawvs commented Mar 8, 2024

If there is an infinite 301 redirect after enabling the proxy, don't forget to turn on Full encryption mode in the SSL settings of CF.

Screenshot 2024-03-09 at 02 01 30

If you prefer not to enable full encryption globally, you can utilize a custom rule.

Screenshot 2024-03-09 at 02 07 46

If the SSL/TLS encryption method selected in Cloudflare is Flexible, then the connection between Cloudflare and Github Pages is HTTP, and the connection between Cloudflare and the user is HTTPS. If you enable forced HTTPS in Github Pages, there will be an issue of infinite redirection.

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