A ModSecurityt az OWASP CRS szabálykészletével tíz perc alatt kapcsolják be, és három nap múlva ki — miután az adminban nem mentődnek a cikkek, elromlik a fájlfeltöltés, és az ügyfél nem tud rendelést leadni, mert a címben apostróf volt. A „a WAF akadályozza a munkát” következtetés magától adódik, de téves: majdnem mindegyik ilyen blokkolás három-négy célzott kivétellel megoldható, és az egész azon múlik, hogy helyesen találd meg őket.

Ne kapcsold be azonnal a blokkolást

Az első hét csak megfigyelés. A /etc/modsecurity/modsecurity.conf fájlban:

SecRuleEngine DetectionOnly

Ebben az üzemmódban a WAF mindent feljegyez, amit blokkolt volna, de semmit nem blokkol. Egy hét valós forgalom — beleértve a saját munkádat az adminban, a képfeltöltést és a rendelés leadását — a valódi téves riasztások listáját adja a feltételezettek helyett. Az On értékre váltás csak akkor észszerű, ha ez a lista már át van nézve.

Hogyan működik a CRS: nem egy szabály, hanem összeg

Ez a kulcs minden továbbihoz. A CRS szinte soha nem blokkol kérést egyetlen szabállyal. Minden működésbe lépő szabály anomáliapontot ad a kéréshez, és a blokkolás akkor következik be, amikor az összeg meghaladja a küszöböt. Ezért a naplóban nem egy sort látsz, hanem többet, és az utolsó a 949110 azonosítójú szabály lesz — az, amely összegez.

Gyakorlati következtetés: a kivételt arra a szabályra kell megadni, amely a pontokat adta, nem a 949110-re. Az összegző szabály kikapcsolásával az egész készletet kikapcsolod, és a WAF csak egy sorként marad meg a konfigurációban.

A második következmény a paranoiaszint. Alapból az első, és ez a helyes választás. A 2-es és 3-as szint olyan szabályokat ad hozzá, amelyek szokásos webhelyeken biztosan téves riasztásokat okoznak, és csak akkor érdemes bekapcsolni őket, ha az első szint teljesen be van hangolva.

A hibás szabály megtalálása

Minden szükséges az auditnaplóban (/var/log/modsec_audit.log) és a webszerver hibanaplójában van. A blokkolás ideje alapján keresünk:

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

Ez a működésbe lépett szabályok gyakorisági listája. Azután egy konkrét azonosítónál megnézzük, min lépett működésbe pontosan:

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

Három dolog kell: a szabály azonosítója, a paraméter neve (ARGS:content, ARGS:comment) és a kérés útvonala. Ezekből épül fel a kivétel.

A szokásos gyanúsítottak

A lista webhelyről webhelyre ismétlődik:

  • 942100 — SQL-injekció. Hosszú tartalmú szövegmezőknél lép működésbe: cikk törzse, termékleírás, hozzászólás. Az aposztrófok, zárójelek és az olyan szavak, mint a select, a detektor számára normál szövegben is gyanúsnak tűnnek;
  • 941100 és 941xxx — XSS. A vizuális szerkesztővel együtt érkeznek: a mezőben lévő HTML-címkék adják a működésének egész lényegét;
  • 920420 — nem engedélyezett Content-Type. Elrontja az API-kat és a fájlfeltöltést: az engedélyezett típusok alapkészlete szűk, és az application/json a régebbi verziókban nem szerepelt benne;
  • 913100 — szkenner a User-Agent alapján. A szkennerekkel együtt jogos eszközöket is elkap: elérhetőség-figyelést, curlt a saját szkriptjeidben;
  • 200002, 200004 — hibák a kérés törzsének feldolgozásakor. Általában nem támadást jelentenek, hanem túllépett törzsméret-korlátot, azaz nagy fájl feltöltését.

Három mód a kivételre

Növekvő durvaság szerint. Mindet saját fájlba írjuk (például /etc/modsecurity/crs/REQUEST-900-EXCLUSION-RULES.conf), nem a CRS saját fájljaiba: a szabálykészlet frissül, és a módosításaid frissítéskor eltűnnek.

Egy paraméter kivétele egy szabály alól. A legpontosabb változat, erre törekszünk:

SecRuleUpdateTargetById 942100 "!ARGS:content"

A szabály kikapcsolása csak egy útvonalon. Akkor jó, ha egy konkrét oldal „zajos” — szerkesztő, importálás, véleményűrlap:

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

A szabály teljes kikapcsolása. Végső eszköz, és szinte mindig annak jele, hogy az okot nem találtad meg:

SecRuleRemoveById 942100

Az első és a harmadik közötti különbség lényeges. Az első esetben a „cikk szövege” mező egyetlen szabály SQL-injekció-ellenőrzése alól kerül ki; a másodikban és a harmadikban az egész webhely kikerül az ellenőrzés alól. A munkamennyiség különbsége körülbelül öt perc.

A módosítások után konfigurációellenőrzés és lágy újratöltés:

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

A sorrend, amely egy hetet spórol

  1. Egy hét DetectionOnly üzemmódban, szokásos munkával a webhelyen, beleértve az admint és a feltöltéseket.
  2. A szabályok gyakorisági listája az auditnaplóból. Fentről lefelé haladva — az első három-négy adja a zaj kilencven százalékát.
  3. Mindegyiknél: derítsd ki, melyik paraméter és melyik oldal. A kivételt paraméter szerint add meg, ne szabály szerint.
  4. Csak most jöhet a SecRuleEngine On.
  5. Havonta egyszer nézz bele a blokkolásokba: ha a webhely változott, új téves riasztások jelennek meg.

Az utolsó ponton szokott minden elbukni: az auditnapló gigabájtnyi szöveg, kézzel senki nem fogja olvasni. Az összegyűjtött panel értelme az, hogy a működésbe lépett szabályok listája, a blokkolt kérések és az aktív készlet szem előtt legyen, ne pedig grep-pel kelljen kibányászni. Hogy néz ki mindez, azt az alábbi bemutatóoldal mutatja.