nginx でプロキシゲートを設定する
このチュートリアルの終わりには、ゲートは nginx の背後にあるサイトの手前で動いています。通過許可のない訪問者はゲームへ送られ、解かれたゲームは Cookie をセットし、後のリクエストはまっすぐ通ります。まずは全体を プレビューモード で観察するので、配線を確かめるまで何もブロックされません。ここでは nginx を使います。Traefik、Caddy、Authelia のレシピ は同じ形に従います。
1. プレビューモードをオンにする
ダッシュボードでチームを開き、プレビューモード をオンにします。オンの間、ゲートのオーソライザーはチャレンジ対パススルーの判断を 統計ページ に記録しますが、決してブロックしません。最後にオフにします。
2. サイトキーでゲートを有効にする
サイトキーを開き、プロキシゲート ページへ行きます。ステータス → 有効 をオンにし、次を設定します:
- 通過許可 TTL:一度の解答が訪問者をどれだけ通過させるか(既定 30 分)。短いほど再チェックが増えますが、Cookie が盗まれた場合の窓は小さくなります。
- フェイルモード:プロキシが Caputchin のオーソライザーに到達できないときに何をするか。fail-closed はブロック(ログインポータルに安全寄り)、fail-open はリクエストを通す(公開サイトのダウンタイムを避ける)。
このページは、あなたのサイトキーがすでに埋め込まれた、コピーしてすぐ使える nginx スニペットも表示します。
3. ゲートをかけるオリジンを許可する
チャレンジは 許可されたオリジン にしか戻りリダイレクトしません。ウィジェットが使うのと同じオリジン許可リストです。ゲートをかけるオリジン、たとえば https://auth.example.com が含まれているか確かめてください。まだなければ、サイトキーの Cap 設定でそれを設定します。
4. オーソライザーとチャレンジのリダイレクトを配線する
二つの location ブロック:内部の オーソライザー サブリクエストと、プロキシが 401 で飛ぶ チャレンジ リダイレクトです。YOUR_SITE_KEY をあなたの公開鍵に置き換えます。
# Gate the protected paths.
location / {
auth_request /_cpt_authz; # 204 = allow, 401 = challenge
error_page 401 = @cpt_challenge;
# ...proxy_pass to your app...
}
location = /_cpt_authz {
internal;
proxy_pass https://verify.caputchin.com/v1/gate/authz?site=YOUR_SITE_KEY;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
proxy_set_header Cookie $http_cookie; # forward the cpt_gate cookie
}
location @cpt_challenge {
return 302 https://verify.caputchin.com/v1/gate/challenge?site=YOUR_SITE_KEY&return=$scheme://$host$request_uri;
}入口パス(ポータルの HTML とログインの POST)にゲートをかけます。オーソライザーのサブリクエスト、ヘルスチェック、下のコールバックには ゲートをかけないで ください。
5. Cookie をセットするコールバックを足す
チャレンジページは終わりに、あなたのオリジンの /__cpt/callback へ小さな POST を自動送信します。ボディ には cpt_gate(パス)と to(訪問者をどこへ送るか)が入ります。ごく小さなハンドラーが Cookie をセットしてリダイレクトします。各 Cookie 属性がなぜ重要かも含む完全な契約は、リバースプロキシのレシピ にあります。最小限:
app.post("/__cpt/callback", express.urlencoded({ extended: false }), (req, res) => {
const pass = String(req.body.cpt_gate || "");
const to = String(req.body.to || "/");
const target = new URL(to, `https://${req.headers.host}`);
if (target.host !== req.headers.host) return res.status(400).end(); // same-origin only
res.setHeader(
"Set-Cookie",
`cpt_gate=${pass}; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=1800`
);
res.redirect(303, target.pathname + target.search);
});6. プレビューで観察する
ゲート付き URL を読み込みます。プレビューがオンなので、あなたはまっすぐ通りますが、統計ページ は challenge_served を記録し(Cookie がなかったため)、解いてコールバックが走ると pass_issued を記録します。再読み込みすると passthrough が上っていくはずです。チャレンジが決して現れないなら、オーソライザーのブロックが当たっていません。コールバックが 400 を返すなら、to のオリジンを確認してください。
7. 本番にする
数字が正しく見えたら、プレビューモード をオフにします。ゲートは今や強制します。通過許可のない訪問者はゲームへ送られ、解いた訪問者はパスが切れるまで歩き回ります。
次にどこへ
- リバースプロキシのレシピ:Traefik、Caddy、そして Authelia の完全な手順。
- プロキシゲートの統計:本番になったら各数字が何を意味するか。
- 概要:概念と、ゲートがあえてしないこと。