Integraties
Forward auth voor nginx, Apache en HAProxy
Eén kleine container die nginx, Nginx Proxy Manager, Apache, HAProxy, Traefik of Caddy bij elk verzoek raadpleegt.
Installatie
- 1Voeg een forward-auth-site toe in het dashboard en kopieer de Site-ID.
- 2Draai de gate op het Docker-netwerk van je proxy met je API-sleutel en de Site-ID. Publiceer zijn poort niet.
- 3Voeg de snippet voor je proxy toe.
ghcr.io/ipscanner/forward-auth is een statische binary voor linux/amd64 en linux/arm64 die zonder root en zonder shell draait. Binaries voor Linux en macOS staan op de releasepagina.
Een nieuwe site start in monitor-modus: hij voegt headers toe en blokkeert niets tot je overschakelt naar enforce.
Overzicht op de pagina voor nginx, Apache en HAProxy, broncode op GitHub.
services:
ipscanner:
image: ghcr.io/ipscanner/forward-auth:0.1
restart: unless-stopped
environment:
IPSCANNER_API_KEY: ${IPSCANNER_API_KEY}
SITE_ID: site_...Snippets per proxy
- nginx
auth_requestauth_requestvraagt/checknaar elk verzoek. Een geblokkeerde bezoeker krijgt de 403-pagina van de gate, en een onbereikbare gate laat verkeer door. nginx zoekt de gate op bij het starten, dus start de gate eerst. - Nginx Proxy Manager
auth_requestHetzelfde, geplakt in het tabblad Advanced van de proxy host, met de gate op het Docker-netwerk van NPM.
- Traefik
ForwardAuthEen ForwardAuth-middleware in de labels van je app. De Traefik-plugin doet hetzelfde zonder container.
- Caddy
forward_authforward_authnaar/check, met deX-IPScanner-*-headers overgenomen. De Caddy-module doet hetzelfde zonder container. - HAProxy
UPSTREAM_URLProxy-modus met
UPSTREAM_URL=http://app:80. De app is de backupserver, dus verkeer loopt door als de gate down is. - Apache
UPSTREAM_URLProxy-modus zoals bij HAProxy, met de app als hot standby.
location / {
auth_request /_ipscanner;
auth_request_set $ipscanner_status $upstream_http_x_ipscanner_status;
auth_request_set $ipscanner_class $upstream_http_x_ipscanner_class;
auth_request_set $ipscanner_action $upstream_http_x_ipscanner_action;
auth_request_set $ipscanner_network $upstream_http_x_ipscanner_network_class;
auth_request_set $ipscanner_anonymized $upstream_http_x_ipscanner_anonymized;
auth_request_set $ipscanner_risk $upstream_http_x_ipscanner_risk;
auth_request_set $ipscanner_country $upstream_http_x_ipscanner_country;
auth_request_set $ipscanner_site $upstream_http_x_ipscanner_site;
auth_request_set $ipscanner_request_id $upstream_http_x_ipscanner_request_id;
error_page 403 = @ipscanner_blocked;
proxy_set_header X-IPScanner-Status $ipscanner_status;
proxy_set_header X-IPScanner-Class $ipscanner_class;
proxy_set_header X-IPScanner-Action $ipscanner_action;
proxy_set_header X-IPScanner-Network-Class $ipscanner_network;
proxy_set_header X-IPScanner-Anonymized $ipscanner_anonymized;
proxy_set_header X-IPScanner-Risk $ipscanner_risk;
proxy_set_header X-IPScanner-Country $ipscanner_country;
proxy_set_header X-IPScanner-Site $ipscanner_site;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://app:80;
}
location = /_ipscanner {
internal;
proxy_pass http://ipscanner:8080/check;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Original-URI $request_uri;
proxy_set_header X-Original-Method $request_method;
proxy_connect_timeout 1s;
proxy_read_timeout 5s;
error_page 500 502 503 504 = @ipscanner_down;
}
location @ipscanner_down {
return 204;
}
location @ipscanner_blocked {
internal;
proxy_method GET;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
proxy_set_header X-IPScanner-Request-Id $ipscanner_request_id;
rewrite ^ /blocked break;
proxy_pass http://ipscanner:8080;
}Endpoints
/checkforward auth200 met de
X-IPScanner-*-headers, of 403 met de blokkadepagina enX-IPScanner-Request-Id./blockedforward authDe 403-pagina voor het request-ID in
X-IPScanner-Request-Id, voorerror_pagein nginx./healthzbeide modi200 als JSON: versie, modus, site, backoff, laatste fout en het gecachete beleid.
/check leest het oorspronkelijke verzoek uit de headers van de proxy: X-Forwarded-For (of IP_HEADERS), User-Agent, X-Forwarded-Uri of X-Original-URI, en X-Forwarded-Method of X-Original-Method.
Configuratie
IPSCANNER_API_KEYJe API-sleutel. Zonder sleutel gaat elk verzoek ongecheckt door.
IPSCANNER_API_KEY_FILEBestand met de sleutel, voor Docker-secrets. Gaat vóór
IPSCANNER_API_KEY.SITE_IDSite-ID uit het dashboard. Modus en beleid komen dan uit het dashboard.
MODEstandaard monitormonitor of enforce. Met een site heeft alleen monitor effect: de site blijft dan in monitor-modus.
BLOCK_CLASSESstandaard malicious_automationZonder site: klassen die enforce blokkeert, gescheiden door komma's, uit malicious_automation, ai_agent, tor, vpn, proxy, hosting, relay of none.
TRUSTED_PROXIESstandaard privateAdressen en CIDR-bereiken waarvan IP- en URI-headers vertrouwd worden. private, cloudflare, of none voor alleen het peer-adres.
IP_HEADERSstandaard X-Forwarded-ForHeaders die op volgorde gelezen worden van een vertrouwde proxy. Achter Cloudflare:
CF-Connecting-IP.TIMEOUT_MSstandaard 1500Tijdbudget voor één check, in milliseconden. Bij een timeout gaat het verzoek door.
CACHE_TTLstandaard 600Seconden dat een oordeel per site, IP en user agent hergebruikt wordt. Duren zoals 10m werken ook.
CACHE_SIZEstandaard 10000Oordelen in het geheugen.
POLICY_TTLstandaard 30Seconden dat het beleid van de site hergebruikt wordt. Duren werken ook.
SKIP_PATHSstandaard statische bestandenRegex op het pad, hoofdletterongevoelig. Passende verzoeken worden niet gecheckt; leeg checkt elk pad.
UPSTREAM_URLZet proxy-modus aan: toegestane verzoeken gaan naar deze URL.
LISTENstandaard :8080Luisteradres.
HEALTH_PATHstandaard /healthzHealth-endpoint.
BLOCK_MESSAGEstandaard Blocked by IPScanner edge guard.Tekst van de 403-pagina.
IPSCANNER_API_URLstandaard https://ipscanner.ioBasis-URL van de API.
DEBUGstandaard falseLogt elke beslissing op één regel. In proxy-modus komen ook de status-, class- en action-headers op responses.
Ongeldige waarden stoppen de gate bij het starten met een logregel. De API-sleutel wordt nooit gelogd.
Client-IP
TRUSTED_PROXIESX-Forwarded-Forwordt alleen gelezen als de peer in deze lijst staat, de keten terug tot het eerste adres dat geen vertrouwde proxy is. Bij iedereen anders telt het peer-adres.privateDe standaard. Past bij een proxy die de gate via een Docker- of privénetwerk bereikt. Kunnen anderen op dat netwerk de gate bereiken, zet dan het adres van je proxy erin.
:8080Publiceer de poort van de gate niet: alleen je proxy hoort hem te bereiken.
Headers die erbij komen
Bij een 200 van /check, zodat je proxy ze aan de app doorgeeft, en in proxy-modus op het verzoek naar je app. Proxy-modus verwijdert inkomende X-IPScanner-*-headers; de snippets doen dat in de proxy.
X-IPScanner-Statusok, error, timeout, backoff, skippedOf de check gedraaid heeft, en zo niet, waarom.
X-IPScanner-Classhuman, verified_bot, ai_agent, …Verkeersklasse van de bezoeker.
X-IPScanner-Actionallow, flag, block, would_flag, would_blockWat er met het verzoek gebeurde. Monitor-modus geeft
would_flagenwould_block.X-IPScanner-Network-Classresidential_clean, hosting, vpn, tor, …Netwerkklasse van het adres.
X-IPScanner-Anonymizedtrue, falseHet netwerk verbergt waar de bezoeker is.
X-IPScanner-Risk0-100Risicoscore van het adres.
X-IPScanner-CountryDELand van het adres.
X-IPScanner-Sitesite_...De Site-ID, als die gezet is.
Mislukt een check of wordt hij overgeslagen, dan is alleen X-IPScanner-Status gezet.
X-IPScanner-Status: ok
X-IPScanner-Class: ai_agent
X-IPScanner-Action: would_block
X-IPScanner-Network-Class: hosting
X-IPScanner-Anonymized: true
X-IPScanner-Risk: 60
X-IPScanner-Country: US
X-IPScanner-Site: site_4fQ8nZ2kLm7xR1vT9cBwCache en fail open
- Beleid van de siteGET /v1/sites/{id}/policy
Modus en beleid per klasse, 30 s gecachet. Mislukt een verversing, dan blijft het laatste goede beleid 24 uur gelden. Wijzigingen werken zonder herstart.
- Oordeel-cache
Eén check per bezoeker (site, IP, user agent) per 10 minuten, in het geheugen, per gate-instantie.
- Fail open
1,5 s voor oordeel en beleid samen. Bij een timeout of API-fout gaat het verzoek door en pauzeren checks 30 s, of 5 minuten na een 401, 402, 403 of 429.
- Gate down
nginx en NPM laten door na de connect-timeout van 1 s, HAProxy stuurt verkeer meteen naar de app, Apache laat één verzoek mislukken en gebruikt daarna de app. Traefik geeft 500 en Caddy 502, dus draai de gate met
restart: unless-stopped. - Altijd door
Geverifieerde crawlers, OPTIONS-verzoeken, private en loopback-adressen, en paden op de uitzonderingslijst.
- Geblokkeerd
Een 403-pagina met het request-ID. Monitor-modus blokkeert nooit.
- Free-abonnement
Sites op het Free-abonnement blijven in monitor-modus.
- Kosten
2 request-eenheden per bezoeker die niet in de cache zit. Herhaalde verzoeken binnen het cachevenster zijn gratis.
Wat er verstuurd wordt
- POST /v1/edge/checkTelt als 2 verzoeken
Eén call per bezoeker die niet in de cache zit.
- GET /v1/sites/{id}/policyTelt niet mee
Het beleid van de site, als een Site-ID gezet is.
X-IPScanner-Source: forward_authMarkeert de calls in je verkeer en verbruik als die van deze integratie.
User-Agent: ipscanner-forward-auth/<version>De versie, zichtbaar op de pagina van de site in het dashboard.
Request-body
sitestringDe Site-ID, als die gezet is.
ipstringHet adres van de bezoeker.
user_agentstringDe User-Agent van de bezoeker.
headersobjectAccept, Accept-Language, Accept-Encoding, Sec-CH-UA* en Sec-Fetch-*, elk ingekort tot 512 bytes.
request_idstringDe
X-Request-Idvan het verzoek of een nieuw ID, dat ook op de blokkadepagina staat.
curl https://ipscanner.io/v1/edge/check \
-H "Authorization: Bearer $IPSCANNER_API_KEY" \
-H "X-IPScanner-Source: forward_auth" \
-H "User-Agent: ipscanner-forward-auth/0.1.0" \
-H "Content-Type: application/json" \
-d '{
"site": "site_4fQ8nZ2kLm7xR1vT9cBw",
"ip": "203.0.113.7",
"user_agent": "Mozilla/5.0",
"headers": {
"accept-language": "en-US"
},
"request_id": "9f2c41b7d03e77f2"
}'