LoginSignup
0
0

Cloudflare Tunnel で利用するエフェメラルポート範囲を Windows Server で設定する

Last updated at Posted at 2024-05-29

Cloudflare Tunnel のユースケース

Cloudflare Zero Trust では Cloudflare Tunnel を使って社内ネットワークを接続する等のユースケースを実現することができます。

プライベートネットワークには、サーバーとクライアントという2つの主要コンポーネントがあります。サーバーのインフラストラクチャ(単一のアプリケーション、複数のアプリケーション、ネットワークセグメントのいずれでも)はCloudflare TunnelによってCloudflareのグローバルネットワークに接続されます。これはサーバー上でcloudflaredデーモンを実行することで行われる。

クライアント側では、エンドユーザーはCloudflare WARPクライアントを使用してCloudflareのグローバルネットワークに接続します。WARPクライアントは、社内のMDMツールを使用してわずか数分で組織全体にロールアウトできます。ユーザーがCloudflare Tunnelを通じて利用可能になったIPに接続すると、WARPはCloudflareのネットワークを通じて対応するトンネルに接続を送信します。

image.png

Cloudflare Tunnel システム要件

システム要件としては、以下のように各ホストあたり 50000 ポートの割り当てにより、ホストあたり4,000人程度の処理を担えるとしています。

Cloudflare Tunnelのスループットは主にシステムソフトウェアで設定されたポート数によって制限されます。したがって、cloudflaredサーバーのサイズを決める際に最も重要な要素は、TCPとUDPトラフィックの予想スループットを反映するようにマシンで利用可能なポートのサイズを決めることです。
...
ほとんどのユースケースでは、以下のベースライン構成を推奨する:
ネットワークロケーションごとに2台の専用ホストマシンでcloudflaredレプリカを実行する。2台のホストを使用することで、サーバー側の冗長性とトラフィックバランシングが可能になります。
各ホストには最低4GBのRAMと4つのCPUコアを搭載します。
各ホスト上のcloudflaredプロセスに50,000ポートを割り当てる。
この設定は通常、8,000人のWARPユーザー(ホストあたり4,000人)のトラフィックを処理するのに十分です。

Windows Server におけるエフェメラルポート

以下の既定範囲が割り当てられています。

インターネット割り当て番号機関 (IANA) の推奨事項に準拠するために、Microsoft は Windows Vista と Windows Server 2008 の送信接続の動的クライアント ポート範囲を増やしました。 新しい既定の開始ポートは 49152 で、新しい既定のエンド ポートは 65535 です。 これは、既定のポート範囲 1025 から 5000 を使用した以前のバージョンの Windows の構成からの変更です。

cmd
> netsh int ipv4 show dynamicport tcp

Protocol tcp Dynamic Port Range
---------------------------------
Start Port      : 49152
Number of Ports : 16384

ポート枯渇問題

同時セッション数が増え、エフェメラルポート範囲からの割り当てが不足すると、接続が失敗します。

同じブラウザーが複数の Web サイトへの多数の接続を作成しているシナリオでは、ブラウザーが試行している新しい接続に対して、エフェメラル ポートが使用されます。 しばらくすると、接続が失敗し始め、このエラーの可能性が高くなる可能性が 1 つあります。これは、ブラウザーが使用可能なすべてのポートを使用して外部に接続を行い、使用可能なポートがなくなったため、接続を確立するための新しい試行が失敗するためです。 マシン上のすべてのポートが使用されると、ポート枯渇と呼ばれます。

エフェメラルポートの確認と変更

以下の記事が参考になります。

IPv4のエフェメラルポートを変更すると、同時にIPv6のエフェメラルポートも変更されるようです。

cmd
netsh int ipv4 show dynamicport tcp
netsh int ipv4 show dynamicport udp
netsh int ipv6 show dynamicport tcp
netsh int ipv6 show dynamicport udp

設定できるポートの最小範囲は 255 です。 設定できる最小開始ポートは 1025 です。 最大エンド ポート (構成されている範囲に基づく) は、65535 を超えることはできません。 Windows Server 2003 の既定の動作を複製するには、開始ポートとして 1025 を使用し、TCP と UDP の両方の範囲として 3976 を使用します。 これにより、開始ポートは 1025、終了ポートは 5000 になります。

cmd
netsh int ipv4 set dynamicport tcp start=60000 num=255
netsh int ipv4 set dynamicport udp start=60000 num=255
netsh int ipv6 set dynamicport tcp start=60000 num=255
netsh int ipv6 set dynamicport udp start=60000 num=255

Cloudflare Tunnel 用のエフェメラルポート範囲設定

以下のように各ホストごとに 50000 ポート分を割り当てるようにします。

