Cloudflare Tunnelとは?ngrokとの違いとQuick Tunnelの使い方

システム開発

はじめに

外部のクラウドサービスから、社内ネットワークや自宅のパソコンで動いているWebサーバへ、Webhookを送信したいことがあります。

しかし、通常はネットワークとインターネットの間にファイアウォールが設置されており、インターネット側から内部のサーバへ直接アクセスすることはできません。

一般的な方法は、ファイアウォールで受信ポートを開放し、公開IPアドレスやDNSを設定することです。ただし、会社のネットワークでは、ファイアウォールの設定変更に申請やセキュリティ審査が必要になります。

そこで候補になるのが、内部のサーバから外部サービスへ接続を確立する「リバーストンネル」です。

今回は、リバーストンネルを構築できるサービスの一つであるCloudflare Tunnelについて、基本的な仕組みとngrokとの違いを整理します。

後半では、Cloudflareのアカウントや独自ドメインを使用せずに試せる「Quick Tunnel」を使い、ローカル環境で動かしているWebhook受信サーバをインターネットへ一時的に公開します。

本記事で実施すること

次の流れでCloudflare Tunnelを試します。

  1. Cloudflare Tunnelの仕組みを確認する
  2. 通常のポート開放との違いを確認する
  3. ngrokとの違いを確認する
  4. Windows 11へcloudflaredをインストールする
  5. ローカル環境でWebhook受信サーバを起動する
  6. Quick Tunnelで一時的な公開URLを発行する
  7. インターネット経由でWebhookを送信する

Cloudflare Tunnelとは

Cloudflare Tunnelは、ローカル環境や社内ネットワーク内のサーバと、Cloudflareのネットワークを接続するサービスです。

サーバ側にcloudflaredという軽量なプログラムをインストールすると、cloudflaredがCloudflareのネットワークへ外向きの接続を確立します。

Cloudflare Tunnelでは、サーバにインターネットから到達できる公開IPアドレスを割り当てなくても、ローカルのWebサーバやAPIをCloudflare経由で公開できます。

基本的な通信経路は、次のようになります。

cloudflaredは、内部ネットワーク側からCloudflareへ接続します。

外部からファイアウォールの受信ポートに直接接続する方式ではありません。cloudflaredが確立した接続を利用して、Cloudflareが受け取ったリクエストをローカルのWebサーバへ転送します。

通常のポート開放との違い

通常のポート開放では、インターネット側から内部のサーバへ接続できるように、ファイアウォールやルーターへ受信規則を設定します。

一方、Cloudflare Tunnelでは、cloudflaredからCloudflareへの外向き接続を利用します。

項目 通常のポート開放 Cloudflare Tunnel
接続を開始する側 インターネット側 内側ネットワーク側
公開IPアドレス 原則として必要 不要
受信ポートの開放 必要 原則不要
公開URL DNSなどを自分で設定 Cloudflare側で設定
通信の中継 なし Cloudflareが中継
外部サービスへの依存 比較的少ない Cloudflareに依存

Cloudflareの公式ドキュメントでは、ファイアウォールの受信通信を遮断し、cloudflaredに必要な外向き通信だけを許可する構成が説明されています。トンネルで外部公開されるのは、トンネル設定で指定したサービスです。

ただし、ここで注意が必要です。

受信ポートを開けないことと、外部から内部サービスへ到達できないことは同じではありません。

Cloudflare Tunnelを作成すると、インターネットからCloudflareを経由して、内部のWebサーバへ到達できる通信経路ができます。

そのため、会社のネットワークでCloudflare Tunnelを利用する場合は、ファイアウォール設定の変更が不要だったとしても、ネットワーク管理部門やセキュリティ部門の承認が必要です。

Cloudflare Tunnelの通信経路

たとえば、ローカル環境で次のWeb APIが動いているとします。

http://localhost:8080/webhook

このAPIは通常、同じパソコンからしか利用できません。

Cloudflare Tunnelを起動し、公開URLとローカルサービスを対応付けると、次のような経路でアクセスできるようになります。

固定ドメインを使った通常のCloudflare Tunnelでは、公開ホスト名とローカルサービスの対応関係を設定できます。

たとえば、次のような設定です。

https://webhook.example.com
  ↓
404 Not Found

Cloudflare Tunnelでは、1つの公開ホスト名を1つのローカルサービスへ転送するだけでなく、複数のアプリケーションを1つのトンネルで公開することもできます。

ngrokとの違い

ローカル環境をインターネットへ公開するサービスとしては、ngrokもよく知られています。

ngrokもCloudflare Tunnelと同様に、ローカル側でエージェントを動かし、エージェントからngrokのクラウドへ外向きの接続を確立します。公開URLへ届いた通信は、その接続を通ってローカルサービスへ転送されます。

つまり、両者の基本的な仕組みはよく似ています。

ngrokが向いているケース

ngrokは、次のような用途で使いやすいサービスです。

  • Webhookを短時間だけテストする
  • ローカルの開発画面をほかの人に見せる
  • コマンド一つで公開URLを取得する
  • APIのコールバックを開発環境で受信する

