独自ドメイン設定の文脈で出てくる「CNAME」とか「ネイキッドドメイン」とか調べた

GitHub Pages には、独自ドメインを割り当てられる「カスタムドメイン」機能がある。実際に使ったことはないのだが、リポジトリ内に「CNAME ファイル」というファイルを配置してなんやかんやして〜、という手順は聞いたことがあった。

DNS レコードの一種であることは何となく分かっていたが、どういうモノなのかよく知らなかったので、今回は CNAME に関するアレコレを調べてみた。

目次

DNS とは?おさらい

まず DNS のおさらい。DNS は Domain Name System の略で、簡単にいえば「ドメイン名」と「サーバの Public IP アドレス」を紐付けるための仕組み。

Value Domain などのサービスの管理画面で「DNS 設定」画面なんかがあったりするが、こうした設定画面に情報を入力すると、「DNS コンテンツサーバ」がそれを保持する。

ブラウザなどでドメイン名を入力すると、裏で「DNS キャッシュサーバ」が対応する IP アドレスを探しに行く。手元に対応する IP アドレスの情報が見つからなければ、よその「DNS キャッシュサーバ」や「DNS コンテンツサーバ」に問合せて情報を取得し、キャッシュしておく仕組みだ。

ついでに:DHCP とは

DNS に関連して DHCP という単語もよく出てくるので、ついでに紹介しておく。

DHCP は Dynamic Host Configuration Protocol の略。マシンがインターネットに接続する際、自分の IP アドレスが必要になるが、コレを自動的に割り当ててくれる仕組みのこと。手元の PC には「DHCP クライアント」が導入されており、指定した「DHCP サーバ」に問合せを行うことで、そのマシン用の IP アドレスや、接続情報を取得して自動的に設定してくれるという動きだ。

身近な例だと、ルータに「DHCP サーバ」機能が含まれていて、それがマシンごとの Private IP を自動的に割り当てている。

DNS レコードとは

DNS の1つの設定のことは「リソースレコード」と呼ばれ、俗に「DNS レコード」と呼ばれている。DNS レコードは、

の3つの情報が記述されている。

一般的に「ドメイン名と IPv4 アドレス」を紐付けているのは A レコードという DNS レコードだ。ドメインと IPv6 アドレスを紐付ける際は「AAAA レコード」を宣言する (アドレスの長さが 32 bit の IPv4 に対し、4倍の 128 bit になっていることから AAAA になったらしい)。

そのドメインに対するメールサーバを宣言する際は MX レコード (Mail eXchanger record) を宣言したりする。@example.com といったメールアドレスでメールが送信された時に、メールサーバのドメインや IP アドレスを返すためのレコードだ。

このように、DNS レコードにはいくつかレコードの種類があり、設定情報の役割が異なるワケだ。

本題・CNAME レコードとは何か

本題の CNAME レコード。CNAME レコードは、ドメインを別のドメインに紐付けるための DNS レコードだ。紐付け先のドメインの A レコードで最終的に IP アドレスを解決させられる。

DNS レコードの設定イメージは以下のとおり。

;; CNAME レコード定義
;; http://alias.example.com/ でアクセスした時に、http://www.example.com/ が返せるような紐付け
alias.example.com.    3600    IN    CNAME    www.example.com.

;; A レコード定義
;; http://example.com/ というドメインは、200.50.000.000 という IP アドレスに解決される
www.example.com.      3600    IN    A        200.50.000.000

こんな感じで、alias.example.com というドメインは CNAME レコードによって www.example.com というドメインに解決され、www.example.com というドメインの DNS レコードを見ると、A レコードによってウェブサーバの IP アドレスが分かる、という流れだ。要するに別ドメインへのエイリアスを宣言できるのが、CNAME レコードだと思えば良い。

CNAME レコードの制限と「ネイキッドドメイン」

CNAME レコードにはいくつかの制約があるので、それを説明するためにちょっと例を話してみる。

GitHub Pages の URL は https://user-name.github.io/ といった形式になる。任意の DNS 管理サービスで CNAME レコードを宣言して、自分が保有する example.com ドメインに紐付けて、https://example.com/ で GitHub Pages にアクセスできるように設定してみたいと思う。

先程の流れで考えると、

