The Linux TCP keepalive default is 7200 seconds -- 2 hours -- before an idle connection is probed. Most web servers inherit this or have their own multi-minute idle timeout defaults. An attacker exploiting this opens thousands of connections, sends one byte, and holds them open. Your connection table fills. Legitimate users cannot connect. The defense is two configuration lines; the fix takes 10 minutes. But it requires knowing the default is wrong.
| Component | Default idle timeout | Recommended value |
|---|---|---|
| Linux TCP keepalive idle | 7200s (2 hours) | 60s |
| Nginx keepalive_timeout | 75s | 15-30s |
| Nginx client_body_timeout | 60s | 10s |
| Nginx client_header_timeout | 60s | 10s |
| Apache KeepAliveTimeout | 5s (modern) / 15s (legacy) | 5s |
| HAProxy timeout connect | None (unlimited) | 5s |
| HAProxy timeout client | None (unlimited) | 30s |
| Node.js http server timeout | 0 (no timeout in some versions) | 30000ms |
Nginx Configuration
http {
# Close idle keep-alive connections after 15 seconds
keepalive_timeout 15;
# Abort slow clients (Slowloris protection)
client_body_timeout 10;
client_header_timeout 10;
# Maximum time to read client request body
send_timeout 10;
# Limit number of keepalive requests per connection
keepalive_requests 100;
# For upstream (origin) connections
proxy_connect_timeout 5;
proxy_send_timeout 30;
proxy_read_timeout 30;
}
Linux TCP Parameters
# /etc/sysctl.conf
# Reduce idle connection timeout from 2 hours to 60 seconds
net.ipv4.tcp_keepalive_time = 60
net.ipv4.tcp_keepalive_intvl = 10
net.ipv4.tcp_keepalive_probes = 6
# Maximum number of connection requests in backlog queue
net.core.somaxconn = 65535
# Reduce FIN_WAIT_2 time
net.ipv4.tcp_fin_timeout = 30
# Apply immediately:
# sudo sysctl -p
Why This Matters Even Behind a CDN
Connections between the CDN edge and your origin also use TCP keepalive. If your origin has a 2-hour idle timeout, CDN connection pool exhaustion can occur from slow requests that the CDN keeps alive to the origin. Additionally, any services not fronted by the CDN (internal APIs, monitoring endpoints, direct-IP exposed services) have full exposure to connection-exhaustion attacks that rely on default timeouts. DDactic measures idle timeout behavior as part of Stage 3 -- a response to an idle connection that persists for more than 30 seconds is reported as a configuration gap.
TLS Handshake Timeouts
TLS handshake timeouts are a separate setting from TCP keepalive. A client that initiates a TLS handshake but never completes it holds a connection in the handshake state. Nginx defaults to 60 seconds for TLS handshake completion. Set ssl_handshake_timeout 10; for internet-facing servers. This is a distinct control from keepalive timeouts -- both need to be explicitly set.
Check Your Timeout Configuration
DDactic measures actual idle connection behavior during Stage 3 scanning and reports default or excessive timeouts as configuration gaps.
Run a Free Scan