Caputchin
Gerbang proxy

Resep reverse proxy dan kontrak callback

Lihat sebagai Markdown

Tiap reverse proxy butuh dua bagian yang sama: sebuah pemeriksaan otorisator yang bertanya ke Caputchin apakah sebuah permintaan membawa pass sah, dan sebuah callback pada origin-mu yang mengubah pass terpecahkan menjadi cookie cpt_gate. Penelusuran nginx menunjukkan bentuknya ujung ke ujung; halaman ini memberi proxy lain, kontrak callback yang tepat, dan contoh Authelia lengkap. Ganti YOUR_SITE_KEY dengan kunci publikmu di mana-mana.

Endpoint-nya sama di mana-mana:

  • Otorisator: GET https://verify.caputchin.com/v1/gate/authz?site=YOUR_SITE_KEY, dengan header Cookie pengunjung diteruskan. 204 berarti izinkan, 401 berarti tantangan.
  • Tantangan: alihkan peramban ke https://verify.caputchin.com/v1/gate/challenge?site=YOUR_SITE_KEY&return=<URL asli>.

Traefik

Pakai middleware forwardAuth untuk otorisator. Traefik meneruskan header Cookie yang masuk secara default. Pada 401 dari middleware, alihkan peramban ke tantangan (sebuah middleware halaman-galat yang menunjuk rute kecil yang mengeluarkan 302, atau tangani 401 di edge-mu).

http:
  middlewares:
    cpt-gate:
      forwardAuth:
        address: "https://verify.caputchin.com/v1/gate/authz?site=YOUR_SITE_KEY"
        # The 401 from forwardAuth is your signal to send the browser to:
        #   https://verify.caputchin.com/v1/gate/challenge?site=YOUR_SITE_KEY&return=<original-url>
  routers:
    portal:
      rule: "Host(`auth.example.com`)"
      middlewares: ["cpt-gate"]
      service: your-app

Caddy

Pakai forward_auth untuk otorisator dan handle_errors untuk mengubah 401 menjadi pengalihan. Ini titik awal; sesuaikan sintaks direktif untuk versi Caddy-mu.

auth.example.com {
  forward_auth https://verify.caputchin.com {
    uri /v1/gate/authz?site=YOUR_SITE_KEY
    copy_headers Cookie
  }
  handle_errors {
    @challenge expression {http.error.status_code} == 401
    redir @challenge https://verify.caputchin.com/v1/gate/challenge?site=YOUR_SITE_KEY&return={scheme}://{host}{uri} 302
  }
  reverse_proxy your-app:8080
}

Callback

Halaman tantangan terhosting menyelesaikan dengan auto-mengirim sebuah formulir POST ke https://<origin-mu>/__cpt/callback dengan dua field di body: cpt_gate (pass) dan to (ke mana mengirim pengunjung). Tambahkan satu rute ini ke origin-mu (atau sebagai location khusus pada proxy). Ia harus:

  1. Membaca cpt_gate dan to dari body POST, tak pernah dari URL (pass di URL bocor ke log dan perujuk).
  2. Memastikan to ada di origin-mu sendiri, dan menolak apa pun selainnya, agar callback tak bisa diubah menjadi open redirect.
  3. Men-set cookie dengan atribut di bawah.
  4. Mengalihkan (303) ke to.
// Any tiny handler on your origin works. Express shown; ~15 lines.
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);
});

Atribut cookie adalah keseluruhan model keamanan. Karena pass tak terikat ke perangkat, HttpOnly (memblokir pencurian oleh skrip), Secure (hanya HTTPS), SameSite=Lax, dan Max-Age pendek (cocokkan dengan TTL izin lewat-mu) adalah yang melindunginya. Juga: jangan catat nilai cpt_gate di access log-mu, dan pertahankan Referrer-Policy: no-referrer pada callback agar pass tak pernah ikut menumpang di header perujuk.

Contoh terpecahkan: Authelia

Portal login Authelia adalah app mono-halaman terkompilasi tanpa tempat untuk menyisipkan widget dan tanpa hook plugin, jadi gerbang adalah cara melindunginya. Authelia sudah duduk di balik sebuah reverse proxy (begitulah ForwardAuth-nya sendiri bekerja), dan proxy itulah tempat gerbang berada. Authelia sendiri dibiarkan sepenuhnya tanpa modifikasi.

Pasang gerbang pada vhost portal (misalnya auth.example.com):

  • Gerbangi HTML portal dan endpoint login faktor-pertama (/api/firstfactor).
  • Kecualikan endpoint verify milik ForwardAuth Authelia sendiri (/api/verify), yang proxy panggil untuk tiap permintaan upstream terlindungi. Menggerbanginya akan merusak tiap app terlindungi di balik Authelia.
  • Kecualikan health check dan aset statis yang halaman tantangan itu sendiri butuhkan.
  • Tambahkan rute /__cpt/callback seperti di atas.

Gerbang menjauhkan bot dari portal; Regulation bawaan Authelia (batas percobaan ulang dan ban) tetap membatasi percobaan ulang kredensial bagi siapa pun yang lolos, jadi kedua lapisan bertumpuk. Gerbang melindungi hanya portal interaktif (UI login dan persetujuan); ia tak menggerbangi, dan tak seharusnya, endpoint token non-interaktif.

Lihat juga

  • Siapkan gerbang proxy: penelusuran nginx dan rollout mode-pratinjau-dulu.
  • Ikhtisar: konsepnya dan cookie izin lewat.
  • Statistik: pastikan penyambungan dengan mengamati tantangan lawan lolos langsung.

Di halaman ini