cmc/cleberg.net

My personal web garden & blog.

clone: git clone https://gitbay.org/cmc/cleberg.net.git

main: content/blog/2020-08-22-redirect-github-pages.org · raw

  1#+date:        [2020-08-22 Sat 00:00:00]
  2#+title:       GitHub Pages Redirect Subdomain to TLD
  3#+description: A quick recap of a Stack Overflow answer that I want to exist in perpetuity.
  4#+slug:        redirect-github-pages
  5#+filetags:    :web:
  6
  7* Short answer
  8
  9** Step 1
 10
 11Add a new file called =CNAME= (canonical name) to your GitHub Pages repository
 12containing only one line: your top-level domain name. E.g.: =example.com=
 13
 14** Step 2
 15
 16[Optional] but highly recommended
 17
 182.1: Remove all other top-level records (prefixed with @) of type A from your
 19DNS configuration.
 20
 212.2: Remove a CNAME record for the second-level domain =www=, if it is present.
 22
 23** Step 3
 24
 25Add these 5 entries to the very top of your domain name system (DNS)
 26configuration:
 27
 28#+begin_src txt
 29@        A        185.199.108.153
 30@        A        185.199.109.153
 31@        A        185.199.110.153
 32@        A        185.199.111.153
 33www      CNAME    your_github_username.github.io.
 34#+end_src
 35
 36Replace =your_github_username= with your actual GitHub username.
 37
 38** Step 4
 39
 40Wait for your DNS changes to propagate. DNS changes aren't effective
 41immediately. They can take up to a full day to propagate.
 42
 43* Long answer
 44
 45This issue has two sides. One is the DNS configuration itself. Another one is
 46the way GitHub Pages will forward hypertext transfer protocol (HTTP) requests.
 47
 48We need to know a few things to understand what GitHub is trying to say in their
 49documentation.
 50
 51** DNS Entry Types
 52
 53There are two types of DNS records which interest us: CNAME and A.
 54
 55=A= is also known as =Apex= or sometimes as =root entry=. It forwards requests
 56to a specified fixed IP address. =CNAME= entry forwards requests to a specified
 57URL (actual valid plain text URL, not an internet protocol (IP) address).
 58
 59** DNS Load balancing
 60
 61GitHub has one central URL address which accepts all DNS requests for GitHub
 62Pages: =http://username.github.io=. That URL is resolved to different IP
 63addresses based on your geographical location. Website hosted on GitHub Pages is
 64a simple collection of =HTML=, =CSS= and =JS= files. GitHub distributes these
 65files to different servers across the globe. So that when your browser sends a
 66request from Europe, it receives data from a server in Europe. The same is valid
 67for the requests from Asia and the USA.
 68
 69** What GitHub is trying to say
 70
 71Since =A= records in DNS must contain IP addresses, and they must be either
 72=185.199.108.153= or =185.199.109.153= or =185.199.110.153= or
 73=185.199.111.153=, there is no way to forward requests to a server located
 74somewhere in Europe or Asia. Your website hosted at GitHub Pages will be
 75downloaded from a central GitHub Pages server. There is a minor risk that if
 76GitHub Pages DNS servers (=x.x.x.153=) are down for some reason, all custom
 77domains which use fixed GitHub Pages IP addresses will not be accessible (their
 78DNS requests will not be resolvable).
 79
 80That is why GitHub strongly suggests to either use a second-level domain for
 81your GitHub Pages (e.g. =blog.example.com=) or use a DNS service provider that
 82supports a record type =ALIAS= that acts as =A= record but forwards request to a
 83URL address (e.g. =username.github.io=) instead of a fixed IP address.
 84
 85** How GitHub Pages treats HTTP requests
 86
 87After a DNS request for =your_github_username.github.io= is resolved into an IP
 88address, e.g. =185.199.108.153= your browser sends an HTTP request to that
 89server with an HTTP header =Host=. Below are =curl= examples that load the same
 90website (these examples might not work if you are behind a proxy server):
 91
 92#+begin_src sh
 93curl --header "Host: your_github_username.github.io" http://185.199.108.153/
 94curl --header "Host: www.example.com" http://185.199.108.153/
 95curl --header "Host: example.com" http://185.199.108.153/
 96#+end_src
 97
 98This way GitHub Pages servers know which user website to serve.
 99
100#+begin_quote
101GitHub Pages server will automatically redirect HTTP requests to the top-level
102domain if your =CNAME= file contains =example.com= but =www.example.com= is
103requested.
104
105The same is valid if your =CNAME= file contains =www.example.com= but the header
106=Host= in the =HTTP= request contains =example.com=.
107#+end_quote
108
109** Why can't I add a =CNAME= record entry that accepts a top-level request (=@=) to my DNS configuration?
110
111Quote from the GitHub Pages documentation:
112
113#+begin_quote
114Warning: Do not create a CNAME record for your custom apex domain! Doing so may
115cause issues with other services, such as email, on that domain.
116#+end_quote
117
118** References:
119
1201. [[https://docs.github.com/en/github/working-with-github-pages/configuring-a-custom-domain-for-your-github-pages-site][Setting up a custom domain with GitHub Pages]]
1212. [[https://docs.github.com/en/github/working-with-github-pages/troubleshooting-custom-domains-and-github-pages][My custom domain isn't working]]
1223. [[https://serverfault.com/questions/589370/cannot-access-my-github-pages-website-by-ip-address][Cannot access my GitHub Pages website by IP Address]]
1234. [[https://stackoverflow.com/questions/23375422/how-do-i-set-up-github-pages-to-redirect-dns-requests-from-a-subdomain-e-g-www][How do I set up GitHub Pages to redirect DNS requests from a subdomain (e.g.
124   www) to the top-level domain (TLD, Apex record)?]]