İçindekiler
- 1 Kahve Molasında Gelen Blok: Yanlış Pozitifin Sessiz Tokadı
- 2 Yanlış Pozitifler Neden Kapıyı Sert Kapatır?
- 3 İlk Buluşma: DetectionOnly ile Trafiği Dinlemek ve Anomali Eşiği
- 4 OWASP CRS ile Uysal Başlangıç: Paranoia Seviyeleri ve Eşikler
- 5 Dışlama Kuralları: “Bunu Engelleme, Şunu Sıkı Tut” Dengesi
- 6 Performans: Hızlı WAF, Huzurlu Sunucu
- 7 Uygulama Örnekleri: WordPress, WooCommerce ve Laravel API
- 8 Log, Gözlem ve Sessiz Alarm: WAF’ı Sürekli Öğretmek
- 9 Yapı Taşları: Küçük Ayarlar, Büyük Etkiler
- 10 Kapanış: WAF’la Küslük Bitince Trafik de Gülüyor
Kahve Molasında Gelen Blok: Yanlış Pozitifin Sessiz Tokadı
Hiç böyle oldu mu? Üçüncü kahveni almışsın, minik bir kutlanacak an yakaladığını düşünüyorsun, birden “ödeme başarısız” bildirimleri art arda düşmeye başlıyor. İlk refleks olarak ödeme sağlayıcısını arıyorsun, onların tarafı tertemiz. Dönüp log’lara bakınca küçük bir ipucu: “Access denied by security policy.” İşte tam burada anlıyorsun, kapıda duran nazik ama fazla şüpheci bekçi WAF, iyi niyetli müşterilerini de içeri almıyor. Benimle de böyle olmuştu; ModSecurity ve OWASP CRS ikilisiyle tatlı sert bir sohbetten sonra, yanlış pozitifleri epeyce uysallaştırdık.
Bu yazıda tam da bunu konuşacağız. ModSecurity’ye “gel bakalım, önce bir tanışalım” diyeceğiz. OWASP CRS’in paranoya seviyelerinden, eşiklerden ve dışlama kurallarından söz edeceğiz. Performansı neden bazen WAF’ın kendisi değil, onun ayarlarına gösterdiğimiz özen belirliyor, onu anlatacağım. Arada gerçek hayattan örnekler var, WordPress ve WooCommerce tarafında başı ağrıtan admin-ajax hikâyelerinden, Laravel API’lerinde webhook’ların kırılgan dünyasına kadar. Sonunda elinizde daha az yanlış pozitif, daha akıcı bir trafik ve daha mutlu kullanıcılar kalsın istiyorum. Hazırsanız, kapıdaki bekçiyle tanışıp dost olalım.
Yanlış Pozitifler Neden Kapıyı Sert Kapatır?
WAF dediğin şey biraz kapıya asılan zincir gibi. İçeri giren her paket, her parametre küçük bir sorgudan geçer. OWASP CRS ise bu sorgunun kurallar kitabı. Normalde “zararlı kokuları” ayırt eder; tuhaf karakter dizileri, şüpheli query string’ler, garip header’lar… Fakat hayat her zaman siyah beyaz akmıyor. Mesela bir kullanıcı yorumda bazı özel karakterleri kullanır, WooCommerce tarafında filtreleme parametreleri biraz keskin görünür ya da bir ödeme sağlayıcısının webhook’u beklenmedik bir içerik tipi yollar. WAF “Bu bana XSS gibi koktu” diyebilir. Niyet iyi, ama sonuç yanlış pozitif.
Bunun temel nedeni tek bir büyü değil. Çoğu zaman kural seti gereğinden fazla temkinli, uygulamanın kendi dili ise beklenenden farklıdır. Kiminde JSON gövdeyi doğru yorumlamayan ayar, kiminde hiç gereği yokken statik dosyaları da tarayan bir yapı. Bir de eşik meselesi var, CRS’in anomali puanlaması; her şüpheli davranış küçük puanlar toplar, toplam belirli eşiği aşınca ban sesi gelir. İşimiz, gereksiz puanları temizlemek, gerekli olanı ise daha isabetli hale getirmek.
İlk Buluşma: DetectionOnly ile Trafiği Dinlemek ve Anomali Eşiği
Ben genelde WAF’ı sahneye çıkarmadan önce, kuliste biraz prova yaptırırım. ModSecurity’nin modunu “DetectionOnly” olarak açıp birkaç gün trafiği dinlemek, kimin ne dediğini anlamak için harika. Bu modda engelleme yok, sadece işaretleme var. Gün sonunda hangi kurallar en çok tetiklenmiş, hangi endpoint’ler dertli, kullanıcılar en çok nerede “şüpheli” görünüyor; resim netleşiyor. Bu esnada log’ları boğmamak için seçici davranmak iyi. Sadece ilginç olayları toplayan bir günlük ayarı rahatlatır, gerekmeyen her şeyi kaydetmek hem diski hem de zihni yorar.
CRS’in anomali puanlaması burada elinizi güçlendirir. Her tetikleme küçük bir puan ekler, toplam puan da karar verir. Eşikleri biraz yükseltmek, örneğin içeri giren trafiğin ilk günlerinde yanlış pozitif riskini azaltır. Böylece ılımlı bir başlangıç yaparsınız. Sonrasında yavaş yavaş sıkılaştırmak, daha sağlıklı. Bu, evden çıkmadan önce kapıyı biraz aralık bırakmaya benziyor. Gelenin kim olduğundan daha emin oldukça zinciri kısaltıyorsun.
Uygulamada Ne İşe Yarar?
Mesela yeni bir WooCommerce teması kurdunuz. Filtreleme URL’leri parametre yönünden zengin ve zaman zaman bir SQL kalıbına benziyor. İlk hafta engelleme yapmadan gözlem, sonra en çok tetiklenen birkaç kuralı daraltma veya ilgili endpoint için dışlama, ardından eşikleri makul seviyeye çekme… Böyle yapılandırıldığında, gerçek saldırılar yakalanırken müşterinin filtresi rahatça çalışır. Sessiz ve düzenli bir başlangıç, en büyük gürültüyü önler.
OWASP CRS ile Uysal Başlangıç: Paranoia Seviyeleri ve Eşikler
CRS’in “paranoia” dediği şey aslında şüphe seviyesi. Düşük seviyede, yalnızca bariz riskleri yakalar; seviyeyi yükselttikçe daha ince sinyallerde alarm çalar. Benim yaklaşımım basit: önce düşük ile başla, sorunlu endpoint’leri ve meşru kalıpları tanı, sonra seviyeyi artır. Tüm siteyi en üst şüphe modunda çalıştırmak yerine, kritik bölgelere özel ayarlar yapmak daha akıllı. Örneğin giriş, kayıt, ödeme gibi formlar bir tık sıkı olabilir; JSON post eden arka uç API’ler ise daha seçici bir bakışa ihtiyaç duyar.
Anomali puan eşiği ile paranoiayı birlikte düşünmek gerekir. Şüphe seviyesini artırınca, eşiği da aynı oranda ayarlamak gerekebilir. Çünkü kurallar daha çok sinyal üretecek, eşik sabit kalırsa dahası yanlış pozitife döner. Hayali bir çark gibi düşünün, biri artarken diğeri uygun noktaya çekilmeli. Ayarı küçük adımlarla yapmak, yaşanan her değişikliğin etkisini görmek için iyi bir yöntem. Büyük sıçramalar, nerede hata yaptığınızı anlamayı zorlaştırır.
Bir Küçük Not
Kural davranışlarının sürpriz yapmaması için resmi belgeler her zaman el altında olsun. OWASP CRS’in yol gösterici ve anlaşılır dokümantasyonu işinizi kolaylaştırır. Bu konuda OWASP CRS dokümantasyonunda güzel anlatımlar ve yanlış pozitifleri tanıyıp ayıklamak için pratik başlıklar var. Özellikle false positive kavramı üzerine yazılan rehber kısa sürede çok yol aldırır.
Dışlama Kuralları: “Bunu Engelleme, Şunu Sıkı Tut” Dengesi
İşte asıl tatlı ayar burada. Her şeyi “kapat” ya da “aç” mantığıyla yönetmek yerine, bağlama göre dışlamalar eklemek harikalar yaratır. Örneğin WordPress tarafında admin-ajax.php beklenmedik parametreler taşıyabilir. Böyle bir endpoint için, yalnızca bu yola özel olarak belirli kuralları esnetmek hem güvenliği hem akışı korur. Laravel’de webhook endpoint’leri de benzer; ödeme sağlayıcıları bazen fazlaca korumacı kuralları tetikleyen özel başlıklar ve gövdeler gönderir. Sadece bu adresleri beyaz listelemek, koca tarlayı sürmeden çimleri düzeltmek gibidir.
Dışlamayı iki adımda düşünün. Önce “hedefi daraltın”. Yani bütün siteyi gevşetmek yerine, sadece belli yol ya da parametre için esnetin. Ardından “hangi kuralları” kenara aldığınızı görün. Genelde birkaç kural, belirli bir şablon yüzünden sürekli tetiklenir. Bunları seçici şekilde uzaklaştırınca, sistemin geri kalanı sapasağlam kalır. Böyle yaptığım bir WooCommerce projesinde, sepete ekleme ve varyasyon filtreleri bir anda yağ gibi aktı. Saldırı denemelerini yakalayan ana iskelet ise yerli yerinde durdu.
JSON Gövde ve Dosya Yükleme Üzerine
API ağırlıklı uygulamalarda, gövdeyi doğru okumak kritik. JSON içeriği düzgün çözümlenmezse kurallar yanlış alarmlar üretebilir. Gövdedeki büyük dosyalar ya da resimler için de gereksiz tarama yapmak performansı boğar. Statik dosyalar gibi davranan yüklemelerde, sadece gerekli yerlerde tarama yapmak ve JSON akışını doğru işlemek, şikâyetleri ciddi biçimde azaltır. Bir yerde “fazla merak” her zaman iyi değildir.
Performans: Hızlı WAF, Huzurlu Sunucu
Performans konusu genelde en son konuşulur ama ben onu ortaya alırım. Çünkü yanlış pozitif kadar can sıkıcı bir şey varsa, o da ağırlaşan sayfalar. ModSecurity’yi her şeye dahil etmek zorunda değilsiniz. Statik dosyaların sunulduğu yerlerde WAF’ı kapatmak ilk büyük kazanım. CSS, JS, resim, font gibi trafiği taramamak, kapıdaki bekçiyi sadece misafirlerin geldiği salona oturtmak gibi. Hemen hissedilir.
Yanıt gövdesini taramayı çoğu senaryoda kapatmak, log’ları gerçekten ilginç olaylara indirgemek, belirli endpoint’lerde incelemeyi derinleştirmek gibi küçük hamlelerin etkisi büyük. Gövde limiti ayarlarını makul sınırlarda tutmak ve devasa yükleri gereksiz yere analiz etmemek, hem gecikmeyi hem de CPU kullanımını azaltır. Trafikte yük artınca bu ayarların değeri iki kat anlaşılır. Sunucu üzerindeki başka servislerle uyum, örneğin PHP-FPM ve veritabanı tarafında sağlıklı kuyruğa dönüş, WAF’ın attığı her ufak kolun çarpan etkisini dengeler.
Bir başka güçlü kombinasyon da önbellekleme ve kenar (edge) politikaları. Akışın önemli bölümü zaten önbellekten geliyorsa, WAF’ın iş yükü de doğal olarak düşer. Bu konuda pratik dokunuşlar için WordPress’te tam sayfa önbellekleme üzerine anlattığımız rehberi göz atılacak güzel bir kaynak olarak kenara bırakıyorum.
Kenar ve Ön Kapı Arasında Uyum
Bazen WAF yükünü azaltmanın en kolay yolu, ilk kapıyı dışarıda tutmaktır. Bir kenar güvenlik katmanı, kötü trafiği daha içeri girmeden eleyebilir. ModSecurity içerde hassas işlerle ilgilenirken, dışarıdaki bekçi kaba gürültüyü alır. Bu ikiliyi uyumlu çalıştırmanın hikâyesini yumuşak bir dille anlattığım bir yazıda, Cloudflare, ModSecurity ve Fail2ban’ı aynı masada buluşturmuştuk. Uğramak isterseniz, bu WAF ve bot koruması yazısında örnek senaryolar var.
Uygulama Örnekleri: WordPress, WooCommerce ve Laravel API
WordPress tarafında en sık gördüğüm meselelerden biri admin-ajax ve REST API çağrıları. Bir eklenti beklenmedik parametreler ekliyor, bir filtreleme eklentisi URL’e görece keskin desenler koyuyor ve CRS bunları şüpheli buluyor. Burada yapacağım ilk iş, sadece bu endpoint’ler için belirli kuralları esnetmek. Tam siteyi gevşetmek yok, nokta atışı esneme var. WooCommerce’de sepete ekleme ve varyasyon filtreleri, özellikle kampanya dönemlerinde yoğunlaştığı için, akışı kesmeye en az hevesli yerler olmalı.
Laravel tarafında ise genellikle webhook’lar ve JSON post eden mobil uygulamalar konuyu alevlendiriyor. Ödeme ve bildirim servisleri, içerikte özel karakterler taşıyabiliyor. En sevdiğim pratik, sadece /webhook/ ile başlayan endpoint’lerde belirli kuralları dışlamak ve JSON gövdeyi doğru çözümlemek. Gelenin “beklenen misafir” olduğunu bildiğimiz durumda, kapıyı çalanın lafını kesmemek gerekiyor. Böylece hem bütün API’yi koruyor hem de kritik iletiyi duyarak hızlı cevap veriyorsunuz.
Bu akışların önüne küçük setler çekmek için kenarda tutacağınız bir katman işinizi kolaylaştırır. Oran sınırlama gibi ön kapı taktikleri, gereksiz yoğunluğu törpüler. Anlatması kolay, uygulaması basit örnekler için Cloudflare WAF kuralları ve oran sınırlama ile WordPress’i bot’lardan koruma notları tam tadında bir eşlikçi olur.
Küçük Bir Senaryo
Bir müşteride kampanya günü trafiği arttı, sepet işlemleri bazen takılıyor, bazen uçuyor. Log’lara baktığımızda iki kural sürekli tetikleniyor, ikisi de belirli parametrelerdeki karakter dizilerine hassas. Sadece sepete ekleme ve varyasyon URL’lerinde bu iki kuralı dışladık. Eşik değerini çok az yükselttik, tetikleyicinin ağırlığı düştü. Aynı anda statik dosyalarda WAF’ı kapattık, yanıt taramasını devreden aldık. Sayfa süreleri gözle görülür kısaldı. Hem sınıfta kalan bir “güvenlik yok” senaryosu değil, hem de “her şeyi kapattık” demeden akış sağlandı.
Log, Gözlem ve Sessiz Alarm: WAF’ı Sürekli Öğretmek
WAF ayarı “kurduk, bitti” değil. Düzenli olarak log’lara bakmak, anlamlı örnekleri biriktirmek ve alınan aksiyonun etkisini görmek şart. Log’ların yüzünü güldürmek için “gereksiz her şeyi yazma” prensibini benimsiyorum. Sadece ilginç olaylar kaydedilsin, geri kalan akış boşuna deftere düşmesin. Bu sayede gerçek problemleri daha net seçiyor, alarm ayarlarını daha doğru konumlandırıyorsunuz.
Gözlemin yolu çok. Sunucunun genel sağlığını tutarlı bir yerden izlemek, WAF’ın getirdiği ek yükü de görmeyi kolaylaştırır. Kimi zaman artan gecikme bir kuralın taşmasına işaret eder, kimi zaman log’ların büyümesi gereksiz yazımın işareti olur. Böyle anlarda hızlıca geri almak ya da küçük bir güncelleme ile esnetmek, çığ büyümeden yol aldırır. Bu konuyu merak ederseniz, Prometheus ve Grafana ile uyarı kurma rehberinde izleme ve alarmı kısa adımlarla toparlamıştık.
Deneme, Geri Alma, Küçük Adımlar
Ne kadar teknik olursa olsun, süreç aslında bahçecilik gibi. Biraz buda, biraz su ver, biraz gölge yap. WAF ayarları da böyle. Önce küçük değiştir, etkisini gör, sonra bir adım daha. Büyük bir “kullanıcıları kilitledik” sürprizi yerine, hızlı geri alınabilir ufak dokunuşlar her zaman güvenli olan. WAF’ı düzenli öğretmek, kuralları bağlama göre esnetmek, müşterinin ağzında iyi bir tat bırakır.
Yapı Taşları: Küçük Ayarlar, Büyük Etkiler
Konuya biraz içeriden bakalım ama göz yormadan. Trafik öğrenme döneminde, WAF’ı engelleme moduna almadan önce bir süre dinlemek en kritik hamle. Statik varlıklarda taramayı devre dışı bırakmak, hem gereksiz işler hem de performans kayıplarını azaltır. Yanıt gövdesi taramasını çoğu yerde kapatmak makul. Büyük gövdeleri okuyup işlemek zaman alır; gerçekten gerekliyse açın, değilse bırakın akış serin kalsın.
Log’larda sadece “ilginç” olayları tutmak, disk ve zihin sağlığı için bire iki kazanç. Dışlamaları geniş değil dar alana uygulamak, yani tüm siteyi gevşetmek yerine belirli endpoint ya da parametreye odaklanmak, güvenliği budamadan akışı açar. Paranoia seviyesiyle eşikleri birlikte ayarlamak, yanlış pozitifleri minimuma indirir. Düzenli olarak gözden geçirmek, bazen tek sihirdir.
Bu noktada resmi referans elinizin altında olsun. ModSecurity’nin davranış detaylarına dair güncel bilgilere ModSecurity referans el kitabından bakmak, “bu ayar neye dokunuyor” sorusunu dakikalar içinde cevaplatır.
Kapanış: WAF’la Küslük Bitince Trafik de Gülüyor
Özetle mevzu şu: ModSecurity ve OWASP CRS, doğru tanıştırıldıklarında şahane bir ikili. Yanlış pozitifleri azaltmanın yolu, önce dinlemek, sonra nokta atışı dışlamalar yapmak ve paranoya seviyesini eşiklerle birlikte ayarlamak. Performans tarafında statik dosyalarda taramayı kapatmak, yanıt gövdesini gereksiz yere incelememek ve log’ları sadeleştirmek sunucunun nefesini açıyor. En güzeli de bu adımlar zor değil; birkaç bilinçli dokunuşla, kullanıcı şikâyetleri azalıyor, saldırılar ise kayıp kaçmadan yakalanıyor.
Size pratik bir plan bırakayım. Önce kısa bir öğrenme dönemiyle trafiği dinleyin. En çok tetiklenen kuralları etiketleyin, sadece ilgili endpoint’lerde yumuşatın. Eşiği yavaşça ayarlayın ve statik akışta taramayı kapatın. Ardından önbellek ve kenar politikalarıyla yükü hafifletin, dış kapıda nazik bir bekçi daha ekleyin. Küçük adımlar, hızlı geri alımlar ve düzenli gözden geçirme… Hepsi bir arada çalıştığında WAF kapısı sert değil, güven veren bir şekilde açılıyor. Umarım bu yazı işinizi kolaylaştırır. Bir gün bir kahve molasında “ödeme başarısız” değil, “her şey yolunda” bildirimleri yağar; o gün bu ayarların kıymetini daha çok hissedersiniz.
