OWASP CRS kural kümesiyle birlikte ModSecurity on dakikada açılır ve üç gün sonra kapatılır — yönetim panelinde yazılar kaydedilmez olduktan, dosya yüklemeleri bozulduktan ve bir müşteri adresinde kesme işareti geçtiği için sipariş veremedikten sonra. «WAF işi engelliyor» sonucu kendiliğinden gelir ve yanlıştır: o engellemelerin neredeyse tamamı üç dört isabetli istisnayla iyileşir, bütün marifet de onları doğru bulmaktır.

Engellemeyi hemen açmayın

İlk hafta yalnızca gözlemdir. /etc/modsecurity/modsecurity.conf içinde:

SecRuleEngine DetectionOnly

Bu kipte WAF engelleyeceği her şeyi günlüğe yazar ve hiçbir şeyi engellemez. Bir haftalık gerçek trafik — yönetim panelindeki kendi çalışmanız, resim yüklemeleri ve sipariş verme dahil — varsayımsal değil, gerçek yanlış pozitiflerin listesini verir. On konumuna geçmek ancak o liste halledildikten sonra anlamlıdır.

CRS nasıl çalışır: tek bir kural değil, bir toplam

Bu, sonrasında gelen her şeyin anahtarıdır. CRS bir isteği neredeyse hiçbir zaman tek bir kuralla engellemez. Tetiklenen her kural isteğe anomali puanı ekler ve engelleme toplam bir eşiği aştığında gerçekleşir. Günlükte bir değil birkaç satır görünmesinin ve bunların sonuncusunun 949110 kimlikli kural — toplamı hesaplayan kural — olmasının nedeni budur.

Pratik sonuç: istisna, puanı veren kural için yapılmalıdır, 949110 için değil. Toplayan kuralı kapatırsanız bütün kümeyi kapatmış olursunuz ve WAF bir yapılandırma dosyasındaki bir satırdan ibaret kalır.

İkinci sonuç paranoya seviyesidir. Varsayılan olarak birdir ve doğru seçim de budur. 2 ve 3. seviyeler, sıradan sitelerde tasarımı gereği yanlış pozitif üreten kurallar ekler; ancak birinci seviye tümüyle ayarlandıktan sonra açmaya değer.

Suçlu kuralı bulun

Gereken her şey denetim günlüğünde (/var/log/modsec_audit.log) ve web sunucusunun hata günlüğündedir. Engellemenin saatine göre arayın:

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

Bu, tetiklenen kuralların sıklık listesidir. Ardından belirli bir kimlik için tam olarak neyin onu tetiklediğine bakın:

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

Üç şey gerekir: kural kimliği, parametre adı (ARGS:content, ARGS:comment) ve istek yolu. İstisna bunlardan kurulur.

Alışıldık şüpheliler

Liste siteden siteye tekrarlanır:

  • 942100 — SQL enjeksiyonu. Uzun içerikli metin alanlarında tetiklenir: bir yazının gövdesi, bir ürün açıklaması, bir yorum. Tırnaklar, parantezler ve select gibi kelimeler sıradan bir düzyazının içinde dedektöre şüpheli görünür;
  • 941100 ve 941xxx ailesi — XSS. Görsel bir düzenleyiciyle birlikte gelirler: bir alandaki HTML etiketleri, o alanın çalışma biçiminin ta kendisidir;
  • 920420 — izin verilmeyen Content-Type. API’leri ve dosya yüklemelerini bozar: izin verilen türlerin varsayılan kümesi dardır ve eski sürümlerde application/json onun içinde yoktu;
  • 913100 — User-Agent üzerinden tarayıcı tespiti. Tarayıcılarla birlikte meşru araçları da yakalar: erişilebilirlik izleme, kendi betiklerinizdeki curl;
  • 200002, 200004 — istek gövdesi ayrıştırma hataları. Bunlar genellikle bir saldırıyı değil, aşılmış bir gövde boyutu sınırını, yani büyük bir dosya yüklemesini gösterir.

İstisna yapmanın üç yolu

Kabalık sırasına göre. Hepsi CRS dosyalarının kendisine değil, kendi dosyanıza yazılır (örneğin /etc/modsecurity/crs/REQUEST-900-EXCLUSION-RULES.conf): kural kümesi güncellenir ve düzenlemeleriniz onunla birlikte yok olur.

Bir kuralın altından bir parametreyi çıkarın. En isabetli seçenek ve hedeflenmesi gereken:

SecRuleUpdateTargetById 942100 "!ARGS:content"

Bir kuralı yalnızca tek bir yolda kapatın. Belirli bir sayfa gürültü çıkardığında tam yerinde — bir düzenleyici, bir içe aktarma, bir değerlendirme formu:

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

Kuralı tümüyle kapatın. Son çaredir ve neredeyse her zaman nedenin hiç bulunmamış olduğunun işaretidir:

SecRuleRemoveById 942100

Birinci ile üçüncü arasındaki fark önemlidir. Birinci durumda tek bir alan — yazının gövdesi — tek bir kural tarafından SQL enjeksiyonuna karşı denetlenmemeye başlar; ikinci ve üçüncüde bütün site denetlenmemeye başlar. Emek farkı ise yaklaşık beş dakikadır.

Düzenlemelerden sonra yapılandırmayı kontrol edin ve nazikçe yeniden yükleyin:

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

Bir hafta kazandıran bir sıra

  1. Sitede, yönetim panelinde ve yüklemelerde olağan çalışmayla birlikte DetectionOnly kipinde bir hafta.
  2. Denetim günlüğünden kuralların sıklık listesi. Yukarıdan aşağıya çalışın — ilk üç dört tanesi gürültünün yüzde doksanını oluşturur.
  3. Her biri için: hangi parametre ve hangi sayfa olduğunu çıkarın. İstisnayı kurala göre değil, parametreye göre yapın.
  4. Ancak şimdi SecRuleEngine On.
  5. Ayda bir kez engellemelere göz atın: site değişti, dolayısıyla yeni yanlış pozitifler ortaya çıktı.

İşin genellikle tökezlediği yer bu son maddedir: denetim günlüğü gigabaytlarca metindir ve kimse onu elle okumaz. Toplanmış bir panelin anlamı, tetiklenen kuralların listesini, engellenen istekleri ve etkin kural kümesini grep ile çıkarmak yerine önünüzde bulundurmaktır. Bunun nasıl göründüğü aşağıdaki demo sayfasında.