UDP Optionsパケットのインターネット疎通性の考察

IETFでは「Transport Options for UDP」という仕様の標準化が議論されています。このUDP Optionsの仕様では"Maximum Datagram Size", "Timestamps " などのデータをオプション領域に格納して送信できるようになります。

新しいプロトコル機能の利用については、過去にもTLS1.3やTCP Fast Openといった新しいプロトコルがインターネット上で正しく処理されない(Ossification)問題が知られています (参考リンク)

UDP Optionsは特に変わったパケットになるため、インターネット越しで問題なく疎通するのか確認するというのが今回の目的です。

ちょっと面白い振る舞いも観測されたため書いていきます。

目次

UDP Optionsパケット

まず、UDP Optionsを持つパケットのフォーマットについて補足します。

UDPヘッダは固定長ですのでそこにオプションを配置することはできず、UDPペイロードの後ろにsurplus areaを確保しそこにオプションを格納します。surplus areaは、UDPヘッダで指定されるLengthよりもIPヘッダで指定されるLengthを大きく設定することで設けることができます。

(引用: Overcoming the limitations of UDP Options | APNIC Blog )

通常の実装であれば surplus area 領域はそのまま無視するため、UDPとしての通信は問題なく行われるはずです。

UDP Optionsの詳細は以前書いたとおりです。
asnokaze.hatenablog.com

実験

surplus areaをもつUDP パケットを 自宅からインターネット上の公開サーバに送信し返信が返ってくるか確認する。

利用したパブリックサーバは次のプロトコルを喋るものを幾つか選定。

  • DNS
  • NTP
  • QUIC (HTTP/3)

手順としては、各公開サーバに対して以下の2つを試す。送るパケットは、それぞれのプロトコルに合わせて適切なパケットを送るものとする。

  • 1. surplus areaのないUDPパケットを送信し、返信があることを確認する
  • 2. surplus areaのあるUDPパケットを送信し、返信があることを確認する
パケットの例

パケットキャプチャすると、このようにDNSパケットとして正しく解釈されるものです (この例はDNSクエリのUDPパケットにsurplus areaを追加)
surplus areaに『this is surplus area』という文字列が格納されています。

結果

データ

  • DNS: 21公開サーバに送信した。surplus areaがあると6サーバが返信しなくなった
  • NTP: 10公開サーバに送信した。surplus areaがあると2サーバが返信しなくなった
  • QUIC: 6公開サーバに送信した。surplus areaがあると2サーバが返信しなくなった

surplus areaがあると返信が返ってこなくなるサーバがいくつか観測された。幾つかは返ってくるためミドルウェア実装は問題なく処理できているのではないかとおもう。想像するに、返信がないケースはWAFなどにより不正なパケットとして遮断されているケースかなと思われる。

実際に、Google Cloud Platform (GCP)にVMインスタンスを起動しsurplus areaのあるパケットを送ってみると、VM側までパケットが到達してないことが確認できた(通常のUDPパケットは届く)。

また、次に示すように一部アプライアンス製品では、surplus areaがあるとパケット処理が特殊なケースも有るかもしれない。

奇妙な振る舞い

奇妙なことに、サーバ側 surplus area をそのまま送り返してくるケースが確認された。

NTPサーバ側からsurplus areaに『this is surplus area』という文字列入っているパケットが返ってきている。

調べたところサーバはNTP専用のアプライアンス製品であるもよう。想像するに、受け取ったパケットを格納しているバッファ領域を再利用してる感じなんだろうか?

このようなことが有ると、相手が送ってきたUDP Optionsが信頼できないので、コピーされてないことを保証する仕組みが必要になりそう
(例えば、追加のUDP Optionsとして"client bit", "server bit" みたいな送信方向を示すoptionsなどを定義するなど)

まとめ

今回はパブリックなサーバに対しsurplus areaを含むUDPパケットを送信した。

実験結果として以下のことがわかった

  • surplus areaがあると疎通しないケースが有る
  • surplus areaをそのまま送り返してくるサーバが居る

UDP Optionsは対応してない相手には無視されることが期待されるが、疎通しないケースが存在すると、UDP Optionsをつけずに再送しなおす必要が出てくる。

