QUICやHTTP/3で利用を避けるべき送信元ポートの議論についての考察

f:id:yuyarin:20210722233918p:plain

https://www.slideshare.net/yuyarin/quicnat

最近QUICとNATについての話をJANOGで紹介するぐらいQUICという新しいプロトコルに既存のネットワークインフラがどう適応していくかを考えています。

id:asnokaze さんの記事で紹介されているように、QUICやHTTP3/3で送信元UDPポートとして利用を避けるべきポートの議論が行われています。これはUDPのリフレクション攻撃のへの対応としてインフラストラクチャ側で特定のUDPポートのトラフィックをブロックしているケースがあるからです。実際に私もこのブロックの設定を行ったことがあります。 これはUDPというプロトコルの特性に起因する問題であり、QUIC, HTTP/3に限らずUDPを使うプロトコルに広くある問題です。

asnokaze.hatenablog.com

QUICクライアント側で送信元ポートとして利用を避けた場合でもインフラストラクチャ側のミドルボックスによって避けるべきポートを送信元ポートとして使用されてしまう可能性があります。一番大きな障害となるのがIPv4 Source NATでしょう

この記事ではHTTP/3を提供する場合についてのみ考察します。この記事でHTTP/3に対して問題ないと判断しても、QUICを使用する別のまだ見ぬ新しいアプリケーションレイヤープロトコルでは問題が生じるかもしれません。

結論

結論から述べるとHTTP/3でサービスを提供する事業者が制御可能な範囲内でこの問題を回避することができます。ただし世の中には例外があり100%ではありませんが、おおよそ問題になることはないでしょう。

IPv4 Source NATとUDP増幅問題

IPv4 Source NAT(以下SNAT)では一般のNATでもCGN/LSNでもwell-knownポートを送信元ポートには使用しませんので、問題になるポート番号は1024 - 65535の範囲でUDP増幅攻撃に使用されるポートです。これに該当するポートを増幅率の順で並べると次のようになります。

問題になりそうなポートをUDPの増幅率で並べ替えると次のとおりです。増幅率はA10さんの資料を参考にしました。

ポート番号 プロトコル 増幅率 主な利用者
11211 memcached 10,000-51,000 コンテンツプロバイダ
27910 Quake 2 63.9 Eyeball/クラウド
1900 SSDP 30.8 Eyeball
1433 MSQL 25 エンタープライズ/クラウド
4672 Kad 16.3 Eyeball
27000-27030 Steam Protocol 5.5 Eyeball/コンテンツプロバイダ/クラウド
1024-65534 BitTorrent 3.8 Eyeball
5353 mDNS 2-10 Eyeball

本来であれば増幅率の他にプロトコルの普及率などで考える必要があります。個人的な感覚では危ないのは次の3つかなと思います。これはMLの元のリストのうちwell-knownポートのプロトコル以外のものと一致します。

ポート番号 プロトコル 増幅率 主な利用者
11211 memcached 10,000-51,000 コンテンツプロバイダ
1900 SSDP 30.8 Eyeball
5353 mDNS 2-10 Eyeball

memcachedはオンメモリのKey-Valueデータベースで主にコンテンツプロバイダなどのサービス提供側で使用されることが多いソフトウェアでありプロトコルです。UDP増幅攻撃においては非常に大きな増幅率を誇っており、一時期大きな問題になりました。

SSDPUPnP(Universal Plug and Play)で使用されるプロトコルです。UPnPに対応している機器は家庭用ブロードバンドルータやプリンタなど主にEyeball側で利用される機器が多く、ターゲットもEyeball側になることが多いです。

mDNSは元々ローカルで提供されるサービスですが、一部の実装が外部からの問い合わせに応答してしまうことでUDP増幅攻撃に利用されています。

SNATで送信元ポートとしてこれらのポートを使うかどうか

結論から言うと使われる可能性があります。仕様として明確に禁止しているものがないため、実装や運用に依存します。

一般的なブロードバンドルータではそもそもSNATのエントリー数が数千と小さいため、エフェメラルポートの範囲で十分ですが、SOHO・中規模用のルータなどではSNATのポート範囲を1024まで拡張している場合があります。特定のポート番号についてそのポート番号を使用しないようにしている実装は稀だと思います(個人の感想)。

一番問題になるのがIPoEでのCGN/LSNの実装方式であるMAP-EなどのIPv6アドレスをIPv4アドレスとポート番号のレンジに静的にマッピングするタイプのSNATです。Subscriberあたり256個や512個のポート番号を連続した領域として割り当てるため、個別のポート番号だけを抜き取る実装はありません。そのポート番号を含むレンジをまるごと使用不可にすることは考えられますが、私の知る限りそのような実装はありません。

以降でこれらのポート番号が送信元ポート番号として使われたとしてもおそらく問題がないであろう(大きな問題にならないであろう)理由を述べます。

Eyeball側をターゲットとしたUDP増幅攻撃への対処

f:id:yuyarin:20210722233632p:plain

SSDPやmDNSはEyeball側の機器が増幅器になります。この攻撃を防ぐ箇所としては以下の8箇所が考えられます。これらのうち実際にブロックを行う可能性があるのは③か⑧です。

