ModSecurity sa skupom pravila OWASP CRS uključi se za deset minuta i isključi tri dana kasnije — pošto se članci prestanu čuvati u administraciji, otpremanje fajlova se pokvari, a kupac ne može da napravi porudžbinu jer je njegova adresa sadržala apostrof. Zaključak „WAF smeta radu" sam se nameće, i pogrešan je: gotovo sve te blokade leče se sa tri ili četiri precizna izuzetka, a sav trik je u tome da se pronađu ispravno.

Nemojte odmah uključivati blokiranje

Prva nedelja je samo posmatranje. U /etc/modsecurity/modsecurity.conf:

SecRuleEngine DetectionOnly

U ovom režimu WAF beleži sve što bi blokirao i ne blokira ništa. Nedelja stvarnog saobraćaja — uključujući vaš sopstveni rad u administraciji, otpremanje slika i kreiranje porudžbine — daje listu stvarnih lažnih pozitiva umesto hipotetičkih. Prelazak na On ima smisla tek kada je ta lista sređena.

Kako CRS radi: ne jedno pravilo nego zbir

Ovo je ključ svega što sledi. CRS gotovo nikada ne blokira zahtev jednim pravilom. Svako pravilo koje se aktivira dodaje zahtevu bodove anomalije, a blokada nastupa kada zbir pređe prag. Zato dnevnik prikazuje ne jedan red nego nekoliko, i zato je poslednji od njih pravilo sa identifikatorom 949110 — ono koje sabira ukupno.

Praktična posledica: izuzetak mora biti napravljen za pravilo koje je dodelilo bodove, a ne za 949110. Isključite pravilo koje sabira i isključili ste ceo skup, a WAF ostaje red u konfiguracionom fajlu.

Druga posledica je nivo paranoje. Podrazumevano je jedan, i to je ispravan izbor. Nivoi 2 i 3 dodaju pravila koja po svojoj prirodi proizvode lažne pozitive na običnim sajtovima i vredi ih uključiti tek kada je prvi nivo potpuno podešen.

Pronađite krivo pravilo

Sve što vam treba nalazi se u revizorskom dnevniku (/var/log/modsec_audit.log) i u dnevniku grešaka veb servera. Tražite po vremenu blokade:

sudo grep -o 'id "[0-9]*"' /var/log/modsec_audit.log | sort | uniq -c | sort -rn | head

To je lista učestalosti pravila koja su se aktivirala. Zatim, za određeni identifikator, pogledajte šta ga je tačno pokrenulo:

sudo grep -A5 'id "942100"' /var/log/modsec_audit.log | head -40

Potrebne su tri stvari: identifikator pravila, naziv parametra (ARGS:content, ARGS:comment) i putanja zahteva. Od njih se gradi izuzetak.

Uobičajeni osumnjičeni

Lista se ponavlja od sajta do sajta:

  • 942100 — SQL injekcija. Aktivira se na tekstualnim poljima sa dugim sadržajem: telo članka, opis proizvoda, komentar. Navodnici, zagrade i reči poput select detektoru izgledaju sumnjivo usred obične proze;
  • 941100 i porodica 941xxx — XSS. Dolaze zajedno sa vizuelnim uređivačem: HTML oznake u polju čitav su smisao načina na koji ono radi;
  • 920420 — nedozvoljen Content-Type. Kvari API-je i otpremanje fajlova: podrazumevani skup dozvoljenih tipova je uzak, a u starijim verzijama application/json u njemu nije ni bio;
  • 913100 — skener po User-Agent-u. Hvata legitimne alate zajedno sa skenerima: praćenje dostupnosti, curl u vašim sopstvenim skriptama;
  • 200002, 200004 — greške razlaganja tela zahteva. Obično ne znače napad nego prekoračeno ograničenje veličine tela, to jest otpremanje velikog fajla.

Tri načina da napravite izuzetak

Po rastućem redu grubosti. Svi idu u vaš sopstveni fajl (na primer /etc/modsecurity/crs/REQUEST-900-EXCLUSION-RULES.conf) a ne u same CRS fajlove: skup pravila se ažurira i vaše izmene bi nestale sa njim.

Uklonite jedan parametar ispod jednog pravila. Najpreciznija opcija, i ona kojoj težite:

SecRuleUpdateTargetById 942100 "!ARGS:content"

Isključite pravilo samo na jednoj putanji. Baš kada određena stranica pravi buku — uređivač, uvoz, forma za ocenu:

SecRule REQUEST_URI "@beginsWith /admin/post" \
    "id:1001,phase:1,pass,nolog,ctl:ruleRemoveById=942100"

Isključite pravilo u celosti. Poslednje sredstvo i gotovo uvek znak da uzrok nikada nije ni pronađen:

SecRuleRemoveById 942100

Razlika između prvog i trećeg je suštinska. U prvom slučaju jedno polje — telo članka — prestaje da se proverava na SQL injekciju jednim pravilom; u drugom i trećem prestaje da se proverava ceo sajt. Razlika u trudu je oko pet minuta.

Posle izmena proverite konfiguraciju i nežno je ponovo učitajte:

sudo apachectl configtest && sudo systemctl reload apache2
sudo nginx -t && sudo systemctl reload nginx

Redosled koji štedi nedelju dana

  1. Nedelja u DetectionOnly sa normalnim radom na sajtu, u administraciji i pri otpremanju.
  2. Lista učestalosti pravila iz revizorskog dnevnika. Radite od vrha nadole — prva tri-četiri čine devedeset odsto šuma.
  3. Za svako: utvrdite koji parametar i na kojoj stranici. Napravite izuzetak po parametru, ne po pravilu.
  4. Tek sada SecRuleEngine On.
  5. Jednom mesečno pogledajte blokade: sajt se promenio, znači pojavili su se novi lažni pozitivi.

Na toj poslednjoj stavci obično sve pada: revizorski dnevnik je gigabajt teksta i niko ga neće čitati ručno. Smisao objedinjenog panela je da pred sobom imate listu pravila koja su se aktivirala, blokirane zahteve i aktivan skup pravila, umesto da ih vadite grep-om. Kako to izgleda pokazuje demo stranica ispod.