example.com.    3600    IN    CNAME    user-name.github.io.

こんな CNAME レコードを設定したらいいのかな?という気がするのだが、実はコレだと上手くいかない。

CNAME レコードのルールは RFC1912 で規定されており、

と決まっている。

先程の例の何が悪いかというと、example.com のようなネイキッド・ドメインには NS レコードを必ず設定しないといけないという制約があるのだ。

NS レコードは、そのドメインの情報を持つ「DNS コンテンツサーバ (= 権威サーバ)」を指定するモノ。Value Domain (GMO グループ) の場合なんかは dnsv.jp といったネームサーバの URL をいくつか指定していたりする。つまり、example.com というネイキッドドメインの場合、

example.com.    3600    IN    NS    xx.dnsv.jp.
example.com.    3600    IN    NS    yy.dnsv.jp.

このような NS レコードが既に記述されているので、ココに CNAME レコードを併記しても認識されないワケだ。

example.com.    3600    IN    NS       xx.dnsv.jp.
example.com.    3600    IN    NS       yy.dnsv.jp.
example.com.    3600    IN    CNAME    user-name.github.io.
;; ↑ コレは NG (CNAME は他のレコードと併記できない)

ネイキッドドメインでなければ NS レコードは要らないので、例えば www.example.com というような www サブドメインが付いている URL で良ければ、CNAME レコード1つを設定して終わりになる。

;; コレならネイキッドドメインじゃないから OK
www.example.com.    3600    IN    CNAME    user-name.github.io.

この場合、https://www.example.com/ であれば紐付けた GitHub Pages にアクセスできるが、https://example.com/ にアクセスしても GitHub Pages には転送されないことになる。

ネイキッドドメインで CNAME を使いたい

コレでようやく、「ネイキッドドメインで GitHub Pages を使いたい」とか、「Apex ドメインで CNAME を指定したい」とかいうテック記事の意味が分かってきた。

ネイキッドドメインには NS レコードが必ず設定されているので、他のレコードと併記できない CNAME レコードは書けないので、何らかの回避策を講じなければならないワケである。

ALIAS レコード・ANAME レコード

回避策の一つは、ALIAS レコードというモノだ。コレは正規の DNS レコードではなく、一部の DNS サービスが独自実装している機能なので注意。「CNAME Flattening」といった呼ばれ方もしている。

コレは DNS 内部で、CNAME 風の解決を行える仕組みだ。 CloudFlare DNS (無料らしい) だったり、AWS Route53 (ただし AWS サービス内での適用に限る) だったりで対応している。

他に、策定中の仕様として ANAME レコードというモノがある。他に A レコードが宣言されていなければ、ANAME レコードが CNAME レコードのように振る舞うというモノだ。ALIAS レコードではなく ANAME レコードを先行して独自に実装している DNS サービスもあったりするので、DNS サービス次第でこうした機能を使って回避できる可能性がある。

ネイキッドドメインと www ドメインに同じ A レコードを書く

最終的に紐付けたい IP アドレスが固定で決まっている場合は、CNAME レコードを使わず A レコードを書けば良い。よく www のありなしで同じコンテンツを返すための設定として、こうした方法が採用できる。

example.com.        3600    IN    A    200.50.000.000
www.example.com.    3600    IN    A    200.50.000.000

もしくは、ネイキッドドメインに A レコードを書いておき、www はネイキッドドメインへの CNAME を指定する方法もある。

example.com.        3600    IN    A        200.50.000.000
www.example.com.    3600    IN    CNAME    example.com.

GitHub Pages のようなウェブサービスだと IP アドレスは分からないし、IP アドレスががコロコロ変わるような場合はこうした手段が使えない。

GitHub Pages と Netlify でネイキッドドメインを扱うには

ほんで、GitHub Pages でネイキッドドメインを扱うにはどうしたらいいかというと、ちゃんと公式でやり方が紹介されているのでご安心を。

ついでに、Netlify も同様の機能が提供されていたので、設定方法の情報を紹介しておく。

以上

CNAME よく分かった。ネイキッドドメイン = Apex ドメインの仕様、CNAME の仕様が競合して CNAME 的なことをしたい時にすんなりいかない件も理解した。

参考文献