Forward auth para tu servidor
Un contenedor junto a tu servidor revisa cada solicitud en busca de bots, Tor, VPN y proxies. Empieza en modo monitor y no bloquea nada hasta que cambies.
Gratis, licencia MITDocker, amd64 y arm64
Clases de tráfico
Cada clase llega a tu app como X-IPScanner-Class. Permítela, márcala o bloquéala por sitio en el panel.
malicious_automation
ai_agent
tor
vpn
proxy
hosting
relay
verified_bot
human
Instalación
El plan gratis basta para empezar.
IPSCANNER_API_KEY
pk_live_••••••••3f9a
En la misma red Docker que tu proxy. No publiques su puerto.
services:
ipscanner:
image: ghcr.io/ipscanner/forward-auth:0.1
restart: unless-stopped
environment:
IPSCANNER_API_KEY: ${IPSCANNER_API_KEY}
SITE_ID: site_...SITE_IDEl panel guarda entonces la política del sitio y muestra su tráfico.
SITE_ID
site_4fQ8nZ2kLm7xR1vT9cBw
Elige tu servidor abajo. Cada fragmento está probado de punta a punta.
Configuración del servidor
Copia el de tu configuración. Traefik y Caddy también funcionan con el mismo contenedor.
Va en tu bloque server. Inicia primero la pasarela: nginx resuelve ipscanner al arrancar.
Pasarela caída: pasan tras 1 s
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;
}Ajustes
Defínelas en el contenedor. CACHE_TTL y POLICY_TTL también aceptan valores como 10m.
| Variable | Por defecto | Qué hace |
|---|---|---|
IPSCANNER_API_KEYTu clave de API. Sin ella, todas las solicitudes pasanPor defecto:Vacío | Vacío | Tu clave de API. Sin ella, todas las solicitudes pasan |
IPSCANNER_API_KEY_FILELee la clave de un archivo, para Docker secretsPor defecto:Vacío | Vacío | Lee la clave de un archivo, para Docker secrets |
SITE_IDVincula la pasarela a un sitio y su políticaPor defecto:Vacío | Vacío | Vincula la pasarela a un sitio y su política |
MODEmonitor o enforce. Con SITE_ID decide el panel, salvo con monitorPor defecto:monitor | monitor | monitor o enforce. Con SITE_ID decide el panel, salvo con monitor |
BLOCK_CLASSESClases bloqueadas en modo enforce sin SITE_IDPor defecto:malicious_automation | malicious_automation | Clases bloqueadas en modo enforce sin SITE_ID |
TRUSTED_PROXIESProxies cuyo X-Forwarded-For se aceptaPor defecto:private | private | Proxies cuyo X-Forwarded-For se acepta |
IP_HEADERSEncabezados leídos para la IP del visitante, en ordenPor defecto:X-Forwarded-For | X-Forwarded-For | Encabezados leídos para la IP del visitante, en orden |
TIMEOUT_MSTiempo por revisión; después la solicitud pasaPor defecto:1500 | 1500 | Tiempo por revisión; después la solicitud pasa |
CACHE_TTLSegundos que se reutiliza un veredicto por visitantePor defecto:600 | 600 | Segundos que se reutiliza un veredicto por visitante |
CACHE_SIZEVeredictos guardados en memoriaPor defecto:10000 | 10000 | Veredictos guardados en memoria |
POLICY_TTLSegundos que se reutiliza la política de un sitioPor defecto:30 | 30 | Segundos que se reutiliza la política de un sitio |
SKIP_PATHSRegex de ruta que omite la revisiónPor defecto:Archivos estáticos | Archivos estáticos | Regex de ruta que omite la revisión |
UPSTREAM_URLActiva el modo proxy y envía aquí las solicitudes permitidasPor defecto:Vacío | Vacío | Activa el modo proxy y envía aquí las solicitudes permitidas |
LISTENDirección de escuchaPor defecto::8080 | :8080 | Dirección de escucha |
HEALTH_PATHEndpoint de saludPor defecto:/healthz | /healthz | Endpoint de salud |
BLOCK_MESSAGETexto de la página 403Por defecto:Blocked by IPScanner edge guard. | Blocked by IPScanner edge guard. | Texto de la página 403 |
IPSCANNER_API_URLURL base de la APIPor defecto:https://ipscanner.io | https://ipscanner.io | URL base de la API |
DEBUGUna línea de log por decisiónPor defecto:false | false | Una línea de log por decisión |
Contenedor
GET /healthz siempre responde 200 y muestra qué hace la pasarela.
{
"status": "ok",
"version": "0.1.0",
"mode": "forward_auth",
"enabled": true,
"site": "site_4fQ8nZ2kLm7xR1vT9cBw",
"backoff": false,
"policyMode": "monitor",
"policyVersion": 3,
"cachedVerdicts": 128
}ghcr.io/ipscanner/forward-auth:0.1
Preguntas
Ejecuta la pasarela, lee una semana de decisiones y luego bloquea.