Skip to content
Code on the Road
Go back

【HTTPS化編】ngrok から Cloudflare Tunnel へ — 認証付きで trade.codeontheroad.jp を公開する

VPS構築編アプリ運用編では、自作トレードシステム Logical225ngrok の無料固定ドメインで公開していた。これを Cloudflare Tunnel に移行し、独自サブドメイン trade.codeontheroad.jp + HTTPS + 認証ゲートを全部無料で実現した記録。

なぜ ngrok から乗り換えるのか

ngrok でも「固定URL + HTTPS」は手に入る。ただ本番運用には物足りなかった。

これらをまとめて解決できるのが Cloudflare Tunnel + Cloudflare Access。しかも無料枠で収まる。

選択肢の比較

ngrok 無料Cloudflare クイックトンネルCloudflare 通常トンネル
URL固定(xxxx.ngrok-free.appランダム・毎回変わる自分のドメイン
ドメイン要否不要不要必要(Cloudflare管理)
認証(Access)××○(無料枠あり)
警告ページありなしなし
本番向き✕(テスト用)

「手軽さだけ」なら ngrok の固定ドメインで十分。認証付きで本番公開したいから通常トンネルを選ぶ。

Cloudflare Access とは

公開URLに誰かがアクセスすると、アプリに届く前に Cloudflare のログイン画面が出る仕組み。許可した人だけが通過できる。

構成

ゴール: https://trade.codeontheroad.jp で Logical225 を HTTPS + 認証で公開。

フェーズ1: DNSを Cloudflare へ移す

Cloudflare Tunnel は「ゾーンが Cloudflare 管理下」であることが条件。無料では部分移管できないので、ドメイン全体のネームサーバを Cloudflare に向ける。ブログを壊さないよう、レコードを完全に引き継ぐのが肝。

  1. Cloudflare に codeontheroad.jp を追加(プラン Free)
  2. 既存DNSレコードを引き継ぐ
  3. バリュードメインでネームサーバを Cloudflare の2つに変更
  4. ステータスが Active になり、ブログが正常表示されることを確認

ハマり①: 自動スキャンが0件 → 手動で登録

Cloudflare の自動スキャンが既存レコードを0件しか拾えなかった(レジストラによってはよくある)。なので手動で登録した。今回は apex の A レコード1件だけ:

Type: A / Name: @ / IPv4: 216.198.79.1 / Proxy: DNS only(グレー雲)

**Vercel 向けのレコードは必ず「DNS only(グレー雲)」**にする。Cloudflare のプロキシ(オレンジ雲)を通すと二重CDNになり、ブログのSSLが不安定になる。

ハマり②: ドメイン名のタイポで pending 地獄

ネームサーバを変えたのに、何時間経っても pending(Active にならない)。原因は、Cloudflare に追加したドメイン名をタイポしていたこと(codeontheroad.jp の先頭の c が抜けた別物を登録していた)。

切り分けに使えたのが dig。割り当てられたネームサーバに正しいドメインを直接問い合わせると REFUSED(=そのゾーンを持っていない)が返ってきた:

dig codeontheroad.jp SOA @<割り当てられたNS>
# status: REFUSED  ← このNSは codeontheroad.jp を担当していない

登録ドメイン名のミスを疑い、間違ったゾーンを削除して正しい codeontheroad.jp で追加し直したら解決。

注意: Cloudflare のゾーンを Remove → 再Add すると、割り当てネームサーバが変わることがある。実際に変わったので、レジストラ側のネームサーバも新しい値に更新した。

再追加後、.jp の委任と Cloudflare の応答が一致して Active。apex も 216.198.79.1 に解決し、ブログは無傷で動き続けた。

フェーズ2: Tunnel を立てて VPS に常駐させる

Zero Trust Free の有効化(カード登録に注意)

Cloudflare の Zero Trust ダッシュボード(one.dash.cloudflare.com)を初めて開くと、チーム名とプラン選択を求められる。Free を選んでも「支払い方法の登録」が必須で少し驚くが、請求は $0。無料枠(50ユーザー)を超えなければ課金されない(個人利用なら超えない)。

cloudflared をサービス導入

  1. Zero Trust → Networks → Tunnels → Create a tunnel → コネクタは Cloudflared → 名前を付けて保存
  2. 環境で Windows / 64-bit を選ぶ
  3. 案内どおり VPS で:
    • MSI をダウンロードして実行(cloudflared 本体)
    • 管理者でコマンドプロンプト/PowerShell を開き、トークン入りコマンドを実行
cloudflared.exe service install eyJ...(トークンは秘密。表示はコピーボタンで全文取得)

これで cloudflared が Windows サービスとして常駐インストールされる(=再起動後も自動起動)。実行ログに installed successfully が出て、ダッシュボードのコネクタが Connected になればOK。

🔒 トークンは秘密情報。これを持っていれば誰でもこのトンネルを起動できてしまう。漏れたら Tunnel → Refresh token で再発行する。

公開ホスト名を設定

トンネルの Public Hostname に次を登録:

Subdomain: trade / Domain: codeontheroad.jp / Service: HTTP → localhost:3000

trade のDNS(CNAME・プロキシon)は Cloudflare が自動作成する。これで https://trade.codeontheroad.jp が、Cloudflare 発行の有効な証明書付きで開通した(VPSのポート開放は不要)。

フェーズ3: 認証(Cloudflare Access)

この時点ではURLを知っていれば誰でも開ける状態。売買システムなので、すぐ認証を付ける。

  1. Zero Trust → Access → Applications → Add an application
  2. Public DNS(公開ホスト名のアプリ)→ Self-hosted
  3. Public hostname に trade.codeontheroad.jp
  4. ポリシー: Action Allow / Include → Emails → 自分のメールアドレス
  5. ログイン方法は One-time PIN(メールOTP)
  6. 保存

ハマり③: 「設定したのに未ログインで見える」

保存直後に「未ログインでもアクセスできてしまう」ように見えた。原因は同じブラウザに前のセッションが残っていただけ。シークレットウィンドウで確認すると、ちゃんと Cloudflare のログインへリダイレクトされた:

curl -sS -o /dev/null -w "%{http_code}" https://trade.codeontheroad.jp/
# 302 → https://<team>.cloudflareaccess.com/cdn-cgi/access/login/...

未認証アクセスは Cloudflare 側で 302 リダイレクトされ、VPS まで到達しない。許可したメールで OTP ログインした時だけ Logical225 が開く。

できたこと

注意: 「常駐」したのはトンネルだけ

cloudflared をサービス化したのでトンネル自体は再起動後も自動復活する。ただし——

対象再起動後
cloudflared(トンネル)✅ 自動復活
Cloudflare Access(認証)✅ 有効のまま
Logical225 本体(localhost:3000)❌ 起動しない
kabuステーション❌ 起動しない

つまり今 VPS を再起動すると、trade.codeontheroad.jp は開けるが中身が動いておらず 502 になる。トンネルは生きているのに、その先のアプリが落ちている状態だ。

次回予告: 常駐化編

残るはアプリ本体の常駐

「再起動しても、人が触らずに売買が再開する」状態を目指して、次は常駐化に取り組む。


シリーズ:

  1. VPS構築編
  2. アプリ運用編
  3. HTTPS化編(この記事)


Next Post
【アプリ運用編】kabuステーションAPI × Next.js(Logical225)を VPS で動かして公開する