Windows+Cloudflare Tunnel+Caddy+PHPでローカルHTTPS接続を追加する方法

ちゃっぴーがWindows、Cloudflare Tunnel、Caddyの構成図を指さしながらローカルHTTPS接続を紹介するイラスト。

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を変えずにローカル通信を追加できる。余計な外回りを減らせるのが気持ちいい。

コメントを残す