Botvédelem reverse proxy-ban: Nginx, HAProxy és Traefik

Hogyan építs botvédelmet a web szervered elé, mielőtt a kérés egyáltalán eljutna a backendig.

Miért a proxy-ban?

A botvédelem leghatékonyabb helye nem az alkalmazás, hanem a reverse proxy réteg. Itt van három jó ok:

  1. Korai elkapás — a rossz kéréseket már a connect/fázisban vagy a header-feldolgozás közben elutasíthatod, mielőtt a backend bármilyen erőforrást felhasználna.
  2. Egységes védelem — egy proxy több backend szolgáltatást is véd, függetlenül attól, hogy Node.js, PHP, Python vagy Go fut mögötte.
  3. Teljesítmény — egy return 444 (Nginx) vagy http-request deny (HAProxy) mikroszekundumok alatt fut, míg egy WAF-szabály vagy alkalmazásbeli ellenőrzés ezerszer lassabb.

Ebben a cikkben végigmegyünk a három legnépszerűbb reverse proxy botvédelmi lehetőségein — konfigurációs példákkal.

1. réteg: User-Agent szűrés

A legegyszerűbb és leggyorsabb védelem: bizonyos User-Agent stringeket már a proxy szintjén elutasítunk.

Nginx — map-alapú User-Agent blokkolás

Az if-alapú megoldás egyszerű, de sok blokkolt User-Agent esetén lassú. A map hash-táblát használ, és hatékonyabban kezeli a növekvő szabálylistákat:

# http blokkban
map $http_user_agent $blocked_ua {
    default 0;

    # Üres User-Agent — durva szkennerek jellemzője
    "" 1;

    # Önmagukat azonosító szkennerek/scraperek
    ~*(?:curl|wget|python-requests|httpclient|libwww-perl) 1;
    ~*(?:go-http-client|aiohttp|scrapy|node-fetch) 1;

    # SEO-szkennerek, letöltők
    ~*(?:HTTrack|SiteSucker|Teleport|WebCopier) 1;
    ~*(?:Nimbostratus|MJ12bot|MegaIndex) 1;
}

# server blokkban
if ($blocked_ua) { return 403; }

HAProxy — ACL + fájl alapú blokkolás

A HAProxy ACL-eket használ, és a blokkolt User-Agent-eket külön fájlban tarthatod:

# /etc/haproxy/bad-bots.txt — egy string soronként
python-requests
go-http-client
scrapy
curl/
wget/
frontend fe_main
    bind :80

    acl is_bad_bot hdr_sub(user-agent) -i -f /etc/haproxy/bad-bots.txt
    http-request deny deny_status 403 if is_bad_bot

Traefik — Bot Wrangler plugin

A Bot Wrangler plugin automatikusan lekéri a legfrissebb LLM-bot User-Agent listáját az ai-robots-txt adatbázisból, és Aho-Corasick algoritmust használ a gyors egyeztetéshez:

# statikus konfiguráció
experimental:
  plugins:
    wrangler:
      moduleName: github.com/holysoles/bot-wrangler-traefik-plugin
      version: v0.5.0

# dinamikus konfiguráció
http:
  middlewares:
    bot-wrangler:
      plugin:
        wrangler:
          botAction: BLOCK
          botBlockHttpCode: 403

Fontos: a User-Agent blokkolás soha nem lehet az egyetlen védelmi réteg — bármely kliens bármilyen User-Agent-et küldhet. De a nyers szkennerek és a lusta botok ellen gyors és olcsó megoldás.

2. réteg: Rate limiting és viselkedéselemzés

Ha az User-Agent-szűrés nem elég, a következő lépés a kliensek viselkedésének figyelése: kérési sebesség, egyedi oldalak száma, hibaarány.

Nginx — limit_req + Fail2Ban

# Kapcsolási sebesség korlátozása
limit_conn_zone $binary_remote_addr zone=perIP:10m;
limit_conn perIP 10;

# Kérésmérete korlátozása (botok néha nagy POST-okat küldenek)
client_max_body_size 1m;
client_body_timeout 10s;
client_header_timeout 10s;