自分たちがサーバ側もクライアント側もコントロール出来るケースにおいてはUDP Optionsは気にせず利用できるが、そうではない場合は常に疎通しないケースを考慮する必要がでてくる。

終わりに

この実験結果をもってしてなにか改善にとりくめるか、一緒に議論できる方がおりましたら是非よろしくお願いします

HTTPレイヤで追加のサーバ証明書を送信する Secondary Certificate の仕様について

HTTP/2やHTTP/3のレイヤで追加のサーバ証明書を送信可能にする『Secondary Certificate Authentication of HTTP Servers』という仕様がHTTP WGで議論されています。著者はAppleの方とAkamaiの方の共著になっています。

以前にも、共著に入っているMike Bishop氏から2016年~2018年に同様の提案が出ておりましたが改めて提案されています。前回はクライアント側からのクライアント証明書の追加送信サポートしていましたが、今回はサーバからの追加の証明書を送信するユースケースに絞った提案になっています。

モチベーション

HTTPレイヤで追加のサーバ証明書を送信するモチベーションについて説明します。

HTTP/2ではTCPコネクション、HTTP/3ではQUICコネクション上でHTTPリクエストを送信します。極力そのコネクションを使い回すことが出来たほうが、コネクションを確立する手間も少ないですし、輻輳制御上もメリットがあります。

HTTP/2およびHTTP/3において、コネクションを再利用できる条件は次のとおりです

  • リクエストを送るドメインのIPが同一なこと
  • コネクションを確立した際の証明書が、リクエストを送るドメインとマッチしていること

具体的には *.example.com の証明書で接続したコネクション上では、下記のドメインへのリクエストを送信しても良いことになります

このように証明書がカバーするドメインが多ければコネクションを再利用できる機会が増えます。

今回の提案仕様により、追加のサーバ証明書を送ることができれば、コネクションを再利用できる機会を増やすことが出来ます。

Secondary Certificate Authentication of HTTP Servers

CERTIFICATEフレーム

この仕様では、サーバ側からHTTPレイヤで証明書を送信するために CERTIFICATEフレームを新しく定義しています。

HTTP/2およびHTTP/3でCERTIFICATEフレームを定義していますが、例えばHTTP/3では次のようなメッセージです。

Authenticatorフィールドは証明書と紐づく秘密鍵の所持の証明をするデータです。具体的には『RFC 9261 Exported Authenticators in TLS』を介してえられるデータです

通信の流れ

この拡張仕様を使うためには、SETTINGS_HTTP_SERVER_CERT_AUTHパラメータを交換する必要があります。
その後、CERTIFICATEフレームフレームをh2ではstream 0 、h3ではcontrol streamで送信します。

その他

セキュリティ上の考慮事項についても『Secondary Certificate Authentication of HTTP Servers』にかかれておりますので、気になる方はそちらをご覧頂くのが良いと思います。

個人情報を共有しないように要求する Sec-GPC リクエストヘッダ

W3CのPrivacy Community Groupでは、Webのプライバシーについて取り組んでいます。

その取り組みとして「Global Privacy Control (GPC)」というドキュメントが書かれています。このドキュメントでは、ユーザが個人情報を共有しないように要求する Sec-GPC リクエストヘッダが定義されています。

多くのWebサイトでは個人情報の取り扱いについてオプトアウト方法を提供していますが、ユーザが個々にオプトアウトを行うよりか簡単な手段を提供するというモチベーションがあるようです。

また、この仕様は、各国のプライバシー法などの法的枠組みにおけるオプトアウトの意思表示として扱えることを意図しているようです。

Firefoxでも実装が進められています。
Intent to Prototype: Global Privacy Control

Sec-GPC リクエストヘッダ

Sec-GPCに1を指定することで、個人情報を共有しないように要求できます。

GET /something/here HTTP/2
Host: example.com
Sec-GPC: 1

Sec-GPC リクエストヘッダのサポート

サーバ側がSec-GPC リクエストヘッダをサポートしていることを示すのに、well-known path を定義しています

/.well-known/gpc.json

