ModSecurity OWASP CRS -sääntökokoelmalla kytketään päälle kymmenessä minuutissa ja pois kolme päivää myöhemmin — sen jälkeen kun artikkelit lakkaavat tallentumasta hallintapaneelissa, tiedostojen lataus hajoaa eikä asiakas saa tehtyä tilausta, koska osoitteessa sattui olemaan heittomerkki. Johtopäätös ”WAF haittaa työtä” tulee mieleen helposti, mutta se on väärä: lähes kaikki nämä estot ratkeavat kolmella tai neljällä täsmäpoikkeuksella, ja koko asia on siinä, että ne löydetään oikealla tavalla.
Älä kytke estoa heti päälle
Ensimmäinen viikko on pelkkää seurantaa. Tiedostossa /etc/modsecurity/modsecurity.conf:
SecRuleEngine DetectionOnly
Tässä tilassa WAF kirjaa kaiken, minkä se olisi estänyt, mutta ei estä mitään. Viikko oikeaa liikennettä — mukaan lukien oma työsi hallintapaneelissa, kuvien lataus ja tilauksen tekeminen — antaa listan todellisista vääristä hälytyksistä hypoteettisten sijaan. Tilaan On vaihtaminen on järkevää vasta, kun tuo lista on käyty läpi.
Näin CRS toimii: ei yksi sääntö vaan summa
Avain kaikkeen seuraavaan. CRS ei lähes koskaan estä pyyntöä yhdellä säännöllä. Jokainen laukeava sääntö lisää pyynnölle poikkeavuuspisteitä, ja esto tapahtuu, kun summa ylittää kynnyksen. Siksi lokissa ei näy yhtä riviä vaan useita, ja viimeinen on sääntö tunnuksella 949110 — se, joka laskee yhteen.
Käytännön johtopäätös: poikkeus tehdään sille säännölle, joka antoi pisteet, ei säännölle 949110. Jos kytket yhteenlaskevan säännön pois, kytket koko kokoelman pois, ja WAF jää jäljelle vain rivinä asetuksissa.
Seuraava seuraus on vainoharhaisuustaso. Oletuksena se on yksi, ja se on oikea valinta. Tasot 2 ja 3 lisäävät sääntöjä, jotka varmasti tuottavat vääriä hälytyksiä tavallisilla sivustoilla, ja ne kannattaa kytkeä päälle vasta kun taso yksi on täysin viritetty.
Löydä syyllinen sääntö
Kaikki tarpeellinen on auditointilokissa (/var/log/modsec_audit.log) ja verkkopalvelimen virhelokissa. Haemme eston ajankohdan perusteella:
sudo grep -o 'id "[0-9]*"' /var/log/modsec_audit.log | sort | uniq -c | sort -rn | head
Tämä on laukeavien sääntöjen frekvenssilista. Sitten katsomme, mistä tietty tunnus todella laukesi:
sudo grep -A5 'id "942100"' /var/log/modsec_audit.log | head -40
Kolme asiaa tarvitaan: säännön tunnus, parametrin nimi (ARGS:content, ARGS:comment) ja pyynnön polku. Niistä rakennetaan poikkeus.
Tavalliset epäillyt
Lista toistuu sivustosta toiseen:
- 942100 — SQL-injektio. Laukeaa pitkäsisältöisissä tekstikentissä: artikkelin teksti, tuotekuvaus, kommentti. Heittomerkit, sulkeet ja sanat kuten
selectnäyttävät tunnistimen silmissä epäilyttäviltä myös tavallisessa tekstissä; - 941100 ja 941xxx — XSS. Tulee visuaalisen editorin mukana: HTML-tagit kentässä ovat sen koko toimintatapa;
- 920420 — sallimaton Content-Type. Rikkoo rajapinnat ja tiedostojen latauksen: sallittujen tyyppien oletuskokoelma on kapea, eikä
application/jsonkuulunut siihen vanhemmissa versioissa; - 913100 — skanneri User-Agentin perusteella. Nappaa skannereiden ohella myös lailliset työkalut: saatavuuden valvonnan, curlin omissa skripteissäsi;
- 200002, 200004 — virheet pyynnön rungon jäsennyksessä. Ei yleensä tarkoita hyökkäystä vaan ylitettyä kokorajaa, siis suuren tiedoston latausta.
Kolme tapaa tehdä poikkeus
Karkeusjärjestyksessä. Kaikki kirjoitetaan omaan tiedostoon (esimerkiksi /etc/modsecurity/crs/REQUEST-900-EXCLUSION-RULES.conf) eikä CRS:n omiin tiedostoihin: sääntökokoelma päivittyy, ja muutoksesi katoavat päivityksessä.
Poista yksi parametri yhden säännön alta. Tarkin vaihtoehto, ja se, johon pyritään:
SecRuleUpdateTargetById 942100 "!ARGS:content"
Kytke sääntö pois vain yhdellä polulla. Sopii, kun tietty sivu meluaa — editori, tuonti, palautelomake:
SecRule REQUEST_URI "@beginsWith /admin/post" \
"id:1001,phase:1,pass,nolog,ctl:ruleRemoveById=942100"
Kytke sääntö kokonaan pois. Viimeinen keino ja lähes aina merkki siitä, ettei syytä ole löydetty:
SecRuleRemoveById 942100
Ero ensimmäisen ja kolmannen välillä on merkittävä. Ensimmäisessä tapauksessa kenttä ”artikkelin teksti” lakkaa olemasta yhden säännön SQL-injektiotarkastuksen kohteena; toisessa ja kolmannessa koko sivusto lakkaa olemasta tarkastuksen kohteena. Työmäärän ero on noin viisi minuuttia.
Muutosten jälkeen — asetusten tarkistus ja pehmeä uudelleenlataus:
sudo apachectl configtest && sudo systemctl reload apache2
sudo nginx -t && sudo systemctl reload nginx
Järjestys, joka säästää viikon
- Viikko tilassa
DetectionOnlytavallisella työskentelyllä sivustolla, mukaan lukien hallintapaneeli ja lataukset. - Sääntöjen frekvenssilista auditointilokista. Käy ylhäältä alas — kolme ensimmäistä antavat yhdeksänkymmentä prosenttia melusta.
- Kunkin kohdalla: selvitä, mikä parametri ja mikä sivu. Tee poikkeus parametrin, ei säännön, perusteella.
- Vasta nyt
SecRuleEngine On. - Katso estoja kerran kuussa: kun sivusto muuttuu, ilmaantuu uusia vääriä hälytyksiä.
Viimeinen kohta on se, mihin kaikki yleensä kaatuu: auditointiloki on gigatavuja tekstiä, eikä kukaan lue sitä käsin. Kootun paneelin pointti on siinä, että laukeavien sääntöjen lista, estetyt pyynnöt ja aktiivinen kokoelma ovat silmien edessä sen sijaan, että ne kaivettaisiin esiin grepillä. Miltä se näyttää, näkyy alla olevalla esittelysivulla.