Fail2Ban-nel automatizálhatod az ismételten visszaélő IP-k tűzfal-szintű tiltását:

# /etc/fail2ban/filter.d/nginx-badbots.conf
[Definition]
failregex = ^<HOST> .* "(GET|POST) /(wp-login\.php|xmlrpc\.php|\.env|\.git|cgi-bin/).*" (403|404)
ignoreregex =

# /etc/fail2ban/jail.d/nginx-badbots.conf
[nginx-badbots]
enabled = true
filter = nginx-badbots
logpath = /var/log/nginx/access.log
maxretry = 15
findtime = 10m
bantime = 6h

HAProxy — stick table alapú viselkedéselemzés

A HAProxy egyik legerősebb funkciója a stick table — memóriában tárolt számlálók, amelyek valós idejű viselkedési mintákat követnek nyomon:

backend per_ip_rates
    stick-table type ip size 1m expire 24h store gpc0,gpc0_rate(30s),http_err_rate(5m)

frontend fe_main
    bind :80
    http-request track-sc0 src table per_ip_rates

    # Új oldalak száma: ha 30 másodperc alatt 15-nél több egyedi oldalt kér → bot
    acl exceeds_limit sc_gpc0_rate(0) gt 15
    http-request sc-inc-gpc0(0) if { sc_http_req_rate(1) eq 1 } !exceeds_limit
    http-request deny if exceeds_limit

    # Hibás válaszok aránya: ha 5 perc alatt 10-nél több 4xx → szkenner
    acl scanner sc_http_err_rate(0) gt 10
    http-request deny if scanner

A stick table előnye: nincs külső adatbázis, minden a memóriában történik, és a számlálók automatikusan lejárnak (expire).

Traefik — RateLimit middleware

http:
  middlewares:
    rate-limit:
      rateLimit:
        average: 100       # átlagos kérések/másodperc
        burst: 50          # rövid ideig megengedett túllépés
        period: 1s
        sourceCriterion:
          ipStrategy:
            depth: 1        # X-Forwarded-For mélység (CDN mögött)

3. réteg: JavaScript challenge (testcookie / Anubis)

Ha egy bot User-Agent-et hamisít és rate limitet is betart, a következő lépés a böngésző-képesség ellenőrzése: a kliensnek futtatnia kell egy egyszerű JavaScript kihívást.

Nginx — testcookie modul

A testcookie modul cookie-alapú challenge-response mechanizmust valósít meg — a valódi böngészők automatikusan átmennek rajta, a statikus HTTP-kliensek nem:

http {
    testcookie on;
    testcookie_name BPC;
    testcookie_secret "Legalább32KarakterHosszúTitkosKulcs123";
    testcookie_session $remote_addr;
    testcookie_max_attempts 3;
    testcookie_fallback /blocked.html;

    server {
        listen 443 ssl;
        location / {
            testcookie on;
            proxy_pass http://backend;
        }

        location = /blocked.html {
            internal;
            return 403 "Kérjük, engedélyezd a JavaScriptet és a cookie-kat.";
        }
    }
}

Nginx — Abuse Guard (kereskedelmi)

A GetPageSpeed Abuse Guard modulja valós idejű hibaarány-figyelést végez: ha egy kliens túl sok 403/404 választ generál, automatikusan kitiltja. A döntés a Nginx worker folyamatban történik, külső folyamat nélkül:

abuse_guard_zone  zone=clients:10m
                  statuses=403,404
                  interval=300s
                  threshold=100
                  block=60m;

server {
    abuse_guard zone=clients;
}

HAProxy — JavaScript challenge (Enterprise)

A HAProxy Enterprise Antibot modulja JavaScript kihívást küld a gyanús klienseknek — a statikus botok meghalnak, a valódi böngészők észre sem veszik. Nyílt forráskódú alternatívaként a Nepenthes tarpit megoldás használható: a botokat egy lassú, labirintusszerű válaszba tereli, amely időt és erőforrást pazarol.