{
  "gpc": true,
  "lastUpdate": "1997-03-10"
}

逆向きに接続する Reverse HTTP Transport の仕様

Reverse HTTP Transport』という提案仕様がIETFに提出されています。著者はMetaとNokiaの方々らです。また、HAProxyの方も同様の機能を検討しているそうです(参考URL)。

普通のProxyサーバでは、Proxyサーバからオリジンサーバにコネクション確立するのが一般的です。そのためにオリジンサーバが外部から接続を受けられるようにする必要があります。

Reverse HTTP Transportでは、逆にオリジンサーバからProxyサーバにコネクションを確立し、HTTPリクエストを受け付けるという構成になります。コネクションの確立/TLSハンドシェイクだけが逆向きで、コネクション確立された接続上で、ProxyからHTTPリクエストが送られます。

これによりオリジンサーバをインターネットに公開する必要がなくなります。

プロトコルについて

この Reverse HTTP Transport はプロトコルスタック的にはHTTP2/TLS or HTTP/3/QUICという主要な技術は変更無く使用されます。通常の場合との違いは次のとおりです

  • ALPN IDとして"h2-reverse", "h3-reverse"を使用する
  • Proxy側はTLS CertificateRequestを送信する必要がある
  • オリジンサーバは有効な証明書チェーンを応答する必要がある
  • オリジンサーバはORIGINフレームを送信し、自身がホストするオリジン名を通知する。なお、このオリジン名は送信したクライアント証明書とマッチする必要がある。
  • Proxy側は、オリジンサーバの送ってきたORIGINフレームとクライアント証明書を照合する

Proxyはオリジンサーバがホストしてるオリジン名を把握できるので、HTTPリクエストをオリジンサーバ宛に中継できるようになる。

ブラウザにWebサイトの閲覧履歴を残さないようにする Request-OTR ヘッダ

The Off-The-Record Response Header Field」という仕様がIETFに提出されています。これは、Webサイトの閲覧履歴をブラウザが保存しないように指示するHTTPレスポンスヘッダです。

このレスポンスヘッダを使うことで、Webサーバ側から自身のサイトの閲覧履歴を残さないようにすることができます。家庭内暴力の相談やセンシティブな医療サイトの閲覧情報がブラウザに残らないようにできます。

Braveブラウザの1.53 (beta)ではflagsで有効にするとすでに使えるようになっています。動作としては、Webサイトを閲覧する際にOTRモードで閲覧するか確認画面が出るようです。


Request-OTR ヘッダ

Request-OTR ヘッダは、RFC 8941 Structured Field Valuesに準じており、ブール値を指定します

Request-OTR: ?1

何が保存されないか?

Braveのサイトの解説「リクエストOff the Record | Brave Browser」によれば、OTRモードでは次のようになります

  • アクセス履歴が保存されなくなる
  • キャッシュ、Cookie、権限設定が一時領域に作成され、タブを閉じたりサイトを離れたときに破棄される

P2P QUICの提案仕様

P2P QUIC」という提案仕様がIETFに提出さています。著者はMicrosoftのPeter Thatcher氏になっています。

Peter Thatcher氏らは、W3Cでも「QUIC API for Peer-to-peer Connections」という提案を行っており、ブラウザ上でQUICを用いたP2P メディア・コミュニケーションを行えるようにより組んでいます。

まだ標準化の議論が盛り上がってるわけではないが、「P2P QUIC」自体はかなり短い仕様ですのでざっくり目を通しておく

P2P QUICについて

P2P QUICではICEを用います。

その中で次の値をネゴシエーションします

  • どちらがactive (client)とpassive (server) の役割を担うか
  • 証明書のフィンガープリント
  • QUICでgrease bitを使うか
  • MuliplexingIDを使うか (MuliplexingIDはQUICコネクションに複数の通信を多重化する仕組み)
SDP

SDPの例として次のとおりになります

v=0
o=- 4962303333179871722 1 IN IP4 0.0.0.0
s=-
t=0 0
a=ice-ufrag:7sFv
a=ice-pwd:dOTZKZNVlO9RSGsEGM63JXT2
a=ice-options:trickle
a=quic-options:grease
a=fingerprint:sha-256
   7B:8B:F0:65:5F:78:E2:51:3B:AC:6F:F3:3F:46:1B:35:
   DC:B8:5F:64:1A:24:C2:43:F0:A1:58:D0:A1:2C:19:08
