在搭建博客的過程當中,按照個人想法,我只要直接把阿里雲買的域名,用 CNAME 的方式指向 github pages 提供的域名就 OK 了。html
好比,我想把 test.forelax.space 這個域名指向我 github pages 的地址,我就在阿里雲上增長一條配置,如圖所示:git
但是這時當我訪問 test.forelax.space 這個域名的時候,獲得的倒是一個 404 的頁面:github
查看 github pages 的說明,我必需要在個人倉庫的設置中添加一個自定義域名選項,我才能正確的把個人域名 forelax.space.io 正確的指向 github pages 上的頁面:瀏覽器
可這是爲毛啊?我就直接指過來怎麼就不行?這個設置項到底作了什麼?咱們一個個問題來解決。緩存
當我嘗試刪除而後從新填入這個設置項後,我發現我倉庫中多出了兩個 commit:服務器
由此看來,這個設置項僅僅是幫咱們在倉庫的 master 分支中更方便的修改一個叫作 CNAME 的文件而已。那麼 github pages 何時會用到這個問題呢?這個問題咱們要從域名的過程提及。dom
簡單來講,阿里雲(實際上是萬網,不過提及來都同樣:P)經過本身域名經銷商的身份,向 .space 域名服務器增長了兩條記錄,當有人向 .space 域名服務器詢問 forelax.space 的 IP 地址的時候,就告訴詢問者,我不知道這個域名的 IP 是多少,可是你能夠去 dns17.hichina.com 或者 dns18.hichina.com 這兩個域名對應的服務器去問一下,他們知道。由於我在購買域名的時候,選擇了默認的域名解析服務,因此給 .space 域名服務器中添加的記錄是阿里雲本身的域名服務器。若是有能力本身搭建 DNS 服務器,也能夠在阿里雲的控制檯把 DNS 解析服務器改爲本身的 DNS 服務器的 IP。以下圖:ide
如何證明這個過程呢?咱們能夠用 dig +trace forelax.space
這個命令來看看域名解析過程當中的每一步都發生了什麼:ui
; <<>> DiG 9.9.7-P3 <<>> +trace forelax.space # 上面只是輸出 dig 的版本號以及咱們此次命令的參數 ;; global options: +cmd # 上面表示 dig 這個命令默認還會加上 +cmd 選項 . 63324 IN NS e.root-servers.net. . 63324 IN NS a.root-servers.net. . 63324 IN NS c.root-servers.net. . 63324 IN NS k.root-servers.net. . 63324 IN NS l.root-servers.net. . 63324 IN NS g.root-servers.net. . 63324 IN NS f.root-servers.net. . 63324 IN NS j.root-servers.net. . 63324 IN NS h.root-servers.net. . 63324 IN NS d.root-servers.net. . 63324 IN NS i.root-servers.net. . 63324 IN NS m.root-servers.net. . 63324 IN NS b.root-servers.net. ;; Received 508 bytes from 192.168.31.1#53(192.168.31.1) in 38 ms # 上面表示咱們從本地的路由器中,獲得了 13 臺根 DNS 服務器的地址, . 表示這是根服務器, 63324 表示 TTL,也就是這個信息還會緩存多久,在 63324s 內咱們訪問獲得的還會是這個結果 # IN 表示咱們返回的是 IP 協議,基本上咱們都是 IP 協議,因此能夠忽略他 # NS 表示這條記錄是一個 Name Server 記錄,告知請求者任何根目錄如下的記錄均可以找這個服務器 space. 172800 IN NS a.nic.space. space. 172800 IN NS b.nic.space. space. 172800 IN NS c.nic.space. space. 172800 IN NS d.nic.space. space. 86400 IN DS 44251 8 1 36ACB68B734DFE465CC1112F9DAC08B8B66627CC space. 86400 IN DS 44251 8 2 A82D8ED2B07D66D6E7AF375E0E44B22A82F4479AD45F5D8E1859DF6F C170E67C space. 86400 IN RRSIG DS 8 1 86400 20171202050000 20171119040000 46809 . Fg9GkuRICx7mfbOmfuQumQ5ofrxniMi4+lw0AKbE15CJO6Sqj8S1H45T 9LyVhdjxWZ5oRsLOG4YIJum7rAa1IlORTePVlSwLjwz1AuDDOdb603C4 ibqknFSkjYJgw82wTbx5K48SvWRUk8u7aIqvX29Tdl0YR/5FPicjOAvi 0hkRCir8vyg1DHebDNiKKl0/l2f4YJG9x2LUxdUYlRPHOwYbhgscMcJf 8q5TvqW4mC1BdfaysfwLUA1Uf+9qAO4y51QSnxAsXReZH5r296Er7/sQ 6pGigQXiGJhlm9etpKyzqtpe3EcK5TBVKcc6S8Xu2OLUSShbEx+3l9ga CBS0Fw== ;; Received 657 bytes from 198.41.0.4#53(a.root-servers.net) in 500 ms # 上面表示咱們從 a.root-servers.net 這個根服務器中得知了 .space 這個域名服務器的記錄 # 其中 DS 表示這是一條 DS 類型的 DNS 記錄,能夠暫時理解爲一種添加時要求更高的記錄類型,好比這裏就比 NS 多了不少的數據,細節有興趣能夠去維基百科查查 List of DNS record types forelax.space. 3600 IN NS dns17.hichina.com. forelax.space. 3600 IN NS dns18.hichina.com. 0eldeflreldugqhaejqrp17ppn34aaqp.space. 3600 IN NSEC3 1 1 1 - 0FIBQMPFM95T51I962J7PVBKHVQGF4Q1 NS SOA RRSIG DNSKEY NSEC3PARAM 0eldeflreldugqhaejqrp17ppn34aaqp.space. 3600 IN RRSIG NSEC3 8 2 3600 20171214211930 20171114215839 46195 space. nUIuP4ZS4WyiF4vdrPYeasfWR54ckTK4NBybw0vI42ZwWbcMV8kdwd0J VVDcYhR2OQTImjSoy945LwmSEM1nyV72EwldpjCX/ynIWfyH8FLJtuQr K2WP7IUAeAT9gBiI8bF+Y+Ir81Q9MDOHrDrPL5hZH8GFjQwkh+9aljjD nFc= om8amflncknjroa3cjf9287ka296qfvm.space. 3600 IN NSEC3 1 1 1 - ONF07RDF2DJM0FDED9AG6MC3HK38HQEJ NS DS RRSIG om8amflncknjroa3cjf9287ka296qfvm.space. 3600 IN RRSIG NSEC3 8 2 3600 20171214011525 20171114103910 46195 space. E9xkbsyIh6h+4faNQhAILNNALmF9EPveH5EiGzHPJpyJD0AIMzbcG1Iw b2+ahUtoHYgQjG+oqr/PvCV9ikub0i86WWrxIOwCnBLZG45t/so1P9Cz dQb1hZY39z5b0cv0Swzog/jyQnIQTWjZOgp0ZdP+Vtru+MbFmOtSGfZC zlQ= ;; Received 582 bytes from 194.169.218.51#53(a.nic.space) in 202 ms # 上面表示咱們從 a.nic.space 這個域名服務器獲得了全部能夠得知 forelax.space 這個域名地址的記錄,這裏咱們看到了兩個熟悉的阿里雲的 DNS 解析服務器
也許你會疑惑這裏獲取到根服務器的時候,並無給出 IP 啊,那下一步是怎麼知道根服務器的地址的?其實返回的請求裏頭是帶有地址的,只是 dig
這個命令沒有顯示出來,用 WireShark 抓取這一次的返回包咱們就能夠看到返回的內容中是包含有根服務器的 IP 地址的:阿里雲
阿里雲本身搭建的 DNS 解析服務器上,增長了一條新的 CNAME 記錄。上邊執行的 dig +trace forelax.space
命令其實最後還有一段,我把他截掉放在這裏了:
forelax.space. 600 IN CNAME forelaxx.github.io. ;; Received 74 bytes from 106.11.211.57#53(dns17.hichina.com) in 9 ms # 最終,咱們從 dns17.hichina.com 這個服務器中獲得了 forelax.space 須要跳轉到 forelaxx.github.io 的記錄,這是一個 CNAME 類型的記錄,表示咱們若是想知道 forelax.space 的 # IP 地址,只要知道 forelaxx.github.io 的 IP 地址就能夠了
如今咱們知道,若是想得知 forelax.space 的 IP ,只要得知 forelaxx.github.io 的 IP 就行了,因而咱們繼續發 DNS 請求包來查詢,咱們繼續經過 dig +trace forelaxx.github.io
命令能夠得知,若是想知道 forelaxx.github.io 的 IP,只要知道 sni.github.map.fastly.net 的地址就能夠了,繼續查找,咱們得知了 sni.github.map.fastly.net 的 IP 地址爲 151.101.73.147。
以上的過程在瀏覽器最終發起對 forelax.space 的 HTTP 請求以前就會完成,所以當咱們最終給 forelax.space 發起 HTTP 請求的時候,瀏覽器已經得知他最終須要給哪一個 IP 發送 HTTP 請求了:
這裏注意,github pages 這個服務無論你是哪一個倉庫的靜態資源,最終他都是部署在同一臺服務器上面的,好比這裏我用 dig sketchk.github.io
來看看個人好夥計七爺的博客的地址,最終會發現獲得的結果也是 151.101.73.147。
因而問題來了, 151.101.73.147 這臺服務器在接收到一個 HTTP 的請求的時候,他怎麼知道到底要返回哪一個博客的靜態資源呢?此時,咱們以前在倉庫裏的 CNAME 文件便起了做用。當咱們建立了一個 CNAME 文件的時候, github 便給 151.101.73.147 這臺服務器增長了一條記錄,告訴他,若是 HTTP 請求中的 Host 字段中的值是 forelax.space 的話,就返回給他這個倉庫裏頭的靜態資源。
因爲 Host 字段是 HTTP 在 header 中要求必有的一個字段,所以這個機制保證了 github 能夠正確返回那個倉庫裏的靜態資源。
答案是 NO,github 禁止你這樣作,在設置項裏頭徹底不容許你這麼作,即使你修改了 CNAME 文件並強行 push 上去,github 也不會認你的這個 CNAME 文件,而且會在設置項中給出警告:
同時結合上面咱們已知的內容,即使你把本身的域名解析改爲別人的 github pages 頁面也是沒有用的,由於別人的倉庫中的 CNAME 並無記錄你的域名,因此訪問你的域名跳轉過去就會顯示文章一開頭的那個 404 頁面。