ngrok・Cloudflare Tunnelでローカルを公開|Webhook開発とデモ環境の作り方

kento_morota 10分で読めます
社内のAI・IT活用、技術がわかる相手に無料相談。 相談 →
目次

「Stripeの決済完了Webhookを受け取る処理を書いたが、手元のPCには外から届かないので本番に上げるまで試せない」「LINE Botの動作確認のたびにステージングへデプロイしている」「取引先にデモを見せたいが、サーバーを用意するほどではない」。Webhookや外部連携の開発では、こうした"ローカルに外から届かない"問題が必ず出てきます。

この記事では、NATの内側にあるローカル環境に外部からのリクエストを届けるトンネリングの仕組みと、ngrok・Cloudflare Tunnel・localtunnelの違い、固定ドメインと認証の付け方、届いたリクエストの検査方法、公開時に気をつけるセキュリティ、自宅サーバー公開への応用までを解説します。Webhookの概念そのものは既知として、開発環境の作り方に集中します。

なぜローカルにWebhookが届かないのか|トンネリングの仕組み

NATの内側からは「こちらから出る」しかできない

自宅やオフィスのPCはルーターのNATの内側にあり、プライベートIPしか持ちません。PCからインターネットへは出ていけますが、外部のStripeやGitHubが「あなたのPCの3000番」を宛先に指定することはできません。グローバルIPはルーターのものであり、ルーターはどのPCに転送すべきか知らないからです。ポート開放で対処する方法もありますが、集合住宅や法人回線ではCGNAT(キャリア側で二重にNATされる構成)のため開放自体が不可能なことも多く、なにより開発用途で常時ポートを開けるのは危険です。

トンネリングは「内から外へ張った接続」を逆向きに使う