Cloudflare Tunnelが向いているケース

Cloudflare Tunnelは、次のような用途で候補になります。

  • Cloudflareで管理している独自ドメインを使用する
  • CloudflareのDNSやセキュリティ機能と組み合わせる
  • 複数のローカルサービスを公開する
  • 組織でトンネルを一元管理する
  • 継続的に使用する公開URLを設定する

Cloudflare Tunnelは単なる一時公開ツールというより、Cloudflareのネットワークとローカル環境を接続する仕組みとして設計されています。

一方、今回使用するQuick Tunnelは、ngrokで一時的な公開URLを発行する使い方に近い機能です。

Quick Tunnelとは

Quick Tunnelは、Cloudflareアカウントや独自ドメインを準備せずに、Cloudflare Tunnelを試せる機能です。

次のコマンドを実行すると、ランダムな文字列を含むtrycloudflare.comのURLが発行されます。

cloudflared tunnel --url http://localhost:8080

発行されるURLは、次のような形式です。

https://ランダムな文字列.trycloudflare.com

このURLへ届いたリクエストが、ローカル環境のhttp://localhost:8080へ転送されます。

Quick Tunnelは、Cloudflareの公式ドキュメントでもテスト・開発用途の機能と位置付けられています。本番環境では、管理対象の通常のトンネルを作成することが推奨されています。

Quick Tunnelを使ってみる

ここからは、Windows 11上で簡単なWebhook受信サーバを起動し、Quick Tunnelを使ってインターネットからアクセスします。

今回の検証環境

今回の検証では、次の環境を使用します。

項目 内容
OS Windows11
Webhook受信サーバ Python3
ローカルポート 8080
トンネル Cloudflare Quick Tunnel
公開対象パス /webhook

Pythonは追加ライブラリを使用せず、標準ライブラリだけでWebhook受信サーバを作成します。

手順1:cloudflaredをインストールする

Cloudflare Tunnelを利用するには、ローカル環境へcloudflaredをインストールします。

Windows版は、Cloudflare公式のダウンロードページから実行ファイルまたはMSI形式のインストーラーを取得できます。なお、Windows版のcloudflaredは自動更新されないため、継続利用する場合は更新方法も検討する必要があります。

インストール後、PowerShellまたはコマンドプロンプトを開き、次のコマンドを実行します。

cloudflared --version

バージョン情報が表示されれば、インストールは完了です。

cloudflared version 20xx.x.x

cloudflaredが見つからないというエラーが表示された場合は、次を確認します。

  • cloudflared.exeが保存されている場所
  • 環境変数PATHへ登録されているか
  • インストール後にターミナルを開き直したか

検証だけであれば、cloudflared.exeが保存されているフォルダーへ移動して、コマンドを実行しても構いません。

手順2:Webhook受信サーバを作成する

任意の作業フォルダーを作成し、webhook_receiver.pyという名前でファイルを作成します。

from http.server import BaseHTTPRequestHandler, HTTPServer
import json


class WebhookHandler(BaseHTTPRequestHandler):
    """POST /webhook でJSON形式のWebhookを受信する簡易サーバーです。"""

    def _send_json_response(self, status_code: int, data: dict) -> None:
        response_body = json.dumps(
            data,
            ensure_ascii=False
        ).encode("utf-8")

        self.send_response(status_code)
        self.send_header("Content-Type", "application/json; charset=utf-8")
        self.send_header("Content-Length", str(len(response_body)))
        self.end_headers()
        self.wfile.write(response_body)

    def do_POST(self) -> None:
        if self.path != "/webhook":
            self._send_json_response(404, {"error": "not found"})
            return

        try:
            content_length = int(self.headers.get("Content-Length", "0"))
        except ValueError:
            self._send_json_response(400, {"error": "invalid Content-Length"})
            return

        request_body = self.rfile.read(content_length)

        try:
            payload = json.loads(request_body.decode("utf-8"))
        except (json.JSONDecodeError, UnicodeDecodeError):
            self._send_json_response(400, {"error": "invalid JSON"})
            return

        print("\nWebhookを受信しました")
        print(json.dumps(payload, ensure_ascii=False, indent=2))

        self._send_json_response(202, {"status": "accepted"})

    def log_message(self, format: str, *args) -> None:
        """標準のアクセスログを見やすい形式で出力します。"""
        print(f"[HTTP] {self.address_string()} - {format % args}")


def main() -> None:
    host = "127.0.0.1"
    port = 8080

    server = HTTPServer((host, port), WebhookHandler)

    print("Webhook受信サーバーを起動しました")
    print(f"受信URL: http://{host}:{port}/webhook")
    print("終了する場合は Ctrl+C を押してください")

    try:
        server.serve_forever()
    except KeyboardInterrupt:
        print("\nWebhook受信サーバーを停止します")
    finally:
        server.server_close()


if __name__ == "__main__":
    main()

保存したら、PowerShellでファイルのあるフォルダーへ移動し、次のコマンドを実行します。

python webhook_receiver.py

次のように表示されれば、ローカルのWebhook受信サーバが起動しています。

