Technical deep dive
Windows Server DDoS Hardening: What Still Needs Tuning and What the OS Already Handles
Last updated: August 2026 · Autotuning templates, WFP, http.sys and RSS · Reading time ~20 min

Most Windows DDoS registry advice is obsolete: keys like SynAttackProtect and TcpMaxHalfOpen were removed after Server 2003 because the stack now handles SYN attacks automatically. What you actually tune is different: the TCP autotuning template, Windows Filtering Platform rate limits, the http.sys request queue and adapter RSS. Verified with PowerShell and netsh, not with a registry editor.
This guide is about hardening the Windows Server host itself against the state- and request-exhausting part of a DDoS attack, with no device in front of it. It is deliberately shorter on registry edits than most Windows guides, for one reason: most of those edits are obsolete, and following them ranges from useless to harmful.
The single most valuable thing to know about Windows DDoS hardening is what not to do. The
registry keys that fill older guides — SynAttackProtect, TcpMaxHalfOpen,
TcpMaxHalfOpenRetried, a hardcoded TcpWindowSize — were either removed after Windows Server
2003 or are overridden by autotuning. Setting them does nothing at best; hardcoding a window size
actively defeats the stack’s per-connection tuning.
| Appliance | Old advice (do not follow) | Why it is obsolete | What to do instead |
|---|---|---|---|
| SynAttackProtect | Set registry SynAttackProtect=2 | Removed after Server 2003; SYN protection is automatic | Verify with netstat; rate-limit at WFP if needed |
| TcpMaxHalfOpen | Cap half-open connections in registry | No longer read by the stack | Get-NetTCPConnection -State SynReceived to observe |
| TCP receive window | Hardcode TcpWindowSize | Autotuning sizes it per connection since Vista/2008 | Set-NetTCPSetting template, do not hardcode |
| Connection limits | Rely on the OS default | Default is generous; nothing enforces per-source | WFP filter or firewall rule, per source address |
The whole left column is the internet's accumulated Windows-2003 folklore. The modern stack made most of it automatic; setting the removed keys does nothing, and a few hardcoded values make things worse by overriding autotuning.
0. Baseline first: read the counters before you change anything
Windows exposes its state through performance counters and the Get-Net* cmdlets rather than
/proc. Record a normal week from these:
# Connection count by TCP state (the SynReceived row is your half-open backlog)
Get-NetTCPConnection | Group-Object -Property State | Sort-Object Count -Descending
# TCP-stack counters: segments, resets, failed connections
Get-Counter '\TCPv4\*' -SampleInterval 5 -MaxSamples 3
# Active connection template and its autotuning level
Get-NetTCPSetting -SettingName Internet | Format-List *
# Adapter RSS state and queue count
Get-NetAdapterRss | Format-Table Name, Enabled, NumberOfReceiveQueues
Save this output. Every judgement below is relative to it — “the SynReceived count is high” only means something against a normal-week number.
1. The TCP stack: templates, not registry keys
Modern Windows Server does not expose the old scalar TCP registry values as the tuning surface.
Instead it applies a template per connection type, and you adjust the template. The templates
are Internet, Datacenter, Datacenter Custom, Internet Custom, and Compat.
# See every setting the active template applies
Get-NetTCPSetting -SettingName Internet
# Autotuning receive window — leave at 'normal' unless you have a measured reason
Set-NetTCPSetting -SettingName InternetCustom -AutoTuningLevelLocal Normal
# Confirm autotuning is not disabled by an old hardening script (a common finding)
Get-NetTCPSetting | Format-Table SettingName, AutoTuningLevelLocal
netsh int tcp show global
The most common real problem on an audited Windows server is not a missing tweak; it is an
old hardening script that disabled autotuning with netsh int tcp set global autotuninglevel=disabled.
That one line caps the receive window at a small fixed value and throttles every legitimate
connection. Re-enabling it is usually the single biggest improvement:
netsh int tcp set global autotuninglevel=normal
SYN-flood protection itself is automatic and cannot be meaningfully improved from the registry on a supported OS. You verify it is coping rather than configure it:
# Half-open connections right now
(Get-NetTCPConnection -State SynReceived).Count
# Failed connection attempts and resets, from the stack counters
Get-Counter '\TCPv4\Connection Failures','\TCPv4\Connections Reset'
If the SynReceived count climbs toward the tens of thousands during an event, the answer is not a registry key — it is a per-source limit at the WFP layer or an upstream layer, covered below.
2. Windows Filtering Platform: where per-source limiting lives
Linux does per-source rate limiting with an nftables dynamic set. The Windows equivalent lives in the Windows Filtering Platform, and for most operators the accessible face of it is a firewall rule. There is no built-in “N connections per second per source” primitive as clean as nftables’, so the practical pattern is a scoped block driven by monitoring, plus connection-security rules that shrink the exposed surface.
# Block a specific abusive source (what an automated responder would call)
New-NetFirewallRule -DisplayName "DDoS-block-203.0.113.0/24" -Direction Inbound `
-RemoteAddress 203.0.113.0/24 -Action Block
# Restrict a service to the addresses that should ever reach it — the largest
# single reduction in attack surface, and it needs no rate logic at all
New-NetFirewallRule -DisplayName "RDP-restrict" -Direction Inbound -Protocol TCP `
-LocalPort 3389 -RemoteAddress 10.0.0.0/8 -Action Allow
# Inspect what is actually enabled
Get-NetFirewallRule -Enabled True -Direction Inbound |
Where-Object Action -eq Allow | Format-Table DisplayName, Profile
The honest limitation: Windows Firewall alone does not rate-limit new connections per source the way the nftables set does. Where that is required, it comes from a WFP callout driver, a third-party layer, or — the usual real answer at any scale — the network tier in front of the host. The firewall’s strongest contribution to DDoS resilience is not rate limiting; it is surface reduction, making sure every listening port is reachable only from where it should be.
For services that must face the internet, connection-security (IPsec) rules can require authentication before a connection consumes application resources, which turns an anonymous flood into an authentication failure at a cheaper layer:
Get-NetIPsecRule | Format-Table DisplayName, Enabled, Profile
3. http.sys: the kernel request queue in front of IIS
For any HTTP workload, the first queue a request flood hits is not IIS — it is http.sys, the
kernel-mode driver that accepts and queues HTTP requests before a worker process sees them. Its
parameters live under the HTTP service, and its queue is a distinct resource from anything IIS
configures.
# The kernel request queues and their depth
Get-Counter '\HTTP Service Request Queues(*)\CurrentQueueSize'
Get-Counter '\HTTP Service Request Queues(*)\RejectedRequests'
The key behaviours to understand — and mostly to leave at default unless a counter proves otherwise — are the request-queue length, connection timeout and header-wait timeout. The header-wait timeout is the http.sys-level defence against slow-header attacks (opening a connection and sending headers one byte at a time): the driver drops a connection that has not completed its headers within the timeout, before IIS ever allocates a worker to it.
The IIS-side settings — application-pool queue length, dynamic IP restrictions, request filtering — are a separate layer and get their own IIS hardening guide. The point here is that http.sys is the queue below IIS: a site can stay up while the worker is saturated because http.sys is absorbing, or fail while the worker looks idle because http.sys is rejecting.
4. Receive Side Scaling: the packet-rate defence
Before the circuit fills, a high packet rate can pin one CPU core at 100% handling interrupts while the others idle. On Windows the fix is Receive Side Scaling, which spreads inbound packet processing across cores. On physical NICs it is usually on; on virtualised NICs it is frequently off or under-queued by default, and that default is where a Windows VM quietly loses to a packet-rate attack well below its nominal bandwidth.
# Is RSS on, and how many queues?
Get-NetAdapterRss -Name * | Format-Table Name, Enabled, NumberOfReceiveQueues, MaxProcessors
# Enable and give it enough queues (match to available cores)
Enable-NetAdapterRss -Name "Ethernet"
Set-NetAdapterRss -Name "Ethernet" -NumberOfReceiveQueues 8
# Watch per-processor interrupt load during a test — one hot core means RSS is not spreading
Get-Counter '\Processor(*)\% Interrupt Time' -SampleInterval 2 -MaxSamples 5
# Receive Segment Coalescing can help throughput but hurt latency-sensitive workloads; measure
Get-NetAdapterRsc | Format-Table Name, IPv4Enabled, IPv6Enabled
A single hot core under load, with the rest idle, is the signature that RSS is not doing its job —
the exact Windows counterpart of a climbing third column in Linux’s softnet_stat.
5. Application-layer connection behaviour
Two host-level items support whatever web server sits on top. TCP keep-alive detects and reclaims dead connections, and the dynamic port range governs how many outbound/ephemeral connections the host can sustain:
# Ephemeral port range — widen if the host makes many outbound connections
netsh int ipv4 show dynamicport tcp
netsh int ipv4 set dynamicport tcp start=1024 num=64511
# TCP keep-alive is a per-connection stack setting; the template carries it
Get-NetTCPSetting -SettingName Internet | Select-Object SettingName, *KeepAlive*
Slow-connection attacks are ultimately answered by the web server’s own timeouts, not the OS. Those live in the IIS guide for IIS, and in the nginx or Apache guides if you run those on Windows.
The counters to wire into monitoring
Windows hardening, like Linux, is read from counters rather than felt. Wire these into the monitoring system:
# One-shot health read a responder can call
Get-Counter @(
'\TCPv4\Connection Failures',
'\TCPv4\Connections Reset',
'\HTTP Service Request Queues(_Total)\CurrentQueueSize',
'\HTTP Service Request Queues(_Total)\RejectedRequests',
'\Processor(_Total)\% Interrupt Time'
) -SampleInterval 5 -MaxSamples 1
# Half-open backlog as a single number
(Get-NetTCPConnection -State SynReceived).Count
These answer, during an attack, the same question the Linux counters do: is the host narrowing, or is the circuit filling.
The honest limit of this layer
Everything above reduces to one sentence: a Windows Server is defensible against attacks that exhaust its own connection tables, request queues and per-core processing. Two cases sit outside it and neither is solved on the host.
The first is circuit saturation. Volume above the access circuit never reaches the Windows stack, and no template, firewall rule or RSS queue changes that.
The second is packet rate beyond what even well-spread cores can process, which is the ceiling RSS raises but does not remove. Above these two thresholds the subject is the network architecture, not the server. Host hardening keeps the server standing until an upper layer engages — but it is not that layer, and treating it as one produces false confidence.
Order of application
- Record the baseline (Section 0): connections by state, TCP counters, template, RSS state.
- Confirm autotuning is not disabled by an old script; re-enable if it is. This is the most common single win.
- Reduce firewall surface: every listening port reachable only from where it should be.
- Verify RSS is on with enough queues, especially on virtualised NICs.
- Leave http.sys and the TCP template at default unless a counter proves a specific bottleneck.
- Wire the counters into monitoring as alarms.
Note what is missing from this list: a long registry section. On a supported Windows Server, that section is the sign of a guide written twenty years ago.
Frequently asked questions
- Is Windows Server harder or easier to harden than Linux for DDoS?
- Different, not harder. Linux exposes dozens of individually tunable sysctl knobs; Windows made most of the equivalent decisions automatic and hides them behind templates. That means fewer things to set and fewer things to break, but also less granular control. The work shifts from tuning kernel parameters to configuring the Windows Filtering Platform and http.sys, and to confirming that autotuning is actually on rather than disabled by an old hardening script.
- Which registry keys should I actually set?
- Almost none, and that is the point. The SYN-attack and half-open keys that fill older guides were removed and are ignored by modern Windows Server. The exceptions worth setting are under the HTTP service parameters for http.sys queue behaviour, and even those are better left at default unless a measurement shows a specific queue is the bottleneck. Treat any guide that opens with a long registry list as written for Server 2003.
- What is the Windows Filtering Platform's role here?
- WFP is where per-source rate limiting actually lives on Windows. Windows Firewall rules sit on top of it, but for DDoS the useful layer is a filter that limits new connections per source address, which you express as a firewall rule with New-NetFirewallRule or, for finer control, a WFP filter. It is the closest equivalent to the nftables dynamic set on Linux, and like that rule it defends against a flood from few sources, not a spread-out one.
- How does http.sys matter for a DDoS?
- http.sys is the kernel-mode driver that queues HTTP requests before IIS ever sees them, so its queue is the first thing a request flood fills. The application-pool queue length, the connection and header timeouts, and the request-queue limit are set at this layer, which is why an IIS site can stay responsive while the worker process is saturated, or fail while the worker looks idle. The IIS-specific settings get their own guide; here the point is that http.sys is a separate queue from anything IIS configures.
- Does adapter RSS have anything to do with DDoS?
- Yes, at high packet rates. Receive Side Scaling spreads inbound packet processing across CPU cores; with RSS off or misconfigured, a packet flood pins a single core at 100% while the others sit idle, and the server stops responding well below its nominal capacity. Confirming RSS is on and has enough queues is the Windows equivalent of the Linux receive-path tuning, and it is the item most often left at a wrong default on virtualised NICs.
- Do these settings stop a volumetric attack?
- No. Traffic that fills the access circuit never reaches the Windows stack, and nothing you configure on the host changes that. Every setting here defends against state and request exhaustion — connection tables, the http.sys queue, per-core packet processing. Volume above the circuit is a network-side problem and is not solved on the server.
- How do I verify any of this without an attack?
- With PowerShell counters and a load generator in a lab. Get-NetTCPConnection groups connections by state, Get-Counter reads the TCPv4 and HTTP Service Request Queue counters, and a tool that opens connections at a rising rate shows which counter moves first. That first-moving counter is your real threshold. In production, the same counters leaving their baseline are what you wire into the monitoring system.
Published: August 2026
This guide is updated as vendors release new models and pricing. How we compare vendors