Draft: Service binding and parameter specification via the DNS (DNS SVCB and HTTPS RRs)
こんにちは、まれいんです。
この記事は ひとりRFCの旅 Advent Calender 5日目の記事です。
今回はRFCではありませんが、IETFのDomain Name System Operationsというワーキンググループで議論が進行中の、HTTPSリソースレコードについてのドラフトを見て行こうと思います。執筆当時の最新バージョンは02です。
draft-ietf-dnsop-svcb-https-02
概要
最初にAbstractを引用しておきます。
This document specifies the "SVCB" and "HTTPS" DNS resource record (RR) types to facilitate the lookup of information needed to make connections to network services, such as for HTTPS origins. SVCB records allow a service to be provided from multiple alternative endpoints, each with associated parameters (such as transport protocol configuration and keys for encrypting the TLS ClientHello). They also enable aliasing of apex domains, which is not possible with CNAME. The HTTPS RR is a variation of SVCB for HTTPS and HTTP origins. By providing more information to the client before it attempts to establish a connection, these records offer potential benefits to both performance and privacy.
HTTPSに代表されるネットワークサービスについての情報をDNSから引っ張ってこれるようにするもので、 このdraftではSVCB (Service Binding) レコードとHTTPSレコードが追加されるようです。
また、HTTPSプロトコルはクライアント側がサーバ側の情報を事前に知っておいた方がいいことがいくつかあるらしいため、HTTPSレコードではそういった情報を事前に知ることができるようにすることを目指しているようです。
SVCB, HTTPSリソースレコード
SVCBリソースレコードはAliasModeとServiceModeの2種類のモードを持ちます。
モード名 | 用途 |
---|---|
AliasMode | ほかのドメイン名へのaliasを貼る |
ServiceMode | エンドポイントへの接続情報を提供する |
また、以下の3つのフィールドを持ちます。
フィールド名 | 用途 |
---|---|
SvcPriority | 優先度(低い方が優先)、0のときはAliasMode |
TargetName | alias先(AliasMode) or alternative endpoint(ServiceMode) |
SvcParams | ServiceMode限定かつ任意でkey-value形式でtargetの情報を出せる |
必要であればAdditional SectionにAレコードやAAAA, CNAMEレコードを返してもOKです。
リソースレコードタイプの番号は64です。
HTTPSはSVCBリソースレコードとほぼ同様ですが、HTTPSプロトコル特有のものを扱えるようになっています。 リソースレコードタイプの番号は65です。
wire format
wire formatは以下です。 ASCIIの図はなかったので、それっぽい感じで作ってみました。
RDATA
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | SvcPriority | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | | / TargetName / | | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | | / SvcParams / | | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
SvcParams
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | SvcParamKey | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | SvcParamValueの長さ | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | | / SvcParamValue / | | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
それではリソースレコードの詳細を見て行きましょう。
AliasMode
AliasModeはあるドメイン名にて指定したプロトコル、指定したポートで動作しているサービスを別のドメイン名に飛ばすものです。
例えば example.jp
というドメイン名でWebサーバ(443)とDNSサーバ(53)とTFTPサーバ(69)が動いているとき、各サービスごとに別のドメイン名を用意して飛ばす、という状況を想定してください。
このとき、サービス毎にAliasModeでSVCBレコードを作ることで分散させることができます。
|--> dns.example.com (DNSサーバ) | example.com -----> www.example.com (Webサーバ) | |--> tftp.example.com (TFTPサーバ)
例えば、tftp://example.com:69
というサービスを svc4.example.net
へaliasするときは、ポート番号とプロトコル名を含めた以下のようなレコードになります。
_69._tftp.example.com. 7200 IN SVCB 0 web.example.com.
HTTPSレコードはHTTPSであることが分かっているので、ポート番号とプロトコルのprefixなしで記載することができます。
example.com. 7200 IN HTTPS 0 www.example.com.
また、TargetNameに .
が指定されている場合は、サービスが稼働していない or 存在しないことを表します。
_3389._rdp.example.com. 7200 IN HTTPS 0 . # => RDPは稼働していない
ServiceMode
www.example.com
でwebサービスを動かしているが、裏では www[1-5].example.com
という複数のサーバが動いている状況を考えてください。
(draftでいうところのmultiple endpoint)
この時、以下のようにして裏のサーバの情報を教えることができます。
www.example.net. 7200 IN SVCB 3 www1.example.net. alpn="bar" port="8004" echconfig="..."
また、一部のサーバは暗号化の種類が多いだったり新しい機能が使えるなどで優先的に使わせたい場合は、SvcPriorityを利用することで優先的に使わせることができます。
TargetNameに .
が指定されている場合は、そのドメイン名でサービスが動いていることを表します。
利用イメージは以下のような感じです。(draftから引用)
example.com. 7200 IN HTTPS 0 svc.example.net. svc.example.net. 7200 IN CNAME svc2.example.net. svc2.example.net. 7200 IN HTTPS 1 . port=8002 echconfig="..." svc2.example.net. 300 IN A 192.0.2.2 svc2.example.net. 300 IN AAAA 2001:db8::2
SvcParam
ServiceModeの時にだけkey-value形式で情報を渡せるSvcParamsですが、このdraftでいくつか定義されています。
SvcParamsKey | 意味 |
---|---|
"alpn", "no-default-alpn" | Application-Layer Protocol Negotiation(よく知らない)で利用 |
"port" | サービスが提供されているポート番号 |
"echconfig" | TLSのEncrypted Client Hello(よく知らない)の設定 |
"ipv4hint", "ipv6hint" | ipv[46]アドレスのヒント |
おまけ
cloudflareは試験的に対応しているようです。
$ dig blog.cloudflare.com -t TYPE65 @1.1.1.1 ; <<>> DiG 9.16.8-Debian <<>> blog.cloudflare.com -t TYPE65 @1.1.1.1 ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 40109 ;; flags: qr rd ra ad; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 1232 ;; QUESTION SECTION: ;blog.cloudflare.com. IN TYPE65 ;; ANSWER SECTION: blog.cloudflare.com. 300 IN TYPE65 \# 76 000100000100150568332D32390568332D32380568332D3237026832 0004000868121A2E68121B2E00060020260647000000000000000000 68121A2E26064700000000000000000068121B2E ;; Query time: 0 msec ;; SERVER: 1.1.1.1#53(1.1.1.1) ;; WHEN: Mon Nov 30 01:54:43 JST 2020 ;; MSG SIZE rcvd: 136