Windows 11で Cloudflare Tunnel+Caddy+PHP を動かしていると、同じPCから自分のサイトにアクセスするときまでCloudflareを経由しがち。そこで、外部アクセスは従来どおりTunnel、同じPCからは127.0.0.1へ直結するようにした。実際に使っている mf235.com の環境を例にまとめる。
完成形
外部:ブラウザ → Cloudflare Tunnel → Caddy :8080 → PHP
同じPC:ブラウザ/音声アプリ → Caddy :443 (HTTPS) → PHP
どちらの入口もCaddy内で同じホスト名別ルーティングを共有する。URL自体は変更しないので、MCPのOAuth設定もそのまま利用できる。
1. CaddyにローカルHTTPSを追加
この環境ではCaddyが 127.0.0.1:8080 でCloudflare TunnelからのHTTPを受けていた。443番を追加し、共通の (shared_sites) を両方から読み込む。下は実際のCaddyfileをもとに、ログ設定と一部サイトのルートだけ省いた抜粋。
{
auto_https disable_redirects
}
# HTTPとHTTPSから共通利用するサイト設定
(shared_sites) {
@wp host wp.mf235.com
handle @wp {
root * C:\Server\wordpress
php_fastcgi 127.0.0.1:9001 127.0.0.1:9002 {
lb_policy least_conn
}
file_server
}
@mcp host mcp.mf235.com
handle @mcp {
root * C:\Server\chappy-mcp-server\public
php_fastcgi 127.0.0.1:9000
file_server
rewrite /.well-known/oauth-protected-resource /oauth-resource.php
rewrite /.well-known/oauth-authorization-server /oauth-server.php
}
# media / game / chappy-form / 既定サイトのhandleは省略
}
# Cloudflare Tunnelからの転送先
:8080 {
bind 127.0.0.1
import shared_sites
}
# 同じPCからアクセスするためのHTTPS
https://mf235.com, https://*.mf235.com {
bind 127.0.0.1
tls internal
import shared_sites
}
bind 127.0.0.1 なので443番も8080番もLAN・インターネットには公開しない。tls internal はCaddyのローカル認証局でHTTPS証明書を発行する設定。既存のPHP-FastCGI(9000番、WordPressは9001・9002番)はそのまま使う。
変更後は caddy validate --config Caddyfile で検証し、設定をリロード。既存の8080番が動くことも先に確認しておく。
2. Caddyの認証局をWindowsで信頼する
ローカルHTTPSを証明書エラーなしで使うため、Caddyの公開ルート証明書をWindowsの「現在のユーザー」の信頼されたルート証明機関に追加する。Caddyを同じユーザーで実行している場合の例:
certutil -user -addstore Root "%APPDATA%\Caddy\pki\authorities\local\root.crt"
※Caddyを別アカウントやサービスで実行している場合は、そのアカウント側の証明書保存場所を確認する。秘密鍵をコピー・公開しない。
PHPのcURLなど独自のCAバンドルを使うプログラムでは、Windowsの信頼設定だけでは不足する場合がある。今回の環境では C:\Server\php\cacert.pem をバックアップし、Caddyの公開ルート証明書を追加して解決した。SSL_VERIFYPEER は無効化しない。
3. hostsで各サブドメインを127.0.0.1へ
管理者権限で C:\Windows\System32\drivers\etc\hosts を開き、実際に使うドメインを追加する。
127.0.0.1 mf235.com
127.0.0.1 mcp.mf235.com
127.0.0.1 wp.mf235.com
127.0.0.1 media.mf235.com
127.0.0.1 game.mf235.com
127.0.0.1 chappy-form.mf235.com
hostsはワイルドカード非対応なのでサブドメインごとに1行必要。ただし接続先IPが変わるだけで、URL・TLSのSNI・HTTPのHost名は mcp.mf235.com など元のまま。Caddyのホスト名による振り分けやOAuthの認証対象URLを変更する必要はない。通常、Windowsの再起動も不要。
4. 動作確認
次のコマンドで IP=127.0.0.1 HTTP=200 になれば、MCPのOAuthメタデータはローカルHTTPS経由で取得できている。
curl.exe --ssl-revoke-best-effort -o NUL -w "IP=%{remote_ip} HTTP=%{http_code}\n" https://mcp.mf235.com/.well-known/oauth-authorization-server
--ssl-revoke-best-effort はWindowsのcurl(Schannel)で内部認証局の失効情報が取得できない場合への対処で、証明書チェーンやホスト名の検証を無効化する -k とは違う。WordPressなどほかのサイトも個別に確認する。アプリが接続を保持しているなら、アプリだけ再起動すると確実。
注意点
このPCからのアクセスはCloudflareのWAF・アクセス制限を経由しなくなるので、認証やアクセス制御をCloudflareだけに依存させないこと。また、公開サイト向けのDNSやCloudflare Tunnelの設定は変更しない。今回の構成では、外部からは従来どおりTunnelを利用できる。
以上。1台のWindows PCでCaddyとアプリを同居させているなら、アプリのURLを変えずにローカル通信を追加できる。余計な外回りを減らせるのが気持ちいい。
