Pe harta atacurilor stă o pată densă deasupra unei țări și se impune de la sine regula „interzicem țara în întregime”. Nu va aduce aproape nimic: schimbarea țării de ieșire îl costă pe atacator câteva minute, în schimb sub interdicție vor cădea propriii tăi vizitatori și tu însuți în călătorie. Mai rău, un robot vizibil care vine dintr-un singur nor se va muta, după blocare, pe adrese rezidențiale și va deveni imposibil de deosebit de oameni.
Mai jos sunt cinci pași care pe același server dau într-adevăr rezultat: taie scanerele, limitează ritmul, nu tăia ceea ce îți trebuie și, dacă tot e nevoie, blochează corect. Totul se poate verifica și configura dintr-o singură ședință.
Pasul 1. Vezi cine creează de fapt pata
Întâi găsește jurnalul cererilor. Pe un server cu mai multe site-uri, access.log este adesea gol, în timp ce înregistrările ajung în jurnalul gazdei virtuale respective:
sudo ls -lS /var/log/apache2/*access*.log /var/log/apache2/*requests*.log 2>/dev/null
În toate comenzile următoare se înlocuiește cu fișierul ajuns în capul acelei liste. Mai întâi adresele fruntașe pe zi, apoi ce anume cere cea din vârful listei:
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 doua comandă răspunde la întrebarea principală. Dacă în rezultat apar zeci de pagini diferite ale site-ului tău, este un colector de conținut: e inofensiv și e de ajuns să nu îl socotești vizitator. Dacă acolo apar /wp-login.php, /.env, /phpmyadmin și alte lucruri pe care nu le ai, este un scaner, iar de el se ocupă pasul 2. La nginx jurnalele se află în /var/log/nginx/, câmpurile sunt aceleași.
Pasul 2. Un jail pentru cererile către ceea ce nu ai
Calea cerută nu poate fi falsificată — ea însăși este intenția, spre deosebire de adresă și de User-Agent. Filtrul /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 =
Jail-ul /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
Aici maxretry = 1 este justificat: nimeni nu ajunge din întâmplare în panoul de administrare al altcuiva. Aplică și asigură-te că filtrul prinde rânduri din propriul tău jurnal:
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
Pasul 3. Limitează ritmul
Scanerul și robotul se dau de gol prin viteză, indiferent din ce țară vin. Treizeci de pagini pe minut de la o singură adresă este un prag care nu atinge omul care răsfoiește un catalog:
[http-flood]
enabled = true
port = http,https
filter = apache-overflows
logpath = /var/log/apache2/site_access.log
maxretry = 30
findtime = 60
bantime = 1h
Detaliul hotărâtor este ce jurnal apare în logpath. Dacă sub tipar intră jurnalul panoului de administrare însuși sau al zonei de admin, te vei bloca singur: o singură pagină de acolo trage după ea vreo zece cereri către stiluri și scripturi, iar treizeci se adună din două clicuri. De aceea panoului i se dă un fișier de jurnal separat, care nu se potrivește cu tiparul jail-ului, iar fișierelor statice un termen lung de păstrare în memoria tampon, ca browserul să nu le ceară din nou la fiecare pagină. Semnul, dacă totuși s-a întâmplat: HTML-ul ajunge, aspectul nu, pagina atârnă. Ridicarea blocării:
sudo fail2ban-client set http-flood unbanip 203.0.113.10
Pasul 4. Protejează ceea ce nu trebuie tăiat
Înainte de a porni blocările, notează excepțiile — altfel primul lucru care cade sub ele este tocmai cel necesar:
[DEFAULT]
ignoreip = 127.0.0.1/8 ::1 203.0.113.0/24 66.249.64.0/19
Ce trebuie neapărat să fie pe acest rând și de ce:
- Propria ta adresă sau subrețeaua biroului. Cea mai frecventă cauză a pierderii accesului la server este propria regulă, nu un atac;
- Intervalul
66.249.64.0/19. Robotul de căutare Google se recunoaște după User-Agent, însă acea parte a lui care execută JavaScript vine ca unChrome/Linuxobișnuit și nu se prezintă. Orice regulă de felul „blocăm traficul din centrele de date” lovește tocmai în ea, după care paginile ies tăcut din index. O adresă suspectă poate fi verificată printr-o interogare inversă:dig -x 66.249.66.1 +shorttrebuie să întoarcă un nume din zonagooglebot.com; - Adresele notificărilor de plată. Webhook-urile sistemelor de plată sosesc de pe servere AWS și Azure. Dacă închizi acești nori în întregime, confirmările de plată nu mai ajung, iar vei afla despre asta atunci când un client îți scrie că banii au fost luați, dar accesul lipsește. Intervalele se iau din documentația furnizorului tău de plăți.
Pasul 5. Dacă blocarea e totuși necesară — blochează o subrețea, nu o țară
O îngroșare stabilă dintr-o singură rețea, care ține zile la rând și este însoțită de cereri de același fel, înseamnă un singur executant care merge pe o listă. Acest caz se blochează punctual și pe timp limitat:
sudo ufw deny from 198.51.100.0/22 to any
sudo ufw status numbered
Cu a doua comandă reține numărul regulii: blocarea va trebui ridicată tocmai prin el, sudo ufw delete <număr>. Stabilește cu tine însuți un termen — de pildă o lună — și trece ridicarea în calendar. Regulile puse „pentru totdeauna” se transformă, după un an, într-o listă de care nimeni nu îndrăznește să se atingă, fiindcă nimeni nu mai ține minte pentru ce au ajuns acolo acele adrese.
Ce subrețea să blochezi poți afla pornind de la adresa din primul pas: whois 198.51.100.17 | grep -iE 'route|cidr|netname'.
Ce se schimbă după acești cinci pași
Scanerele sunt tăiate după intenție, nu după proveniență, și sunt prinse de la prima cerere. Roboții se lovesc de limita de ritm. Robotul de căutare și notificările de plată trec mai departe. Singura blocare rămasă largă este punctuală, cu termen cunoscut și motiv limpede.
Harta nu dispare între timp, dar rolul ei se schimbă: nu este acolo pentru a închide țări, ci pentru a observa însăși îngroșarea și a o compara cu ce era cu o săptămână în urmă. Pentru asta e nevoie de un istoric, nu de o fotografie a zilei curente. Cum arată o astfel de hartă alături de jurnalul blocărilor și de lista porturilor deschise arată paginile demonstrative de mai jos.