nginx로 프록시 게이트 설정하기
이 튜토리얼이 끝나면 게이트는 nginx 뒤의 사이트 앞에서 돌고 있을 것입니다. 통과되지 않은 방문자는 게임으로 보내지고, 풀린 게임은 쿠키를 설정하며, 이후 요청은 곧장 통과합니다. 당신은 먼저 그 전체를 미리보기 모드에서 지켜볼 테니, 배선을 확인하기 전까지는 아무것도 막히지 않습니다. 여기서는 nginx를 씁니다. Traefik, Caddy, Authelia 레시피는 같은 형태를 따릅니다.
1. 미리보기 모드를 켭니다
대시보드에서 팀을 열고 미리보기 모드를 켭니다. 켜진 동안, 게이트 인가자는 챌린지 대 통과 결정을 통계 페이지에 기록하지만 결코 막지 않습니다. 마지막에 끄게 됩니다.
2. 사이트 키에서 게이트를 활성화합니다
사이트 키를 열고 프록시 게이트 페이지로 갑니다. 상태 → 활성화를 켠 뒤 설정합니다:
- 통과 TTL: 한 번의 풀이가 방문자를 얼마나 오래 통과시키는지(기본값 30분). 짧을수록 재확인이 많아지지만 쿠키가 도난당했을 때의 창은 작아집니다.
- 실패 모드: 프록시가 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. 쿠키를 설정하는 콜백을 더합니다
챌린지 페이지는 끝에 당신 오리진의 /__cpt/callback으로 작은 POST를 자동 제출하며, 본문에 cpt_gate(패스)와 to(방문자를 어디로 보낼지)를 담습니다. 아주 작은 핸들러가 쿠키를 설정하고 리디렉션합니다. 각 쿠키 속성이 왜 중요한지를 포함한 전체 계약은 리버스 프록시 레시피에 있습니다. 최소한:
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를 기록하고(당신에게 쿠키가 없었으므로), 당신이 풀고 콜백이 돌면 pass_issued를 기록합니다. 새로고침하면 passthrough가 오르는 것을 봐야 합니다. 챌린지가 결코 나타나지 않으면 인가자 블록이 맞지 않는 것이고, 콜백이 400을 내면 to 오리진을 확인하세요.
7. 라이브로 갑니다
숫자가 옳아 보이면 미리보기 모드를 끕니다. 게이트는 이제 강제합니다. 통과되지 않은 방문자는 게임으로 보내지고, 푼 방문자는 그의 패스가 만료될 때까지 돌아다닙니다.
다음으로 갈 곳
- 리버스 프록시 레시피: Traefik, Caddy, 그리고 Authelia 전체 안내.
- 프록시 게이트 통계: 라이브가 되면 각 숫자가 무엇을 뜻하는지.
- 개요: 개념과 게이트가 일부러 하지 않는 것.