Zone ApexにHTTPSリソースレコードでエイリアスを登録してみた

DNS SVCB/HTTPSレコードを使うと、DNSレベルでサーバーとネゴシエーションできるし、Zone APEXにエイリアスを設定することもできます。
2021.07.20

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

JANOG48 Meetingでの株式会社インターネットイニシアティブの発表はご覧になったでしょうか?

WebサーバのDNSへの登録方法が変わるよ – :

公開発表スライドから

WebサーバのDNS登録がA/AAAAレコードから、HTTPSレコードに移行していくというものです。

このレコードを使うと、以下の様なことを実現できます。

  • ApexドメインでCNAMEを使用
  • HSTSがやっていたようなサーバーとのネゴシエーションをDNSレコードに委譲

発表概要から引用します。

HTTPSというDNSレコードタイプを定義するdraft-ietf-dnsop-svcb-httpsがもうすぐRFCになります。実利用はすでにはじまっており、WebサーバのDNSへの登録は従来のA/AAAAレコードから今後は新しいHTTPSレコードに移行していくことになるでしょう。本発表ではHTTPSレコードの簡単な紹介と、それにともなう注意点を説明します。

今回は、SVCB/HTTPS RRを本番デプロイしている Cloudflare の権威DNSサーバーとSafariを利用し、HTTPS RRを試してみました。

draft-ietf-dnsop-svcb-https の背景

DNS問い合わせ時にサーバーとのネゴシエーションを済ませる、つまり、サービス情報やプロトコルなど諸々の情報も返却してしまえば、パフォーマンス面でもプライバシー面でもより良くなるハズ。

そんな思いから、 Internet Draft の Service binding and parameter specification via the DNS (DNS SVCB and HTTPS RRs)/draft-ietf-dnsop-svcb-https

  • SVCB:汎用
  • HTTPS:SVCBのHTTP(S)特化型

という新しいリソースレコード(RR)を提案し、IANAに登録されました。

解決したい課題としては、 SRV レコードHSTS(HTTP Strict Transport Security)などの延長上にあるものです。

この新しいRRを利用すると

  • エイペックスにエイリアス指定(CNAMEはゾーンエイペックスに指定できない)
  • サーバーのサービス・プロトコルの指定
  • 複数のCDNの指定

といったことが可能になります (draft-ietf-dnsop-svcb-https : 10.3 Examples 参照)。

この新しいリソースレコードは

  • エイリアスモード
  • サービスモード

の2種類のモードがあります。

エイリアスモード

エイリアスモードでは、CNAMEのように別名を定義します。 CNAME との違いは、Zone ルートでも利用できることです。

AWS Route 53では、CloudFrontやALBのようなAWSリソースをAliasレコードとしてゾーンのルートに指定できます。 SVCB/HTTPSのエイリアスモードは同じことを実現できます。

レコード例です。

example.com. 3600 IN HTTPS 0 example.org.

レコードタイプ(HTTPS)の後ろにある数字の0は priority です。

priority が 0の場合、エイリアスモードとしてCNAMEのように動作します。

サービスモード

サービスモードでは、オリジンのホスト名や通信情報を記述します。

CloudflareのDNSサーバーでプロキシーを有効にしていると、サービスモードのHTTPS RR が暗黙のうちに登録されています。

Cloudflare の HTTPS レコードを確認してみます。

$ dig a www.cloudflare.com. +short
104.16.124.96
104.16.123.96
$ dig aaaa www.cloudflare.com. +short
2606:4700::6810:7b60
2606:4700::6810:7c60

$ drill https www.cloudflare.com
...
www.cloudflare.com.   300  IN  HTTPS  1 . alpn=h3-29,h3-28,h3-27,h2 ipv4hint=104.16.123.96,104.16.124.96 ipv6hint=2606:4700::6810:7b60,2606:4700::6810:7c60
...

priority が1以上の場合、サービスモードとして動作します。 例えば、 識別子 alpn はサーバーが対応しているHTTPのバージョンです。h3-29,h3-28,h3-27,h2 から HTTP/3とHTTP/2 に対応していることがわかります。

Safari で www.cloudflare.com にアクセスしたときのパケットキャプチャです。

