Cloudflare Tunnel の背後で動かす
Cloudflare Tunnel はオリジンを外側へ接続します。cloudflared が Cloudflare へ
ダイヤルし、Cloudflare はその接続を通して要求を返します。公開ポートで待ち受ける
ものはなく、エッジが TLS を終端し、オリジンはループバックで平文 HTTP を見ます。
このページはそれを設定し、最初に必ずつまずく一点――すべての要求が
127.0.0.1 として記録される――を直します。
🧾 はじめる前に
Section titled “🧾 はじめる前に”- そのドメインが Cloudflare アカウントにあり、Zero Trust が使えること。
- Pingclair と同じホストに
cloudflared、そしてサイトを配信する Pingclair (静的サイトを配信する)。 - ダッシュボード(Zero Trust → Networks → Tunnels)か、Cloudflare Tunnel:
Write とゾーンの DNS: Edit を持つ API トークン。例では API を使い、
$CF_TOKEN、$ACCOUNT、$ZONEを設定します。
🌐 トンネルを作る
Section titled “🌐 トンネルを作る”curl -s -X POST -H "Authorization: Bearer $CF_TOKEN" -H 'Content-Type: application/json' \ --data '{"name":"docs-origin","config_src":"cloudflare"}' \ "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT/cfd_tunnel"{"success":true,"result":{"id":"bc6869fa-19cf-4780-b95b-f11be77eb329","name":"docs-origin", …}}config_src: cloudflare はトンネルをリモート管理にします。ingress ルールは
Cloudflare 側にあり API で投入されるので、接続子の隣に何かを書く必要はありません。
接続子の資格情報は別の呼び出しです。
curl -s -H "Authorization: Bearer $CF_TOKEN" \ "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT/cfd_tunnel/$TUNNEL_ID/token"このトークンは秘密情報で、ホストをトンネルに参加させる鍵です。パスワードと同様に 扱い、漏れたら交換してください。
🔌 ホストを接続する
Section titled “🔌 ホストを接続する”curl -fsSL -o /tmp/cloudflared.deb \ https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.debsudo dpkg -i /tmp/cloudflared.debsudo cloudflared service install "$TUNNEL_TOKEN"INF Linux service for cloudflared installed successfully接続子は最寄りの Cloudflare 拠点へ 4 本の接続を登録し、既定で QUIC を使います。
INF Registered tunnel connection connIndex=2 … location=pdx02 protocol=quicINF Registered tunnel connection connIndex=3 … location=sea10 protocol=quic🌍 ホスト名を経路にする
Section titled “🌍 ホスト名を経路にする”ingress ルールが、どのホスト名をどのオリジンサービスへ送るかを決めます。
curl -s -X PUT -H "Authorization: Bearer $CF_TOKEN" -H 'Content-Type: application/json' \ --data '{"config":{"ingress":[ {"hostname":"tunnel-test.pingclair.com","service":"http://127.0.0.1:80"}, {"service":"http_status:404"}]}}' \ "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT/cfd_tunnel/$TUNNEL_ID/configurations"最後のルールは受け皿です。他のホスト名は既定のサイトではなく 404 になります。
次に、その名前をトンネルへ向けます。プロキシは有効にします。
curl -s -X POST -H "Authorization: Bearer $CF_TOKEN" -H 'Content-Type: application/json' \ --data '{"type":"CNAME","name":"tunnel-test.pingclair.com","content":"'$TUNNEL_ID'.cfargotunnel.com","proxied":true,"ttl":60}' \ "https://api.cloudflare.com/client/v4/zones/$ZONE/dns_records"どこからでも:
curl -I https://tunnel-test.pingclair.com/HTTP/2 200content-type: text/html; charset=utf-8accept-ranges: bytesserver: cloudflareserver: cloudflare はエッジが応答している印です。オリジンへはトンネル経由で
到達しており、どのポートも開いていません。
🎯 オリジンにクライアントを見せる
Section titled “🎯 オリジンにクライアントを見せる”既定では、すべての要求が接続子からループバック経由で届きます。アクセスログは クライアントが誰かを何も語りません。
📝 Access … host="tunnel-test.pingclair.com" status=200 remote_ip=127.0.0.1 user_agent="curl/8.7.1"trusted_proxies は、どの相手がクライアントアドレスを主張してよいかを Pingclair に
伝えます。接続子は同じホストで動くので、ループバックだけで足ります。
{ admin 127.0.0.1:2019 trusted_proxies 127.0.0.1/32}
http://:80 { root * /srv/site file_server}オプションの前後で同じ要求を測った結果:
remote_ip=127.0.0.1 # 前remote_ip=16.162.199.171 # 後: 要求を始めたクライアントこの設定は、トンネルの背後で IP 単位の制限やルールを意味のあるものにするものでも あります。起動時に確立されるため、変更には再読み込みではなく再起動が要ります (再読み込みの意味)。
⚠️ うまくいかないとき
Section titled “⚠️ うまくいかないとき”HTTP/2 530とerror code: 1033。 トンネルに接続子がありません。 オリジン側のsystemctl is-active cloudflaredが状態を示し、接続子が登録され れば数秒で200に戻ります。- 別のサイトに届く、または
404。 ingress ルールは順に評価され、最後は受け皿 です。DNS を疑う前にルール内のホスト名の綴りを確認します。 - エッジからの
502。 接続子は生きていますが、オリジンサービスが接続を拒否 しました。ルールが指すポートで Pingclair が待ち受けていません。 - アクセスログが常に
127.0.0.1。 上記のとおりtrusted_proxiesが ありません。 - ホスト名が解決しない。 レコードは
<tunnel-id>.cfargotunnel.comへの プロキシされた CNAME である必要があります。グレー雲のレコードはトンネルを 迂回します。 - 接続子トークンが漏れた。 トンネルのトークンを削除し、新しいものでサービスを 入れ直します。古い資格情報は API から取り戻せません。
🧭 次の手順
Section titled “🧭 次の手順”- 静的サイトを配信する: この例が指すオリジン。
- TLS で調整できること: エッジが終端しないとき、 オリジンが証明書でできること。
- サービスとして動かす: オリジン側のユニットと、
trusted_proxiesの注意が参照する再読み込みの意味。
