ModSecurity so sadou pravidiel OWASP CRS sa zapína za desať minút a vypína o tri dni — potom, čo sa prestanú ukladať články v administrácii, rozbije sa nahrávanie súborov a zákazník nemôže dokončiť objednávku, lebo v adrese bol apostrof. Záver „WAF prekáža v práci“ sa ponúka sám, ale je nesprávny: takmer všetky tieto blokovania sa riešia tromi až štyrmi cielenými výnimkami a celá vec je v tom nájsť ich správne.
Nezapínajte blokovanie hneď
Prvý týždeň len pozorovanie. V /etc/modsecurity/modsecurity.conf:
SecRuleEngine DetectionOnly
V tomto režime WAF zapisuje všetko, čo by zablokoval, ale neblokuje nič. Týždeň skutočnej prevádzky — vrátane vašej vlastnej práce v administrácii, nahrávania obrázkov a dokončenia objednávky — dá zoznam skutočných falošných poplachov namiesto hypotetických. Prepnúť na On má zmysel až potom, čo je tento zoznam prebraný.
Ako CRS funguje: nie jedno pravidlo, ale súčet
Kľúč k pochopeniu všetkého ďalšieho. CRS takmer nikdy neblokuje požiadavku jediným pravidlom. Každé spustené pravidlo pridá požiadavke body anomálie a k blokovaniu dôjde, keď súčet prekročí prah. Preto v logu neuvidíte jeden riadok, ale niekoľko, a posledné bude pravidlo s identifikátorom 949110 — to, ktoré sčítava.
Praktický záver: výnimku treba urobiť pre pravidlo, ktoré body pridalo, nie pre 949110. Vypnutím sčítavacieho pravidla vypnete celú sadu a WAF zostane len ako riadok v konfigurácii.
Druhý dôsledok je úroveň paranoje. V predvolenom stave je prvá a je to správna voľba. Úrovne 2 a 3 pridávajú pravidlá, ktoré na bežných weboch zaručene vyvolávajú falošné poplachy, a zapínať ich má zmysel až vtedy, keď je prvá úroveň úplne vyladená.
Nájsť vinníka
Všetko potrebné je v auditnom logu (/var/log/modsec_audit.log) a v chybovom logu webového servera. Hľadáme podľa času blokovania:
sudo grep -o 'id "[0-9]*"' /var/log/modsec_audit.log | sort | uniq -c | sort -rn | head
To je početnostný zoznam spustených pravidiel. Ďalej sa pri konkrétnom identifikátore pozrieme, na čom presne sa spustilo:
sudo grep -A5 'id "942100"' /var/log/modsec_audit.log | head -40
Potrebujete tri veci: identifikátor pravidla, názov parametra (ARGS:content, ARGS:comment) a cestu požiadavky. Z nich sa výnimka stavia.
Obvyklí podozriví
Zoznam sa opakuje od webu k webu:
- 942100 — SQL injection. Spúšťa sa na textových poliach s dlhým obsahom: telo článku, opis tovaru, komentár. Apostrofy, zátvorky a slová ako
selectvyzerajú detektoru podozrivo aj v normálnom texte; - 941100 a 941xxx — XSS. Prichádzajú spolu s vizuálnym editorom: HTML značky v poli sú celý zmysel jeho práce;
- 920420 — nepovolený Content-Type. Rozbíja API a nahrávanie súborov: predvolená sada povolených typov je úzka a
application/jsondo nej v starších verziách nepatril; - 913100 — skener podľa User-Agent. Chytá spolu so skenermi aj legitímne nástroje: monitoring dostupnosti, curl vo vašich vlastných skriptoch;
- 200002, 200004 — chyby pri parsovaní tela požiadavky. Zvyčajne neznamenajú útok, ale prekročený limit veľkosti tela, teda nahrávanie veľkého súboru.
Tri spôsoby, ako urobiť výnimku
Vzostupne podľa hrubosti. Všetky sa píšu do vlastného súboru (napríklad /etc/modsecurity/crs/REQUEST-900-EXCLUSION-RULES.conf), nie do súborov samotnej CRS: sada pravidiel sa aktualizuje a vaše úpravy pri aktualizácii zmiznú.
Vyňať jeden parameter spod pôsobnosti jedného pravidla. Najpresnejší variant, o ktorý sa usilujeme:
SecRuleUpdateTargetById 942100 "!ARGS:content"
Vypnúť pravidlo len na jednej ceste. Hodí sa, keď „hlučí“ konkrétna stránka — editor, import, formulár recenzie:
SecRule REQUEST_URI "@beginsWith /admin/post" \
"id:1001,phase:1,pass,nolog,ctl:ruleRemoveById=942100"
Vypnúť pravidlo úplne. Krajné opatrenie a takmer vždy znak toho, že príčina nebola nájdená:
SecRuleRemoveById 942100
Rozdiel medzi prvým a tretím je podstatný. V prvom prípade prestane byť pole „text článku“ kontrolované na SQL injection jedným pravidlom; v druhom a treťom prestane byť kontrolovaný celý web. Rozdiel v objeme práce je asi päť minút.
Po úpravách kontrola konfigurácie a mäkký reštart:
sudo apachectl configtest && sudo systemctl reload apache2
sudo nginx -t && sudo systemctl reload nginx
Poradie, ktoré ušetrí týždeň
- Týždeň v režime
DetectionOnlys bežnou prácou na webe vrátane administrácie a nahrávania. - Početnostný zoznam pravidiel z auditného logu. Preberať zhora nadol — prvé tri až štyri dajú deväťdesiat percent šumu.
- Pri každom: zistiť, ktorý parameter a na ktorej stránke. Výnimku robiť podľa parametra, nie podľa pravidla.
- Až teraz
SecRuleEngine On. - Raz za mesiac nazrieť do blokovaní: web sa zmenil — objavili sa nové falošné poplachy.
Posledný bod je to, o čo sa všetko obvykle rozbije: auditný log sú gigabajty textu, ručne ho nikto čítať nebude. Zmysel zhromaždeného panela je v tom, aby zoznam spustených pravidiel, zablokovaných požiadaviek a aktívnej sady bol pred očami, a nie aby sa dobýval grepom. Ako to vyzerá, ukazuje ukážková stránka nižšie.