4. réteg: TLS-ujjlenyomat és CrowdSec

TLS-fingerprint (JA3/JA4)

Ahogy az előző cikkben (Web scraping a valóságban) láttuk, a TLS ClientHello üzenetből számolt JA3/JA4 ujjlenyomat megbízhatóan azonosítja a klienst — még akkor is, ha a HTTP-fejlécek hamisítva vannak. Az abuse.ch SSLBL közzéteszi az ismert rosszindulatú szoftverek és botnet-hálózatok JA3 lenyomatait.

A nginx-http-sentinel-module (kísérleti) ezt az elméletet valósítja meg: minden kérést több szignál alapján pontoz (bot User-Agent, hibaarány, scanner-útvonalak, sebesség, datacenter ASN, TLS/TCP ujjlenyomat), és a pontszám alapján dönt — allow, challenge, tarpit, vagy block.

CrowdSec — közösségi alapú fenyegetésintelligencia

A CrowdSec egy ingyenes, nyílt forráskódú megoldás, amely közösségi alapú fenyegetési adatbázist épít: minden telepítés jelenti a rosszindulatú IP-címeket, és a központi szerver aggregálja és terjeszti ezeket. Támogatja a Nginx-et, HAProxy-t és a Traefik-et is.

# Telepítés
curl -s https://packagecloud.io/install/repositories/crowdsec/crowdsec/script.deb.sh | sudo bash
apt install crowdsec crowdsec-firewall-bouncer-nginx

A CrowdSec bouncer a tűzfal szintjén blokkolja a jelentett IP-címeket, a蜜蜜蜜蜜 (honeypot) modulok pedig csapdába ejtik a szkennereket.

Összehasonlítás

Réteg Nginx HAProxy Traefik
User-Agent-szűrésmap + ifACL + fájlBot Wrangler plugin
Rate limitlimit_req / limit_connstick tableRateLimit middleware
JS challengetestcookie modulEnterprise AntibotNepenthes tarpit
ViselkedéselemzésAbuse Guard / nginx-autoblockstick table gpc0Botfilter plugin
TLS-fingerprintnginx-http-sentinel (kísérleti)--
Közösségi fenyegetésadatCrowdSec bouncerCrowdSec bouncerCrowdSec bouncer

Gyakorlati tanácsok

  • Rétegezd a védelmet. Ne támaszkodj egyetlen megoldásra: User-Agent-szűrés + rate limit + JS-challenge kombináció a leghatékonyabb.
  • Ne blokkold a keresőrobotokat. A Googlebot, Bingbot és társaik IP-tartományai publikusak — engedélyezd őket, különben a SEOrangSOROdasod romlik. A bot-verifier modul reverse DNS ellenőrzéssel igazolja, hogy a kérés valóban a Google szervereiről jön.
  • Használj honeypot-okat. Rejtett linkek és útvonalak (pl. /iamabot/, /.env) csapdába ejtik azokat a botokat, amelyek nem olvassák el a robots.txt-et. Aki ezekre kattint, automatikusan tiltólistára kerül.
  • Monitorozd a naplókat. A legjobb botvédelem is csak akkor működik, ha figyelsz a naplókra. Állíts be külön naplóformátumot a bot-kéréseknek, és rendszeresen nézd át a tiltásokat.
  • Ne feledd: a botvédelem nem WAF. A reverse proxy-ban lévő botvédelem a nem kívánt automatizált forgalmat szűri — a SQL injection, XSS és egyéb alkalmazásszintű támadások ellen továbbra is WAF (pl. ModSecurity, Coraza) kell.

Etika és jog

A botvédelem önmagában semleges eszköz — a használat számít. A robots.txt önkéntes protokoll, de a jóindulatú botok (keresőrobotok, AI-kódkeresők) tiszteletben tartják. A rosszindulatú botok ellen a technikai védelem mellett az ÁSZF-ben és a szerződési feltételekben is hivatkozhatsz az automatizált hozzáférés tilalmára. Nyilvános termékadatok esetén GDPR tipikusan nem merül fel, mert nem személyes adatot kezelsz.