Rate Limiting: DDoS ve Brute Force Saldırılarını Engelleme
Merhaba değerli okuyucular! Bugün, web uygulamalarının güvenliğini artırmak için kritik öneme sahip bir konu olan Rate Limiting'i derinlemesine inceleyeceğiz. DDoS (Distributed Denial of Service) ve Brute Force saldırılarına karşı etkili bir savunma mekanizması olan Rate Limiting'in nasıl uygulanacağını, farklı stratejileri ve en iyi uygulamaları ele alacağız. Hazırsanız, uygulamalarınızı daha güvenli hale getirmenin bu önemli yöntemine dalalım!
Rate Limiting Nedir?
Rate Limiting, bir kullanıcının veya IP adresinin belirli bir zaman diliminde yapabileceği istek sayısını sınırlandıran bir tekniktir. Bu, aşırı kaynak kullanımını önler ve potansiyel kötüye kullanımları engeller.
Neden Rate Limiting Önemlidir?
- DDoS saldırılarına karşı koruma sağlar
- Brute Force girişimlerini engeller
- API'leri kötüye kullanımdan korur
- Sunucu kaynaklarını korur
- Adil kullanımı teşvik eder
Rate Limiting Stratejileri
1. Fixed Window
Belirli bir zaman diliminde sabit sayıda istek izin verilir.
const WINDOW_SIZE_IN_SECONDS = 60; const MAX_REQUESTS_PER_WINDOW = 100; const requestCounts = new Map(); function fixedWindowRateLimiter(req, res, next) { const now = Math.floor(Date.now() / 1000); const windowStart = now - (now % WINDOW_SIZE_IN_SECONDS); const clientIp = req.ip; const windowCount = requestCounts.get(clientIp + ':' + windowStart) || 0; if (windowCount >= MAX_REQUESTS_PER_WINDOW) { return res.status(429).send('Too Many Requests'); } requestCounts.set(clientIp + ':' + windowStart, windowCount + 1); next(); }
2. Sliding Window
Daha yumuşak bir geçiş sağlayan, kayan zaman penceresi yaklaşımı.
const WINDOW_SIZE_IN_SECONDS = 60; const MAX_REQUESTS_PER_WINDOW = 100; const requestTimestamps = new Map(); function slidingWindowRateLimiter(req, res, next) { const now = Date.now(); const clientIp = req.ip; let clientRequests = requestTimestamps.get(clientIp) || []; clientRequests = clientRequests.filter(timestamp => now - timestamp < WINDOW_SIZE_IN_SECONDS * 1000); if (clientRequests.length >= MAX_REQUESTS_PER_WINDOW) { return res.status(429).send('Too Many Requests'); } clientRequests.push(now); requestTimestamps.set(clientIp, clientRequests); next(); }
3. Token Bucket
Her istek için bir "token" harcanır, ve tokenlar zamanla yenilenir.
class TokenBucket { constructor(capacity, fillPerSecond) { this.capacity = capacity; this.tokens = capacity; this.lastFilled = Date.now(); this.fillPerSecond = fillPerSecond; } take() { this.refill(); if (this.tokens > 0) { this.tokens--; return true; } return false; } refill() { const now = Date.now(); const secondsPassed = (now - this.lastFilled) / 1000; this.tokens = Math.min(this.capacity, this.tokens + secondsPassed * this.fillPerSecond); this.lastFilled = now; } } const buckets = new Map(); function tokenBucketRateLimiter(req, res, next) { const clientIp = req.ip; let bucket = buckets.get(clientIp); if (!bucket) { bucket = new TokenBucket(10, 1); // 10 tokens, refills 1 per second buckets.set(clientIp, bucket); } if (bucket.take()) { next(); } else { res.status(429).send('Too Many Requests'); } }
Rate Limiting Uygulaması
Express.js ile Rate Limiting
Express.js için popüler bir rate limiting middleware'i olan express-rate-limit kullanarak basit bir uygulama:
const express = require('express'); const rateLimit = require('express-rate-limit'); const app = express(); const limiter = rateLimit({ windowMs: 15 * 60 * 1000, // 15 dakika max: 100 // Her IP için 15 dakikada maksimum 100 istek }); // Tüm isteklere rate limiter uygula app.use(limiter); app.get('/', (req, res) => { res.send('Hello World!'); }); app.listen(3000, () => console.log('Server running on port 3000'));
Nginx ile Rate Limiting
Nginx web sunucusu kullanıyorsanız, built-in rate limiting modülünü kullanabilirsiniz:
http { limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r/s; server { location / { limit_req zone=mylimit burst=20 nodelay; proxy_pass http://backend; } } }
Rate Limiting Best Practices
1. Uygun Limit Belirleyin
Çok düşük limitler meşru kullanıcıları engelleyebilir, çok yüksek limitler ise koruma sağlamaz. Uygulamanızın ihtiyaçlarına göre dengelemeyi yapın.
2. Kademeli Rate Limiting
Farklı endpoint'ler veya kullanıcı tipleri için farklı limitler belirleyin.
const publicLimiter = rateLimit({ windowMs: 15 * 60 * 1000, max: 100 }); const apiLimiter = rateLimit({ windowMs: 15 * 60 * 1000, max: 1000 }); app.use('/public', publicLimiter); app.use('/api', apiLimiter);
3. Kullanıcı Dostu Hata Mesajları
Limit aşıldığında kullanıcıya ne zaman tekrar deneyebileceğini bildirin.
const limiter = rateLimit({ windowMs: 15 * 60 * 1000, max: 100, message: 'Too many requests, please try again after 15 minutes.' });
4. Beyaz Liste ve Kara Liste
Güvenilir IP'leri beyaz listeye alın, sürekli kötüye kullanan IP'leri kara listeye alın.
const whitelist = ['127.0.0.1', '::1']; const blacklist = ['123.456.78.9']; const limiter = rateLimit({ windowMs: 15 * 60 * 1000, max: 100, skip: (req, res) => whitelist.includes(req.ip), handler: (req, res, next) => { if (blacklist.includes(req.ip)) { res.status(403).send('Forbidden'); } else { res.status(429).send('Too Many Requests'); } } });
5. Monitör ve Loglama
Rate limiting olaylarını izleyin ve loglarınızda kaydedin.
6. Dağıtık Sistemlerde Dikkatli Olun
Birden fazla sunucu kullanıyorsanız, merkezi bir rate limiting çözümü (örn. Redis kullanarak) düşünün.
Rate Limiting'in Geleceği
Rate limiting teknikleri sürekli gelişiyor. İşte gelecekte beklenen bazı trendler:
- Makine Öğrenimi Tabanlı Rate Limiting: Normal ve anormal trafik desenlerini otomatik olarak öğrenen ve buna göre limitleri ayarlayan sistemler.
- Bağlama Duyarlı Limitler: Kullanıcı davranışı, geçmiş kullanım ve diğer faktörlere göre dinamik olarak ayarlanan limitler.
- Daha Sofistike DDoS Koruması: Rate limiting ile diğer güvenlik önlemlerinin daha entegre hale gelmesi.
Etkili Bir Savunma Mekanizması
Rate limiting, web uygulamalarınızı DDoS ve Brute Force saldırılarına karşı korumak için etkili bir yöntemdir. Doğru uygulandığında, uygulamanızın güvenliğini ve performansını önemli ölçüde artırabilir.
İşte rate limiting uygulamanız için genel bir yapı:
class RateLimiter { constructor(maxRequests, perSeconds) { this.maxRequests = maxRequests; this.perSeconds = perSeconds; this.clients = new Map(); } limitReached(clientId) { const now = Date.now(); if (!this.clients.has(clientId)) { this.clients.set(clientId, []); } const clientRequests = this.clients.get(clientId); const windowStart = now - this.perSeconds * 1000; while (clientRequests.length > 0 && clientRequests[0] <= windowStart) { clientRequests.shift(); } if (clientRequests.length >= this.maxRequests) { return true; } clientRequests.push(now); return false; } } // Kullanım const limiter = new RateLimiter(100, 60); // 60 saniyede 100 istek function rateLimitMiddleware(req, res, next) { if (limiter.limitReached(req.ip)) { return res.status(429).send('Too Many Requests'); } next(); } app.use(rateLimitMiddleware);
Bu yapı, sliding window yaklaşımını kullanarak esnek ve etkili bir rate limiting çözümü sunar.
Siz uygulamalarınızda rate limiting kullanıyor musunuz? Hangi stratejileri tercih ediyorsunuz? DDoS ve Brute Force saldırılarına karşı başka hangi önlemleri alıyorsunuz? Deneyimlerinizi ve düşüncelerinizi yorumlarda paylaşın!
Güvenli kodlamalar ve her zaman sınırlı istekler!