cmd
netsh int ipv4 set dynamicport tcp start=11000 num=50000
netsh int ipv4 set dynamicport udp start=11000 num=50000
netsh int ipv6 set dynamicport tcp start=11000 num=50000
netsh int ipv6 set dynamicport udp start=11000 num=50000

参考:ポート枯渇の再現

以下のエフェメラルポート範囲設定とした上で、ポート枯渇の状態を再現します。

cmd
netsh int ipv4 set dynamicport tcp start=60000 num=255
netsh int ipv4 set dynamicport udp start=60000 num=255
netsh int ipv6 set dynamicport tcp start=60000 num=255
netsh int ipv6 set dynamicport udp start=60000 num=255

TCPView による初期状態確認

TCPView を使って GUI でポートの使用と解放が確認できます。

TCPView は、ローカルおよびリモート アドレスや TCP 接続の状態など、システム上のすべての TCP および UDP エンドポイントの詳細な一覧を表示する Windows プログラムです。 TCPView では、エンドポイントを所有するプロセスの名前も報告されます。 TCPView には、Windows に付属する Netstat プログラムのより有益で便利なサブセットが用意されています。 TCPView のダウンロードには、同じ機能を持つコマンド ライン バージョンである Tcpvcon が含まれています。

Cloudflare Tunnel サーバーに特に通信が来ていない場合では、以下のような状態です。

1秒ごとにポート状態を自動更新する設定にできます。

TCP Listen 127.0.0.1 となっているポートでは、メトリクスの取得が可能で後ほど使います。

image.png

ポート枯渇テスト

PowerShell 7 で導入された ForEach-Object -Parallel を使って同時並行で TCP 接続を行います。

クラウド、オンプレミス、およびハイブリッド環境向けに設計された PowerShell 7 には、強化された機能と新機能が組み込まれています。

  • Windows PowerShell とのサイド バイ サイドのインストールおよび実行
  • 既存の Windows PowerShell モジュールとの強化された互換性
  • 三項演算子や ForEach-Object -Parallel などの新しい言語機能
    ...

以下のコマンドでは、WARP クライアントから cloudflared を経由して到達可能な RFC 1918 IP レンジ 10.200.0.0/20 に対して同時並行で TCP 接続を行います。

Powershell 7 (x64)
0..15 | ForEach-Object -Parallel { 
    $item = $_
    1..255 | ForEach-Object -Parallel { 
        Invoke-WebRequest -Uri "https://10.200.$using:item.$_" -TimeoutSec 60;
        sleep 1; 
    } -ThrottleLimit 255
} -ThrottleLimit 2

TCPView によるポート枯渇状態確認

今回は 6000060254 までの割り当てとしているため、 60254 以上は割り当てられないことがわかります。

また、ポート使用としては(Local AddressLocal PortRemote AddressRemote Port)の組み合わせで消費されることがわかります。

TCPトラフィックはほぼ瞬時にポートを使用、解放する。つまり、50,000の利用可能なポートを持つcloudflaredインスタンスに過負荷をかけるには、1秒間に50,001のTCPリクエストを継続的に生成する必要があります。

image.png

netstat によるポート枯渇状態確認

netstat -anob コマンドでも、ポート枯渇状態のスナップショットを確認できます。

