Rehber · DDoS koruması
Linux Sunucularda DDoS Sıkılaştırma
Labris Networks Mühendislik Ekibi · Son güncelleme 13 Ağustos 2026 · 16 dk
Kısa cevap
Çekirdek ayarları hacimsel saldırıyı durdurmaz; hattı dolduran trafik sunucuya hiç ulaşmaz. Sıkılaştırmanın gerçekten işe yaradığı yer durum tükenmesi ve uygulama katmanıdır: bağlantı kuyrukları, conntrack tablosu, dosya tanıtıcı sınırları ve kaynak başına oran.
Bu rehberin ilk cümlesi bir sınırı söylemek zorunda: çekirdek ayarları hacimsel saldırıyı durdurmaz. Erişim hattınızı dolduran trafik sunucunun ağ kartına hiç ulaşmaz, dolayısıyla o sunucuda ne ayarlarsanız ayarlayın sonuç değişmez. O sınıf yukarı yönde karşılanır.
Sıkılaştırmanın gerçekten fark yarattığı yer başkadır: durum tükenmesi ve uygulama katmanı. Bu iki sınıfta sunucunun kendi sonlu kaynakları hedeftir ve o kaynakların hepsi ayarlanabilir.
Önce Ölç
Hiçbir değeri, mevcut değeri bilmeden değiştirmeyin. Sıkılaştırma sonrası “daha iyi oldu mu” sorusunun cevabı, öncesinde alınmış temel ölçüler olmadan verilemez.
ss -s # özet. Toplam soket, TCP durumları
nstat -az | grep -i listen # ListenOverflows, ListenDrops
conntrack -C # o anki conntrack kayıt sayısı
sysctl net.netfilter.nf_conntrack_max # tablo kapasitesi
cat /proc/sys/fs/file-nr # kullanılan / sınır dosya tanıtıcı
Bu beş çıktıyı yoğun saatte bir hafta boyunca toplayın. Tepe değerleri alın; ortalama size saldırı anında ne olacağını söylemez.
Bağlantı Kurulumu
TCP bağlantısı kurulurken çekirdek iki ayrı kuyruk tutar. Yarım açık bağlantılar (SYN geldi, ACK bekleniyor) SYN kuyruğunda durur; el sıkışması tamamlanmış ama uygulama henüz accept() etmemiş bağlantılar kabul kuyruğunda bekler.
SYN flood birinciyi hedefler. İkincisi ise uygulamanız yavaşladığında kendiliğinden dolar ve saldırı olmadan da sorun çıkarır.
# /etc/sysctl.d/99-ddos.conf
net.ipv4.tcp_max_syn_backlog = 8192
net.core.somaxconn = 8192
net.ipv4.tcp_synack_retries = 2
net.ipv4.tcp_syncookies = 1
net.core.netdev_max_backlog = 16384
Değerler başlangıç noktasıdır, hedef değil. Kendi tepe oturum sayınıza göre seçilmeli ve değiştirdikten sonra ölçülmelidir.
Çekirdek ayarı tek başına yetmez. somaxconn bir tavandır; uygulamanın listen() çağrısına verdiği backlog değeri bu tavanın altındaysa geçerli olan uygulamanın değeridir. Nginx’te listen ... backlog=8192, systemd soketlerinde Backlog=, Java’da ServerSocket yapıcısının ikinci parametresi. Yalnız sysctl’i değiştirip uygulamayı unutmak, bu konudaki en yaygın eksik sıkılaştırmadır.
SYN Cookie Hakkında İki Yanlış Anlama
Birincisi: tcp_syncookies = 1 sürekli açık değildir. Yalnızca SYN kuyruğu taştığında devreye girer. Yani normal işletimde hiçbir şey yapmaz; ayarı açmış olmak tek başına bir koruma iddiası taşımaz. Devreye girip girmediği loglardan ve sayaçlardan görülür.
İkincisi: bedelsiz değildir. Cookie ile doğrulanan bağlantıda çekirdeğin saklayacak yeri olmadığı için bazı TCP seçenekleri korunamaz; pencere ölçekleme ve seçmeli onaylama gibi başlıklar etkilenebilir. Yüksek gecikmeli bağlantılarda bu, başarımda hissedilir bir düşüş demektir.
Bu yüzden doğru yapılandırma “cookie açık, kuyruk dar” değil, kuyruk yeterince geniş, cookie güvenlik valfi olarak açık biçimindedir.
conntrack
Durum tutan güvenlik duvarı kullanıyorsanız — iptables ya da nftables ile ct state kuralları yazıyorsanız, çekirdek her akış için bir conntrack kaydı tutar. Bu tablo, tükenebilecek ikinci kaynaktır.
# tablo dolduğunda dmesg'de görünür:
# nf_conntrack. Table full, dropping packet
net.netfilter.nf_conntrack_max = 262144
net.netfilter.nf_conntrack_buckets = 65536
net.netfilter.nf_conntrack_tcp_timeout_established = 3600
net.netfilter.nf_conntrack_tcp_timeout_syn_recv = 30
net.netfilter.nf_conntrack_udp_timeout = 30
Buradaki en önemli satır üçüncüsü. Kurulmuş TCP bağlantıları için varsayılan zaman aşımı beş gündür. Kapanışı düzgün görülmemiş her bağlantı tabloda beş gün durur. Yoğun bir sunucuda bu, saldırı olmadan da tablonun dolmasına yeter.
Değeri düşürmenin bir bedeli vardır: gerçekten uzun süre sessiz kalan bağlantılar — bazı veritabanı havuzları ve kalıcı kuyruk bağlantıları gibi, tablodan düşer ve sonraki paket yeni akış sayılır. Uygulamanız böyle bağlantılar tutuyorsa keepalive ayarlarıyla birlikte düşünülmelidir.
Durum tutmaya ihtiyacı olmayan yüksek hacimli trafik için kaydı hiç açmamak da bir seçenektir:
table ip raw {
chain prerouting {
type filter hook prerouting priority raw;
udp dport 53 notrack
}
}
Dosya Tanıtıcıları
Her bağlantı bir dosya tanıtıcısıdır. İki ayrı sınır vardır ve geçerli olan, ikisinden düşük olanıdır.
fs.file-max = 1000000 # sistem geneli, sysctl
# servis birimi
[Service]
LimitNOFILE=200000
ulimit -n ile kabuktan bakmak yanıltıcıdır; servis systemd tarafından başlatılıyorsa geçerli olan birim dosyasındaki değerdir. Çalışan sürecin gerçek sınırı /proc/<pid>/limits dosyasından okunur.
Oran Sınırlama
Oran sınırlama tek başına bir DDoS savunması değildir — dağınık bir saldırıda hiçbir kaynak tavanı aşmaz. Buna karşılık tek kaynaktan gelen yoğunluğu ve geçersiz trafiği ucuza eler.
table inet filter {
set syn_flood {
type ipv4_addr
flags dynamic,timeout
timeout 60s
}
chain input {
type filter hook input priority filter; policy drop;
ct state invalid drop
ct state established,related accept
iif lo accept
# kaynak başına saniyede 25 yeni bağlantı
tcp flags syn / syn,ack \
add @syn_flood { ip saddr limit rate over 25/second } drop
tcp dport { 80, 443 } ct state new accept
}
}
ct state invalid drop satırı sessiz ama değerlidir: hiçbir akışa ait olmayan, sahte bayraklı paketler tabloya kayıt açmadan düşer.
Ters vekil arkasındaysanız dikkat. Kaynak adres başına konan bir sınır, yük dengeleyicinin arkasında bütün trafiği tek adresten geliyor gibi görür ve dengeleyiciyi kısıtlar. O durumda sınır dengeleyicide ya da uygulama katmanında, gerçek istemci adresine göre konur.
Paket Hızı Tarafı
Küçük paketli saldırılarda darboğaz bant genişliği değil, saniyede işlenen paket sayısıdır. Tek bir işlemci çekirdeği bütün kesmeleri işliyorsa, kart daha fazlasını taşıyabilecekken sistem tıkanır.
ethtool -l eth0 # kaç kuyruk var, kaçı açık
ethtool -L eth0 combined 8
cat /proc/interrupts | grep eth0 # kesmeler çekirdeklere dağılmış mı
Çok kuyruklu bir kartta kuyrukların açık olması ve kesmelerin çekirdeklere yayılması, tek satırlık bir sysctl’den daha çok fark yaratır.
Neyi İzlemeli
Sıkılaştırmanın kendisi kadar önemli olan, tükenmenin dolmadan önce görülmesidir.
| Sayaç | Nereden | Ne söyler |
|---|---|---|
TcpExtListenOverflows |
nstat -az |
Kabul kuyruğu taştı, bağlantı düştü |
TcpExtListenDrops |
nstat -az |
SYN kuyruğunda düşen istek |
TcpExtTCPReqQFullDrop |
nstat -az |
İstek kuyruğu doluluğu |
| conntrack doluluk | conntrack -C / nf_conntrack_max |
Tablo tükenmeye ne kadar yakın |
file-nr |
/proc/sys/fs/file-nr |
Tanıtıcı sınırına yaklaşma |
Bu beşine eşik alarmı kurun. Alarm, tablo dolduğunda değil dolmaya yaklaştığında çalmalı; dolduktan sonra gelen bilgi artık bir olay bildirimidir, uyarı değil.
Yapmayın
İnternetten kopyalanan uzun sysctl listelerini toplu uygulamak. İçlerindeki değerlerin bir kısmı yıllar önceki çekirdekler için yazılmıştır, bir kısmı bugün varsayılan olarak zaten açıktır, bir kısmı da sizin trafik profilinizde zarar verir.
Her satırın ne yaptığını bilerek, birer birer ve ölçerek değiştirin. Bir kerede sekiz ayar değiştiren ekip, düzelme olduğunda hangisinin işe yaradığını bilemez.