Cloudflare Tunnel と Zero Trust — インバウンド不要のリモートアクセス
Cloudflare Tunnel は、プライベートネットワーク上のサービスを、オリジン側のインバウンドポートを開放せずに Cloudflare 経由で公開する仕組みです。cloudflared がオリジン上で常駐し、Cloudflare へアウトバウンド接続を張り、その接続を使って Cloudflare Zero Trust(Cloudflare One)の Access 経由でアクセスします。
正確に理解するには、次の3つの区別が重要です。
- Tunnel と connector は別物 — Tunnel は Cloudflare 上の論理オブジェクト、connector はオリジン上で動く
cloudflaredプロセスです。 - 「アウトバウンドのみ」は一方通行ではない — 接続の開始方向が outbound という意味で、確立後は双方向にデータが流れます(リバーストンネル)。
- アクセス経路は1つではない — 公開ホスト名(clientless)とプライベートネットワーク(Cloudflare One Client 必須)で経路が異なります。
全体像
アクセスの流れは次のとおりです。
- 利用者が Cloudflare 上のホスト名(例:
app.example.com)へ HTTPS でアクセスする。 - Cloudflare Access が未認証のリクエストを IdP のログイン画面へリダイレクトする。
- 認証後、Access がポリシー(誰が・どの条件で許可されるか)を評価する。
- 許可されたリクエストだけが、
cloudflaredが確立済みのトンネルを通って VM 内のサービスへ転送される。 - VM 内のサービスは
127.0.0.1やプライベート IP で待ち受けており、インターネットから直接到達できない。
つまり、インターネット側の入口は Cloudflare のエッジだけで、VM はそこへ出ていく接続を維持しているだけです。
用語の整理
| 用語 | 実体 | 役割 |
|---|---|---|
| Cloudflare Tunnel | Cloudflare 上の論理オブジェクト(UUID で識別) | オリジンと Cloudflare を結ぶ永続トンネル |
| connector | VM 上で動く cloudflared プロセス | Tunnel に参加し、Cloudflare へアウトバウンド接続を張る |
| replica | 同じ Tunnel に参加する追加の connector | 冗長化・ローリング更新 |
| route | Tunnel に紐づく転送規則 | 公開ホスト名 / プライベート IP・CIDR / プライベートホスト名 |
| Access application | Cloudflare 上の設定 | ホスト名やプライベート宛先に認証・認可を付ける |
| Access policy | Allow / Block / Bypass / Service Auth | 誰がアクセスできるか。デフォルト拒否 |
| IdP | Entra ID、Google、Okta など | 本人確認(OIDC / SAML) |
| Cloudflare One Client(WARP) | 端末側のソフトウェア | プライベートネットワークルートを使うためのオンプランプ |
以前は「Cloudflare for Teams」「Cloudflare Zero Trust」と呼ばれていた機能群は、現在は Cloudflare One というブランドに統合されています。ダッシュボード上では「Zero Trust」セクションとして表示される場合もあります。
要素技術 1: Cloudflare Tunnel と connector
Tunnel は「論理オブジェクト」、connector は「プロセス」
cloudflared tunnel create やダッシュボードで作成する Tunnel は、Cloudflare 側に存在する論理的な接続先です。これに対して、VM 上で動く cloudflared プロセスが connector です。
- 1 つの Tunnel に複数の connector(replica)を参加させられる。
- 各 connector は、最寄りの Cloudflare データセンターへアウトバウンド接続を張る。
- Cloudflare はリクエストを、その Tunnel に参加している connector のいずれかへ転送する。
アウトバウンド接続の仕様
cloudflared は Cloudflare のエッジへ、次のような接続を張ります。
| 項目 | 内容 |
|---|---|
| 主プロトコル | QUIC(UDP 7844) |
| フォールバック | HTTP/2(TCP 7844) |
| 接続先ホスト名 | region1.v2.argotunnel.com / region2.v2.argotunnel.com |
| 管理 API | api.cloudflare.com:443 |
| DNS | システムのリゾルバ(UDP/TCP 53) |
| 接続本数 | connector あたり 4 本(少なくとも 2 つのデータセンターに分散) |
--protocol のデフォルトは auto です。UDP 7844 が使えれば QUIC、使えなければ HTTP/2 に自動でフォールバックします。
--protocol quic を指定した状態で UDP 7844 がブロックされると、HTTP/2 に切り替わらず接続に失敗します。ネットワーク要件が不明な場合は auto のままにしてください。
「アウトバウンドのみ」の正しい意味
「アウトバウンドのみ」は、接続を開始する方向が VM → Cloudflare であるという意味です。接続が確立した後は、Cloudflare から VM へリクエストが流れ、VM から Cloudflare へレスポンスが流れる双方向通信になります。
- VM 側に待ち受けるパブリックポートは不要。
- NAT やステートフルファイアウォールの内側からでも接続できる。
- ポートフォワーディングやパブリック IP の割り当ても不要。
- ただし、インターネットへのアウトバウンド通信自体は必要(後述)。
リモート管理とトークン
現在の推奨は、ダッシュボードで作成する リモート管理(remotely-managed)Tunnel です。オリジン側ではトークンを渡して cloudflared を起動するだけで、ルートや設定は Cloudflare 側で管理されます。
| 観点 | リモート管理(推奨) | ローカル管理 |
|---|---|---|
| 作成方法 | ダッシュボード / API | cloudflared tunnel create |
| 起動方法 | --token / --token-file | tunnel run <NAME> + config.yml |
| ルート設定 | Cloudflare 側 | config.yml の ingress |
| 認証情報 | トンネルトークン | cert.pem と認証情報 JSON |
| 向いている用途 | 新規構築、複数ホストの一元管理 | ローカル設定を Git で管理したい場合など |
ホスト上でどちらが使われているかは、systemd の ExecStart に --token または --token-file があるか、~/.cloudflared/config.yml や cert.pem が存在するかで判断できます。
# サービスとして登録する例(トークンは秘密情報)
sudo cloudflared service install <TUNNEL_TOKEN>
または、システムドメインのユニットで次のように起動します。
ExecStart=/usr/bin/cloudflared --no-autoupdate tunnel run --token-file /etc/cloudflared/token
トンネルトークンを持っている人は、その Tunnel に connector を参加させられます。ファイル権限を最小化し(例: root:root 600)、Git やチャットに貼らないでください。漏えいした場合は Cloudflare 側でトークンをローテーションしてください。
動作確認の例
cloudflared が正常に動作している場合、サービス状態とプロセスは次のように確認できます。
$ systemctl is-active cloudflared
active
$ ps -o args= -p <PID>
/usr/bin/cloudflared --no-autoupdate tunnel run --token-file /etc/cloudflared/token
$ ls -l /etc/cloudflared/token
-rw------- 1 root root ... /etc/cloudflared/token
起動時のログでは、次の precheck がすべて status=pass になっていれば正常です。
INF | SUMMARY: Environment is healthy. cloudflared will use 'quic' as primary protocol. |
INF precheck component="DNS Resolution" details="DNS Resolved successfully" status=pass target=region1.v2.argotunnel.com
INF precheck component="UDP Connectivity" details="QUIC connection successful" status=pass target=region1.v2.argotunnel.com
INF precheck component="TCP Connectivity" details="HTTP/2 connection successful" status=pass target=region1.v2.argotunnel.com
INF precheck component="Cloudflare API" details="API is reachable" status=pass target=api.cloudflare.com:443
--no-autoupdate が付いているため、cloudflared の更新は手動です。バイナリを更新したらサービスを再起動してください。
アウトバウンド接続が双方向になる仕組み
「outbound で接続したのに、なぜ後から Cloudflare からリクエストが届くのか」は、ネットワーク層とアプリケーション層を分けて考えると理解できます。
1. ファイアウォールが見ているもの
ステートフルファイアウォールや NAT は、TCP/UDP の 5-tuple(送信元 IP、送信元ポート、宛先 IP、宛先ポート、プロトコル)でコネクションの状態を保持します。
cloudflaredがregion1.v2.argotunnel.com:7844へ outbound 接続を開始する。- ファイアウォール / NAT が「内側 → 外側」の flow を記録する。
- Cloudflare から返ってくるパケットは、この記録済み flow に一致する。
- ステートフルファイアウォールは「既存コネクションの戻りトラフィック」として許可する。
つまり、Cloudflare からのリクエストは新しいインバウンドコネクションではなく、確立済みコネクション上のパケットとして届きます。ファイアウォールのポリシー上は inbound ではなく、established / related の通信です。Cloudflare がオリジンに対して新しい TCP コネクションを開くことはありません。
2. トンネルの登録(制御プレーン)
cloudflared はトークン(またはローカル管理の認証情報)で Cloudflare に認証し、自分がどの Tunnel の connector であるかを登録します。Cloudflare 側には「Tunnel UUID → 現在接続中の connector」のマッピングができます。
- 複数の connector が同じ Tunnel に登録できる。
- Cloudflare はリクエストを送る際、登録済み connector の中から1つを選ぶ。
- 接続が切れると登録が外れ、別の connector が選ばれる。
3. 多重化(データプレーン)
1本の QUIC / HTTP/2 接続の上で、複数のリクエストをストリームとして多重化します。
- HTTP/2: 1本の TCP 接続上で複数ストリームを多重化する。
- QUIC: 1本の UDP 接続上で独立したストリームを多重化する。TCP の head-of-line blocking がない。
- WebSocket や TCP ベースのプロトコルも、ストリームとしてトンネル上に載る。
- UDP をトンネルで運ぶ場合は、QUIC の datagram が使われる。
Cloudflare Tunnel は、オリジン側を transport client にした reverse HTTP 的なモデルです。通常の HTTP/2 ではクライアントがリクエストを開始しますが、トンネルでは役割が反転し、Cloudflare が確立済み接続上でリクエストを送り込みます。そのため、オリジン側から新しい inbound 接続を張る必要がありません。
4. オリジン側で起きること
cloudflared は 127.0.0.1:3000 や 10.0.0.50:5432 などへ新規のローカル接続を張ります。これはインターネットからの inbound ではなく、cloudflared プロセスからのローカル / プライベート接続です。
- サービスは
127.0.0.1で待ち受けることができる。 - インターネットから直接到達する待ち受けポートは不要。
- ホスト型ファイアウォールの inbound ルールも不要。
5. シーケンス
6. なぜ「inbound ポートを開けない」と言えるのか
| 層 | 何が起きるか |
|---|---|
| L3/L4 | cloudflared → Cloudflare の outbound flow が確立し、NAT / firewall が状態を保持する |
| トンネル制御 | cloudflared がトンネルトークンで認証し、connector として登録される |
| 多重化 | Cloudflare が既存接続上にストリームを作り、リクエストを流す |
| アプリ | cloudflared がローカルサービスへ接続し、レスポンスを返す |
「inbound ルールがない」は、インターネットから新しいコネクションを受け付けないという意味です。既存の outbound コネクション上でアプリケーションデータが双方向に流れることとは矛盾しません。
NAT のアイドルタイムアウトで接続が切れないよう、cloudflared は keepalive を送ります。接続が切れた場合はバックオフしながら再接続し、複数の connector があればその間も別の connector がリクエストを受けられます。
要素技術 2: ルート(どこへ転送するか)
Tunnel に参加しただけでは、どのリクエストをどこへ転送するかは決まりません。それを決めるのが route です。代表的なルートは次の 2 種類です。
公開ホスト名(public hostname)
公開ホスト名ルートでは、Cloudflare 上の DNS レコードと Tunnel を紐づけます。
- DNS:
app.example.comの CNAME を<TUNNEL_UUID>.cfargotunnel.comに向ける(Proxied)。 - Tunnel の ingress:
app.example.com→http://localhost:3000のように転送先を指定する。 - 利用者はブラウザだけでアクセスできる(Cloudflare One Client 不要)。
- ただし、Access を設定しない限り、そのホスト名は誰でも到達できる公開アプリになる。
利用者 → Cloudflare エッジ → Access → Tunnel → cloudflared → localhost:3000
プライベートネットワークルート(private network route)
プライベート IP / CIDR やプライベートホスト名を Tunnel 経由で到達させるルートです。
- 例:
10.0.0.0/24を VM のプライベートネットワークへルーティングする。 - 利用者側に Cloudflare One Client(WARP) が必要。
- Client が Traffic and DNS モードで動作し、Gateway のリゾルバポリシーがプライベートホスト名を解決する。
- 通常のブラウザから直接
http://10.0.0.50へアクセスしても到達しない。
利用者 → Cloudflare One Client → Cloudflare エッジ → Access → Tunnel → cloudflared → 10.0.0.50
公開ホスト名とプライベートルートの比較
| 観点 | 公開ホスト名 | プライベートネットワークルート |
|---|---|---|
| 利用者のソフトウェア | ブラウザのみ(clientless) | Cloudflare One Client(WARP)または Cloudflare WAN |
| DNS | 公開 DNS の CNAME | Gateway リゾルバ / Local Domain Fallback / プライベートホスト名 |
| Access アプリ種別 | Self-hosted public | Self-hosted private destination / Infrastructure |
| 主な用途 | Web アプリ、API | SSH、DB、内部 IP レンジ、内部ホスト名 |
| オリジンの公開 | Cloudflare 経由で公開される | プライベートのまま |
ルートと Access は別物
- route は「どこへ転送するか」を決める。
- Access application / policy は「誰がアクセスできるか」を決める。
ルートを作っただけでは認証は付きません。Access アプリケーションとポリシーを別途設定する必要があります。
仮想ネットワーク(Virtual Network)
本番とステージングで同じ 10.0.0.0/24 を使うなど、IP レンジが重複する場合は、Virtual Network でルーティングドメインを分離します。Tunnel ルートを仮想ネットワークに割り当て、Cloudflare One Client 側で使用する仮想ネットワークを選択します。重複がない場合は、1 つの Tunnel に複数のルートを持たせられます。
要素技術 3: Zero Trust Access
Zero Trust の考え方
従来のネットワークセキュリティは「社内ネットワーク内なら信頼する」という境界モデルでした。Zero Trust はこれをやめ、リクエストのたびに身元と条件を検証するモデルです。
Cloudflare の文脈では、次のように役割が分かれます。
| 製品 | 守る対象 | 主な機能 |
|---|---|---|
| Cloudflare Access | アプリケーションへのアクセス | IdP 認証、ポリシー評価、JWT 発行 |
| Cloudflare Gateway | 端末から出るトラフィック | DNS / HTTP / ネットワークポリシー、TLS 検査 |
| Cloudflare Tunnel | オリジンへの経路 | アウトバウンド接続、ルーティング |
| Cloudflare One Client(WARP) | 端末側のオンプランプ | プライベートルート、DNS、Gateway への転送 |
Access は「アプリの認証・認可」、Gateway は「通信のフィルタリング」です。両者は別物で、必要に応じて併用します。
Access アプリケーションの種類
| 種類 | Cloudflare One Client | 対象 |
|---|---|---|
| Self-hosted public | 不要(clientless) | 公開ホスト名の Web アプリ・API |
| Self-hosted private destination | 通常必要 | プライベート IP / CIDR / ホスト名 |
| Infrastructure | 必須 | SSH などのプロトコル単位の制御 |
公開ホスト名のアプリは、利用者がブラウザでログインするだけで使えます。一方、プライベート IP や SSH は、端末側に Cloudflare One Client が必要です。
ポリシーの評価モデル
Access ポリシーは「アクション」と「ルール」の組み合わせです。
| 要素 | 意味 |
|---|---|
| Action | Allow / Block / Bypass / Service Auth |
| Include | OR 条件。いずれかを満たせばよい |
| Require | AND 条件。すべてを満たす必要がある |
| Exclude | NOT 条件。該当すると拒否 |
重要な性質は次のとおりです。
- デフォルト拒否: どの Allow ポリシーにも一致しない利用者は拒否される。
- 各ポリシーには最低 1 つの Include ルールが必要。
BypassとService Authが先に評価され、その後Block/Allowが上から順に評価される。- 一度 Allow または Block に一致すると評価が止まる。後続のポリシーで上書きできない。
Bypassは Access の強制を無効化するため、原則として限定的に使う。
認証の流れ
Access JWT の検証
Access は、認可済みのリクエストに Cf-Access-Jwt-Assertion ヘッダーを付けてオリジンへ転送します。ブラウザ経由の場合は CF_Authorization Cookie も使われますが、オリジン側ではヘッダーの JWT を検証するのが確実です。
検証の手順は次のとおりです。
Cf-Access-Jwt-Assertionヘッダーから JWT を取り出す。https://<TEAM_NAME>.cloudflareaccess.com/cdn-cgi/access/certsから公開鍵(JWKS)を取得する。- JWT の
kidに一致する鍵を選ぶ。 - RS256 署名を検証する。
iss(チームドメイン)、aud(アプリケーションの AUD タグ)、exp(有効期限)を検証する。
Access の署名鍵は定期的にローテーションされるため、鍵をハードコードせず、JWKS エンドポイントから動的に取得してください。aud を検証しないと、別の Access アプリ向けに発行されたトークンを使い回される可能性があります。
Tunnel 経由のリクエストは Access を通っていますが、オリジンが別経路(プライベートネットワーク内など)から到達できる場合、ヘッダーを偽装したリクエストが届く可能性があります。オリジン側で JWT を検証しておくと、多層防御になります。
サービス間通信
人間のユーザーではなく、CI/CD やバッチ処理からアクセスする場合は、サービス トークンや mTLS を使います。Access ポリシーの Service Auth アクションで、IdP を介さない認証を設定できます。
なぜインバウンドルールが不要なのか
ネットワーク層の理由
cloudflared は VM から Cloudflare へ接続を開始します。多くのクラウドのセキュリティグループやステートフルなファイアウォールでは、アウトバウンドで開始した接続の戻りトラフィックが自動的に許可されます。
そのため、次のような設定は不要です。
- インターネットからの TCP 443 / 22 のインバウンド許可
- パブリック IP の割り当て
- ポートフォワーディング
- リバースプロキシをインターネットに公開するための LB
セキュリティ上の意味
- オリジンの IP を隠せる: 利用者は Cloudflare のエッジにしか接続しない。
- 攻撃面が減る: VM 上にインターネット向けの待ち受けポートがない。
- 認証がネットワークの手前で行われる: Access が IdP 認証とポリシー評価を済ませてからオリジンへ転送する。
- DDoS / TLS 終端を Cloudflare 側で吸収できる: 必要に応じて WAF やレート制限も追加できる。
ただし「inbound 不要」の落とし穴
| 誤解 | 実際 |
|---|---|
| アウトバウンドのみ = データも一方向 | 接続開始が outbound なだけで、確立後は双方向 |
| inbound 不要 = ホストファイアウォールも不要 | オリジンは 127.0.0.1 にバインドし、ホスト側の防御は残す |
| Tunnel を作れば安全 | Access ポリシーを設定しなければ公開アプリになる |
| Access を設定すればルートもできる | route と Access application は別々に設定する |
| Tunnel は VPN の代替 | アプリ / ルート単位のリバースプロキシ。L3 VPN が必要なら Cloudflare WAN / Mesh を検討 |
| トークンはただの設定値 | Tunnel に connector を参加させるベアラ資格情報 |
VPN とのセキュリティ強度の比較
比較の前提
「Cloudflare Tunnel 対 VPN」は、厳密には同じレイヤーの比較ではありません。
- VPN は L3/L4 のネットワーク接続を提供する。
- Cloudflare Tunnel はアプリケーション / ルート単位のリバースプロキシ / トンネルであり、利用者の認証・認可は Access が担う。
- したがって、比較すべきは「従来型 VPN」対「Cloudflare Tunnel + Access」です。
- Tunnel だけでは利用者認証はないため、VPN の代替にはなりません。
ここでは、一般的な従来型 VPN(IPsec / SSL VPN)を想定しています。近年の VPN 製品には ZTNA 的な機能を持つものもあるため、製品によって強度は異なります。
比較表
| 観点 | 従来型 VPN | Cloudflare Tunnel + Access |
|---|---|---|
| 接続単位 | ネットワーク(L3) | アプリケーション / ルート単位(公開ホスト名は L7、プライベートルートは L3/L4 相当) |
| 認証 | VPN 接続時に認証 | アプリごとに IdP 認証。MFA は IdP、デバイスポスチャは Cloudflare One Client で指定可能 |
| 認可 | ルーティング / FW でネットワーク単位 | Access ポリシーでアプリ単位。デフォルト拒否 |
| 露出面 | VPN ゲートウェイの公開エンドポイント | オリジンに inbound なし。Cloudflare エッジが公開面 |
| ラテラルムーブメント | 接続後に広い内部ネットワークへ到達しやすい | 許可されたアプリ / ルートだけ |
| 監査 | 接続ログ中心 | 認証・認可の判定ログ(Access) |
| クライアント | VPN クライアント | ブラウザ(公開ホスト名)または Cloudflare One Client |
| 対応プロトコル | IP 全般 | HTTP は公開ホスト名、TCP/UDP はプライベートルート / WARP |
| 暗号化 | IPsec / TLS | QUIC / TLS。ユーザー TLS は Cloudflare で終端されやすい |
| 障害点 | VPN 装置 | Cloudflare + connector + オリジン |
| 運用 | 装置のパッチ / 証明書 | cloudflared の更新 / トークン / ポリシー |
| 第三者依存 | 自社運用なら小さい | Cloudflare への依存が大きい |
「どちらが強いか」の考え方
- 最小権限の観点では Tunnel + Access が有利。ネットワーク全体ではなく、アプリ単位で認可できる。VPN は接続後に広い範囲へ到達できるため、侵害時の blast radius が大きくなりやすい。
- 認証の強度は IdP 次第。Access は IdP の MFA / パスキーに加え、Cloudflare One Client のデバイスポスチャを使える。VPN も mTLS / 証明書 / MFA を組み合わせれば強くできる。製品名ではなく、設定で決まる。
- 公開面の縮小は Tunnel が有利。VPN ゲートウェイはインターネットに待ち受ける必要がある。Tunnel はオリジンに inbound を持たない。
- 第三者依存とデータ可視性は VPN が有利な場合がある。Cloudflare のエッジで TLS が終端されるため、Cloudflare を完全に信頼しない要件では、アプリ層のエンドツーエンド暗号化など追加の対策が必要。
- 広い L3 接続やレガシープロトコルは VPN / Cloudflare WAN / Mesh の方が向いている。Tunnel + Access はアプリ単位の公開に向く。
まとめ: アプリ単位の最小権限と公開面の縮小を重視するなら Tunnel + Access、広い L3 接続やレガシープロトコルを扱うなら VPN / Cloudflare WAN / Mesh が向きます。どちらも、IdP の MFA、端末管理、認可の粒度、監査、鍵管理といった設定で強度が決まります。
強度を決める要因
| 要因 | 弱い例 | 強い例 |
|---|---|---|
| 認証 | パスワードのみ | パスキー / ハードウェアキー + MFA |
| 認可 | 全社員に全アプリ | グループ単位の最小権限、デフォルト拒否 |
| 端末 | 任意の端末 | デバイスポスチャ / EDR / 暗号化必須 |
| 公開面 | VPN ゲートウェイ + オリジン公開 | オリジン inbound なし + Access |
| 監査 | 接続ログのみ | 認証・認可ログ + SIEM |
| 鍵管理 | 静的トークン / 共有アカウント | 短命資格情報 / ローテーション / サービス トークン |
| 障害時 | 単一 VPN 装置 | 複数 connector / 複数経路 |
Cloudflare Tunnel は「経路」を提供するだけで、利用者の認証・認可は行いません。Access を設定しない公開ホスト名は、誰でもアクセスできる公開アプリになります。
Azure / AWS における類似サービス
「同じプロトコル」の意味
Cloudflare Tunnel のワイヤプロトコルは、QUIC(UDP 7844)と HTTP/2(TCP 7844)です。本稿で確認した範囲では、Azure / AWS に、オリジン側エージェントが同じ QUIC/7844 でクラウドへ接続するマネージドサービスは見当たりません。
一方で、**「オリジン側からアウトバウンド接続を開始し、クラウド側がその接続上でリクエストを流す」**というリバーストンネルの接続モデルは共通しています。ここでは、このモデルを持つサービスを比較します。
比較表
| クラウド | サービス | トランスポート | オリジン側 | 認証 / 認可 | 主な用途 |
|---|---|---|---|---|---|
| Azure | Microsoft Entra Private Access(Private Network Connector) | TLS over TCP 443(80 は CRL 用) | Windows Server 上の connector | Entra ID + 条件付きアクセス | アプリ / プライベートネットワークへの ZTNA |
| Azure | Azure Arc SSH access | TCP 443 | Azure Connected Machine agent | Entra ID / Azure RBAC | Arc 有効サーバへの SSH |
| Azure | Azure Relay Hybrid Connections / App Service Hybrid Connections | WebSocket over TCP 443(TLS 1.2) | Hybrid Connection Manager / listener | SAS キー | オンプレサービスへのリレー |
| Azure | Azure VPN Gateway | IPsec/IKE / SSL | VPN gateway | 証明書 / RADIUS など | 拠点間・P2S の L3 接続 |
| AWS | AWS Verified Access | HTTPS(クライアント→エンドポイント) | なし(VPC 内の internal LB / ENI) | IAM Identity Center / OIDC / SAML + デバイスポスチャ | Web アプリ / TCP アプリの ZTNA |
| AWS | AWS Systems Manager Session Manager | HTTPS/TLS 1.2 over TCP 443 | SSM Agent | IAM | EC2 / オンプレへの管理アクセス、ポートフォワード |
| AWS | AWS Client VPN / Site-to-Site VPN | IPsec / TLS | VPN endpoint | 証明書 / AD など | L3 接続 |
Microsoft Entra Private Access
- Windows Server 上の Private Network Connector が、TCP 80 / 443 で
*.msappproxy.net/*.servicebus.windows.netへアウトバウンド接続する。 - connector は outbound のみ。inbound ポートは不要。セッション確立後は双方向に通信する。
- connector group でアプリごとに分離し、HA には 2 台以上を推奨。
- 利用者は Global Secure Access client 経由でアクセスし、Entra ID の認証・条件付きアクセス・デバイスポスチャを適用できる。
- HTTP/HTTPS だけでなく、TCP/UDP のプライベートアプリにも対応する。
Cloudflare Tunnel との違い: Cloudflare は Linux / コンテナ / オンプレで動く cloudflared を使い、公開ホスト名は clientless でアクセスできる。Entra Private Access は Windows Server コネクタとクライアント側ソフトウェアが中心。
Azure Arc SSH access
- Azure Connected Machine agent が TCP 443 で Azure へアウトバウンド接続する。
az ssh arcなどで、パブリック IP や inbound SSH ポートなしに Arc 有効サーバへ SSH できる。- Entra ID ログインや RBAC と組み合わせられる。
- 管理アクセス専用で、Web アプリの公開や Access のようなアプリ単位の認可は行わない。
Azure Relay Hybrid Connections / App Service Hybrid Connections
- Azure Relay Hybrid Connections では、オンプレ側の listener アプリケーションが TCP 443 の WebSocket で Azure Relay へアウトバウンド接続する。
- App Service Hybrid Connections では、Hybrid Connection Manager(HCM) が同じく outbound 443 で Azure Relay へ接続する。
- クラウド側の送信者が Relay のエンドポイントへ送り、Relay が既存の双方向ソケットへ中継する。inbound ポートは不要。
- TLS 1.2 と SAS キーで認証する。
- App Service Hybrid Connections は、App Service からオンプレの TCP エンドポイントへ接続する用途。UDP や動的ポートは扱えない。
Cloudflare Tunnel との違い: Relay はトランスポートであり、利用者認証や Access 相当のアプリ単位ポリシーは持たない。Cloudflare は Access と組み合わせて ZTNA になる。
AWS Verified Access
- Verified Access instance / group / endpoint と trust provider で構成する。
- エンドポイントは VPC 内の internal load balancer、network interface、network CIDR、RDS に接続する。アプリにパブリック IP や inbound インターネットポートは不要。
- リクエストごとに Cedar ポリシーを評価し、IdP の身元とデバイスポスチャを確認する。
- HTTP/HTTPS の Web アプリに加え、TCP(SSH / RDP など)は network interface / CIDR endpoint で扱える。
- すべてのアクセス試行をログに記録する。
Cloudflare Tunnel との違い: Verified Access はオリジン側にエージェントを置かず、AWS が VPC 内にリバースプロキシを配置する。AWS の VPC / ALB / ENI が前提で、他クラウドやオンプレの VM をそのまま公開する用途には向かない。
AWS Systems Manager Session Manager
- SSM Agent が
ssm.<region>.amazonaws.com/ssmmessages.<region>.amazonaws.com/ec2messages.<region>.amazonaws.comへ HTTPS 443 でアウトバウンド接続する。 - パブリック IP、踏み台、inbound SSH ポートは不要。
- IAM で認可し、CloudTrail / S3 / CloudWatch Logs にセッションを記録できる。
- シェルアクセス、SSH / RDP ポートフォワード、トンネリングに対応する。
Cloudflare Tunnel との違い: 管理セッション専用で、Web アプリの公開や利用者向けのアプリ単位認可には使わない。Cloudflare は Access と組み合わせてアプリ公開もできる。
VPN サービスとの違い
Azure VPN Gateway / AWS Client VPN / AWS Site-to-Site VPN は、ネットワーク単位(L3) の接続を提供する。VPN ゲートウェイはインターネットに待ち受ける必要があり、接続後は広いネットワークへ到達しやすい。アプリ単位の最小権限や clientless アクセスが要件なら、Tunnel + Access や Entra Private Access / Verified Access の方が適する。
選び方
| 要件 | 候補 |
|---|---|
| 任意のクラウド / オンプレの VM をアプリ単位で公開 | Cloudflare Tunnel + Access |
| Entra ID 中心で Windows Server コネクタを使える | Microsoft Entra Private Access |
| Azure Arc 有効サーバへの SSH | Azure Arc SSH access |
| Azure 上のアプリからオンプレ TCP サービスへ接続 | Azure Relay / App Service Hybrid Connections |
| AWS 内の Web / TCP アプリを ZTNA で公開 | AWS Verified Access |
| AWS EC2 / オンプレへの管理アクセス | AWS Systems Manager Session Manager |
| 拠点間 / 全プロトコルの L3 接続 | VPN / Cloudflare WAN / Mesh |
Cloudflare Tunnel の強みは、クラウド非依存で Linux / コンテナ / オンプレのどこでも動き、公開ホスト名なら clientless、プライベートルートなら Cloudflare One Client でアクセスできる点です。Azure / AWS の類似サービスは、それぞれのエコシステム(Entra ID、AWS VPC / IAM)に最適化されています。
セキュリティ的に弱いところと対策
脅威モデル
| 資産 / 弱点 | 想定する脅威 | 影響 | 主な対策 |
|---|---|---|---|
| トンネルトークン | 漏えい・窃取 | 攻撃者が connector を追加し、トンネルに参加 | ファイル権限 600、秘密管理、定期ローテーション、漏えい時の強制切断 |
| Cloudflare アカウント | アカウント乗っ取り | ルート / Access ポリシーの改ざん | SSO + ハードウェアキー、最小権限ロール、API トークン制限、監査ログ |
| Access ポリシー | 設定ミス / Bypass の乱用 | 未認証アクセス | デフォルト拒否、全ホスト名に Access、Bypass を避ける、定期レビュー |
| オリジン | 別経路からの直接到達 | Access の迂回 | 127.0.0.1 バインド、ホスト FW、ネットワーク分離、JWT 検証 |
| IdP / セッション | フィッシング / セッション窃取 | なりすまし | パスキー / FIDO2、条件付きアクセス、短いセッション、失効 |
| cloudflared / ホスト | 侵害 / サプライチェーン | トンネル内からの横移動 | 署名検証、更新、最小権限、専用ユーザー、EDR |
| データ経路 | Cloudflare での TLS 終端 | 第三者による可視性 | アプリ層のエンドツーエンド暗号化、要件に応じた経路選択 |
| 可用性 | Cloudflare / egress 障害 | アクセス断 | 複数 connector、監視、代替経路、Runbook |
| ログ / 監査 | ログ不足 | インシデント検知の遅れ | Access / Gateway / cloudflared ログを SIEM へ |
| プライベートルート | 広すぎる CIDR | WARP 端末からの過剰到達 | CIDR 最小化、Virtual Network、Gateway ポリシー |
| SSH | 静的鍵 / 共有アカウント | 鍵漏えい・監査不能 | 短命証明書、Infrastructure Access、コマンドログ |
1. トンネルトークンの漏えい
トンネルトークンは ベアラ資格情報です。持っている人は誰でも、その Tunnel に connector を参加させられます。
--tokenをコマンドラインに直接書くと、psやシェル履歴に残る。--token-fileか秘密管理機構を使う。- トークンファイルは
root:root 600など、最小限の読み取り権限にする。 - Git、CI のログ、チャット、コンテナイメージに含めない。
- 定期的にローテーションする。既存の connector は古いトークンでも動き続けるため、新しいトークンを半分の replica に入れ、10 分ほど待ってから残りに入れると無停止で切り替えられる。
- 漏えい時は、トークンを更新したうえで Tunnel の全接続を強制切断し、正規の replica を新しいトークンで再インストールする。
- ダッシュボードで想定外の connector が参加していないか監視する。
2. Cloudflare アカウントの侵害
Cloudflare アカウントは制御プレーンです。アカウントを奪われると、ルートの追加や Access ポリシーの変更ができてしまいます。
- Cloudflare アカウント自体に SSO / ハードウェアキー / MFA を必須にする。
- 管理者ロールを最小限にし、Tunnel 管理者・DNS 管理者・Access 管理者を分ける。
- API トークンはリソーススコープを絞り、有効期限を設定する。
- 監査ログを SIEM に送り、Tunnel / Access / DNS の変更をアラートする。
- 本番と非本番で Cloudflare アカウントを分ける。
3. Access ポリシーの設定ミス
Access はデフォルト拒否ですが、Allow の条件が広すぎると意味がありません。
- 公開ホスト名に Access アプリケーションを付け忘れると、そのまま公開アプリになる。
Everyoneや全社ドメインの Allow は、実質的に「組織内は全員アクセス可」になる。Bypassは Access の強制を無効化し、リクエストもログに残らない。原則として使わない。- ワイルドカードやパス単位の設定は、最も具体的な一致が優先される。意図したアプリだけが対象か確認する。
- グループベースで最小権限にし、四半期ごとにレビューする。
- 認可されないユーザーで実際にアクセスできないことをテストする。
- オリジン側でも JWT を検証するか、Tunnel の Protect with Access を有効にして迂回を防ぐ。
4. オリジンへの直接到達
Tunnel を通らない経路が残っていると、Access を迂回できます。
- オリジンのサービスは
127.0.0.1またはプライベートインターフェースにバインドする。 - ホスト型ファイアウォールで、不要な inbound を拒否する。
- 同じサービスを別の LB / パブリック IP / 別のネットワーク経路で公開しない。
- プライベートネットワーク内から到達できる場合は、
Cf-Access-Jwt-Assertionの偽装が可能。オリジンで JWT を検証する。 - 他のリバースプロキシやアプリが
Cf-Access-*ヘッダーをそのまま信用しない。信頼境界で削除・再付与する。
5. IdP / セッションの侵害
Access の認証強度は IdP に依存します。
- パスキー / FIDO2 など、フィッシング耐性のある MFA を使う。
- 条件付きアクセスで、場所・端末・リスクに応じた制御を行う。
- セッション有効期限を短くし、侵害時はセッションを失効させる。
- 共有アカウントを避け、サービス間はサービス トークンを使う。
- 不審なログインや拒否ログを監視する。
6. cloudflared / ホストの侵害
cloudflared やホストが侵害されると、トンネル内のサービスへ横移動される可能性があります。
cloudflaredを最新版に保つ。--no-autoupdateの場合は手動更新の運用を決める。- 公式パッケージ / 署名済みバイナリを使い、取得元を検証する。
- 専用ユーザーで実行し、トークンファイルと systemd ユニットの編集権限を絞る。
- ホストに EDR / ログ監視を入れ、不要なサービスを停止する。
cloudflaredが到達できるローカルサービスを最小限にする。
7. データ経路と第三者依存
Cloudflare のエッジでユーザー TLS が終端されるため、Cloudflare はアプリケーションデータにアクセスし得ます(オリジンが HTTP の場合は平文)。
- オリジンまで HTTPS を使い、
noTLSVerifyはfalseのままにする。 - プライベート CA を使う場合は
caPool/originServerNameを正しく設定する。 - Cloudflare を信頼しない要件では、アプリケーション層でエンドツーエンド暗号化する。mTLS はオリジン認証には有効だが、Cloudflare エッジでの TLS 終端による可視性は解消しない。
- Access のログには「誰が・いつ・どのアプリへ」アクセスしたかのメタデータが残る。データ residency / 監査要件を確認する。
8. 可用性
Tunnel が切れると、Access もオリジンも到達できなくなります。
- 本番は複数の connector を別ホストで動かす。
- 公開ホスト名で高度なフェイルオーバーが必要なら Cloudflare Load Balancer を使う。
- Cloudflare / egress / DNS の障害を監視し、Runbook を用意する。
- 管理アクセスの唯一の経路にしない。必要なら break-glass の経路を別に用意する。
9. ログと検知
- Access の認証・認可ログ、Gateway の通信ログ、
cloudflaredのログ、Cloudflare の監査ログを収集する。 - SIEM に送り、次のイベントをアラートする。
- 新しい connector の参加
- トンネルトークンのローテーション / 強制切断
- Access ポリシー / ルート / DNS の変更
- 拒否の急増、通常と異なる地域・端末からのアクセス
- ログの保持期間をコンプライアンス要件に合わせる。
10. プライベートルートと SSH
- プライベートルートの CIDR は最小限にする。
0.0.0.0/0のような広いルートを避ける。 - 重複する IP レンジは Virtual Network で分離する。
- Cloudflare One Client のデバイスポスチャ / Split Tunnel / Gateway ポリシーを併用する。
- SSH は静的鍵の共有を避け、Infrastructure Access の短命証明書・コマンドログ・特権アクセス管理を使う。
- ホスト鍵の検証を有効にする。
設定チェックリスト
| 項目 | 確認内容 |
|---|---|
| 公開ホスト名 | すべてに Access アプリケーションがある |
| Access ポリシー | グループベースの最小権限。Everyone や過度なワイルドカードがない |
| Bypass | 原則使用していない |
| オリジン | 127.0.0.1 / プライベートにバインドし、直接到達経路がない |
| JWT | オリジン検証または Protect with Access を有効化 |
| トークン | 600 / 秘密管理。コマンドラインや Git にない |
| ローテーション | 手順と実行者が決まっている。漏えい時の強制切断手順がある |
| Cloudflare アカウント | MFA / 最小権限 / 監査ログ / API トークン制限 |
cloudflared | 最新版。署名 / パッケージを検証。専用ユーザーで実行 |
| 冗長化 | 別ホストの複数 connector。監視とアラートがある |
| ログ | Access / Gateway / cloudflared / 監査ログを SIEM に送っている |
| TLS | noTLSVerify が false。必要ならアプリ層暗号化(mTLS はオリジン認証) |
| プライベートルート | CIDR が最小化され、Virtual Network / Gateway ポリシーがある |
| SSH | 短命証明書 / コマンドログ / ホスト鍵検証 |
オリジン側の通信要件
クラウドのセキュリティグループ、ネットワーク ACL、ファイアウォールなどで egress を制限している場合は、次の通信を許可します。
| 方向 | プロトコル / ポート | 宛先 | 用途 |
|---|---|---|---|
| Outbound | UDP 7844 | region1.v2.argotunnel.com / region2.v2.argotunnel.com | QUIC(主経路) |
| Outbound | TCP 7844 | 同上 | HTTP/2(フォールバック) |
| Outbound | TCP 443 | api.cloudflare.com | 管理 API / precheck |
| Outbound | UDP/TCP 53 | DNS リゾルバ | 名前解決 |
| Inbound | なし | — | 不要 |
補足:
- ホスト名ベースで許可するのが確実です。Cloudflare は固定 CIDR を保証していないため、IP アドレスをハードコードすると将来の変更で接続できなくなる可能性があります。
- プライベートサブネットの VM は、NAT ゲートウェイやプロキシ経由でインターネットへ出られるようにします。パブリック IP は不要です。
- 多くの環境ではデフォルトの egress ルールが全通信を許可していますが、制限している場合は上記を明示的に追加してください。
- IPv6 のみの環境では
--edge-ip-versionの設定も確認します。
運用
サービスの状態確認
systemctl status cloudflared
journalctl -u cloudflared -n 100 --no-pager
journalctl -u cloudflared -f
起動時に precheck が実行され、DNS・UDP(QUIC)・TCP(HTTP/2)・管理 API の到達性が確認されます。Environment is healthy と suggested_protocol=quic が出ていれば正常です。
冗長化
- 1 つの connector は 4 本の接続を、少なくとも 2 つのデータセンターに対して張る。
- 同じ Tunnel に replica を追加すると、合計の接続数が増える。
- ホスト障害に備えるには、別々のホストで replica を動かす。
- Cloudflare は最寄りの replica に転送し、失敗時は他の replica を試す。厳密なラウンドロビンではない。
- 公開ホスト名で高度な負荷分散やヘルスチェックベースのフェイルオーバーが必要なら Cloudflare Load Balancer を使う。プライベートホスト名ルートは Load Balancer と互換性がないため、replica で冗長化する。
更新
--no-autoupdate を指定している場合、cloudflared は自動更新されません。バイナリまたはパッケージマネージャで更新し、サービスを再起動します。更新中は接続が切れる可能性があるため、replica を用意したうえでローリング更新するのが望ましいです。
監視
--metricsを指定すると Prometheus 形式のメトリクスを公開できる。--log-directoryを使うとログローテーション(1 MB × 5 世代)が有効になる。- Cloudflare ダッシュボードの Tunnel 状態と Analytics で、connector の死活監視ができる。
- オリジン側では、
cloudflaredのログとアプリケーションのログを別々に確認できるようにしておく。
最小権限
cloudflaredは特権ポートを待ち受けないため、専用ユーザーで動かせる場合が多い。- トンネルトークンファイルは root のみ読み取り可能にする(例:
600)。 - オリジンのサービスは
127.0.0.1にバインドし、プライベートネットワーク内からの不要な到達も抑える。 - Access ポリシーはグループ単位で管理し、個人メールの列挙を避ける。
トラブルシューティング
| 症状 | 主な原因 | 確認ポイント |
|---|---|---|
| Cloudflare の 1033 | Tunnel が接続していない | systemctl status cloudflared、egress 7844、トークン、DNS |
| 502 / 530 | Tunnel は正常だがオリジンに到達できない | ingress の service URL、アプリの待ち受けポート、ホスト側 firewall |
| 403 | Access のデフォルト拒否 / ポリシー不一致 | Access アプリのホスト名、Allow ポリシー、IdP グループ |
| 404 | ルート / ingress の不一致 | 公開ホスト名、CNAME、Tunnel の ingress 設定 |
| ログインがループする | Cookie / チームドメイン / アプリ設定の不整合 | CF_Authorization、Access のアプリ設定、ブラウザの Cookie |
| QUIC は失敗するが HTTP/2 は成功 | UDP 7844 がブロックされている | auto のままか、--protocol quic を強制していないか |
| SSH できない | sshd / ルート / クライアント側の経路の問題 | sshd の待ち受け、ingress、cloudflared access ssh または Cloudflare One Client、Access ポリシー |
| トークンが読めない | ファイル権限 / 実行ユーザー | /etc/cloudflared/token の所有者とパーミッション、systemd の実行ユーザー |
リモート管理 Tunnel では、cloudflared tunnel info などのローカル管理用コマンドが使えない場合があります。その場合はダッシュボードの Tunnel 状態と journalctl を確認してください。
理解のまとめ
| ポイント | 説明 |
|---|---|
| 接続の開始方向 | cloudflared(connector)が Cloudflare へ outbound 接続を開始する。Tunnel は Cloudflare 上の論理オブジェクト |
| 認証 | Access が IdP 認証とポリシー評価を行う。公開ホスト名かプライベート宛先かで利用者側の経路が変わる |
| インバウンド | オリジン側にインバウンドルールは不要。ただし egress の 7844 / 443 / DNS は必要 |
| データの方向 | outbound-only は接続開始方向の話であり、確立後は双方向に通信する |
設計時の確認事項
- 利用者は ブラウザだけでアクセスしているか、それとも Cloudflare One Client を入れているか。→ 公開ホスト名かプライベートルートかで変わる。
- アクセス先は Web アプリか、SSH / DB か。→ アプリケーション種別とクライアント要件が変わる。
- Access ポリシーは誰を許可しているか。→ デフォルト拒否なので、Allow に一致しないと入れない。
- オリジンは どこにバインドしているか。→
127.0.0.1ならインターネットから直接到達できない。 - トークンは誰が読めるか。→ ベアラ資格情報なので、ファイル権限とローテーションを確認する。
関連技術
| 技術 | いつ必要か |
|---|---|
| Cloudflare One Client(WARP) | プライベート IP / CIDR / ホスト名へアクセスする場合 |
| Cloudflare Gateway | 端末の DNS / HTTP / ネットワーク通信をポリシーで制御する場合 |
| Cloudflare WAN / Mesh | 拠点間や L3 のプライベートネットワーク接続が必要な場合 |
| Infrastructure Access | SSH の短命証明書、コマンドログ、特権アクセス管理が必要な場合 |
| Browser Rendering | クライアントソフトを入れずにブラウザから SSH / RDP / VNC を使う場合 |
| Cloudflare Load Balancer | 複数 Tunnel 間のヘルスチェック付きフェイルオーバーが必要な場合 |
| サービス トークン / mTLS | CI/CD やサービス間の非人間アクセス |
| Entra ID | Access の IdP として利用できる(OIDC / SAML) |
Azure との対比
| 目的 | Azure の近い概念 | Cloudflare の構成 |
|---|---|---|
| VM へのプライベート接続 | VPN Gateway / ExpressRoute | Cloudflare Tunnel(アプリ単位) / Cloudflare WAN(拠点単位) |
| 管理者の SSH / RDP | Azure Bastion | Access + Tunnel / Infrastructure Access / Browser Rendering |
| ネットワーク ACL | NSG / Azure Firewall | Access ポリシー + Gateway |
| 身元基盤 | Entra ID | IdP(Entra ID も利用可能) |
これらは完全な同義語ではありません。Azure Bastion は管理用の踏み台、Cloudflare Access はアプリケーション単位の認証プロキシであり、守るレイヤーが異なります。
参考リンク
Cloudflare
- Cloudflare Tunnel
- Tunnel connectivity prechecks
- Tunnel with firewall
- Tunnel availability
- cloudflared run parameters
- Tunnel permissions
- Origin parameters
- Choose an application type
- Access policies
- Validating Access JWT
- SSH with Cloudflare Tunnel
- Private hostname routes
- Tunnel virtual networks
- Reverse HTTP (IETF 118)
Azure
- Microsoft Entra private network connectors
- SSH access to Azure Arc-enabled servers
- Azure Relay
- App Service Hybrid Connections