什麼是 CNAME 展平?
有些小夥伴們會經常遇到一個問題,在當前主機記錄已經存在 CNAME 類型的記錄後再在當前主機記錄下添加其他記錄類型時會提示
某某類型記錄和 CNAME 記錄可能存在衝突
,甚至有些解析服務商會直接不允許添加,比較常見的就是將主域名解析至 CDN 服務商提供的 CNAME 記錄,然後再添加 MX(郵箱服務記錄)時會碰到這個問題,這是爲什麼,該如何解決呢?接下來就讓我們一起來了解一下吧。
爲什麼會出現這個問題?
在 DNS 標準文件 RFC 1034 中,對 CNAME 記錄的定義如下:
Identifies the canonical name of an alias.
譯文:標識別名的規範名稱。
翻譯起來很拗口,但簡單的來說 CNAME 記錄就是把一個域名託管給另一個域名,該域名的所有解析記錄都會被託管給另外一個域名,包括 MX、TXT、AAAA、A 等。我們以ddnsip.cn
這個域名爲例,它的解析記錄如下:
在圖中我們可以看到,ddnsip.cn
這個域名通過 CNAME 記錄指向了ddnsip.cn.eo.dnse3.com.
,這也就意味着ddnsip.cn
這個域名的所有解析記錄都會被託管給ddnsip.cn.eo.dnse3.com.
,無論我向權威服務器查詢任何記錄類型,都會返回ddnsip.cn.eo.dnse3.com.
所對應的的解析結果,比如說我查詢ddnsip.cn
的 MX 記錄:
可以看到,權威並沒有返回ddnsip.cn
的 MX 記錄,而是返回了ddnsip.cn.eo.dnse3.com.
這條 CNAME 記錄,這也就是爲什麼在當前主機記錄下添加其他記錄時會提示某某類型記錄和 CNAME 記錄可能存在衝突
的原因了,因爲所有記錄已經被託管給了ddnsip.cn.eo.dnse3.com.
,所以無論你添加任何記錄都不會生效。
下圖是遞歸 DNS 的查詢結果,在遞歸 DNS 解析過程中,也是如此,當我們查詢ddnsip.cn
的 MX 記錄時,遞歸 DNS 服務器會先查詢ddnsip.cn
的 mx 記錄,但由於你設置了 CNAME 記錄,權威服務器會返回ddnsip.cn
的 CNAME 記錄ddnsip.cn.eo.dnse3.com.
,這時遞歸 DNS 服務器會去查詢ddnsip.cn.eo.dnse3.com.
的 MX 記錄,最後返回ddnsip.cn.eo.dnse3.com.
的 MX 記錄,也恰恰說明了這一點
如何解決這個問題?
目前解決這個問題方法除了把 CNAME 記錄刪除換成具體的 A/AAAA 記錄外,還有一種方式就是使用 CNAME 展平,CNAME 展平的方式大概有以下幾種,下面我們就一一來了解一下:
ALIAS 或 ANAME 記錄
ALIAS 或 ANAME 記錄是一種特殊的 CNAME 記錄,它可以將 CNAME 轉換爲 A/AAAA 記錄,並在遞歸查詢時直接返回 IPv4/IPv6 地址,而不是返回 CNAME 記錄,這樣既可以解決衝突問題,又可以提高解析性能,流程如下圖所示:
詳細示意如下:
看起來雖然很完美,也解決了衝突的問題,但目前這種記錄類型並沒有被標準化,只有少數幾家 DNS 服務商支持,比如 CloudFlare、NS1 等,國內支持廠商數量較少,此外由於 ALIAS 記錄需要權威通過遞歸查詢來獲取最終的解析結果,由於是在權威服務器所在的網絡環境中進行遞歸查詢,所以可能會導致分區解析等失效,所以並不適用於 CDN 加速的場景。
選擇性 CNAME 應答
這種方案通過對權威服務器的應答邏輯修改而實現的,其大致原理就是允許你同時添加 CNAME 記錄和其他記錄類型,但在解析其他記錄類型時會優先返回其他記錄類型的記錄,而不是 CNAME 記錄,只有當其他記錄類型不存在時纔會返回 CNAME,這樣就可以解決衝突問題,比如下圖:
從圖中我們可以看到,CNAME 記錄和 MX 類型記錄同時存在,但在解析 MX 記錄時,權威服務器會優先返回 MX 記錄,而不是 CNAME 記錄,這樣就避免了遞歸服務器獲取到 CNAME 記錄後再去查詢 CNAME 記錄的 MX 記錄,從而解決了衝突問題,而且也能支持分區域解析,但這種方案很容易受到 LocalDNS 的影響導致不穩定,而且也無法徹底的展平 CNAME,只能解決記錄衝突的問題,目前國內支持的廠商比較少,常見的有阿里雲。
這種方式還可能存在一個問題,如果遞歸 DNS 服務器緩存了 CNAME 記錄,那麼在緩存未過期之前,查詢 MX 記錄時還是會去查詢 CNAME 記錄的 MX 記錄,所以可能存在某些解析不到的情況,所以在使用這種方案時需要注意一下。
記錄映射
這種方案是在權威服務器中直接將 CNAME 記錄映射爲 A/AAAA 記錄,無需通過遞歸查詢來獲取最終的解析結果,如下圖:
從圖中我們可以看到,ddnsip.cn
這個域名通過 CNAME 記錄指向了cname.dnspod.cn.
,當我們查詢ddnsip.cn
的 IP 地址時,由於我們已經進行了記錄映射,所以權威服務器會直接返回cname.dnspod.cn.
所對應的 IP 地址,而非 CNAME 記錄。簡單來說你雖然添加的是 CNAME 記錄,但是映射後系統把cname.dnspod.cn
所設置的A/AAAA記錄放到了ddnsip.cn
的解析記錄中,並且相關的線路、TTL、狀態、記錄值等都與cname.dnspod.cn
相同步,所以實際上相當於你添加的是 A/AAAA 記錄,這樣既可以解決衝突的問題,也可以支持分區解析,但前提需要你的域名和你 CNAME 指向的域名在同一個 DNS 服務商,否則無法實現,目前支持的廠商比較少,常見的有 AWS Route53、DNSPod 等。
總結
從上面的介紹我們可以看到,目前解決 CNAME 衝突的方案有很多,但是每種方案都有自己的優缺點,可以說沒有任何一種方案是完美的,在實際的業務場景中,我們可以根據自己的需求來選擇合適的方案,當然還是由衷的建議大家,還是儘量不要在根域使用 CNAME 記錄,畢竟目前來看絕大多數的衝突問題都發生在根域,而且在根域使用 CNAME 也不符合相關的標準。
長久來看,CNAME 展平不是解決 CNAME 衝突的最佳方案,在不久的將來,隨着 HTTPS/SVCB 記錄類型的普及發展,這個問題也將會最終得到解決。
DNSPod CNAME 展平設置方法
DNSPod 已於近期支持了 CNAME 展平功能,該功能無需你手動開啓,只需要你同時添加 CNAME 記錄和其他記錄類型記錄即可,系統會自動嘗試進行 CNAME 展平,如下圖:
效果如下:
直接返回了對應的 A/AAAA 記錄。
由於自身水平有限,文章中難免存在錯誤,歡迎大家批評指正,謝謝!