cmd
  TCP    10.146.0.10:60006      10.200.2.44:443        SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60007      10.200.3.40:443        SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60008      10.200.3.39:443        SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60009      10.200.2.45:443        SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60010      10.200.3.41:443        SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60011      10.200.2.46:443        SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60012      10.200.2.48:443        SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60013      10.200.2.47:443        SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60014      10.200.3.42:443        SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60015      10.200.2.50:443        SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60016      10.200.2.49:443        SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60017      10.200.2.52:443        SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60018      10.200.2.51:443        SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60019      10.200.2.53:443        SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60020      10.200.3.43:443        SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60021      10.200.3.44:443        SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60170      10.200.3.1:443         SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60171      10.200.2.2:443         SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60172      10.200.2.1:443         SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60173      10.200.3.2:443         SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60174      10.200.3.3:443         SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60175      10.200.2.4:443         SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60176      10.200.2.3:443         SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60177      10.200.3.4:443         SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60178      10.200.2.5:443         SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60179      10.200.3.5:443         SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60180      10.200.2.6:443         SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60181      10.200.3.6:443         SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60182      10.200.2.7:443         SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60183      10.200.2.9:443         SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60184      10.200.2.8:443         SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60186      10.200.3.7:443         SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60187      10.200.3.9:443         SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60188      10.200.3.8:443         SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60189      10.200.2.10:443        SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60190      10.200.2.11:443        SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60191      10.200.2.12:443        SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60192      10.200.3.10:443        SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60193      10.200.2.13:443        SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60194      10.200.3.11:443        SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60195      10.200.3.12:443        SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60196      10.200.3.13:443        SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60197      10.200.2.14:443        SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60198      10.200.3.14:443        SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60199      10.200.2.15:443        SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60200      10.200.3.16:443        SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60201      10.200.3.15:443        SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60202      10.200.2.16:443        SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60203      10.200.3.17:443        SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60204      10.200.2.17:443        SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60205      10.200.2.18:443        SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60206      10.200.3.19:443        SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60207      10.200.2.19:443        SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60208      10.200.3.18:443        SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60209      10.200.2.20:443        SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60210      10.200.2.21:443        SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60211      10.200.3.21:443        SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60212      10.200.3.20:443        SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60213      10.200.2.22:443        SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60215      10.200.2.23:443        SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60216      10.200.3.22:443        SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60217      10.200.2.24:443        SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60218      10.200.2.25:443        SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60219      10.200.3.23:443        SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60220      10.200.3.24:443        SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60221      10.200.2.26:443        SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60222      10.200.2.27:443        SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60223      10.200.3.25:443        SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60224      10.200.2.28:443        SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60225      10.200.3.26:443        SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60226      10.200.2.30:443        SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60227      10.200.2.29:443        SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60228      10.200.3.28:443        SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60229      10.200.2.31:443        SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60230      10.200.3.29:443        SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60231      10.200.3.27:443        SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60232      10.200.3.30:443        SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60233      10.200.2.33:443        SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60234      10.200.2.32:443        SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60235      10.200.2.34:443        SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60236      10.200.3.32:443        SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60237      10.200.3.31:443        SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60240      10.200.3.33:443        SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60241      10.200.2.36:443        SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60242      10.200.2.35:443        SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60243      10.200.3.34:443        SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60244      10.200.2.38:443        SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60245      10.200.2.37:443        SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60246      10.200.2.39:443        SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60247      10.200.2.40:443        SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60248      10.200.3.36:443        SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60249      10.200.3.35:443        SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60250      10.200.2.41:443        SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60251      10.200.2.42:443        SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60252      10.200.3.37:443        SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60253      10.200.3.38:443        SYN_SENT        6864
 [cloudflared.exe]
  TCP    10.146.0.10:60254      10.200.2.43:443        SYN_SENT        6864
 [cloudflared.exe]

cloudflared ログ

以下を参考に、より詳細なデバッグログを入手することができますが、
ポート枯渇時には、cloudflared のログとしては残らないようです。

cloudflared メトリクス

Prometheus と Grafana にも Windows 版があるので、導入してメトリクスを確認します。

Prometheus

globalscrape_interval1s に変更して、cloudflared のメトリクスエンドポイントを追加します。

prometheus.yml
global
-  scrape_interval: 15s # Set the scrape interval to every 15 seconds. Default is every 1 minute.
+  scrape_interval: 1s # Set the scrape interval to every 15 seconds. Default is every 1 minute.
...
+    - job_name: "cloudflared"
+      static_configs:
+        - targets: ["127.0.0.1:60110"] ## cloudflared server IP and the --metrics port configured for the tunnel
cmd
"C:\Program Files (x86)\prometheus\prometheus.exe" ^
--config.file="C:\Program Files (x86)\prometheus\prometheus.yml"

Grafana

Data sourceScrape Interval1s にしておきます。

メトリクス 説明
cloudflared_tcp_active_sessions 任意のオリジンに対してプロキシされているTCPセッションの同時数
cloudflared_tunnel_concurrent_requests_per_tunnel 各トンネルを通してプロキシされるリクエストの同時数

以下のグラフは、上記 PowerShell 実行時のメトリクス推移になります。

image.png

以下のようにエフェメラルポート範囲を増やすと、その分 cloudflared で扱える同時セッション数も増える様子が確認できます。

cmd
netsh int ipv4 set dynamicport tcp start=60000 num=355

image.png

まとめ

Cloudflare Tunnel で利用するエフェメラルポート範囲は netsh int ipv4/ipv6 set dynamicport tcp/udp の設定により制御できることがわかりました。

Windows Server の初期設定では、ポート数の割り当てが 16384 となっているため、Cloudflare Tunnel 導入の際にはポート数の割り当てを 50000 まで拡張することで、一定のキャパシティを捌くことができます。

同時セッションの集中によりポート枯渇の可能性がある場合には、エフェメラルポート範囲を設定するとともに、Cloudflare Tunnel をホストするサーバーの台数を水平スケールする等の検討が必要です。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0