Cloudflare Tunnel のユースケース
Cloudflare Zero Trust では Cloudflare Tunnel を使って社内ネットワークを接続する等のユースケースを実現することができます。
プライベートネットワークには、サーバーとクライアントという2つの主要コンポーネントがあります。サーバーのインフラストラクチャ(単一のアプリケーション、複数のアプリケーション、ネットワークセグメントのいずれでも)はCloudflare TunnelによってCloudflareのグローバルネットワークに接続されます。これはサーバー上でcloudflaredデーモンを実行することで行われる。
クライアント側では、エンドユーザーはCloudflare WARPクライアントを使用してCloudflareのグローバルネットワークに接続します。WARPクライアントは、社内のMDMツールを使用してわずか数分で組織全体にロールアウトできます。ユーザーがCloudflare Tunnelを通じて利用可能になったIPに接続すると、WARPはCloudflareのネットワークを通じて対応するトンネルに接続を送信します。
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 の構成からの変更です。
> netsh int ipv4 show dynamicport tcp
Protocol tcp Dynamic Port Range
---------------------------------
Start Port : 49152
Number of Ports : 16384
ポート枯渇問題
同時セッション数が増え、エフェメラルポート範囲からの割り当てが不足すると、接続が失敗します。
同じブラウザーが複数の Web サイトへの多数の接続を作成しているシナリオでは、ブラウザーが試行している新しい接続に対して、エフェメラル ポートが使用されます。 しばらくすると、接続が失敗し始め、このエラーの可能性が高くなる可能性が 1 つあります。これは、ブラウザーが使用可能なすべてのポートを使用して外部に接続を行い、使用可能なポートがなくなったため、接続を確立するための新しい試行が失敗するためです。 マシン上のすべてのポートが使用されると、ポート枯渇と呼ばれます。
エフェメラルポートの確認と変更
以下の記事が参考になります。
IPv4のエフェメラルポートを変更すると、同時にIPv6のエフェメラルポートも変更されるようです。
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 になります。
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 ポート分を割り当てるようにします。
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
参考:ポート枯渇の再現
以下のエフェメラルポート範囲設定とした上で、ポート枯渇の状態を再現します。
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
となっているポートでは、メトリクスの取得が可能で後ほど使います。
ポート枯渇テスト
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 接続を行います。
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 によるポート枯渇状態確認
今回は 60000
〜 60254
までの割り当てとしているため、 60254
以上は割り当てられないことがわかります。
また、ポート使用としては(Local Address
、Local Port
、Remote Address
、Remote Port
)の組み合わせで消費されることがわかります。
TCPトラフィックはほぼ瞬時にポートを使用、解放する。つまり、50,000の利用可能なポートを持つcloudflaredインスタンスに過負荷をかけるには、1秒間に50,001のTCPリクエストを継続的に生成する必要があります。
netstat によるポート枯渇状態確認
netstat -anob
コマンドでも、ポート枯渇状態のスナップショットを確認できます。
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
のログとしては残らないようです。
クライアントのブラウザから見ると以下のように ERR_CONNECTION_RESET
エラーとなることがあるため、参考にしてください。
cloudflared
メトリクス
Prometheus と Grafana にも Windows 版があるので、導入してメトリクスを確認します。
Prometheus
- Prometheus:http://localhost:9090
global
の scrape_interval
を 1s
に変更して、cloudflared
のメトリクスエンドポイントを追加します。
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
"C:\Program Files (x86)\prometheus\prometheus.exe" ^
--config.file="C:\Program Files (x86)\prometheus\prometheus.yml"
Grafana
- Grafana:http://localhost:3000
Data source
の Scrape Interval
を 1s
にしておきます。
メトリクス | 説明 |
---|---|
cloudflared_tcp_active_sessions |
任意のオリジンに対してプロキシされているTCPセッションの同時数 |
cloudflared_tunnel_concurrent_requests_per_tunnel |
各トンネルを通してプロキシされるリクエストの同時数 |
以下のグラフは、上記 PowerShell 実行時のメトリクス推移になります。
以下のようにエフェメラルポート範囲を増やすと、その分 cloudflared
で扱える同時セッション数も増える様子が確認できます。
netsh int ipv4 set dynamicport tcp start=60000 num=355
まとめ
Cloudflare Tunnel で利用するエフェメラルポート範囲は netsh int ipv4/ipv6 set dynamicport tcp/udp
の設定により制御できることがわかりました。
Windows Server の初期設定では、ポート数の割り当てが 16384
となっているため、Cloudflare Tunnel 導入の際にはポート数の割り当てを 50000
まで拡張することで、一定のキャパシティを捌くことができます。
同時セッションの集中によりポート枯渇の可能性がある場合には、エフェメラルポート範囲を設定するとともに、Cloudflare Tunnel をホストするサーバーの台数を水平スケールする等の検討が必要です。