ngrokなどのトンネリングツールは、この制約を発想の転換で回避します。

  1. ローカルで動くクライアント(ngrokコマンド)が、ベンダーのサーバーへ外向きに常時接続を張る。NATは内から外への接続は許可するので問題なく通る。
  2. ベンダーはあなた専用の公開URL(例:https://abc123.ngrok-free.app)を発行する。
  3. StripeがそのURLにPOSTすると、ベンダーのサーバーが受け取り、すでに張ってある接続を逆向きに使ってローカルのクライアントへ転送する。
  4. クライアントがlocalhost:3000のアプリに渡し、レスポンスを同じ経路で返す。

つまり公開URLで受けているのはベンダーのサーバーで、ローカル側は「常に外向きに接続している」だけです。ファイアウォールもルーターも何も変更せずに済むのはこのためです。

ngrok・Cloudflare Tunnel・localtunnelの比較

項目ngrokCloudflare Tunnellocaltunnel
主な用途開発・Webhookテスト開発〜本番の常設公開簡易テスト
固定ドメイン無料枠で1つ固定可能、独自ドメインは有料自分のCloudflare管理ドメインを無料で使える希望サブドメインを指定可(保証なし)
認証・アクセス制限Basic認証・OAuth・IP制限(プランによる)Cloudflare Accessで社内SSO連携簡易パスワード画面のみ
リクエスト検査ローカルWeb UI(4040番)で再送も可能ダッシュボードのログなし
セットアップコマンド1つドメイン+cloudflaredの設定が必要npxで即時

使い分けの目安は「Webhookの試行錯誤ならngrok」「デモ環境や常設の社内ツール公開ならCloudflare Tunnel」「ちょっと見せるだけならlocaltunnel」です。ngrokは無料枠だと初回アクセス時に警告ページが挟まるため、Webhookの送信元によっては届かない場合があり、その際はリクエストヘッダー(ngrok-skip-browser-warning)の付与か有料プランで回避します。

ngrokでWebhookを受け取る手順

起動と固定ドメイン

# インストール(macOS)とトークン登録
brew install ngrok
ngrok config add-authtoken <YOUR_TOKEN>

# ローカルの3000番を公開(URLは起動のたびに変わる)
ngrok http 3000

# 無料枠で発行できる固定ドメインを使う(Stripe側に毎回登録し直さなくて済む)
ngrok http --url=your-name.ngrok-free.app 3000

# Basic認証をかけて公開
ngrok http --basic-auth="demo:s3cret" 3000

URLが毎回変わると、StripeダッシュボードやLINE Developersコンソールに登録したWebhook URLを都度書き換える手間が発生します。固定ドメインは最初に設定しておくと開発効率が大きく変わります。

リクエスト検査と再送

ngrokは起動時にローカルの http://127.0.0.1:4040 でWeb UIを提供します。届いたリクエストのヘッダー・ボディ・レスポンスをすべて確認でき、同じリクエストを再送(Replay)できます。Webhook開発ではこの再送機能が重要で、決済を何度も発生させずに、一度受け取ったペイロードでハンドラを修正しながら試せます。

# Stripe CLIならngrokなしでもローカルへ転送できる(Stripe専用)
stripe listen --forward-to localhost:3000/webhooks/stripe

# 署名検証は必ず実装する(Express + Stripeの例)
app.post('/webhooks/stripe', express.raw({ type: 'application/json' }), (req, res) => {
  const sig = req.headers['stripe-signature'];
  let event;
  try {
    event = stripe.webhooks.constructEvent(req.body, sig, process.env.STRIPE_WEBHOOK_SECRET);
  } catch (err) {
    return res.status(400).send(`Webhook Error: ${err.message}`);
  }
  // event.type に応じた処理
  res.json({ received: true });
});

公開URLは誰でもPOSTできるため、Webhookハンドラは送信元の署名(Stripeのstripe-signature、LINEのx-line-signature、GitHubのX-Hub-Signature-256)を必ず検証してください。トンネル経由かどうかに関係なく、これは本番でも必須の実装です。

Cloudflare Tunnelで常設のデモ環境を作る

独自ドメインとアクセス制御

Cloudflare Tunnelは、Cloudflareで管理しているドメインのサブドメインをローカルやオフィス内のサーバーに割り当てられます。cloudflaredというクライアントを常駐させる点はngrokと同じですが、DNSとTLSがCloudflare側で完結し、Cloudflare Accessと組み合わせれば「Googleアカウントで社内ドメインのユーザーだけ通す」といった制御が無料枠で可能です。

# 認証とトンネル作成
cloudflared tunnel login
cloudflared tunnel create demo-app

# DNSレコード(demo.example.com → トンネル)を自動作成
cloudflared tunnel route dns demo-app demo.example.com

# ~/.cloudflared/config.yml
tunnel: demo-app
credentials-file: /Users/you/.cloudflared/<TUNNEL_ID>.json
ingress:
  - hostname: demo.example.com
    service: http://localhost:3000
  - hostname: api-demo.example.com
    service: http://localhost:8080
  - service: http_status:404     # 上記以外は404

# 起動(常設ならサービス登録)
cloudflared tunnel run demo-app
sudo cloudflared service install

取引先へのデモやプロトタイプ共有であれば、この構成で十分に「サーバーを借りずに公開する」ことができます。ドメイン側の設定はドメインとDNS設定のガイドを参照してください。

自宅サーバー・オフィスサーバー公開への応用

同じ仕組みで、自宅のRaspberry Piやオフィスの検証サーバーをポート開放なしに公開できます。オリジンのグローバルIPが外部に一切露出しないため、ルーターのポートフォワーディングより安全性が高い方法です。ただし「常設で公開する」以上、そのサーバーは本番相当の扱いが必要になります。OSの更新、Linuxサーバーのセキュリティ強化、Accessによるアクセス制限を前提にしてください。

公開時のセキュリティと、トラブル事例

開発用トンネルで気をつけること

  • 開けっぱなしにしない:作業が終わったらトンネルを止める。固定ドメインは常時同じURLで到達できるため、放置すると開発中の脆弱な画面が公開状態になる
  • 本番の認証情報を使わない:トンネル先のローカルアプリがステージングや本番のDBに繋がっていないか確認する
  • デバッグ機能を露出させない:開発モードのエラーページやGraphQL Playgroundなどが公開URLから見える状態にしない
  • 会社のセキュリティポリシーを確認:ベンダーのサーバーを経由する以上、リクエスト内容が第三者のインフラを通る。個人情報を扱う検証はダミーデータで行う

事例:Webhookは届いているのに処理が二重に走る

症状:ngrok経由で受けたStripeのWebhookで、注文確定メールが2通届く。ngrokのUIでは同じイベントのリクエストが2回記録されている。
原因:ハンドラの処理に時間がかかり、Stripe側のタイムアウト内に2xxを返せなかったため、Stripeがリトライした。ローカル環境はトンネルの往復分だけ遅延が増えるため、本番では起きなかった再送がローカルで顕在化した。
対処:Webhookハンドラは「受け取ったら即座に200を返し、重い処理はジョブキューに回す」構造に変更。あわせてイベントIDをDBに記録し、同じIDが来たら処理をスキップする冪等性チェックを入れた。これは本番でも必要な設計であり、ローカルで再現できたことでむしろ事前に対処できた例です。

まとめ

トンネリングは、NATの内側から外向きに張った接続を逆向きに使うことで、ポート開放なしにローカル環境へ外部リクエストを届ける仕組みです。Webhookの試行錯誤にはリクエスト検査と再送ができるngrok、デモや常設公開には独自ドメインとAccessで守れるCloudflare Tunnelが向いています。どちらを使う場合も、署名検証と冪等性はハンドラ側で必ず実装し、トンネルは使い終わったら閉じる、本番データに繋がない、という基本を守ってください。外部サービス連携の設計や検証環境の整備でお困りの際は、Harmonic Societyのシステム開発・インフラ支援にご相談ください。

#ngrok#Cloudflare Tunnel#Webhook#ローカル開発

Harmonic Society

この記事の内容、自社の業務でも活かせそうですか?

ローカルLLM・AI・クラウドなどの技術導入を、要件整理からPoC・社内展開まで代表エンジニアが伴走します。オンライン対応・全国OK。まずは30分の無料相談から。売り込みはしません。

共有:
無料メルマガ

週1回、最新の技術記事をお届け

AI・クラウド・開発の最新記事を毎週月曜にメールでお届けします。登録は無料、いつでも解除できます。

プライバシーポリシーに基づき管理します

関連記事

Related / 9 articles

  1. プログラミング

    DDoS攻撃の仕組みと対策入門|レイヤー別の防御とCDN・クラウドの活用

    DDoS攻撃をボリューム型・プロトコル型・アプリ層に分けて仕組みを解説し、自前サーバーで防げない理由、CloudflareやAWS Shieldの標準防御、オリジンIPの隠し方、レートリミットとBot対策、攻撃を受けたときの初動、費用が跳ね上がるDenial of Walletへの備えまでわかります。

  2. プログラミング

    WAFとは?仕組み・導入パターン・誤検知対策|Webアプリを攻撃から守る実践ガイド

    WAFがファイアウォールやIDSと何が違うのか、シグネチャとマネージドルールの仕組み、Cloudflare WAF・AWS WAF・ModSecurityの比較、フォーム送信がブロックされる誤検知の調査と例外設定、ログ監視、WAFが代替できないことまで実践的に解説します。

  3. プログラミング

    セキュリティヘッダー入門|CSP・HSTS・X-Frame-Optionsの設定と効果を実践解説

    CSP・HSTS・X-Frame-Options・X-Content-Type-Optionsなど主要セキュリティヘッダーが防ぐ攻撃と、CSPのReport-Onlyからの段階導入、nonce/hash、HSTS preloadの不可逆リスク、Nginx・Next.js・Astroでの設定例、確認方法を解説します。

  4. プログラミング

    クラウドの通信費(Egress)入門|データ転送量課金の仕組みと転送コストを抑える設計

    クラウドの「受信無料・送信有料」の原則、AZ間・リージョン間・インターネット向けの単価差、NATゲートウェイ処理料の罠、CDNで転送量を減らす方法、バックアップやログ転送の見落とし、請求書で転送料を特定する手順を解説。想定外の請求を防げます。

  5. プログラミング

    秘密情報をGitに入れない仕組み|.gitignore・git-secrets・履歴から漏れた鍵の削除

    APIキーや.envをGitにコミットしてしまう典型経路と、.gitignore・.env.exampleの運用、pre-commitでのgitleaks検知、GitHub secret scanningの活用、漏れた鍵の無効化と履歴書き換え(git filter-repo)の手順を解説。仕組みで再発を防げます。

  6. プログラミング

    開発・ステージング・本番環境の分離設計|環境差分をなくす構成とアクセス制御

    開発・ステージング・本番それぞれの目的と、構成をコードで揃える方法、環境別の設定注入、本番データを使わないテストデータ戦略、ステージングの保護(Basic認証・IP制限・noindex)、コストを抑える運用までを解説。環境差分による本番障害を防げます。

  7. プログラミング

    ローカル開発環境のHTTPS化|mkcert・hostsファイル・自己署名証明書の正しい使い方

    ローカル開発をHTTPS前提にすべき理由(Secure Cookie・Service Worker・OAuth)と、mkcertでローカルCAを作りhostsで独自ドメインを割り当ててVite・Next.js・Dockerで使う手順を解説。証明書警告を無視する癖の危険も理解できます。

  8. プログラミング

    localhost・0.0.0.0・127.0.0.1の違い|ポートとUnixソケットを理解して「つながらない」を解決

    localhost・127.0.0.1・0.0.0.0の意味の違い、Dockerで外から接続できない原因、host.docker.internal、ポート競合の調べ方、Unixソケットの利点と権限、1024未満ポートの制約を解説。「つながらない」を仕組みから解決できます。

  9. プログラミング

    GitOps入門|ArgoCD・FluxでGitをインフラの正とするデプロイ運用

    GitOpsのPush型とPull型の違い、差分検知と自動同期の仕組み、リポジトリ構成、ArgoCDの最小導入手順までを解説。git revertで戻せるデプロイ運用が理解でき、Kubernetes以外への応用の考え方もわかります。

Harmonic Society

「読んで終わり」にせず、自社の業務で試してみませんか?

AI・ローカルLLM・クラウドの導入を、要件整理からPoC・社内展開まで代表エンジニアが伴走します。オンライン対応・全国OK・売り込みなし。

無料・30分・オンラインOK|1営業日以内に返信します