---
type: tutorial
title: nginx でプロキシゲートを設定する
summary: サイトキーでゲートを有効にし、nginx リバースプロキシを端から端まで配線し、本物の訪問者を一人もブロックする前にプレビューモードで観察します。
---

このチュートリアルの終わりには、ゲートは nginx の背後にあるサイトの手前で動いています。通過許可のない訪問者はゲームへ送られ、解かれたゲームは Cookie をセットし、後のリクエストはまっすぐ通ります。まずは全体を **プレビューモード** で観察するので、配線を確かめるまで何もブロックされません。ここでは nginx を使います。[Traefik、Caddy、Authelia のレシピ](/docs/proxy-page-gate/reverse-proxy-recipes) は同じ形に従います。

<Callout type="tip">
プロキシに触れる前に手順 1 をしてください。プレビューモードはゲートを監視のみで動かします。ダッシュボードはゲートが何を *していたか* を記録しますが、リクエストはどれもなお通るので、配線の間違いが誰かを締め出すことは決してありません。
</Callout>

## 1. プレビューモードをオンにする

ダッシュボードでチームを開き、**プレビューモード** をオンにします。オンの間、ゲートのオーソライザーはチャレンジ対パススルーの判断を [統計ページ](/docs/proxy-page-gate/statistics) に記録しますが、決してブロックしません。最後にオフにします。

## 2. サイトキーでゲートを有効にする

サイトキーを開き、**プロキシゲート** ページへ行きます。**ステータス → 有効** をオンにし、次を設定します：

- **通過許可 TTL**：一度の解答が訪問者をどれだけ通過させるか（既定 30 分）。短いほど再チェックが増えますが、Cookie が盗まれた場合の窓は小さくなります。
- **フェイルモード**：プロキシが Caputchin のオーソライザーに到達できないときに何をするか。**fail-closed** はブロック（ログインポータルに安全寄り）、**fail-open** はリクエストを通す（公開サイトのダウンタイムを避ける）。

このページは、あなたのサイトキーがすでに埋め込まれた、コピーしてすぐ使える nginx スニペットも表示します。

## 3. ゲートをかけるオリジンを許可する

チャレンジは **許可されたオリジン** にしか戻りリダイレクトしません。ウィジェットが使うのと同じオリジン許可リストです。ゲートをかけるオリジン、たとえば `https://auth.example.com` が含まれているか確かめてください。まだなければ、サイトキーの Cap 設定でそれを設定します。

## 4. オーソライザーとチャレンジのリダイレクトを配線する

二つの `location` ブロック：内部の **オーソライザー** サブリクエストと、プロキシが `401` で飛ぶ **チャレンジ** リダイレクトです。`YOUR_SITE_KEY` をあなたの公開鍵に置き換えます。

```nginx
# 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 属性がなぜ重要かも含む完全な契約は、[リバースプロキシのレシピ](/docs/proxy-page-gate/reverse-proxy-recipes#the-callback) にあります。最小限：

```js
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 を読み込みます。プレビューがオンなので、あなたはまっすぐ通りますが、[統計ページ](/docs/proxy-page-gate/statistics) は `challenge_served` を記録し（Cookie がなかったため）、解いてコールバックが走ると `pass_issued` を記録します。再読み込みすると `passthrough` が上っていくはずです。チャレンジが決して現れないなら、オーソライザーのブロックが当たっていません。コールバックが 400 を返すなら、`to` のオリジンを確認してください。

## 7. 本番にする

数字が正しく見えたら、**プレビューモード** をオフにします。ゲートは今や強制します。通過許可のない訪問者はゲームへ送られ、解いた訪問者はパスが切れるまで歩き回ります。

## 次にどこへ

- [リバースプロキシのレシピ](/docs/proxy-page-gate/reverse-proxy-recipes)：Traefik、Caddy、そして Authelia の完全な手順。
- [プロキシゲートの統計](/docs/proxy-page-gate/statistics)：本番になったら各数字が何を意味するか。
- [概要](/docs/proxy-page-gate/overview)：概念と、ゲートがあえてしないこと。
