Перейти к содержанию

Техническая глубина

Укрепление 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, отвечающие на них
УстройствоФорма атакиМеханизм 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: requestLimits404.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.

Граница, за которой уровень на площадке уже не помогает Ваш канал доступа 10 Гбит/с Канал уже забит — только вышестоящий уровень Устройство на площадке подавляет 2 Гбит/с 8 Гбит/с 25 Гбит/с 120 Гбит/с 1 Тбит/с+ Объём атаки (логарифмическая шкала)
Ниже канала у лимитов IIS есть доля; выше — ни одна настройка ничего не значит.

Второй — слой под IIS: стек TCP Windows, WFP и очередь http.sys, через который запрос проходит до того, как его увидит рабочий, рассмотренный в руководстве по Windows Server. Укрепление IIS предполагает, что этот слой на месте. Выше канала ответ — сетевой уровень; IIS держит край приложения до тех пор.

Порядок применения

  1. Запишите исходные замеры (раздел 0): соединения, частота запросов, очередь http.sys.
  2. Установите IP and Domain Restrictions; добавьте частоту и одновременность DIPR в режиме только-логирование.
  3. Включите proxy mode, если впереди есть прокси, прежде чем доверять лимитам.
  4. Наблюдайте режим только-логирование неделю; затем включите принуждение.
  5. Добавьте лимиты Request Filtering.
  6. Ограничьте очередь пула, задайте rapid-fail protection и ограничение CPU.
  7. Выведите счётчики в мониторинг.

Шаг 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 г.

Руководство обновляется по мере выхода новых моделей и условий лицензирования. Как мы сравниваем производителей