番号 場所 条件 ブロックするか
ISPIngress全般 送信元ポート しない
ISPからSubscriberへのEgress 送信元ポート しない
SubscriverのIngress 送信元ポート しているかもしれない
SubscriverのEgress 宛先ポート しない
ISPのSubscriberからのIngress 宛先ポート しない
ISPのEgress 宛先ポート しない
ISPのSubscriberや顧客や子ASへのEgress 宛先ポート しない
Subscriberや顧客や子ASのIngress 宛先ポート しているかもしれない
Subscriberや顧客や子ASのIngress 宛先ポート しているかもしれない

③のケースではSubscriberのCPEにおいて送信元ポート番号をブロックするケースですが、設定している可能性はそれほど高くなく、また、設定していたとしてもSNATのinside側で行われているかと思うので、無害でしょう。

⑧のケースでは宛先ポートですのでブロッキングを行っていたとしてもQUICには影響がありません。

③と⑧以外の箇所では「しない」としていますが、ISPによってはブロッキングしている箇所がある可能性があります。基本的にポート番号によるブロッキングは通信の秘密を侵害することになります。OP25Bのように正当業務行為による違法性阻却事由が成り立つ場合は、これを根拠に実施しているISPはありえます。ここはどの程度のISPが実施しているかを調査する必要がありますが、それほど多くはないかと思います。

HTTP/3でサービスを提供する事業者になりえるのは⑧、クライアント側になりえるのが③や⑧と考えたときに、上記のことからEyeball側がターゲットになるSSDPやmDNSについては、QUICの送信元ポート番号がこれらのUDP増幅攻撃対策のためのブロッキングから影響を受ける可能性は低いと思います。

コンテンツプロバイダ側をターゲットにしたUDP増幅攻撃への対応

f:id:yuyarin:20210722233647p:plain

memcachedはコンテンツプロバイダ側の機器が増幅器になります。この攻撃を防ぐ箇所としては以下の8箇所が考えられます。これらのうち実際にブロックを行う可能性があるのは③と④と⑧と⑪です。

番号 場所 条件 ブロックするか
ISPIngress全般 送信元ポート しない
ISPから法人顧客や子ASであるコンテンツプロバイダへのEgress 送信元ポート しない
コンテンツプロバイダのIngress 送信元ポート しているかもしれない
コンテンツプロバイダのEgress 宛先ポート しているかもしれない
ISPの法人顧客や子ASであるコンテンツプロバイダからのIngress 宛先ポート しない
ISPのEgress 宛先ポート しない
ISPのSubscriberや顧客や子ASへのEgress 宛先ポート しない
Subscriberや顧客や子ASのIngress 宛先ポート しているかもしれない
Subscriberや顧客や子ASのIngress 宛先ポート しているかもしれない
ISPのSubscriberからのIgress 送信元ポート しない
ISPのSubscriberのIgress 送信元ポート しているかもしれない

ISPでは基本的には法人顧客や子ASに対してトラフィックブロッキングは行いません。

③も④もブロッキングを行っている可能性がありますがネットワーク外部の(例えばクラウドサービス上に立てた)memcachedにアクセスするためには必要なのでブロッキングしている可能性は低いです。③がクライアントからのHTTP/3のトラフィックに関係しますが、これはHTTP/3でサービスを提供する事業者側で制御可能な範囲なので対処可能です。

⑧はブロッキングしている可能性が高いです。これはmemcachedUDP増幅攻撃に使用された場合の対処方法として、ネットワーク内部にmemcachedを立てている場合に信頼できるIPアドレス以外の外部からの宛先ポートが11211であるパケットを落とします。これはブロッキングを行っていてもHTTP/3には影響しません。

⑪はブロッキングされている可能性があります。これはEyeball側で内部でmemcachedがNW管理者の関知しない範囲で立てられていたときにUDP増幅攻撃に加担しないようにNW管理者側でブロックしているケースです。ただしこの場合もブロックはSNATを行う前に実施されるので、HTTP/3トラフィックに対する影響はありません。

HTTP/3でサービスを提供する事業者になりえるのは③、④、⑧ですが、いずれも影響がありません。

HTTP/3でサービスを提供するコンテンツプロバイダ側でできる対策

HTTP/3でサービスを提供しようとした場合に、UDP増幅攻撃の対処としてのブロッキングに影響を受けないためには以下の対応を行えば十分だと考えられます。

  • SNATされないケースを考えて、HTTP/3クライアント側で送信元ポート番号に増幅攻撃に利用されるポート番号を使用しない(現在のWGの方向)
  • 送信元ポート番号が11211であるトラフィックをブロックしているネットワークにHTTP/3のフロントエンドを設置しない(コンテンツ事業者の努力)
  • SNATが行われなくても済むようにIPv6でのサービスを提供する(コンテンツ事業者の努力)

というわけで今のWGの流れは方向性としては概ね正しいかと思います。

もう少し踏み込んで少しの可能性も潰したい場合、memcachedの11211のブロッキングを回避するためには、送信元ポート番号として偶数番号を使うことが対策になりえます。なぜならRFC4787にもあるように多くのSNATの実装ではPort Parityとして送信元ポート番号の偶奇を保つようにしているからです。ただし送信元ポート番号の枯渇が2倍速になる問題があります。

最後に

これらはあくまでコンテンツとEyeballと単純に分割して考察した場合です。コンテンツプロバイダやクラウドサービス同士でHTTP/3でAPI提供が行われた場合なども考察する必要があります。

いずれにせよ、新しいプロトコルの発展を阻害しないためにみんなで協力しあって頑張っていきたいところです。

考慮が足りない箇所があったら遠慮なくコメント欄か @yuyarin までお知らせください。