Webhook受信サーバを起動しました
404 Not Found
終了する場合は Ctrl+C を押してください

このPowerShellは閉じずに、そのまま起動しておきます。

手順3:ローカル環境でWebhookをテストする

別のPowerShellを開き、次のコマンドを実行します。

curl.exe -X POST ` 
 -H "Content-Type: application/json" ` 
 -d '{\"message\":\"ローカルテスト\"}' ` 
 http://127.0.0.1:8080/webhook

正常に処理されると、送信側には次のようなレスポンスが表示されます。

{"status": "accepted"}

Webhook受信サーバ側には、受信したJSONが表示されます。

Webhookを受信しました
{
  "message": "ローカルテスト"
}

この時点では、同じパソコン内で通信しているだけです。まだインターネットからはアクセスできません。

手順4:Quick Tunnelを起動する

さらに別のPowerShellを開き、次のコマンドを実行します。

cloudflared tunnel --url http://127.0.0.1:8080

接続に成功すると、実行結果の中にtrycloudflare.comの公開URLが表示されます。

https://example-random-name.trycloudflare.com

実際には、毎回異なるランダムな文字列が使用されます。

Quick Tunnelを動作させているPowerShellも、閉じずに起動しておきます。PowerShellを閉じるかcloudflaredを停止すると、公開URLは利用できなくなります。

手順5:公開URLへWebhookを送信する

表示された公開URLの末尾に/webhookを追加し、Webhookを送信します。

curl.exe -X POST `
  -H "Content-Type: application/json" `
  -d '{\"message\":\"Cloudflare Tunnel経由のテスト\"}' `
  https://発行されたURL.trycloudflare.com/webhook

正常に処理されると、送信側には次のレスポンスが表示されます。

{"status": "accepted"}

Webhook受信サーバ側には、次のように表示されます。

Webhookを受信しました{
  "message": "Cloudflare Tunnel経由のテスト"
}

これで、インターネット上の公開URLへ送信したリクエストが、Cloudflare Tunnelを通って、ローカル環境のWebhook受信サーバへ届いたことを確認できました。

Quick Tunnelを利用する際の注意点

Quick Tunnelは簡単に利用できますが、本番環境には適していません。

URLが固定されない

Quick Tunnelを起動するたびに、ランダムな公開URLが発行されます。

外部サービスのWebhook URLとして継続的に登録する用途には向いていません。

稼働保証がない

Cloudflareは、Quick TunnelについてSLAや稼働時間を保証していません。あくまでもテスト・開発用の機能です。

同時リクエスト数などに制限がある

2026年7月時点の公式ドキュメントでは、Quick Tunnelで同時処理中にできるリクエスト数は200件までとされており、上限を超えるとHTTP 429が返ります。また、Server-Sent Eventsには対応していません。

URLを知っている人がアクセスできる

Quick Tunnelの公開URLはインターネットからアクセスできます。

今回作成したサンプルには認証機能がありません。そのため、公開URLを知っている人は誰でも/webhookへリクエストを送信できます。

実際のWebhook受信処理では、次の対策が必要です。

  • Webhook署名の検証
  • HMACシークレットの使用
  • タイムスタンプの検証
  • 古いリクエストの拒否
  • リクエストIDによる二重処理の防止
  • リクエストサイズの制限
  • レート制限
  • 受信データの入力チェック

Cloudflare Tunnelは通信経路を作る機能です。

Webhookの送信者が正しい相手かどうかは、Webhook受信アプリケーション側でも検証する必要があります。

Quick Tunnelが向いている用途

Quick Tunnelは、次のような短期間の検証に向いています。

  • Webhook受信処理の開発
  • 外部SaaSからのコールバック確認
  • ローカルAPIの疎通確認
  • スマートフォンからの表示確認
  • 開発中の画面を一時的に共有する
  • 外部サービスとの連携テスト

反対に、次の用途には向いていません。

  • 業務システムの本番運用
  • 固定URLが必要なWebhook
  • 機密情報を扱うAPI
  • 24時間365日の稼働が必要なサービス
  • 社内承認を得ていないサーバ公開
  • データを確実に受信・保存する必要がある連携

今回のまとめ

今回は、Cloudflare Tunnelの基本的な仕組みと、Quick Tunnelを使ったWebhook受信方法を確認しました。

Cloudflare Tunnelでは、ローカル環境で動くcloudflaredがCloudflareへ外向き接続を確立します。そのため、公開IPアドレスをサーバへ割り当てたり、ファイアウォールの受信ポートを直接開放したりせずに、ローカルのWebサーバを公開できます。

また、Quick Tunnelを使用すると、Cloudflareアカウントや独自ドメインを準備しなくても、次のコマンドだけで一時的な公開URLを発行できます。

cloudflared tunnel --url http://127.0.0.1:8080

ただし、Quick Tunnelはテスト・開発用です。

固定URL、アクセス制御、監視、冗長化などが必要な本番環境では、管理対象のCloudflare Tunnelを構築する必要があります。

以上です。

コメント

タイトルとURLをコピーしました