Cloudflare WAF ile Web Uygulama Güvenliği
Web uygulamalarını internete açtığınız andan itibaren saldırı trafiği almaya başlarsınız. Bu bir abartı değil, gerçek hayatta yaşanan bir durum. Bir müşterimizin yeni kurduğu e-ticaret sitesi, yayına alındıktan sadece 6 saat sonra SQL injection denemelerine maruz kalmıştı. Cloudflare WAF, bu tür tehditlere karşı en pratik ve güçlü savunma katmanlarından biri. Bu yazıda Cloudflare WAF’ı sıfırdan nasıl yapılandıracağınızı, özel kurallar nasıl yazacağınızı ve gerçek dünya senaryolarında nasıl kullanacağınızı anlatacağım.
Cloudflare WAF Nedir ve Neden Önemlidir
WAF, yani Web Application Firewall, HTTP/HTTPS trafiğini uygulama katmanında (OSI Layer 7) inceleyen ve zararlı istekleri engelleyen bir güvenlik çözümüdür. Geleneksel güvenlik duvarları port ve IP bazlı çalışırken, WAF request body, header, query string ve cookie gibi uygulama katmanı verilerini analiz eder.
Cloudflare WAF’ın öne çıkmasının birkaç nedeni var. Anycast ağ altyapısı sayesinde filtreleme işlemi isteğin sunucunuza ulaşmadan önce gerçekleşir. Günlük 57 milyarı aşkın isteği işleyen Cloudflare, bu verilerden beslenerek tehdit istihbaratını sürekli güncelliyor. Kendi altyapınıza ek yük bindirmeden WAF koruması almanız mümkün oluyor.
Cloudflare WAF’ın temel bileşenleri şunlardır:
- Managed Rules: Cloudflare’in kendi geliştirdiği ve OWASP tabanlı hazır kural setleri
- Custom Rules: Sizin yazdığınız özel kurallar
- Rate Limiting Rules: Belirli endpoint’lere gelen istek sayısını sınırlayan kurallar
- Transform Rules: İstekleri sunucuya iletmeden önce manipüle eden kurallar
- Firewall Rules (eski adı): Artık Custom Rules ile birleştirilmiş ama API’de hala görülebilir
Cloudflare API ile Temel Kurulum
Dashboard üzerinden WAF ayarlarını yapabilirsiniz ancak production ortamları için API veya Terraform kullanmak çok daha sağlıklı. Değişiklikleri kod olarak yönetmek, geri almak ve versiyonlamak çok daha kolay oluyor.
Önce Cloudflare API token oluşturun. Dashboard’da Profile > API Tokens > Create Token yolunu izleyin ve “Edit zone DNS” ile “Zone WAF” yetkilerini verin.
Zone ID’nizi ve API token’ınızı environment variable olarak tanımlayalım:
export CF_API_TOKEN="your_api_token_here"
export CF_ZONE_ID="your_zone_id_here"
Mevcut WAF kural setlerini listelemek için:
curl -X GET "https://api.cloudflare.com/client/v4/zones/${CF_ZONE_ID}/rulesets"
-H "Authorization: Bearer ${CF_API_TOKEN}"
-H "Content-Type: application/json" | jq '.result[] | {id: .id, name: .name, phase: .phase}'
Bu komut size zone’unuzdaki mevcut kural setlerini ve hangi fazda çalıştıklarını gösterir. Çıktıda http_request_firewall_managed, http_request_firewall_custom gibi fazları göreceksiniz.
Managed Rules Yapılandırması
Cloudflare’in yönetilen kural setleri üç ana gruptan oluşur:
- Cloudflare Managed Ruleset: Genel web saldırılarına karşı 700’den fazla kural
- Cloudflare OWASP Core Ruleset: OWASP Top 10 bazlı kurallar
- Cloudflare Exposed Credentials Check: Sızdırılmış kimlik bilgisi tespiti
OWASP kural setini etkinleştirmek ve hassasiyet seviyesini ayarlamak için şu API çağrısını kullanabilirsiniz:
curl -X PUT "https://api.cloudflare.com/client/v4/zones/${CF_ZONE_ID}/rulesets/phases/http_request_firewall_managed/entrypoint"
-H "Authorization: Bearer ${CF_API_TOKEN}"
-H "Content-Type: application/json"
-d '{
"rules": [
{
"action": "execute",
"action_parameters": {
"id": "efb7b8c949ac4650a09736fc376e9aee",
"overrides": {
"sensitivity_level": "medium"
}
},
"expression": "true",
"enabled": true
}
]
}'
efb7b8c949ac4650a09736fc376e9aee Cloudflare OWASP Core Ruleset’in sabit ID’sidir. sensitivity_level için high, medium veya low seçeneklerini kullanabilirsiniz. Yeni bir siteye başlarken medium ile başlamanızı tavsiye ederim, çünkü high ile false positive oranı artabilir.
Özel WAF Kuralları Yazmak
Özel kurallar Cloudflare’in en güçlü özelliklerinden biri. Wireshark Firewall Rules Expression Language (WREL) ile oldukça esnek kurallar yazabilirsiniz.
SQL Injection Koruması
Aşağıdaki kural, URL parametrelerinde yaygın SQL injection payload’larını tespit eder:
curl -X POST "https://api.cloudflare.com/client/v4/zones/${CF_ZONE_ID}/rulesets/phases/http_request_firewall_custom/entrypoint/rules"
-H "Authorization: Bearer ${CF_API_TOKEN}"
-H "Content-Type: application/json"
-d '{
"action": "block",
"expression": "(http.request.uri.query contains "union+select" or http.request.uri.query contains "1=1" or http.request.uri.query contains "drop+table" or http.request.body contains "union select")",
"description": "SQLi Basic Block",
"enabled": true
}'
Gerçek bir vakadan bahsedeyim: Bir SaaS platformunda /api/search endpoint’i üzerinden sürekli UNION SELECT denemeleri geliyordu. Managed rules bu bazılarını yakalıyordu ama obfuscate edilmiş varyantları geçiyordu. Özel kural yazarak hem URI query hem de request body’yi kontrol etmek durumunda kaldık. Bunun üzerine rate limiting de ekleyince saldırılar pratikte durdu.
Bot ve Scraper Koruması
Gerçek kullanıcıların sahip olmadığı User-Agent değerlerini bloklamak için:
curl -X POST "https://api.cloudflare.com/client/v4/zones/${CF_ZONE_ID}/rulesets/phases/http_request_firewall_custom/entrypoint/rules"
-H "Authorization: Bearer ${CF_API_TOKEN}"
-H "Content-Type: application/json"
-d '{
"action": "managed_challenge",
"expression": "(http.user_agent contains "python-requests" or http.user_agent contains "Go-http-client" or http.user_agent contains "curl" or http.user_agent eq "") and not ip.src in {192.168.1.0/24 10.0.0.0/8}",
"description": "Block Suspicious User Agents",
"enabled": true
}'
Burada managed_challenge kullandım, block değil. Sebep şu: Bazı meşru servisler de bu agent’ları kullanabilir. Challenge ile insan doğrulaması yaparak yanlış engelleme riskini azaltıyoruz. Ayrıca kendi iç networkünüzü whitelist olarak eklemeyi unutmayın.
Admin Panel Koruması
Admin veya yönetim panellerine sadece belirli IP’lerden erişime izin vermek çok kritik:
curl -X POST "https://api.cloudflare.com/client/v4/zones/${CF_ZONE_ID}/rulesets/phases/http_request_firewall_custom/entrypoint/rules"
-H "Authorization: Bearer ${CF_API_TOKEN}"
-H "Content-Type: application/json"
-d '{
"action": "block",
"expression": "(http.request.uri.path contains "/admin" or http.request.uri.path contains "/wp-admin" or http.request.uri.path contains "/phpmyadmin") and not ip.src in {203.0.113.10/32 203.0.113.20/32}",
"description": "Restrict Admin Access by IP",
"enabled": true
}'
Rate Limiting Kuralları
Rate limiting, brute force saldırılarına ve API scraping’e karşı temel savunma mekanizmanızdır. Login endpoint’lerine mutlaka rate limiting uygulayın.
curl -X POST "https://api.cloudflare.com/client/v4/zones/${CF_ZONE_ID}/rulesets/phases/http_ratelimit/entrypoint/rules"
-H "Authorization: Bearer ${CF_API_TOKEN}"
-H "Content-Type: application/json"
-d '{
"action": "block",
"ratelimit": {
"characteristics": ["ip.src", "http.request.headers["cf-connecting-ip"]"],
"period": 60,
"requests_per_period": 5,
"mitigation_timeout": 600
},
"expression": "http.request.uri.path eq "/login" and http.request.method eq "POST"",
"description": "Login Brute Force Protection",
"enabled": true
}'
Bu kural şunu yapıyor: Aynı IP adresi 60 saniye içinde /login endpoint’ine 5’ten fazla POST isteği gönderirse, o IP 600 saniye (10 dakika) boyunca bloklanıyor. Bir e-ticaret sitesinde bu ayarı devreye aldıktan sonra credential stuffing saldırıları %94 oranında düştü.
Dikkat edilecek nokta: mitigation_timeout değerini çok uzun tutmayın. Paylaşımlı IP kullanıcılarını (örneğin kurumsal proxy arkasındaki kullanıcılar) yanlışlıkla uzun süre engelleyebilirsiniz.
Cloudflare WAF Loglama ve İzleme
WAF’ı yapılandırmak yeterli değil, ne olduğunu da izlemeniz gerekiyor. Cloudflare Logs’u S3, Elasticsearch veya başka bir hedefe yönlendirebilirsiniz.
Logpush job oluşturmak için:
curl -X POST "https://api.cloudflare.com/client/v4/zones/${CF_ZONE_ID}/logpush/jobs"
-H "Authorization: Bearer ${CF_API_TOKEN}"
-H "Content-Type: application/json"
-d '{
"name": "waf-logs",
"destination_conf": "s3://your-bucket/logs?region=eu-west-1",
"dataset": "http_requests",
"logpull_options": "fields=ClientIP,ClientRequestHost,ClientRequestMethod,ClientRequestURI,EdgeStartTimestamp,FirewallMatchesActions,FirewallMatchesRuleIDs,FirewallMatchesSources×tamps=rfc3339",
"enabled": true
}'
WAF olaylarını daha hızlı sorgulamak için Cloudflare Analytics API’yi de kullanabilirsiniz:
curl -X POST "https://api.cloudflare.com/client/v4/graphql"
-H "Authorization: Bearer ${CF_API_TOKEN}"
-H "Content-Type: application/json"
-d '{
"query": "{ viewer { zones(filter: {zoneTag: "'${CF_ZONE_ID}'"}) { firewallEventsAdaptive(filter: {datetime_geq: "2024-01-01T00:00:00Z", datetime_leq: "2024-01-02T00:00:00Z", action_neq: "allow"}, limit: 100, orderBy: [datetime_DESC]) { action clientAsn clientCountryName clientIP clientRequestHTTPHost clientRequestHTTPMethodName clientRequestPath datetime ruleId source } } } }"
}' | jq '.data.viewer.zones[0].firewallEventsAdaptive[]'
Bu GraphQL sorgusu size son 24 saatte bloklanan veya challenge gönderilen tüm isteklerin detaylarını verir. Hangi kuralın ne kadar tetiklendiğini, hangi ülkelerden geldiğini ve IP adreslerini görebilirsiniz.
Terraform ile WAF Yönetimi
Production ortamlarında manuel API çağrıları yerine Terraform kullanmak çok daha mantıklı. Infrastructure as Code yaklaşımı WAF kurallarınızı da kapsamalı.
# Önce Cloudflare Terraform provider'ı kurun
cat > main.tf << 'EOF'
terraform {
required_providers {
cloudflare = {
source = "cloudflare/cloudflare"
version = "~> 4.0"
}
}
}
provider "cloudflare" {
api_token = var.cloudflare_api_token
}
resource "cloudflare_ruleset" "custom_waf" {
zone_id = var.zone_id
name = "Custom WAF Rules"
description = "Production WAF kuralları"
kind = "zone"
phase = "http_request_firewall_custom"
rules {
action = "block"
expression = "(http.request.uri.query contains "union+select" or http.request.uri.query contains "../")"
description = "SQLi ve Path Traversal"
enabled = true
}
rules {
action = "managed_challenge"
expression = "cf.threat_score gt 50"
description = "Yüksek tehdit skoru"
enabled = true
}
}
EOF
terraform init
terraform plan
terraform apply
Terraform ile WAF kurallarınızı git repository’de tutabilir, pull request süreci üzerinden gözden geçirebilir ve CI/CD pipeline’ınıza entegre edebilirsiniz. Büyük ekipler için bu yaklaşım zorunlu hale geliyor.
Gerçek Dünya: DDoS + Uygulama Katmanı Saldırısı Senaryosu
Geçen yıl bir medya platformu müşterimiz hem volumetrik DDoS hem de uygulama katmanı saldırısına aynı anda maruz kaldı. Saldırı özellikle ilginçti çünkü HTTP flood ile birlikte ?search= parametresi üzerinden cache’i bypass etmeye çalışıyordu.
Çözüm için uyguladığımız strateji şuydu:
- Cloudflare’in L3/L4 DDoS korumasını zaten aktifti, ek bir şey yapmadık
- Cache bypass denemelerine karşı:
cf.cache_status eq "BYPASS"koşulunu içeren özel bir kural yazdık - Search endpoint’i için agresif rate limiting devreye aldık
- ASN bazlı challenge kuralı ekledik (saldırı trafiği belirli ASN’lerden geliyordu)
cf.bot_management.score lt 30koşulu ile bot skoru düşük olan tüm trafiğe JS challenge uyguladık
20 dakika içinde saldırı trafiği origin sunucuya ulaşmaz hale geldi. Cloudflare’in Firewall Events ekranından gerçek zamanlı olarak engellenen istekleri izleyebildik.
False Positive Yönetimi
WAF’ın en büyük zorluklarından biri false positive, yani meşru trafiği yanlışlıkla engellemek. Özellikle CMS editörleri, API entegrasyonları ve güvenlik tarayıcıları sıkça sorun yaratır.
False positive’leri yönetmek için şu yaklaşımı kullanıyorum:
- Yeni kuralları direkt
blockyerine öncelogveyamanaged_challengemodunda açın - En az 48 saat logları izleyin
- Meşru trafiği whiteliste alarak kuralı daraltın
- Sonra
blockmoduna geçin
Örnek: Bir müşterimizin güvenlik ekibi Burp Suite ile periyodik pentest yapıyordu. WAF bu trafiği sürekli blokluyordu. Pentest IP’lerini IP List olarak tanımlayıp kurallarımıza and not ip.src in $pentest_ips ekleyince sorun çözüldü.
IP listesi oluşturmak için:
curl -X POST "https://api.cloudflare.com/client/v4/accounts/${CF_ACCOUNT_ID}/rules/lists"
-H "Authorization: Bearer ${CF_API_TOKEN}"
-H "Content-Type: application/json"
-d '{
"name": "pentest_ips",
"description": "Güvenlik ekibi ve pentest IP adresleri",
"kind": "ip"
}'
Listeye IP eklemek için:
curl -X POST "https://api.cloudflare.com/client/v4/accounts/${CF_ACCOUNT_ID}/rules/lists/${LIST_ID}/items"
-H "Authorization: Bearer ${CF_API_TOKEN}"
-H "Content-Type: application/json"
-d '[{"ip": "203.0.113.50"}, {"ip": "203.0.113.51"}]'
Security Headers Transform Rules
WAF kurallarının yanı sıra Transform Rules ile güvenlik header’larını merkezi olarak yönetebilirsiniz. Bu, origin sunucunuzu değiştirmeden güvenlik başlıklarını eklemenin en kolay yolu.
curl -X POST "https://api.cloudflare.com/client/v4/zones/${CF_ZONE_ID}/rulesets/phases/http_response_headers_transform/entrypoint/rules"
-H "Authorization: Bearer ${CF_API_TOKEN}"
-H "Content-Type: application/json"
-d '{
"action": "rewrite",
"action_parameters": {
"headers": {
"X-Frame-Options": {
"operation": "set",
"value": "DENY"
},
"X-Content-Type-Options": {
"operation": "set",
"value": "nosniff"
},
"Referrer-Policy": {
"operation": "set",
"value": "strict-origin-when-cross-origin"
},
"Permissions-Policy": {
"operation": "set",
"value": "geolocation=(), microphone=(), camera=()"
},
"Strict-Transport-Security": {
"operation": "set",
"value": "max-age=31536000; includeSubDomains; preload"
}
}
},
"expression": "true",
"description": "Security Headers",
"enabled": true
}'
Bu kural tüm response’lara güvenlik başlıklarını ekliyor. HSTS, X-Frame-Options, CSP gibi başlıkları Cloudflare üzerinden yönetmek, özellikle birden fazla origin sunucusu olan yapılarda büyük kolaylık sağlıyor.
İzleme ve Alarm Sistemi Kurma
WAF’ı kurup bırakmak olmaz. Aktif izleme şart. Cloudflare’in Notifications özelliği ile önemli olaylar için alarm kurabilirsiniz:
- Security Events Alert: Belirli bir sürede WAF olay sayısı eşiği aşarsa bildirim gönderir
- DDoS Attack Alert: L7 DDoS tespitinde anında bildirim
- Advanced Security Events Alert: Bot skoru bazlı anormallikler için
Bunları API ile yapılandırabilirsiniz, ancak dashboard üzerinden yapmak daha hızlı. Security > Security Events ekranını günlük olarak kontrol etme alışkanlığı edinin. Anomalileri erken fark etmek çok kritik.
Ekibiniz varsa Slack veya PagerDuty entegrasyonunu mutlaka kurun. Bir saldırı başladığında ilk 10 dakika hayati önem taşıyor.
Sonuç
Cloudflare WAF, doğru yapılandırıldığında web uygulamalarınız için son derece güçlü bir güvenlik katmanı oluşturuyor. Birkaç temel ilkeyi aklınızdan çıkarmayın:
- Katmanlı savunma: Managed rules, custom rules ve rate limiting birlikte kullanın. Tek bir mekanizmaya güvenmeyin.
- Log önce, blokla sonra: Yeni kuralları test etmeden direkt block moduna almayın. Log ya da challenge ile başlayın.
- Kod olarak yönetin: Terraform veya Git tabanlı bir yaklaşım benimseyin. Kimin ne değiştirdiğini bilmek acil durumlarda hayat kurtarır.
- Düzenli gözden geçirme: Aylık en az bir kez WAF kurallarınızı ve loglarınızı inceleyin. Eski kurallar zamanla gereksiz hale gelir ya da boşluk bırakır.
- False positive’leri ciddiye alın: Meşru kullanıcıları engellemek, saldırıya uğramak kadar can sıkıcı olabilir. WAF’ı bir kez kurup unutmak yerine yaşayan bir sistem olarak yönetin.
Cloudflare WAF özellikle küçük ve orta ölçekli ekipler için inanılmaz değer sunuyor. Kendi WAF altyapısı kurmak için harcayacağınız zaman, para ve eforla kıyaslandığında, Cloudflare’in sunduğu hazır altyapı gerçekten çarpıcı bir avantaj. Ancak teknolojiyi bilmeden kullanmak da tehlikeli. Bu yazıda anlattığım temelleri kavradıktan sonra kendi ortamınıza uygun kuralları yazabilir ve web uygulamalarınızı çok daha güvenli hale getirebilirsiniz.
