同じドメインをメールと Web の両方に使うと CNAME が使えなくて困る
DNS の CNAME (Canonical Name) レコードは、あるドメイン名に対するエイリアスを定義する。例えば、example.com の向き先として、外部のホスティングサービスのドメインを指定する場合などに使われる。
RFC 1034, Section 3.6.2 にある CNAME の制約はかなり強い。 CNAME が設定されると、「このドメイン名に対する問い合わせは、 A であれ MX であれ TXT であれ、すべて指定した別名に丸投げする」という意味になる。CNAME を設定したドメイン名には、他のいかなるレコードも同時に存在させてはならない。
先日経験した失敗は
- foo.example.com. で Web サービスを運用するため、A レコードを設定する
- foo.example.com. でメールも運用するため、MX レコードを設定する
- foo.example.com. を Vercel のような外部サービスで作り直し、そのサービスで独自ドメインを使うために A を消して CNAME で設定しなおしたい -> MX があるためできない!!
というものだった。
非 APEX ドメインでに CNAME を設定したくなるのは Vercel や GitHub Pages のようなホスティングサービスを自分のドメインで公開したいという動機が多いだろう。なので非 APEX ドメインでサービスを開発するときは、メールは mail.foo.example.com.、Web は foo.example.com. というように最初から違うドメインにしておけというのが、ここから得られる教訓だと思う。言われてみると本体とは全然別のドメインからメールを送ってくるサービスは多いということに気づく。
それとは別の簡単な解決方法として、ALIAS レコードが使えることがある。 ALIAS レコードは RFC で標準化された仕様ではなく、一部の DNS プロバイダーが独自に実装した拡張機能である。すべての DNS プロバイダーでサポートされているわけではない。Cloudflare, AWS, Google Cloud などの DNS は対応している。
仕組みとしては、DNS サーバーが問い合わせを受けた際に内部で CNAME のような名前解決を行い、最終的な A レコード (IP アドレス) をクライアントに返す。クライアント側からは通常の A レコードとして見えるため、CNAME の共存不可の制約を回避できる。
これにより、foo.example.com に MX レコードを設定したまま、ALIAS レコードで Vercel などの外部サービスのドメインを指定することが可能になる。まるで私のようにメールと Web が衝突して困ったときのために作られた機能である。知らんけど。試したことはない。