Техническая глубина
Укрепление IIS против DDoS: Dynamic IP Restrictions, Request Filtering и очередь пула
Обновлено: август 2026 г. · Dynamic IP Restrictions, Request Filtering и очередь пула приложений · Время чтения ~18 мин

IIS защищает над очередью ядра http.sys, на уровне приложения. Несущие механизмы — Dynamic IP Restrictions, Request Filtering и очередь пула приложений: лимит частоты и одновременности по источнику, ограничение размера запроса, ограниченная очередь и rapid-fail protection. Настраивается в web.config или appcmd, проверяется счётчиками Web Service, задаётся по вашим собственным исходным замерам.
Это руководство укрепляет сам IIS против исчерпывающей запросы и соединения части DDoS-атаки,
без устройства перед ним. IIS находится на слой выше http.sys — очереди запросов ядра,
рассмотренной в руководстве по Windows Server, — и защищает
на уровне приложения: лимиты по источнику, ограничения размера запроса и ограниченная очередь
рабочих, которая падает предсказуемо, а не бьётся.
Каждая настройка идёт и как фрагмент web.config, и как команда appcmd или PowerShell, со
счётчиком производительности, показывающим её работу.
| Устройство | Форма атаки | Механизм IIS | Проверка |
|---|---|---|---|
| Флуд запросов из немногих источников | Dynamic IP Restrictions: DenyByRequestRate | \Web Service\Total Requests; DIPR пишет 429 | |
| Много соединений с источника | Dynamic IP Restrictions: maxConnections | \Web Service\Current Connections | |
| Медленный заголовок (Slowloris) | http.sys headerWaitTimeout; connectionTimeout | счётчики HTTP Service Request Queues | |
| Злоупотребление большими запросами | Request Filtering: requestLimits | 404.13 / 404.14 / 404.15 в логе | |
| Исчерпание рабочих / цикл падений | App pool queueLength; rapid-fail protection | \W3SVC_W3WP\Requests / Sec; частота 503 |
IIS находится над http.sys — очередью ядра, рассмотренной в руководстве по Windows. Эти механизмы защищают приложение; ни один из них не помогает, когда атака заполняет канал перед сервером.
0. Сначала исходные замеры: читаем счётчики Web Service
Состояние IIS живёт в наборах счётчиков Web Service и W3SVC_W3WP. Запишите обычную неделю.
# Текущие соединения и частота запросов по всем сайтам
Get-Counter '\Web Service(_Total)\Current Connections',
'\Web Service(_Total)\Total Method Requests/sec' -SampleInterval 5 -MaxSamples 3
# Частота запросов на рабочего и очередь http.sys
Get-Counter '\W3SVC_W3WP(*)\Requests / Sec',
'\HTTP Service Request Queues(*)\CurrentQueueSize'
# Число запросов на клиента из лога IIS (индекс поля подстройте под ваш формат лога)
Import-Csv -Delimiter ' ' C:\inetpub\logs\LogFiles\W3SVC1\*.log -Header (1..20) |
Group-Object 'H10' | Sort-Object Count -Descending | Select-Object -First 10
Current Connections и частота запросов на клиента — это исходные замеры, относительно которых
выбирается каждый порог ниже.
1. Dynamic IP Restrictions: частота и одновременность по источнику
Dynamic IP Restrictions (DIPR) — защита IIS от флуда запросов, встроенный аналог nginx-директивы
limit_req. Ей нужна роль IP and Domain Restrictions, затем лимит частоты и одновременности.
<!-- web.config или applicationHost.config -->
<system.webServer>
<security>
<dynamicIpSecurity enableLoggingOnlyMode="true">
<!-- одновременность: макс. одновременных запросов с источника -->
<denyByConcurrentRequests enabled="true" maxConcurrentRequests="20" />
<!-- частота: макс. запросов с источника за окно времени (мс) -->
<denyByRequestRate enabled="true" maxRequests="100" requestIntervalInMilliseconds="2000" />
</dynamicIpSecurity>
</security>
</system.webServer>
# То же через appcmd
appcmd set config /section:system.webServer/security/dynamicIpSecurity `
/denyByRequestRate.enabled:true /denyByRequestRate.maxRequests:100 `
/denyByRequestRate.requestIntervalInMilliseconds:2000
# Отказ с 429, чтобы логи и клиенты читали верно (по умолчанию 403)
appcmd set config /section:system.webServer/security/dynamicIpSecurity `
/denyAction:"TooManyRequests"
Обратите внимание на enableLoggingOnlyMode="true" выше — это пробный прогон IIS. Он пишет в лог,
что заблокировал бы, ничего не блокируя, ровно как nginx-директива limit_req_dry_run. Оставьте
его включённым на показательную неделю, убедитесь, что источники, которые он отклонил бы, — не ваш
реальный трафик, затем поставьте false, чтобы правило действовало.
# Подтвердить, что заблокировал бы режим только-логирование
Get-Counter '\Web Service(_Total)\Total Requests'
# События DIPR появляются в логе IIS с настроенным вами статусом отказа
2. Proxy Mode: IP клиента за ARR или балансировщиком
DIPR привязывается к адресу соединения. За прокси это адрес прокси, если не включить proxy mode
для чтения X-Forwarded-For.
<dynamicIpSecurity>
<denyByRequestRate enabled="true" maxRequests="100" requestIntervalInMilliseconds="2000" />
<!-- оценивать переданный адрес клиента, а не соединение прокси -->
<proxyMode enabled="true" />
</dynamicIpSecurity>
Без proxy mode каждый запрос делит одно ведро прокси, и лимит ничего не защищает — тот же режим
отказа, что и неверно настроенный real_ip в nginx.
3. Request Filtering: поверхность негабаритных запросов
Request Filtering ограничивает размеры запроса на уровне ниже приложения, отклоняя негабаритный запрос до того, как рабочий его разберёт.
<system.webServer>
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="10485760" <!-- 10 MB -->
maxUrl="4096"
maxQueryString="2048">
<headerLimits>
<add header="Content-type" sizeLimit="100" />
</headerLimits>
</requestLimits>
</requestFiltering>
</security>
</system.webServer>
appcmd set config /section:requestFiltering `
/requestLimits.maxAllowedContentLength:10485760 /requestLimits.maxUrl:4096
Отказы появляются в логе как подкоды: 404.13 (длина содержимого), 404.14 (URL), 404.15
(строка запроса). Наблюдайте их относительно исходных замеров.
Select-String -Path C:\inetpub\logs\LogFiles\W3SVC1\*.log -Pattern ' 404 1[345] ' | Measure-Object
4. Очередь пула приложений и rapid-fail protection
У пула приложений своя очередь запросов и своя обработка падений. Ограничьте очередь, чтобы флуд падал предсказуемо, и настройте rapid-fail, чтобы падающее приложение не входило в цикл перезапусков.
# Длина очереди: сколько запросов может ждать рабочего до 503
Set-ItemProperty "IIS:\AppPools\DefaultAppPool" -Name queueLength -Value 4000
# Rapid-fail: вывести пул из сети после N отказов за интервал, не биться
Set-ItemProperty "IIS:\AppPools\DefaultAppPool" -Name failure.rapidFailProtection -Value $true
Set-ItemProperty "IIS:\AppPools\DefaultAppPool" -Name failure.rapidFailProtectionMaxCrashes -Value 5
Set-ItemProperty "IIS:\AppPools\DefaultAppPool" -Name failure.rapidFailProtectionInterval -Value "00:05:00"
# Перерабатывать по расписанию, а не по фикс. числу запросов, чтобы избежать переработки в атаке
Set-ItemProperty "IIS:\AppPools\DefaultAppPool" -Name recycling.periodicRestart.requests -Value 0
# Ограничение CPU: ограничить пул, а не дать одному сайту заморить машину
Set-ItemProperty "IIS:\AppPools\DefaultAppPool" -Name cpu.limit -Value 80000 # 80%
Set-ItemProperty "IIS:\AppPools\DefaultAppPool" -Name cpu.action -Value Throttle
# 503 из-за полной очереди или выведенного пула
Get-Counter '\W3SVC_W3WP(*)\Total HTTP Requests Served'
Select-String -Path C:\inetpub\logs\LogFiles\W3SVC1\*.log -Pattern ' 503 ' | Measure-Object
Растущая частота 503 при простаивающих рабочих означает, что очередь или http.sys отклоняет выше рабочего — признак того, что частота запросов переросла то, что пулу позволено поглотить.
5. Таймауты соединения
Таймаут соединения и таймаут ожидания заголовка http.sys выселяют медленные соединения. Таймаут ожидания заголовка — обращённая к IIS защита от Slowloris, и он задаётся на уровне http.sys.
# Таймаут соединения сайта (простой)
Set-WebConfigurationProperty -Filter system.applicationHost/sites/siteDefaults/limits `
-Name connectionTimeout -Value "00:01:00"
# Таймаут ожидания заголовка http.sys — реестр, параметры службы HTTP
# (на уровне ОС рассмотрено в руководстве по Windows; это ключ, значимый для IIS)
Сигналы для вывода в мониторинг
Get-Counter @(
'\Web Service(_Total)\Current Connections',
'\Web Service(_Total)\Total Method Requests/sec',
'\HTTP Service Request Queues(_Total)\CurrentQueueSize',
'\HTTP Service Request Queues(_Total)\RejectedRequests',
'\W3SVC_W3WP(_Total)\Requests / Sec'
) -SampleInterval 5 -MaxSamples 1
Растущие Current Connections при плоской частоте запросов — атака удержания соединений. Растущие RejectedRequests — http.sys сбрасывает нагрузку до IIS. Частота 503 при простаивающих рабочих — очередь пула заполнена. Каждый указывает на свой лимит.
Честный предел укрепления IIS
Всё здесь защищает край приложения от исчерпания частоты запросов и соединений. Два случая лежат вне этого.
Первый — насыщение канала: объём, заполняющий трубу, не доходит даже до http.sys, не говоря об IIS.
Второй — слой под IIS: стек TCP Windows, WFP и очередь http.sys, через который запрос проходит до того, как его увидит рабочий, рассмотренный в руководстве по Windows Server. Укрепление IIS предполагает, что этот слой на месте. Выше канала ответ — сетевой уровень; IIS держит край приложения до тех пор.
Порядок применения
- Запишите исходные замеры (раздел 0): соединения, частота запросов, очередь http.sys.
- Установите IP and Domain Restrictions; добавьте частоту и одновременность DIPR в режиме только-логирование.
- Включите proxy mode, если впереди есть прокси, прежде чем доверять лимитам.
- Наблюдайте режим только-логирование неделю; затем включите принуждение.
- Добавьте лимиты Request Filtering.
- Ограничьте очередь пула, задайте rapid-fail protection и ограничение CPU.
- Выведите счётчики в мониторинг.
Шаг 3 идёт перед принуждением по той же причине, что и в nginx: лимит по источнику, привязанный к адресу прокси, ничего не защищает, выглядя защитой.
Частые вопросы
- Ограничение частоты делает Dynamic IP Restrictions или правило брандмауэра?
- Dynamic IP Restrictions — для всего, что понимает HTTP. Правило брандмауэра Windows блокирует адрес целиком; DIPR считает запросы и одновременные соединения с источника за окно и возвращает настраиваемый статус, когда источник переходит порог. Именно это нужно против флуда запросов, который выглядит как обычный HTTP. Это встроенный аналог nginx-директивы limit_req в IIS. Установите роль IP and Domain Restrictions, затем задайте DenyByRequestRate и DenyByConcurrentRequests и выберите статус отказа 429, чтобы клиенты и логи читали его верно.
- Что именно останавливает Request Filtering?
- Поверхность негабаритных запросов, дёшево и рано. requestLimits ограничивает длину содержимого, длину URL, длину строки запроса и размер отдельного заголовка, поэтому запрос, построенный для исчерпания памяти или парсера, отклоняется фильтрацией на уровне http.sys до того, как рабочий его обработает. Он не остановит флуд запросов обычного размера — это дело Dynamic IP Restrictions, — но закрывает класс атаки с одним огромным запросом, и его работа не стоит ничего.
- Как очередь пула приложений связана с очередью http.sys?
- Это две очереди подряд. Сначала драйвер ядра http.sys принимает соединения и ставит запросы в очередь; у пула приложений затем своя queueLength для запросов, ждущих рабочего. Под флудом http.sys заполняется первым и начинает отклонять с 503 ещё до того, как задействованы рабочие процессы IIS, — вот почему сайт может отдавать 503, пока рабочий выглядит простаивающим. Руководство по Windows покрывает сторону http.sys; здесь вы ограничиваете очередь пула и настраиваете rapid-fail protection, чтобы падающий рабочий не вошёл в цикл перезапусков под нагрузкой.
- Что такое rapid-fail protection и почему это важно при атаке?
- Она не даёт IIS бесконечно перезапускать рабочий процесс, когда приложение падает. Под DDoS, загоняющим приложение в повторные падения, рабочий, перезапускающийся каждые несколько секунд, тратит процессор на запуск и не обслуживает трафик вовсе. Rapid-fail protection выводит пул из сети после заданного числа отказов за интервал и возвращает 503 — это более чистый отказ, чем цикл перезапусков, потому что он падает предсказуемо, а не бьётся. Настройте число отказов и интервал так, чтобы настоящий кратковременный сбой не срабатывал, а атака срабатывала.
- Откуда берётся IP клиента за ARR или балансировщиком?
- Из заголовка X-Forwarded-For, и Dynamic IP Restrictions нужно указать читать его, иначе каждый запрос приписывается прокси. IIS предлагает это как опцию Proxy Mode в Dynamic IP Restrictions, которая заставляет оценивать переданный адрес клиента вместо адреса соединения. Без неё один адрес прокси делит одно ведро частоты, и лимит бессмыслен — тот же режим отказа, что и nginx, привязанный к неверному адресу.
- Останавливают ли эти настройки объёмную атаку?
- Нет. Если атака заполняет канал перед сервером, ни http.sys, ни IIS не получают запросов, и ни одна настройка не применяется. Всё здесь защищает от исчерпания частоты запросов и соединений на краю приложения. Объём выше ёмкости канала — задача сетевого уровня и не решается в web.config.
Опубликовано: август 2026 г.
Руководство обновляется по мере выхода новых моделей и условий лицензирования. Как мы сравниваем производителей