Caputchin
Puerta de proxy

Configura la puerta de proxy con nginx

Ver como Markdown

Al final de este tutorial la puerta estará corriendo delante de un sitio detrás de nginx: un visitante sin despejar es enviado a un juego, un juego resuelto fija una cookie, y las peticiones posteriores pasan de largo. Verás todo el proceso primero en modo vista previa, así nada se bloquea hasta que hayas confirmado el cableado. Aquí se usa nginx; las recetas de Traefik, Caddy y Authelia siguen la misma forma.

1. Enciende el modo vista previa

En el dashboard, abre el equipo y enciende el modo vista previa. Mientras está encendido, el autorizador de la puerta registra las decisiones de reto frente a paso libre en la página de estadísticas pero nunca bloquea. Lo apagarás al final.

2. Activa la puerta en tu clave de sitio

Abre tu clave de sitio y ve a la página Puerta de proxy. Enciende Estado → Activado, luego ajusta:

  • TTL de paso libre: cuánto tiempo despeja a un visitante una sola resolución (por defecto 30 minutos). Más corto significa más re-comprobaciones pero una ventana más pequeña si roban una cookie.
  • Modo de fallo: qué hace tu proxy cuando no puede alcanzar al autorizador de Caputchin. Fallo cerrado bloquea (más seguro para un portal de inicio de sesión); fallo abierto deja pasar las peticiones (evita caídas en un sitio público).

La página también muestra un fragmento de nginx listo para copiar con tu clave de sitio ya rellenada.

3. Permite el origen que estás cerrando con puerta

El reto solo redirige de vuelta a un origen permitido, la misma lista de orígenes permitidos que usa el widget. Asegúrate de que incluya el origen que estás cerrando con puerta, por ejemplo https://auth.example.com. Ponlo en la configuración Cap de la clave de sitio si no está ya ahí.

4. Cablea el autorizador y la redirección al reto

Dos bloques location: una subpetición autorizador interna, y una redirección reto a la que el proxy salta ante un 401. Reemplaza YOUR_SITE_KEY con tu clave pública.

# 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;
}

Pon puerta a las rutas de entrada (el HTML del portal y el POST de inicio de sesión). No pongas puerta a la subpetición del autorizador, a los health checks, ni al callback de abajo.

La página del reto termina auto-enviando un pequeño POST a /__cpt/callback en tu origen, con cpt_gate (el pase) y to (a dónde enviar al visitante) en el cuerpo. Un manejador diminuto fija la cookie y redirige. El contrato completo, incluyendo por qué importa cada atributo de la cookie, está en las recetas de proxy inverso. Lo mínimo:

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. Obsérvala en vista previa

Carga la URL con puerta. Como la vista previa está encendida, pasas de largo, pero la página de estadísticas registra un challenge_served (no tenías cookie) y, una vez que resuelves y corre el callback, un pass_issued. Recarga y deberías ver passthrough subir. Si los retos nunca aparecen, el bloque del autorizador no se está alcanzando; si el callback devuelve 400, revisa el origen to.

7. Sal en vivo

Cuando los números pinten bien, apaga el modo vista previa. La puerta ahora hace cumplir: los visitantes sin despejar son enviados al juego, los visitantes que resuelven recorren hasta que su pase expira.

Adónde ir después

En esta página