ModSecurity dengan himpunan aturan OWASP CRS dinyalakan dalam sepuluh menit dan dimatikan tiga hari kemudian — setelah artikel di area admin berhenti bisa disimpan, unggahan berkas rusak, dan seorang pelanggan tidak bisa memesan karena alamatnya mengandung tanda petik. Kesimpulan «WAF mengganggu pekerjaan» muncul dengan sendirinya, dan itu keliru: hampir semua pemblokiran itu sembuh dengan tiga atau empat pengecualian yang tepat, dan seluruh kiatnya adalah menemukannya dengan benar.
Jangan langsung nyalakan mode pemblokiran
Pekan pertama hanya untuk pengamatan. Di /etc/modsecurity/modsecurity.conf:
SecRuleEngine DetectionOnly
Dalam mode ini WAF mencatat semua yang akan diblokirnya dan tidak memblokir apa pun. Sepekan lalu lintas nyata — termasuk pekerjaan Anda sendiri di area admin, unggahan gambar dan pemesanan — memberi daftar positif palsu yang sungguhan alih-alih yang hipotetis. Beralih ke On baru masuk akal setelah daftar itu ditangani.
Cara kerja CRS: bukan satu aturan melainkan jumlah
Inilah kunci untuk semua yang menyusul. CRS hampir tidak pernah memblokir sebuah permintaan dengan satu aturan tunggal. Setiap aturan yang menyala menambahkan poin anomali ke permintaan, dan pemblokiran terjadi ketika jumlahnya melewati ambang. Karena itulah di log muncul bukan satu baris melainkan beberapa, dan yang terakhir adalah aturan dengan pengenal 949110 — yang menjumlahkan totalnya.
Akibat praktisnya: pengecualian harus dibuat untuk aturan yang menambahkan poin, bukan untuk 949110. Mematikan aturan penjumlah berarti mematikan seluruh himpunan, dan WAF tinggal menjadi satu baris di berkas konfigurasi.
Akibat kedua adalah tingkat paranoia. Secara bawaan nilainya satu, dan itu pilihan yang benar. Tingkat 2 dan 3 menambahkan aturan yang memang menghasilkan positif palsu pada situs biasa, dan baru layak dinyalakan setelah tingkat satu disetel sepenuhnya.
Temukan aturan penyebabnya
Semua yang diperlukan ada di log audit (/var/log/modsec_audit.log) dan di log galat server web. Carilah berdasarkan waktu pemblokiran:
sudo grep -o 'id "[0-9]*"' /var/log/modsec_audit.log | sort | uniq -c | sort -rn | head
Itu adalah daftar frekuensi aturan yang menyala. Lalu untuk pengenal tertentu, lihat apa persisnya yang memicunya:
sudo grep -A5 'id "942100"' /var/log/modsec_audit.log | head -40
Diperlukan tiga hal: pengenal aturan, nama parameter (ARGS:content, ARGS:comment) dan jalur permintaan. Pengecualian disusun dari itu.
Tersangka yang biasa
Daftar ini berulang dari situs ke situs:
- 942100 — SQL injection. Menyala pada bidang teks dengan isi panjang: badan artikel, deskripsi produk, komentar. Tanda petik, kurung dan kata seperti
selectdi dalam prosa biasa tampak mencurigakan bagi pendeteksi; - 941100 dan keluarga 941xxx — XSS. Mereka datang bersama editor visual: tag HTML di sebuah bidang justru merupakan seluruh makna cara kerjanya;
- 920420 — Content-Type yang tidak diizinkan. Merusak API dan unggahan berkas: himpunan tipe yang diizinkan secara bawaan sangat sempit, dan pada versi lama
application/jsonbahkan tidak ada di dalamnya; - 913100 — pemindai berdasarkan User-Agent. Menangkap perkakas yang sah bersama para pemindai: pemantauan ketersediaan, curl di skrip Anda sendiri;
- 200002, 200004 — galat pembacaan badan permintaan. Biasanya itu bukan berarti serangan melainkan terlampauinya batas ukuran badan, yakni unggahan berkas besar.
Tiga cara membuat pengecualian
Menurut urutan kekasarannya yang meningkat. Semuanya masuk ke berkas Anda sendiri (misalnya /etc/modsecurity/crs/REQUEST-900-EXCLUSION-RULES.conf) bukan ke berkas CRS sendiri: himpunan aturan diperbarui dan suntingan Anda akan lenyap bersamanya.
Keluarkan satu parameter dari bawah satu aturan. Pilihan yang paling tepat, dan yang seharusnya dituju:
SecRuleUpdateTargetById 942100 "!ARGS:content"
Matikan aturan hanya pada satu jalur. Pas ketika satu halaman tertentu yang berisik — editor, impor, formulir ulasan:
SecRule REQUEST_URI "@beginsWith /admin/post" \
"id:1001,phase:1,pass,nolog,ctl:ruleRemoveById=942100"
Matikan aturan sepenuhnya. Jalan terakhir dan hampir selalu tanda bahwa penyebabnya tidak pernah ditemukan:
SecRuleRemoveById 942100
Perbedaan antara cara pertama dan ketiga sangat besar. Pada kasus pertama satu bidang — badan artikel — berhenti diperiksa terhadap SQL injection oleh satu aturan; pada kasus kedua dan ketiga seluruh situs berhenti diperiksa. Perbedaan usahanya sekitar lima menit.
Setelah menyunting, periksa konfigurasi dan muat ulang dengan lembut:
sudo apachectl configtest && sudo systemctl reload apache2
sudo nginx -t && sudo systemctl reload nginx
Urutan yang menghemat sepekan
- Sepekan di
DetectionOnlydengan pekerjaan normal, termasuk situs, area admin dan unggahan. - Daftar frekuensi aturan dari log audit. Kerjakan dari atas — tiga atau empat yang pertama menyumbang sembilan puluh persen kebisingan.
- Untuk masing-masing: tentukan parameter mana dan di halaman mana. Buat pengecualian menurut parameter, bukan menurut aturan.
- Dan baru sekarang
SecRuleEngine On. - Sebulan sekali tengoklah pemblokirannya: situs berubah, jadi muncul positif palsu yang baru.
Justru pada butir terakhir inilah semuanya biasanya runtuh: log audit adalah teks bergigabita dan tidak ada yang akan membacanya dengan tangan. Makna sebuah panel yang mengumpulkan semuanya adalah agar daftar aturan yang menyala, permintaan yang diblokir dan himpunan aturan yang aktif ada di depan mata Anda alih-alih harus digali dengan grep. Bagaimana tampilannya — lihat di halaman demo di bawah.