A támadási térképen sűrű folt ül egy ország fölött, és magától kínálkozik a szabály: „tiltsuk le az egészet”. Szinte semmit nem ad: a kilépési ország cseréje néhány percébe kerül a támadónak, a tiltás alá viszont a saját látogatóink esnek, meg mi magunk utazás közben. Ami rosszabb: a látható, egyetlen felhőből érkező robot a tiltás után lakossági címekre költözik, és megkülönböztethetetlenné válik az emberektől.
Alább öt lépés következik, amely ugyanazon a szerveren valóban eredményt hoz: vágjuk el a szkennereket, korlátozzuk az ütemet, ne vágjuk el a szükségeset, és ha mégis kell, tiltsunk helyesen. Mindez egyetlen nekifutásra ellenőrizhető és beállítható.
1. lépés. Nézzük meg, ki hozza létre valójában a foltot
Először keressük meg a kéréseket rögzítő naplót. Több webhelyet kiszolgáló szerveren az access.log gyakran üres, a bejegyzések pedig az adott virtuális kiszolgáló naplójába kerülnek:
sudo ls -lS /var/log/apache2/*access*.log /var/log/apache2/*requests*.log 2>/dev/null
A további parancsokban mindig azt a fájlt helyettesítsük be, amelyik a lista élére került. Előbb a nap vezető címei, aztán hogy pontosan mit kér a lista tetején álló:
sudo awk '{print $1}' /var/log/apache2/access.log | sort | uniq -c | sort -rn | head -20
sudo grep '^203\.0\.113\.' /var/log/apache2/access.log | awk '{print $7}' | sort | uniq -c | sort -rn | head -20
A második parancs válaszol a fő kérdésre. Ha a kimenetben a saját webhelyünk tucatnyi különböző oldala szerepel, tartalomgyűjtőről van szó: ártalmatlan, és elég annyi, hogy ne számítsuk látogatónak. Ha viszont /wp-login.php, /.env, /phpmyadmin és más olyasmi áll ott, ami nálunk nincs is, az szkenner, és vele a 2. lépés foglalkozik. Az nginxnél a naplók a /var/log/nginx/ könyvtárban vannak, a mezők ugyanazok.
2. lépés. Jail az olyasmire irányuló kérésekre, amink nincs
A kért útvonalat nem lehet hamisítani — a címmel és a User-Agenttel ellentétben maga a szándék. A szűrő, /etc/fail2ban/filter.d/web-probes.local:
[Definition]
failregex = ^<HOST> .* "(GET|POST|HEAD) /(wp-login\.php|wp-admin|xmlrpc\.php|\.env|\.git/|phpmyadmin|administrator/)
ignoreregex =
A jail, /etc/fail2ban/jail.d/web-probes.local:
[web-probes]
enabled = true
port = http,https
filter = web-probes
logpath = /var/log/apache2/*access.log
maxretry = 1
findtime = 1h
bantime = 1d
Itt a maxretry = 1 indokolt: idegen adminfelületre nem téved be véletlenül senki. Alkalmazzuk, és győződjünk meg róla, hogy a szűrő fog a saját naplónk sorain:
sudo fail2ban-regex /var/log/apache2/access.log /etc/fail2ban/filter.d/web-probes.local
sudo systemctl reload fail2ban && sudo fail2ban-client status web-probes
3. lépés. Korlátozzuk az ütemet
A szkenner és a robot a sebességével árulja el magát, függetlenül attól, melyik országból jön. Percenként harminc oldal egyetlen címről olyan küszöb, amely nem érinti a katalógust lapozgató embert:
[http-flood]
enabled = true
port = http,https
filter = apache-overflows
logpath = /var/log/apache2/site_access.log
maxretry = 30
findtime = 60
bantime = 1h
A döntő részlet az, hogy melyik napló szerepel a logpath sorban. Ha a minta alá esik magának a vezérlőpanelnek vagy az adminfelületnek a naplója, saját magunkat tiltjuk ki: ott egyetlen oldal tucatnyi kérést húz maga után stílusokra és parancsfájlokra, harminc pedig két kattintásból összejön. Ezért a panelnek külön naplófájlt adunk, amely nem illik a jail mintájára, a statikus fájloknak pedig hosszú gyorsítótárazási időt, hogy a böngésző ne kérje le őket minden oldalváltásnál. A tünet, ha mégis megtörténik: a HTML megérkezik, a megjelenés nem, az oldal lóg. A tiltás feloldása:
sudo fail2ban-client set http-flood unbanip 203.0.113.10
4. lépés. Védjük meg azt, amit nem szabad elvágni
Mielőtt bekapcsolnánk a tiltásokat, írjuk fel a kivételeket — különben elsőként éppen a szükséges esik alájuk:
[DEFAULT]
ignoreip = 127.0.0.1/8 ::1 203.0.113.0/24 66.249.64.0/19
Mi az, aminek feltétlenül szerepelnie kell ebben a sorban, és miért:
- A saját címünk vagy az iroda alhálózata. A szerverhez való hozzáférés elvesztésének leggyakoribb oka a saját szabály, nem a támadás;
- A
66.249.64.0/19tartomány. A Google keresőrobotja a User-Agent alapján ismerhető fel, de az a része, amelyik JavaScriptet futtat, közönségesChrome/Linuxnéven érkezik, és nem nevezi meg magát. Minden olyan szabály, hogy „tiltsuk az adatközpontokból érkező forgalmat”, éppen őt találja el, majd az oldalak csendben kiesnek az indexből. A gyanús cím fordított lekérdezéssel ellenőrizhető: adig -x 66.249.66.1 +shortparancsnak agooglebot.comzónába tartozó nevet kell visszaadnia; - A fizetési értesítések címei. A fizetési rendszerek webhookjai AWS- és Azure-kiszolgálókról érkeznek. Ha ezeket a felhőket teljesen lezárjuk, a fizetési visszaigazolások nem jutnak el hozzánk, és akkor szerzünk róla tudomást, amikor az ügyfél azt írja, hogy a pénzt levonták, a hozzáférés viszont nincs meg. A tartományok a fizetési szolgáltató dokumentációjában találhatók.
5. lépés. Ha a tiltás mégis szükséges — alhálózatot tiltsunk, ne országot
Az egyetlen hálózatból érkező tartós sűrűsödés, amely napokig kitart, és egyforma kérések kísérik, egyetlen végrehajtó, aki egy listát jár végig. Az ilyen eset pontszerűen és időre tiltandó:
sudo ufw deny from 198.51.100.0/22 to any
sudo ufw status numbered
A második paranccsal jegyezzük meg a szabály sorszámát: a tiltást később éppen ezen keresztül kell feloldani, sudo ufw delete <sorszám>. Állapodjunk meg magunkkal egy határidőben — mondjuk egy hónapban —, és írjuk be a feloldást a naptárba. Az „örökre” beállított szabályok egy év múlva olyan listává válnak, amelyhez senki sem mer hozzányúlni, mert senki nem emlékszik, mivel kerültek oda azok a címek.
Hogy melyik alhálózatot tiltsuk, az első lépés címéből deríthető ki: whois 198.51.100.17 | grep -iE 'route|cidr|netname'.
Mi változik az öt lépés után
A szkennereket a szándék alapján vágjuk el, nem a származás alapján, és már az első kérésnél fennakadnak. A robotok beleütköznek az ütemkorlátba. A keresőrobot és a fizetési értesítések továbbra is átjutnak. Az egyetlen megmaradt széles tiltás pontszerű, ismert határidővel és érthető okkal.
A térkép közben nem tűnik el, de a szerepe megváltozik: nem arra való, hogy országokat zárjunk ki, hanem hogy a sűrűsödést egyáltalán észrevegyük, és összevessük azzal, ami egy hete volt. Ehhez előzmény kell, nem az aktuális nap pillanatfelvétele. Hogy néz ki egy ilyen térkép a tiltási napló és a nyitott portok listája mellett, azt az alábbi bemutató oldalak mutatják.