Birden fazla sunucu yönetiyorsanız ve her birinde ayrı ayrı fail2ban konfigürasyonu yapıyorsanız, bu yazı tam size göre. Özellikle 10-20 sunucuyu geçtikten sonra her makinede ayrı fail2ban yönetimi yapmak hem zaman kaybı hem de tutarsız güvenlik politikalarına yol açıyor. Merkezi bir yapı kurarak tüm sunucularınızdaki ban listelerini, log analizlerini ve kural güncellemelerini tek noktadan yönetebilirsiniz.
Merkezi Fail2ban Yönetiminin Mantığı
Temel fikir şu: Bir “master” sunucu belirleyip diğer tüm sunuculardan gelen ban bilgilerini bu noktada topluyorsunuz. Bir IP adresi herhangi bir sunucunuzda kötü niyetli davranış sergilediğinde, bu bilgi tüm sisteme yayılıyor. Buna distributed blacklisting diyoruz.
Bu yapının avantajları somut:
- Bir sunucuyu hedef alan saldırgan otomatik olarak diğer tüm sunuculardan bloklanır
- Merkezi log analizi ile saldırı trendlerini daha net görürsünüz
- Kural güncellemelerini tek yerden yaparsınız
- Whitelist yönetimi tutarlı kalır
- Audit ve compliance raporlaması çok daha kolay olur
Altyapı Gereksinimleri
Bu yapıyı kurmadan önce birkaç şeyi netleştirmemiz gerekiyor. Master sunucunuzun diğer tüm sunucular tarafından erişilebilir olması şart. Genellikle iç ağda bir yönetim sunucusu bu rolü üstlenir.
Gerekli bileşenler:
- Master sunucu: Merkezi veritabanı, API servisi ve dashboard
- Agent sunucular: Standart fail2ban + özel action scriptleri
- Veritabanı: SQLite yeterli olmaz, PostgreSQL veya MySQL kullanın
- Güvenli iletişim: SSH tüneli veya TLS sertifikası zorunlu
Adım 1: Master Sunucu Kurulumu
Önce master sunucuda gerekli paketleri kuralım. Bu örnekte Ubuntu/Debian tabanlı sistem kullanıyoruz.
apt update && apt install -y fail2ban python3-pip postgresql postgresql-contrib nginx
pip3 install flask flask-sqlalchemy psycopg2-binary requests cryptography
# Fail2ban'ı başlat
systemctl enable fail2ban
systemctl start fail2ban
PostgreSQL veritabanını hazırlayalım:
sudo -u postgres psql << 'EOF'
CREATE DATABASE fail2ban_central;
CREATE USER fail2ban_user WITH ENCRYPTED PASSWORD 'G3lismisPaSS_2024!';
GRANT ALL PRIVILEGES ON DATABASE fail2ban_central TO fail2ban_user;
c fail2ban_central
CREATE TABLE banned_ips (
id SERIAL PRIMARY KEY,
ip_address INET NOT NULL,
server_hostname VARCHAR(255) NOT NULL,
jail_name VARCHAR(100) NOT NULL,
ban_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
unban_time TIMESTAMP,
attempts INTEGER DEFAULT 0,
is_active BOOLEAN DEFAULT TRUE
);
CREATE TABLE servers (
id SERIAL PRIMARY KEY,
hostname VARCHAR(255) UNIQUE NOT NULL,
ip_address INET NOT NULL,
api_key VARCHAR(64) NOT NULL,
last_seen TIMESTAMP,
is_active BOOLEAN DEFAULT TRUE
);
CREATE INDEX idx_banned_ips_ip ON banned_ips(ip_address);
CREATE INDEX idx_banned_ips_active ON banned_ips(is_active);
EOF
Adım 2: Merkezi API Servisi
Master sunucuda çalışacak Python Flask API’sini oluşturalım. Bu servis agent sunuculardan gelen ban bilgilerini alacak ve sorgulara cevap verecek.
# /opt/fail2ban-central/api.py
from flask import Flask, request, jsonify
from flask_sqlalchemy import SQLAlchemy
from datetime import datetime
import hashlib
import os
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://fail2ban_user:G3lismisPaSS_2024!@localhost/fail2ban_central'
db = SQLAlchemy(app)
def verify_api_key(server_hostname, api_key):
server = Server.query.filter_by(hostname=server_hostname, api_key=api_key, is_active=True).first()
if server:
server.last_seen = datetime.utcnow()
db.session.commit()
return True
return False
@app.route('/api/v1/ban', methods=['POST'])
def report_ban():
data = request.get_json()
hostname = request.headers.get('X-Server-Hostname')
api_key = request.headers.get('X-API-Key')
if not verify_api_key(hostname, api_key):
return jsonify({'error': 'Unauthorized'}), 401
banned_ip = BannedIP(
ip_address=data['ip'],
server_hostname=hostname,
jail_name=data['jail'],
attempts=data.get('attempts', 0)
)
db.session.add(banned_ip)
db.session.commit()
return jsonify({'status': 'ok', 'id': banned_ip.id}), 201
@app.route('/api/v1/blacklist', methods=['GET'])
def get_blacklist():
hostname = request.headers.get('X-Server-Hostname')
api_key = request.headers.get('X-API-Key')
if not verify_api_key(hostname, api_key):
return jsonify({'error': 'Unauthorized'}), 401
active_bans = BannedIP.query.filter_by(is_active=True).all()
ip_list = list(set([str(ban.ip_address) for ban in active_bans]))
return jsonify({'ips': ip_list, 'count': len(ip_list)}), 200
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000, debug=False)
Servisi systemd ile yönetelim:
cat > /etc/systemd/system/fail2ban-api.service << 'EOF'
[Unit]
Description=Fail2ban Central API
After=network.target postgresql.service
[Service]
Type=simple
User=www-data
WorkingDirectory=/opt/fail2ban-central
ExecStart=/usr/bin/python3 /opt/fail2ban-central/api.py
Restart=always
RestartSec=10
Environment=FLASK_ENV=production
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable fail2ban-api
systemctl start fail2ban-api
Adım 3: Agent Sunucularda Fail2ban Yapılandırması
Her agent sunucuda fail2ban kurulu olmalı. Buradaki kritik nokta, ban olaylarını master API’ye raporlayan custom action yazmak.
# /etc/fail2ban/action.d/central-report.conf
[Definition]
actionstart =
actionstop =
actioncheck =
actionban = curl -s -X POST
-H "Content-Type: application/json"
-H "X-Server-Hostname: $(hostname)"
-H "X-API-Key: <api_key>"
-d '{"ip": "<ip>", "jail": "<name>", "attempts": <failures>}'
https://master.sirketiniz.com/api/v1/ban
|| true
actionunban = curl -s -X DELETE
-H "Content-Type: application/json"
-H "X-Server-Hostname: $(hostname)"
-H "X-API-Key: <api_key>"
-d '{"ip": "<ip>", "jail": "<name>"}'
https://master.sirketiniz.com/api/v1/ban
|| true
Fail2ban jail konfigürasyonuna bu action’ı ekleyin:
# /etc/fail2ban/jail.local
[DEFAULT]
bantime = 3600
findtime = 600
maxretry = 5
action = %(action_mwl)s
central-report[api_key="SUNUCU_API_ANAHTARI_BURAYA"]
[sshd]
enabled = true
port = ssh
logpath = %(sshd_log)s
backend = %(sshd_backend)s
maxretry = 3
bantime = 86400
[nginx-http-auth]
enabled = true
port = http,https
logpath = /var/log/nginx/error.log
maxretry = 5
[nginx-limit-req]
enabled = true
port = http,https
logpath = /var/log/nginx/error.log
maxretry = 10
findtime = 60
Adım 4: Merkezi Blacklist Senkronizasyonu
Bu yapının en değerli özelliği şu: Bir sunucuda banlanan IP otomatik olarak diğerlerine de uygulanmalı. Bunun için her agent sunucuda çalışacak bir senkronizasyon scripti yazıyoruz.
#!/bin/bash
# /usr/local/bin/fail2ban-sync.sh
MASTER_URL="https://master.sirketiniz.com"
API_KEY="$(cat /etc/fail2ban/api.key)"
HOSTNAME="$(hostname)"
IPSET_NAME="fail2ban-central"
LOG_FILE="/var/log/fail2ban-sync.log"
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> "$LOG_FILE"
}
# Master'dan güncel blacklist'i çek
RESPONSE=$(curl -s -f
-H "X-Server-Hostname: $HOSTNAME"
-H "X-API-Key: $API_KEY"
"$MASTER_URL/api/v1/blacklist")
if [ $? -ne 0 ]; then
log "HATA: Master sunucuya ulasilamiyor"
exit 1
fi
IP_COUNT=$(echo "$RESPONSE" | python3 -c "import sys,json; data=json.load(sys.stdin); print(data['count'])")
log "Master'dan $IP_COUNT aktif ban alindi"
# Mevcut ipset'i yedekle ve güncelle
ipset create "$IPSET_NAME-new" hash:ip timeout 0 2>/dev/null || true
ipset flush "$IPSET_NAME-new"
# Yeni IP'leri ekle
echo "$RESPONSE" | python3 -c "
import sys, json
data = json.load(sys.stdin)
for ip in data['ips']:
print(ip)
" | while read ip; do
ipset add "$IPSET_NAME-new" "$ip" 2>/dev/null || true
done
# Atomik swap
ipset create "$IPSET_NAME" hash:ip timeout 0 2>/dev/null || true
ipset swap "$IPSET_NAME-new" "$IPSET_NAME"
ipset destroy "$IPSET_NAME-new"
# iptables kuralını kontrol et
if ! iptables -C INPUT -m set --match-set "$IPSET_NAME" src -j DROP 2>/dev/null; then
iptables -I INPUT 1 -m set --match-set "$IPSET_NAME" src -j DROP
log "iptables kurali eklendi"
fi
log "Senkronizasyon tamamlandi. Toplam engellenen IP: $IP_COUNT"
Bu scripti cron ile her 5 dakikada çalıştırın:
chmod +x /usr/local/bin/fail2ban-sync.sh
# Crontab ekle
echo "*/5 * * * * root /usr/local/bin/fail2ban-sync.sh" > /etc/cron.d/fail2ban-sync
# ipset paketini kur
apt install -y ipset
# Servisi başlat
systemctl enable netfilter-persistent
Adım 5: Otomatik Sunucu Kaydı
Yeni bir sunucu eklediğinizde manuel müdahale istemiyorsanız, otomatik kayıt mekanizması kurabilirsiniz. Master sunucuda güvenli bir endpoint açıp, agent sunucuların kendini kaydettirmesini sağlayabilirsiniz.
#!/bin/bash
# /usr/local/bin/fail2ban-register.sh
# Agent sunucularda bir kez çalıştırılır
MASTER_URL="https://master.sirketiniz.com"
BOOTSTRAP_TOKEN="$(cat /etc/fail2ban/bootstrap.token)"
HOSTNAME="$(hostname)"
SERVER_IP="$(curl -s ifconfig.me)"
# Kayıt isteği gönder
RESPONSE=$(curl -s -X POST
-H "Content-Type: application/json"
-H "X-Bootstrap-Token: $BOOTSTRAP_TOKEN"
-d "{"hostname": "$HOSTNAME", "ip": "$SERVER_IP"}"
"$MASTER_URL/api/v1/register")
API_KEY=$(echo "$RESPONSE" | python3 -c "import sys,json; print(json.load(sys.stdin)['api_key'])")
if [ -z "$API_KEY" ]; then
echo "Kayit basarisiz!"
exit 1
fi
# API anahtarını güvenli şekilde sakla
echo "$API_KEY" > /etc/fail2ban/api.key
chmod 600 /etc/fail2ban/api.key
# Fail2ban konfigürasyonunu güncelle
sed -i "s/SUNUCU_API_ANAHTARI_BURAYA/$API_KEY/" /etc/fail2ban/jail.local
systemctl restart fail2ban
echo "Sunucu basariyla kaydedildi. API Key: $API_KEY"
Gerçek Dünya Senaryosu: E-ticaret Altyapısı
Diyelim ki 3 web sunucusu, 2 API sunucusu ve 1 veritabanı sunucusu olan bir e-ticaret altyapısı yönetiyorsunuz. Kara Cuma döneminde web sunucularınızdan biri credential stuffing saldırısına uğruyor. Merkezi yapı olmadan bu saldırganlar diğer sunuculara geçebilir.
Bu yapıyla şöyle çalışıyor:
- web-01 üzerinde bir IP adresi /login endpoint’ini 10 kez 30 saniyede deniyor
- fail2ban bu IP’yi banlıyor ve central-report action’ı devreye giriyor
- Master API ban kaydını veritabanına yazıyor
- 5 dakika içinde diğer tüm sunuculardaki senkronizasyon scripti bu IP’yi kendi ipset’lerine ekliyor
- Saldırgan artık hiçbir sunucunuza erişemiyor
Bu senaryoda özellikle faydalı olan bir durum daha var: Aynı saldırgan farklı sunucularda farklı jaillerden ban yemişse, özel bir sorgu ile bu “çok cepheli saldırganları” tespit edebilirsiniz.
# Master sunucuda çalıştırın - birden fazla sunucudan saldıran IP'leri bulur
psql -U fail2ban_user -d fail2ban_central << 'EOF'
SELECT
ip_address,
COUNT(DISTINCT server_hostname) as sunucu_sayisi,
COUNT(DISTINCT jail_name) as jail_sayisi,
SUM(attempts) as toplam_deneme,
MIN(ban_time) as ilk_ban,
MAX(ban_time) as son_ban
FROM banned_ips
WHERE is_active = TRUE
AND ban_time > NOW() - INTERVAL '24 hours'
GROUP BY ip_address
HAVING COUNT(DISTINCT server_hostname) > 1
ORDER BY sunucu_sayisi DESC, toplam_deneme DESC
LIMIT 20;
EOF
Uyarı Sistemi Entegrasyonu
Merkezi yapının bir diğer güzel yanı, anlamlı alertler üretebilmek. Slack veya e-posta entegrasyonu için basit bir script:
#!/bin/bash
# /usr/local/bin/fail2ban-alert.sh
# Dakikada bir cron ile çalıştır, çok sık ban yiyen IP'leri raporla
SLACK_WEBHOOK="https://hooks.slack.com/services/XXX/YYY/ZZZ"
THRESHOLD=5 # Son 1 saatte 5'ten fazla sunucudan ban yiyen IP'ler
RESULT=$(psql -U fail2ban_user -d fail2ban_central -t -A -F',' << 'EOF'
SELECT ip_address, COUNT(DISTINCT server_hostname)
FROM banned_ips
WHERE ban_time > NOW() - INTERVAL '1 hour'
AND is_active = TRUE
GROUP BY ip_address
HAVING COUNT(DISTINCT server_hostname) >= 5;
EOF
)
if [ -n "$RESULT" ]; then
MESSAGE="*[FAIL2BAN UYARI]* Son 1 saatte 5+ sunucudan ban yiyen IP'ler:n$RESULT"
curl -s -X POST
-H 'Content-type: application/json'
--data "{"text":"$MESSAGE"}"
"$SLACK_WEBHOOK"
fi
Whitelist Merkezi Yönetimi
Ofis IP adresi, monitoring sistemleri, CDN aralıkları gibi IP’lerin merkezi whitelist’te tutulması hayat kurtarır. Bir sunucuda yanlışlıkla banlanmış monitoring IP’sini tek tek her sunucuda açmak yerine master’dan halledersiniz.
# Master sunucuda whitelist tablosu
sudo -u postgres psql -d fail2ban_central << 'EOF'
CREATE TABLE whitelist (
id SERIAL PRIMARY KEY,
ip_cidr CIDR NOT NULL,
description VARCHAR(255),
added_by VARCHAR(100),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
INSERT INTO whitelist (ip_cidr, description, added_by) VALUES
('10.0.0.0/8', 'Ic ag', 'admin'),
('203.0.113.0/24', 'Ofis cikis IP blogu', 'admin'),
('192.168.1.100/32', 'Monitoring sunucusu', 'admin');
EOF
Senkronizasyon scriptine whitelist kontrolü ekleyin:
# fail2ban-sync.sh içine eklenecek whitelist bölümü
WHITELIST=$(psql -U fail2ban_user -d fail2ban_central -t -A
-c "SELECT ip_cidr FROM whitelist;")
echo "$RESPONSE" | python3 -c "
import sys, json, ipaddress
data = json.load(sys.stdin)
whitelist_raw = '''$WHITELIST'''.strip().split('n')
whitelist = [ipaddress.ip_network(w.strip()) for w in whitelist_raw if w.strip()]
for ip in data['ips']:
try:
ip_obj = ipaddress.ip_address(ip)
if not any(ip_obj in net for net in whitelist):
print(ip)
except:
pass
" | while read ip; do
ipset add "$IPSET_NAME-new" "$ip" 2>/dev/null || true
done
Performans ve Ölçekleme
50 sunucuyu geçtiğinizde birkaç noktaya dikkat etmek gerekiyor:
API rate limiting: Her sunucu 5 dakikada bir istek atıyor. 100 sunucu için dakikada 20 istek demek, bu tamamen yönetilebilir. Ama senkronizasyon sıklığını artırmak isterseniz, Nginx ile rate limiting ekleyin.
Veritabanı büyümesi: Yoğun saldırı dönemlerinde günde yüz binlerce kayıt oluşabilir. Eski kayıtları temizleyen bir cronjob şart:
# Her gece çalıştır
sudo -u postgres psql -d fail2ban_central -c "
DELETE FROM banned_ips
WHERE ban_time < NOW() - INTERVAL '30 days'
AND is_active = FALSE;
VACUUM ANALYZE banned_ips;
"
Yüksek erişilebilirlik: Master sunucu single point of failure olmamalı. En basit çözüm, master’ın çökmesi durumunda agent sunucuların mevcut ipset’leri koruyarak çalışmaya devam etmesi. fail2ban-sync.sh scriptindeki hata yönetimi tam da bunun için orada: exit 1 ile çıkıp mevcut kuralları bozmuyoruz.
Sonuç
Merkezi fail2ban yönetimi ilk kurulumda biraz emek istiyor ama birkaç sunucuyu geçer geçmez bu yatırımın karşılığını fazlasıyla alıyorsunuz. En kritik kazanım koordineli savunma kapasitesi: tek bir saldırı noktası tüm altyapınızı korur hale geliyor.
Uygulamada şu sırayı takip etmenizi öneririm: Önce master sunucuyu ve veritabanını kurun, birkaç sunucuyu agent olarak bağlayın ve bir hafta boyunca log’ları izleyin. Yapının istikrarlı çalıştığını gördükten sonra kalan sunucuları ekleyin. Otomatik kayıt mekanizması ise özellikle sık sunucu açıp kapattığınız cloud ortamlarda büyük konfor sağlıyor.
Son bir not: Bu yapıyı production’a almadan önce test ortamında mutlaka birkaç senaryo çalıştırın. Özellikle whitelist kontrolünü test edin, monitoring sunucunuzun kendi kendini bloklaması hiç de nadir karşılaşılan bir durum değil.