HTTPS レコードを問い合わせていることがわかります。

エイリアスモードで別ホストを指定してみた

Cloudflare の DNS サーバーは HTTPS/SVCB レコードを直接追加できます。 この機能を利用し、ゾーンのルートに別リソースへの HTTPS エイリアスレコードを登録し、Safari から接続できることを確認します。

なお、Cloudflare の DNS サーバーは CNAME Flattening 機能のために、ルートにも CNAME レコードを登録できます。実運用上は SVCB・HTTPS レコードを追加する必要はありません。

Cloudflare DNS サーバーに HTTPS レコードを追加

以下の HTTPS レコードを追加します。

  • Type : HTTPS
  • Name : @(ルートのため)
  • TTL : 任意
  • Priority : 0(エイリアスモードのため)
  • Target : CloudFront のホスト名
  • Value : ブランク(エイリアスモードのため)

エイリアスモードでは、Target へ DNS 問い合わせをするため、エイリアスレコードでは Value をブランクにします。

HTTPS レコードを確認

  • HTTPS レコードが登録されていること
  • A/AAAAレコードが登録されていないこと

を確認します。

$ drill https example.com.
...
example.com. 300  IN  HTTPS  0 xxx.cloudfront.net.

$ dig a example.com. +short
$
$ dig aaaa example.com. +short
$

Safari から接続

この状態で Safari でゾーンのルートにアクセスします。

パケットキャプチャーすると

  1. ゾーンルートに対して HTTP&A レコードを問い合わせ(HTTPS の仕様として投機的に A レコードも問い合わせる)
  2. HTTPS のTargetレスポンスから CloudFront のFQDN を取得(Aレコードは空振り)
  3. CloudFrontのFQDNに対して HTTP&A レコードを問い合わせ
  4. A レコードのレスポンスから IP アドレスを取得(HTTPSレコードは空振り)

していることがわかります。

当然ながら、この設定では HTTPS RR に対応していないブラウザではアクセスできません。

まとめ

DNS SVCB/HTTPSリソースレコードを利用すると、ゾーンルートにエイリアスを指定したり、サーバーの対応HTTPプロトコルやEncrypted Client Hello(ECH)の鍵を指定するなどして、サーバー接続時のパフォーマンスとプライバシーを改善できます。

一般インフラエンジニアが SVCB/HTTPS レコードを登録するのはもうしばらく先かもしれませんが、 IIJの発表のように、将来的にA/AAAAレコードに移行する可能性が高いです。

現時点で対応サーバー・クライアントが限定的にも関わらず、A、AAAAレコードに次ぐ問い合わせが発生していることからも、そのインパクトの大きさが伺えます。

SVCB・HTTPSリソースレコードにキャッチアップする資料としては、以下がおすすめです

それでは。

付録 : SVCB/HTTPS 対応した drill のインストール

dig は SVCB/HTTPS RR に対応していません。

$ dig -t HTTPS cloudflare.com +short
;; Warning, ignoring invalid type HTTPS
104.16.132.229
104.16.133.229

明示的に SVCB/HTTPS に対応した番号を指定すれば、デコードまでのデータを確認できるものの、使い勝手は良くないでしょう。

$ dig type65 cloudflare.com +short
\# 76 000100000100150568332D32390568332D32380568332D3237026832 00040008681084E5681085E500060020260647000000000000000000 681084E5260647000000000000000000681085E5

コマンドラインからこれらレコードを確認する場合は、drill がおすすめです。

バージョン 1.7.2 から対応しています。

* SVCB and HTTPS draft rrtypes.
  Enable with --enable-rrtype-svcb-https.

参考 DNSコマンドラインツールのdrillをソースコードからコンパイルしてみた | DevelopersIO

$ drill -v
drill version 1.7.2 (ldns version 1.7.2)
Written by NLnet Labs.

Copyright (c) 2004-2008 NLnet Labs.
Licensed under the revised BSD license.
There is NO warranty; not even for MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE.

SVCB/HTTPS RR を問い合わせる場合は、手元の drill が 1.7.2 以上であることを確認してください。

ソースコードからのビルド方法は README.git にあります。