Teknik derinlik
Tomcat DDoS Sıkılaştırma: Connector Thread Havuzları, Zaman Aşımları ve Ön Katman
Son güncelleme: Ağustos 2026 · Connector havuzu, zaman aşımları ve zorunlu ön katman · Okuma süresi ~18 dk

Tomcat'in DDoS maruziyeti Connector'ında yaşar. maxThreads, acceptCount, maxConnections ve connectionTimeout taşıyıcı ayarlardır ve NIO protokolü yavaş bir bağlantının koca bir thread'e mal olmasını önler. Ama en büyük karar mimaridir: 8080 portunda çıplak duran bir Tomcat, hiçbir Connector değerinin gideremeyeceği biçimde açıktır. Bu yüzden önce ön katman gelir.
Bu rehber, bir DDoS saldırısının bağlantı ve thread tüketen kısmına karşı Apache Tomcat’in kendisini sertleştirir. Web sunucusu rehberlerinden yapısal bir noktada ayrılır ve bunu önce söylemek gerekir: Tomcat bir uygulama sunucusudur ve standart üretim tasarımı onu doğrudan açmaz. Önünde sertleştirilmiş bir web sunucusu veya yük dengeleyici durur, bağlantıyı sonlandırır ve temiz istekleri özel bir ağ üzerinden iletir. Bu serinin savunmalarının çoğu o ön katmanda yaşar.
Dolayısıyla aşağıdaki Connector ayarları ön katmanın arkasına uygulanan ikinci hattır. Yine de önemlidir, çünkü bir ön katman çökebilir, iç ağda atlatılabilir ya da yakalayamadığı bir saldırıyı iletebilir. Ama önüne sertleştirilmiş bir katman koymanın yerine geçmez. Her ayar, değeriyle ve işlediğini gösteren JMX veya kayıt sayacıyla birlikte gelir.
| Cihaz | Saldırı biçimi | Tomcat ayarı | Doğrulama |
|---|---|---|---|
| Yavaş başlık / yavaş gövde (Slowloris) | connectionTimeout; NIO protokolü; keepAliveTimeout | Manager: R durumundaki thread'ler; erişim kaydında %D | |
| Bağlantı seli | maxConnections; acceptCount (işletim sistemi backlog'u) | jmx Connector connectionCount | |
| Thread havuzu tükenmesi | maxThreads; connector'lar arasında paylaşılan Executor | jmx ThreadPool currentThreadsBusy | |
| Büyük istek istismarı | maxHttpHeaderSize, maxParameterCount, maxPostSize | Erişim kaydında 400 oranı | |
| Doğrudan internet maruziyeti | 8080'i açma; önce bir ön katman sonlandırır | netstat: 8080 yalnız localhost/iç adrese bağlı |
Son satır diğerlerini yeniden çerçeveler: Tomcat bir uygulama sunucusudur ve en savunulabilir standart tasarım, önüne sertleştirilmiş bir web sunucusu veya proxy koyar. Aşağıdaki Connector ayarları o ön katmanın var olduğunu varsayar.
0. Önce temel ölçüler: Connector metriklerini açığa çıkarın
Tomcat’in canlı durumu JMX’te ve erişim kaydındadır. İşleme süresini kaydeden bir erişim kaydı açın ve Connector’ın thread havuzunu normal bir hafta boyunca okuyun:
<!-- server.xml, <Host> içinde — %D milisaniye cinsinden istek süresi, %S oturum -->
<Valve className="org.apache.catalina.valves.AccessLogValve"
directory="logs" prefix="access." suffix=".log"
pattern="%h %t "%r" %s %b %D" />
# Thread havuzu ve bağlantı sayısı JMX üzerinden (jconsole ya da başsız jmxterm)
# Catalina:type=ThreadPool,name="http-nio-8080" -> currentThreadsBusy, connectionCount
# Erişim kaydından en yavaş istekler (son alan %D, ms)
awk '{print $NF, $0}' logs/access.*.log | sort -rn | head
# İstemci başına istek sayısı, normal bir hafta
awk '{print $1}' logs/access.*.log | sort | uniq -c | sort -rn | head
maxThreads’e karşı currentThreadsBusy ve maxConnections’a karşı connectionCount, aşağıdaki her
değerin karşısında ayarlandığı iki temel ölçüdür.
1. Önce ön katman gelir
server.xml’e dokunmadan önce Tomcat’in doğrudan açık olmadığını doğrulayın:
# HTTP Connector localhost'a veya iç adrese bağlanmalı, açık bir sunucuda asla 0.0.0.0'a değil
ss -ltnp | grep 8080
8080 açık bir arayüze bağlıysa ilk düzeltilecek şey budur. Onu ön katmanın kullandığı iç adrese bağlayın ve internet’e bakan bağlantıyı nginx veya Apache httpd sonlandırsın. Bu ön katmanlar nginx ve Apache rehberlerinde sertleştirildi; TLS’i, yavaş bağlantı tahliyesini ve oran sınırlamayı Connector’dan çok daha iyi taşırlar.
<!-- server.xml — yalnız iç arayüze bağla -->
<Connector port="8080" address="10.0.0.5"
protocol="org.apache.coyote.http11.Http11NioProtocol"
... />
2. Connector protokolü: bloklayan değil, NIO
protocol özniteliği, yavaş bir bağlantının bir thread’e mal olup olmayacağını belirler. NIO connector’ı kullanın; eski bloklayan connector bağlantı başına bir thread harcar ve Slowloris’i ucuz kılardı:
<Connector port="8080" address="10.0.0.5"
protocol="org.apache.coyote.http11.Http11NioProtocol"
connectionTimeout="20000"
maxThreads="400"
minSpareThreads="25"
maxConnections="8192"
acceptCount="200"
maxKeepAliveRequests="100"
keepAliveTimeout="15000" />
# Çalışan protokolü doğrula
grep -i 'protocol=' conf/server.xml
# Başlangıç kaydında: "Initializing ProtocolHandler [http-nio-8080]"
grep -i 'ProtocolHandler' logs/catalina.out | tail
3. Üç bağlantı sınırı, birlikte boyutlandırılır
maxConnections, acceptCount ve maxThreads sırayla üç sınırdır: tutulan bağlantılar, backlog’a
alınan bağlantılar, işlenen istekler. Bunları bir küme olarak boyutlandırın:
maxConnections = 8192 # aynı anda kabul edilip tutulan bağlantılar
acceptCount = 200 # maxConnections dolunca işletim sistemi backlog'u (listen backlog'una karşılık gelir)
maxThreads = 400 # aynı anda işlenen istekler
minSpareThreads = 25 # sıcak tutulan thread'ler
Küçük bir maxThreads arkasında büyük bir maxConnections koruma değildir; birkaç thread’i bekleyen
uzun bir bağlantı kuyruğudur ve yavaş, kafa karıştırıcı biçimde çöker. maxThreads’i uygulamanın ve
yığının yük altında gerçekten desteklediği değere ayarlayın, sonra maxConnections’ı bunun sağlıklı
bir katı üzerinde ve acceptCount’u büyük değil kısa bir backlog olarak belirleyin. Büyük bir
backlog, havuzu koruyan reddi yalnızca geciktirir.
# Meşgul thread'ler tavana karşı, canlı
# JMX: Catalina:type=ThreadPool,name="http-nio-8080" currentThreadsBusy / maxThreads
# busy == maxThreads ve connectionCount tırmanıyorsa darboğaz havuzdur
4. Connector’lar arasında paylaşılan Executor
Sunucuda birden çok connector varsa (HTTP ve HTTPS), her connector’ın kendi havuzunu tutması yerine
paylaşılan bir Executor toplam thread’leri ikisi arasında sınırlar:
<Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
maxThreads="400" minSpareThreads="25"
maxIdleTime="60000" prestartminSpareThreads="true" />
<Connector executor="tomcatThreadPool" port="8080" ... />
<Connector executor="tomcatThreadPool" port="8443" ... />
Bu, bir connector’a gelen selin diğerini aç bırakmasını önler ve yığına karşı boyutlandıracak tek bir sayı verir.
5. Zaman aşımları ve istek boyutu sınırları
connectionTimeout Slowloris’e karşı emniyet ağıdır; boyut sınırları büyük istek yüzeyini kapatır:
<Connector ...
connectionTimeout="20000" <!-- istek satırı + başlıkları almak için ms -->
keepAliveTimeout="15000" <!-- keep-alive bağlantısını kapatmadan önce boşta ms -->
maxKeepAliveRequests="100"
maxHttpHeaderSize="8192" <!-- bayt -->
maxParameterCount="1000" <!-- istek parametresi; hash çakışması istismarını sınırlar -->
maxPostSize="2097152" <!-- 2 MB istek gövdesi -->
maxSwallowSize="2097152" />
maxParameterCount’u açıkça ayarlamakta yarar vardır. Sınırsız bir parametre sayısı, istek
ayrıştırmada işlemci yakmanın ucuz bir yoludur. Negatif değer sınırsız demektir ve bu, proxy
arkasında bile internet’e komşu bir sunucu için yanlış varsayılandır.
# Büyük/reddedilen istekler erişim kaydında 400 olarak görünür
awk '$4==400' logs/access.*.log | wc -l
6. Ön katman arkasında istemci IP’si
Ön katman varken RemoteIpValve yapılandırılmadıkça her erişim kaydı ve her RemoteAddrValve kuralı proxy’yi görür:
<!-- server.xml, <Host> içinde -->
<Valve className="org.apache.catalina.valves.RemoteIpValve"
remoteIpHeader="X-Forwarded-For"
protocolHeader="X-Forwarded-Proto"
internalProxies="10\.\d+\.\d+\.\d+|172\.1[6-9]\.\d+\.\d+" />
Bu valf olmadan kayıtlar her isteği ön katmana atfeder ve adrese dayalı her kural anlamsızlaşır. Bu, seri boyunca yinelenen proxy-IP çöküşüdür.
7. İsteğe bağlı: StuckThreadDetectionValve
Uygulamayı yavaş veya asılı isteklere iten bir saldırı altında takılı thread valfi, bir eşiği aşan thread’leri kaydeder ve görünmez bir thread sızıntısını alarma dönüştürür:
<Valve className="org.apache.catalina.valves.StuckThreadDetectionValve"
threshold="60" />
İzlemeye bağlanacak sinyaller
# 1. Meşgul thread'ler / maxThreads (JMX currentThreadsBusy) — havuz doygunluğu
# 2. connectionCount / maxConnections (JMX) — bağlantı tutma saldırısı
# 3. 400 oranı — büyük/bozuk istek seli
awk '$4==400' logs/access.*.log | wc -l
# 4. Yavaş istekler — %D sütunu tırmanıyor
awk '{print $NF}' logs/access.*.log | sort -rn | head -1
maxThreads’te currentThreadsBusy ile tırmanan bir connectionCount, istek hızının havuzu aştığının
işaretidir. Bu, ön katmanın veya bir üst katmanın Tomcat’in ememeyeceğini emmesi gereken noktadır.
Tomcat sıkılaştırmasının dürüst sınırı
Buradaki her şey, çoğunu ilk ön katmanın yakalaması gereken bir düzenin arkasında, uygulama katmanını bağlantı ve thread havuzu tükenmesine karşı savunur. İki durum bunun dışında kalır.
Birincisi hat doluluğudur. Hattı dolduran hacim ne ön katmana ne de Tomcat’e ulaşır.
İkincisi Tomcat’in ve ön katmanının altındaki her şeydir: işletim sistemi TCP yığını ve ön host’un kendi sıkılaştırması. Bunlar Linux veya Windows rehberlerinde ele alınır. Tomcat sıkılaştırması hem ön katmanın hem işletim sistemi katmanının yerinde olduğunu varsayar. Hat kapasitesinin üstünde cevap şebeke tarafındadır.
Uygulama sırası
- Connector’ın açık bir arayüze bağlı olmadığını doğrulayın; önüne sertleştirilmiş bir ön katman koyun.
- Temel ölçüleri kaydedin: meşgul thread’ler, bağlantı sayısı, istek süreleri.
- Connector protokolünü NIO değilse NIO’ya çekin.
- maxThreads’i yığına göre boyutlandırın, sonra çevresine maxConnections ve kısa bir acceptCount koyun.
- Kayıtların ve kuralların gerçek istemciyi görmesi için RemoteIpValve’i yapılandırın.
- connectionTimeout ve istek boyutu sınırlarını ayarlayın.
- Dört sinyali izlemeye bağlayın.
Sonucu en çok değiştiren birinci adımdır. Onu izleyen Connector ayarları ikinci hattır ve ikinci bir hat, ancak arkasında durduğu birinci hat kadar işe yarar.
Sık sorulan sorular
- Tomcat hiç doğrudan internete bakmalı mı?
- Nadiren, ve bunu açıkça söylemekte yarar var. Tomcat bir uygulama sunucusudur; standart üretim tasarımı bağlantıyı sertleştirilmiş bir ön katmanda sonlandırır. Bu katman nginx, Apache httpd veya bir yük dengeleyici olur; TLS'i, yavaş bağlantı tahliyesini, oran sınırlamayı ve statik içeriği o üstlenir ve temiz istekleri Tomcat'e özel bir ağ üzerinden iletir. Bu serideki DDoS savunmalarının çoğu aslında o ön katmanda yaşar. Tomcat'in 8080 Connector'ını doğrudan internete açmak, bütün bunları Connector içinde yeniden kurmak demektir ve Connector bu işi daha zayıf yapar. Buradaki Connector sıkılaştırması ön katmanın arkasına uygulanan ikinci hattır, onun yerine geçmez.
- Dayanıklılık için hangi Connector protokolü: NIO, NIO2 yoksa APR?
- NIO veya NIO2; eski bloklayan connector değil. Bloklayan BIO connector, bağlantı başına bir thread'i tüm istek boyunca harcardı ve bu Slowloris'i ona karşı ucuz kılardı; Tomcat 8.5 ile kaldırıldı. NIO ve NIO2 bloklamayan G/Ç ve bir poller kullanır, böylece yavaş bir bağlantı adanmış bir iş parçacığını değil bir soketi tutar. Bu, nginx'in sahip olduğu mimari avantajın aynısıdır. NIO varsayılandır ve neredeyse herkes için doğru seçimdir; NIO ile NIO2 arasındaki fark bu amaç için küçüktür. BIO'ya sabitlenmiş eski bir yapılandırmada değil, bunlardan birinde olduğunuzu doğrulayın.
- maxThreads, maxConnections ve acceptCount arasındaki ilişki nedir?
- Sırayla üç sınır. maxConnections, Tomcat'in aynı anda kabul edip tutacağı bağlantı sayısıdır; acceptCount, maxConnections dolduktan sonra kabul edilmeyi bekleyen bağlantıların işletim sistemi düzeyindeki backlog'udur; maxThreads ise aynı anda işlenebilen istek sayısıdır. Sel altında bağlantılar maxConnections'a kadar dolar, sonra acceptCount'ta kuyruğa girer, sonra işletim sistemi tarafından reddedilir. maxThreads bunun arkasındaki işleme tavanıdır. Üçünü birlikte boyutlandırmak önemlidir: küçük bir maxThreads arkasında büyük bir maxConnections, yalnızca birkaç thread'i bekleyen çok sayıda bağlantı demektir ve bu kendi başına yavaş bir çöküştür.
- Tomcat'te yavaş istek saldırısını özellikle nasıl durdururum?
- connectionTimeout ile, ve altındaki NIO connector ile. connectionTimeout, bir bağlantı açıldıktan sonra Tomcat'in istek satırını ve başlıkları ne kadar bekleyeceğini sınırlar; başlıkları damla damla gönderen bir Slowloris istemcisi zaman aşımında düşürülür. Değerini birkaç on saniye aralığında tutun. NIO üzerinde takılı bağlantı zaten ucuz olduğundan zaman aşımı yüksek oranda etkilidir; bu birleşim, olay döngüsü üzerindeki nginx'in client_header_timeout ayarının Tomcat karşılığıdır. Bir ön katman varsa bunu ilk o yakalamalı, Connector zaman aşımı ise emniyet ağıdır.
- Proxy arkasında istemci IP'si nereden gelir?
- RemoteIpValve'den; bu valf yapılandırılmazsa her IP başına karar ve her erişim kaydı proxy adresini yazar. RemoteIpValve, X-Forwarded-For ve X-Forwarded-Proto başlıklarını okur ve isteğin uzak adresini gerçek istemciye ayarlar; böylece erişim kayıtları, varsa RemoteAddrValve kuralları ve uygulamanın kendisi gerçek kaynağı görür. Bu valf olmadan bir ön katman her istemciyi tek bir adresin arkasına gizler. Bu, nginx'te yanlış yapılandırılmış real_ip ile aynı çöküş biçimidir.
- Bu ayarlar hacimsel bir saldırıyı durdurur mu?
- Hayır. Saldırı sunucuların önündeki hattı doldurursa ne ön katman ne de Tomcat istekleri alır ve hiçbir Connector değeri devreye girmez. Buradaki her şey uygulama katmanında bağlantı ve thread havuzu tükenmesine karşı savunur. Hat kapasitesinin üzerindeki hacim şebeke tarafının sorunudur ve server.xml içinde çözülmez.
Yayım: Ağustos 2026
Bu rehber, üreticiler yeni modeller ve fiyatlandırma açıkladıkça güncellenir. Üreticileri nasıl karşılaştırıyoruz