Caputchin
Porte de page au proxy

Configurer la porte de page au proxy avec nginx

Voir en Markdown

À la fin de ce tutoriel, la porte tournera devant un site derrière nginx : un visiteur non dégagé est envoyé à une vérification, la passer pose un cookie, et les requêtes suivantes passent tout droit. Tu observeras tout le processus d'abord en mode aperçu, pour que rien ne soit bloqué tant que tu n'as pas confirmé le câblage. Ici on utilise nginx ; les recettes Traefik, Caddy et Authelia suivent la même forme.

1. Active le mode aperçu

Dans le tableau de bord, ouvre l'équipe et active le mode aperçu. Tant qu'il est actif, l'autorisateur de la porte note les décisions défi contre passage direct sur la page de statistiques mais ne bloque jamais. Tu le désactiveras à la fin.

2. Active la porte sur ta clé de site

Ouvre ta clé de site et va à la page Porte de proxy. Active État → Activé, puis règle :

  • Type de défi : Jouer à un jeu (par défaut) ou Confirmer avec une case à cocher. Une clé de site qui exige un jeu montre toujours un jeu, et la page le dit. Choisir un jeu demande au moins un jeu installé avec un artefact rejouable.
  • TTL de laissez-passer : combien de temps une seule résolution dégage un visiteur (par défaut 30 minutes). Plus court veut dire plus de re-contrôles mais une fenêtre plus petite si un cookie est volé.
  • Mode d'échec : ce que ton proxy fait quand il ne peut pas atteindre l'autorisateur de Caputchin. Fail-closed bloque (plus sûr pour un portail de connexion) ; fail-open laisse passer les requêtes (évite les coupures sur un site public).

Laisse Langue et Thème sur suivre le visiteur : la vérification parle alors la langue du visiteur, suit sa préférence clair ou sombre, et porte automatiquement la marque de cette clé de site. Sous Avancé, tu peux renommer le cookie de la porte, déplacer le chemin du callback, et restreindre la porte à certains chemins ; cette marche à suivre utilise les valeurs par défaut. Vois Personnalise le défi.

La page montre aussi un extrait nginx prêt à copier avec tes réglages déjà remplis. Les réglages mettent jusqu'à dix secondes à atteindre l'edge après que tu les changes.

3. Autorise l'origine que tu protèges

La vérification ne redirige jamais que vers une origine autorisée, la même liste d'origines autorisées qu'utilise le widget. Assure-toi qu'elle inclut l'origine que tu protèges, par exemple https://auth.example.com. Mets-la dans la configuration Cap de la clé de site si elle n'y est pas déjà.

4. Câble l'autorisateur et la redirection vers le défi

Deux blocs location : une sous-requête autorisateur interne, et une redirection défi vers laquelle le proxy saute sur un 401. Remplace YOUR_SITE_KEY par ta clé publique.

# Gate the protected paths.
location / {
  auth_request /_cpt_authz;             # 204 = allow, 401 = challenge
  error_page 401 = @cpt_challenge;
  proxy_intercept_errors on;
  error_page 500 502 503 504 = @cpt_unreachable;
  # ...proxy_pass to your app...
}

location = /_cpt_authz {
  internal;
  auth_request off;
  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
  proxy_connect_timeout 2s;
  proxy_read_timeout 2s;
}

location @cpt_challenge {
  return 302 https://verify.caputchin.com/v1/gate/challenge?site=YOUR_SITE_KEY&return=$scheme://$host$request_uri;
}

# This is your fail mode. `return 403` blocks when Caputchin is unreachable
# (fail closed); `return 204` lets the request through (fail open).
location @cpt_unreachable {
  return 403;
}

L'autorisateur ne répond jamais que 204 ou 401, donc tout le reste, timeout compris, veut dire que Caputchin est injoignable et que ton mode d'échec décide. Copie l'extrait depuis le tableau de bord et il correspond déjà au mode d'échec que tu as choisi.

Mets une porte aux chemins d'entrée (le HTML du portail et le POST de connexion). Ne mets pas de porte à la sous-requête de l'autorisateur, aux health checks, ni au callback ci-dessous.

La page de vérification se termine en auto-envoyant un petit POST vers /__cpt/callback sur ton origine (ou vers le chemin de callback que tu as réglé), avec cpt_gate (le laissez-passer) et to (où envoyer le visiteur) dans le corps. Le champ s'appelle cpt_gate même si tu as renommé le cookie. Un handler minuscule pose le cookie et redirige. Le contrat complet, y compris pourquoi chaque attribut de cookie compte, est dans les recettes de proxy inverse. Le minimum :

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. Observe-la en aperçu

Charge l'URL protégée. Comme l'aperçu est actif, tu passes tout droit, mais la page de statistiques note un challenge_served (tu n'avais pas de cookie) et, une fois que tu résous et que le callback tourne, un pass_issued. Recharge et tu devrais voir passthrough grimper. Si les défis n'apparaissent jamais, le bloc de l'autorisateur n'est pas atteint ; si le callback renvoie 400, vérifie l'origine to.

7. Passe en direct

Quand les chiffres ont bonne allure, désactive le mode aperçu. La porte fait maintenant respecter la règle : les visiteurs non dégagés sont envoyés au jeu, les visiteurs qui résolvent se promènent jusqu'à ce que leur laissez-passer expire.

Où aller ensuite

Sur cette page