CNAME

**真實名稱記錄**（英語：Canonical Name Record），即 **CNAME 記錄**，是域名系統（DNS）的一種記錄。CNAME 記錄用於將一個域名（同名）映射到另一個域名（真實名稱），域名解析伺服器遇到 CNAME 記錄會以映射到的目標重新開始查詢。

這對於需要在同一個 IP 位址上運行多個服務的情況來說非常方便。若要同時運行文件傳輸服務和 Web 服務，則可以把 _ftp.example.com_ 和 _www.example.com_ 都指向 DNS 記錄 _example.com_，而後者則有一個指向 IP 位址的 A 記錄。如此一來，若伺服器 IP 位址改變，則只需修改 _example.com_ 的 A 記錄即可。

CNAME 記錄必須指向另一個域名，而不能是 IP 位址。

## 細節

《RFC 1034》詳細定義了 CNAME 記錄的標準，並在《RFC 2181》的第十節中做了進一步規範。

CNAME 記錄在域名系統中的使用有諸多限制。當一個 DNS 解析伺服器在查詢各類記錄時遇到一則 CNAME 記錄時，它會立即重啟查詢，查詢所映射到域名的對應記錄。（除非是要查詢 CNAME 記錄本身，在那種情況下會返回所映射到的域名。）CNAME 記錄所映射的域名可以是域名服務中的任何域名。在同一伺服器上，在遠程伺服器上，甚至在屬於不同 DNS zone（解析空間）的伺服器上，都可以。

假設有下述 DNS zone：

```
NAME                    TYPE   VALUE
--------------------------------------------------
bar.example.com.        CNAME  foo.example.com.
foo.example.com.        A      192.0.2.23
```

當要查詢 _bar.example.com_ 的 A 記錄時，域名解析器會查到對應的 CNAME 記錄，即 _foo.example.com_，隨即開始查詢該域名的 A 記錄，查到 192.0.2.23 則返回結果。

### 誤會

可以使用 CNAME 記錄將「_bar.example.com_」指向「_foo.example.com_」。因此，可能會有人隨意的將 _bar.example.com_ 稱作是 _foo.example.com_ 的「CNAME」。然而事實並非如此，_bar.example.com_ 的「CNAME」是 _foo.example.com_，因為 CNAME 的意思是真實名稱，而右側才是真實名稱，才是 CNAME。

這則誤會在《RFC 2181》「DNS 規範的解釋」一章中有提到。應當說左側標籤是右側真實名稱的一個同名。即下述 CNAME 記錄：

```
bar.example.com.        CNAME  foo.example.com.
```

應當讀作：

_bar.example.com_ 的真實名稱是 _foo.example.com_。請求訪問 _bar.example.com_ 的客戶端會得到 _foo.example.com_ 返回的結果。

### 限制

* CNAME 記錄總是指向另一則域名，而非 IP 位址。
* 有 CNAME 記錄的域名不能有其他任何記錄（MX 記錄、A 記錄等，《RFC 1034》第 3.6.2 節、《RFC 1912》第 2.4 節) 唯一的例外是在使用 DNSSEC 的情況下，這時可以設置相關的 DNSSEC 相關記錄，比如 RRSIG，NSEC 等（《RFC 2181》第 10.1 節）
* 為了保證效率，應當避免將 CNAME 記錄指向其他的 CNAME 記錄，但並非不可以。因此，可以通過 CNAME 記錄創造無法被解析的循環，比如：

```
foo.example.com.  CNAME  bar.example.com.
bar.example.com.  CNAME  foo.example.com.
```

* MX 記錄和 NS 記錄永遠都不應指向由 CNAME 記錄標記的域名（《RFC 2181》第 10.3 節）。因此，解析空間不應有下述結構：

```
example.com.      MX     0   foo.example.com.
foo.example.com.  CNAME  host.example.com.
host.example.com. A      192.0.2.1
```

* 根據（《RFC1912》）第 2.4 節，根網域（Root Domain）不應該被添加 CNAME 紀錄。但部分 DNS 服務商（例如 DNSPod、NS1）可以忽略該 RFC 標準而針對根網域做出 CNAME 解析，比如：

```
example.com.  CNAME  foo.example.com.
```

但這樣做會導致該網域若有用於郵箱服務，則可能造成錯誤，詳見如下方。

而願意遵守 RFC 標準的 DNS 供應商 (例如 Neustar UltraDNS、Cloudflare DNS）則採用了 Apex Alias 或 CNAME flattening 技術，這個技術將使得由 DNS 服務商自行處理 CNAME 解析的過程，並將最終解析的 A 紀錄作為實際解析的結果，從而不與 RFC 標準抵觸，比如：

```
example.com.  A      192.0.2.1
```

* 用於郵箱服務的域名不應有 CNAME 記錄。在實踐中，這或許不會出錯，但由於郵件服務的不同，可能會有意料之外的效果。

## DNAME 記錄

**DNAME 記錄**，即**代理名稱記錄**，由《RFC 6672》定義（原《RFC 2672》已經廢棄）。一條 DNAME 記錄會將某個域名的整個解析子樹映射到另一域名，而 CNAME 只映射設定的域名，不映射子域名。如同 CNAME 一樣，在 DNS 查詢過程中，會查找所映射到的新域名的地址。域名解析伺服器會為每一個被查詢的子域名生成一則 CNAME 記錄。為某個域名設置 DNAME 記錄和為該域名的所有子域名設置 CNAME 記錄的效果是一樣的。

例如下述記錄：

```
foo.example.com.        DNAME  bar.example.com.
bar.example.com.        A      192.0.2.23
xyzzy.bar.example.com.  A      192.0.2.24
*.bar.example.com.      A      192.0.2.25
```

查詢 _foo.example.com_ 的 A 記錄不會返回任何結果。不同於 CNAME 記錄，DNAME 不會直接影響所設置域名的解析。

如果我們需要查詢 _xyzzy.**foo**.example.com_，則由於 DNAME 記錄的映射會返回 _xyzzy.**bar**.example.com_ 的 A 記錄，即 192.0.2.24。而如果將 DNAME 記錄換成是 CNAME 記錄的話，這樣的請求則會報錯提示無法找到。

由此，查詢 _foobar.foo.example.com_ 會由於 DNAME 記錄映射返回 192.0.2.25。

## ANAME 記錄

部分 DNS 平台支持尚未被標準化的 ALIAS 或 ANAME 記錄類型。此類偽記錄由 DNS 伺服器維護，類似於 CNAME 記錄，但在（某些）客戶端解析時等同於 A 記錄。ANAME 記錄通常會被設置指向另一域名。但在被客戶端請求時候，則會直接返回對應的 IP 位址。ANAME 記錄的標準化過程正在進行中，但已經有許多不同的實現，所以由於平台的不同，效果也多種多樣。有些存在於域名解析區的頂端，有些則為了提供郵件服務而存在。ANAME 記錄相對 CNAME 記錄的一大優勢是速度。服務端解析 A 記錄的速度通常比客戶端快，同時可以緩存對應的 IP 位址以備查詢。IETF 正在討論和考慮 ANAME 記錄的標準化。

## 參見

* DNS 記錄類型列表
* IANA
* ICANN

## 參考資料

## 外部連結

* RFC 1912 is wrongMeng Weng Wong's analysis of CNAME restrictions (from （頁面存檔備份，存於網際網路檔案館）).
* RFC 2219 – Use of DNS Aliases for Network Services （為網絡服務使用 DNS 別名）