a=setup:active
a=group:BUNDLE 1 2 3
m=audio 9 UDP/QUIC/RTP/AVPF 99
a=mid:1
a=sendrecv
a=rtpmap:99 OPUS/4800/2
m=video 9 UDP/QUIC/RTP/AVPF 100
a=mid:2
a=sendrecv
a=rtpmap:100 VP8/90000
a=rtcp-fb:100 ccm fir
m=application 9 UDP/QUIC generic
a=mid:3

QUICの機能など

P2P QUICにおいては、QUICの持ってる機能について幾つか言及があります

  • ALPNでは、"q2q"を使う
  • 各ピアは証明書の検証を行う (クライアント証明書の検証を行う)。なお自己署名証明書を許容してもよい(MAY)
  • Multipathを使うべきではない (SHOULD NOT)
  • QUIC Datagramsをサポートするべき (SHOULD)
  • コネクションマイグレーションはICEを通して行い、コネクションIDを変更すべきでない (SHOUD NOT)

UDPにオプション領域を追加する仕様

現状UDPヘッダには、TCPやSCTPにあるようなオプションを指定できません。

新しい「Transport Options for UDP」という仕様では、UDPにおいてオプションを付けられるようになります。

その仕組が面白かったので簡単に紹介します。

どこが面白いかというと、UDPヘッダは下記の通り「送信元ポート」「送信先ポート」「長さ」「チェックサム」からなり、その後に実際のデータが続きます。

固定長のヘッダしかないUDPにおいて、既存の実装に対してもそのままUDPパケットを扱えるようにオプション領域をどう確保したのか、考えてみると面白そうと感じていただけると思います。

Transport Options for UDP

Transport Options for UDP」では、UDPオプションを格納するのにsurplus areaという領域を確保します。それはIPヘッダについても知る必要があります。

surplus area

IPv4ヘッダとUDPヘッダをくっつけると次のようになります

IPヘッダ領域とUDPヘッダ領域の両方に長さを示す領域があります。IPヘッダで示されたTotal Lengthを全てUDPで使い切る必要はありません。余らせても仕様上は問題ありません。この余らせた領域をUDPオプションを格納する領域 (surplus area) として利用します。
(そのようなことをしてもLinux, MacOS, NATでUDPは正しく扱われるとdraftには記述されています)

図にすると次のように、長さの差からsurplus areaが生まれています。

この仕様に対応していない実装はこの領域をそのまま無視しますので、そのまま通信を継続できます。

UDP Options

surplus areaにはまず、2バイト境界まで0でパディングされます。そのあとにOCS (The Option Checksum)が続きます。OCSはOption領域の整合性を確認できるできるチェックサムです。

UDP Optionは基本的には、Kind・Length/データからなる可変長データです

詳細はを割愛しますが、Kindについては、すでに定義されているものもあります。

  • 0 End of Options List (EOL)
  • 1 No operation (NOP)
  • 2 Alternate payload checksum (APC)
  • 3 Fragmentation (FRAG)
  • 4 Maximum datagram size (MDS)
  • 5 Maximum reassembled datagram size (MRDS)
  • 6 Request (REQ)
  • 7 Response (RES)
  • 8 Timestamps (TIME)
  • 9 Authentication (AUTH)
  • 10-126 UNASSIGNED (assignable by IANA)
  • 127 RFC 3692-style experiments (EXP)
  • 128-191 RESERVED
  • 192 Encryption (UENC)
  • 193-253 UNASSIGNED-UNSAFE (assignable by IANA)
  • 254 RFC 3692-style experiments (UEXP)
  • 255 RESERVED-UNSAFE

0~7は実装が必要なオプションです。Reserved領域はまだ使用されていない領域です。SAFEなオプション(0~191)とは無視されても通信に影響を与えないオプションであり、UNSAFE(192~255)は無視するとパケットを正しく解釈できなくなるオプションです。