Техническая глубина
Укрепление JBoss / WildFly от DDoS: лимиты слушателя Undertow и IO-потоки
Обновлено: август 2026 г. · Лимиты слушателя Undertow, IO-потоки и фронтальный слой · Время чтения ~16 мин

В JBoss EAP и WildFly поверхность DDoS — это Undertow, а не коннектор Tomcat. Несущие атрибуты — max-connections, тайм-ауты запроса и разделение IO/рабочих потоков, все они задаются через management CLI. Undertow неблокирующий, поэтому медленное соединение стоит буфера, а не рабочего потока. Но, как и Tomcat, сервер приложений ставится за укреплённым фронтальным слоем, а не в открытый интернет.
Это руководство укрепляет сам JBoss EAP и WildFly от той части DDoS-атаки, что исчерпывает соединения и потоки. Сначала важное различие: в современном EAP или WildFly веб-сервер — это Undertow, а не старый коннектор JBossWeb, и всё настраивается в подсистеме Undertow через management CLI. Если вы всё ещё на JBoss AS 5/6 с JBossWeb, руководство по Tomcat ближе к вашей конфигурации, а более крупная мысль такова: сервер, снятый с поддержки, сам по себе — уязвимость.
Как и Tomcat, JBoss — это сервер приложений, и он ставится за укреплённым фронтальным слоем. Лимиты
Undertow ниже — это вторая линия за этим слоем. Каждый атрибут приводится с командой
jboss-cli.sh и счётчиком, который показывает его работу.
| Устройство | Форма атаки | Атрибут Undertow | Путь CLI |
|---|---|---|---|
| Медленный заголовок / медленное тело | no-request-timeout, request-parse-timeout | /subsystem=undertow/server=*/http-listener=* | |
| Флуд соединений | max-connections; tcp-backlog | http-listener + socket-binding | |
| Исчерпание потоков / IO | io-threads, task-max-threads (worker) | /subsystem=io/worker=default | |
| Злоупотребление большими запросами | max-header-size, max-parameters, max-post-size | /subsystem=undertow/server=*/http-listener=* | |
| Прямая доступность из интернета | Привязать слушатель к внутреннему интерфейсу; терминирует фронт | интерфейс socket-binding |
Как и Tomcat, JBoss — это сервер приложений: стандартная схема ставит перед ним укреплённый фронтальный слой, а эти лимиты Undertow — вторая линия за ним. Ничто из этого не помогает, когда атака заполняет канал.
0. Сначала базовые показатели: читаем метрики слушателя и рабочего пула
Undertow и подсистема IO дают метрики времени выполнения через CLI. Включите статистику и читайте её в течение обычной недели:
# Включить статистику Undertow
/subsystem=undertow:write-attribute(name=statistics-enabled,value=true)
# Активные соединения и обработка на HTTP-слушателе
/subsystem=undertow/server=default-server/http-listener=default:read-resource(include-runtime=true)
# Рабочий пул: занятые потоки против core/max
/subsystem=io/worker=default:read-resource(include-runtime=true)
Число активных соединений слушателя и число занятых потоков рабочего пула — базовые показатели, относительно которых задаётся каждое значение ниже.
1. Сначала фронтальный слой
Убедитесь, что Undertow не выставлен напрямую на публичный интерфейс:
# http socket-binding должен быть на внутреннем интерфейсе, а не на публичном
/socket-binding-group=standard-sockets/socket-binding=http:read-resource(include-runtime=true)
ss -ltnp | grep 8080
Если он публичный, привяжите его внутренне и дайте укреплённому фронтальному слою терминировать интернет-соединение. Этот слой разбирают руководства по nginx и Apache. Фронтальный слой несёт TLS, ограничение частоты и вытеснение медленных соединений лучше, чем это положено серверу приложений.
2. Лимиты соединений и тайм-ауты слушателя
http-listener несёт потолок соединений и два тайм-аута, отвечающих на атаки на медленный запрос. Задайте их через CLI:
# Ограничить одновременные соединения на слушателе
/subsystem=undertow/server=default-server/http-listener=default:write-attribute(name=max-connections,value=8192)
# Slowloris: время на разбор заголовков запроса
/subsystem=undertow/server=default-server/http-listener=default:write-attribute(name=request-parse-timeout,value=30000)
# Простаивающее соединение без отправленного запроса
/subsystem=undertow/server=default-server/http-listener=default:write-attribute(name=no-request-timeout,value=30000)
# Применить через reload, а не перезапуск
reload
Ни один из тайм-аутов не задан по умолчанию, поэтому на любом открытом слушателе оба настраиваются явно. request-parse-timeout ловит клиента, капающего заголовки; no-request-timeout ловит того, кто открыл соединение и ничего не шлёт.
3. Разделение IO / рабочих потоков
Undertow отделяет неблокирующие IO-потоки от блокирующего рабочего пула. Размеряйте их независимо и не путайте:
# IO-потоки крутят цикл событий; размеряйте по числу ядер (частое правило: ядра или ядра*2)
/subsystem=io/worker=default:write-attribute(name=io-threads,value=8)
# Рабочий пул обрабатывает блокирующую работу (сервлеты); размеряйте по тому, что выдержат куча/приложение
/subsystem=io/worker=default:write-attribute(name=task-max-threads,value=128)
reload
Раздувание io-threads ничего не даёт при узком месте в блокирующей работе, а раздувание task-max-threads сверх того, что выдержит куча, меняет одно исчерпание на нехватку памяти. Медленное соединение обслуживается IO-потоками как буфер, поэтому Undertow сопротивляется Slowloris по своей природе. Тайм-ауты выше превращают эту почти-неуязвимость в вытеснение.
4. Ограничения размера запроса
Закройте поверхность больших запросов на слушателе:
/subsystem=undertow/server=default-server/http-listener=default:write-attribute(name=max-header-size,value=8192)
/subsystem=undertow/server=default-server/http-listener=default:write-attribute(name=max-parameters,value=1000)
/subsystem=undertow/server=default-server/http-listener=default:write-attribute(name=max-headers,value=100)
/subsystem=undertow/server=default-server/http-listener=default:write-attribute(name=max-cookies,value=50)
/subsystem=undertow/server=default-server/http-listener=default:write-attribute(name=max-post-size,value=10485760)
reload
max-parameters и max-headers важны не только для памяти: неограниченное число — дешёвый способ сжечь процессор на разборе и, исторически, вызвать атаку на коллизии хешей. Значения по умолчанию щедрые; их ужесточение на открытом слушателе не стоит ничего законного.
5. TCP backlog
backlog у socket-binding — это очередь соединений уровня ОС, ждущих приёма, аналог acceptCount в Tomcat:
/socket-binding-group=standard-sockets/socket-binding=http:write-attribute(name=backlog,value=200)
reload
Держите backlog коротким, а не большим. Большой backlog лишь откладывает отказ, защищающий рабочий пул.
6. IP клиента за фронтальным слоем
При наличии фронтального слоя нужно включить proxy-address-forwarding, иначе каждая запись лога и каждое правило по адресу пишут фронтальный слой, а не клиента:
# Включить обработку forwarded-for на слушателе
/subsystem=undertow/server=default-server/http-listener=default:write-attribute(name=proxy-address-forwarding,value=true)
reload
Без этого каждый запрос приписывается фронтальному слою — повторяющийся сбой с proxy-IP по всей серии.
Счётчики для мониторинга
# 1. Активные соединения на слушателе (read-resource include-runtime) против max-connections
# 2. Занятые рабочие потоки против task-max-threads (/subsystem=io/worker=default)
# 3. Счётчики request-parse-timeout и no-request-timeout (статистика времени выполнения слушателя)
# 4. Счётчики ошибок/обработки из статистики слушателя
/subsystem=undertow/server=default-server/http-listener=default:read-resource(include-runtime=true,recursive=true)
Активные соединения на уровне max-connections при занятом рабочем пуле — признак того, что частота запросов переросла то, что способен поглотить Undertow. Это точка, где излишек должен принять фронтальный слой или вышестоящий уровень.
Честный предел укрепления JBoss
Всё здесь защищает прикладной уровень за фронтальным слоем, который должен ловить большую часть первым. Два случая лежат вне этого.
Первый — насыщение канала: объём, заполняющий трубу, не доходит ни до фронтального слоя, ни до Undertow.
Второй — уровень ОС под серверами, разобранный в руководствах по Linux и Windows. Укрепление JBoss предполагает, что и фронтальный слой, и уровень ОС уже на месте. Выше канала ответ — на сетевом уровне.
Порядок применения
- Убедитесь, что слушатель привязан внутренне; поставьте перед ним укреплённый слой.
- Включите статистику Undertow; запишите базовые показатели.
- Задайте max-connections и оба тайм-аута запроса через CLI.
- Размерьте io-threads по ядрам, а task-max-threads — по куче.
- Включите proxy-address-forwarding, чтобы логи и правила видели реального клиента.
- Задайте ограничения размера запроса и короткий backlog.
- Подключите метрики времени выполнения к мониторингу.
Больше всего исход меняет опять же первый шаг. Лимиты Undertow — вторая линия, а вторая линия полезна лишь настолько, насколько хороша первая, за которой она стоит.
Частые вопросы
- Старый коннектор JBoss AS — это то же самое, что Undertow в WildFly?
- Нет, и это различие определяет, какие настройки применимы. Старый JBoss AS (5/6) использовал JBossWeb — производную Tomcat с коннектором; JBoss EAP 7+ и WildFly заменили его на Undertow, неблокирующий веб-сервер на основе XNIO. Если вы на современном EAP или WildFly, всё настраивается в подсистеме Undertow через management CLI, а не на коннекторе в стиле Tomcat. Если вы всё ещё на JBossWeb, руководство по Tomcat ближе к вашей реальности, а более ценный шаг — уйти с сервера, снятого с поддержки.
- Чем модель потоков Undertow отличается от Tomcat применительно к DDoS?
- Undertow отделяет IO-потоки от рабочих. Небольшой пул IO-потоков крутит неблокирующий цикл событий и никогда не блокируется; рабочий пул обрабатывает блокирующие запросы, такие как вызовы сервлетов. Медленное соединение обслуживается IO-потоками как буфер, а не занимает рабочий поток, поэтому Undertow сопротивляется атакам на медленное соединение по своей природе. Практическая настройка — задать io-threads по числу ядер, а task-max-threads (рабочий пул) — по тому, что выдержат приложение и куча, и не путать одно с другим: раздувание IO-потоков ничего не даёт при узком месте в блокирующей работе, и наоборот.
- Какой тайм-аут останавливает атаку на медленный запрос в Undertow?
- Два работают вместе. request-parse-timeout ограничивает время, которое Undertow тратит на разбор заголовков запроса, а no-request-timeout ограничивает, сколько простаивающее соединение остаётся открытым без отправки запроса. Клиент Slowloris, посылающий заголовки по капле, ловится request-parse-timeout; тот, кто открыл соединение и ничего не шлёт, ловится no-request-timeout. Ни один не задан по умолчанию, поэтому на открытом слушателе оба настраиваются явно, в диапазоне десятков секунд.
- Задавать это в standalone.xml или через CLI?
- Через CLI, и пусть он пишет конфигурацию. Править standalone.xml вручную можно, но это подвержено ошибкам и теряется, если сервером управляет контроллер домена или оператор, как в OpenShift. Команды jboss-cli.sh в этом руководстве идемпотентны, проверяют имена атрибутов и применяются к работающему серверу через reload, а не перезапуск. Ручная правка XML — это аналог записи Windows-параметра в реестр там, где есть поддерживаемый cmdlet.
- Нужен ли JBoss фронтальный слой, если Undertow укреплён?
- Да, по тем же причинам, что и Tomcat. Undertow способен и смотрит в интернет безопаснее блокирующего коннектора, но стандартная промышленная схема всё равно терминирует TLS, ограничивает частоту и вытесняет медленные соединения на выделенном фронтальном слое, а чистые запросы передаёт Undertow по частной сети. Лимиты Undertow здесь — вторая линия за этим слоем. Они ценны потому, что фронтальный слой можно обойти во внутренней сети или он может пропустить атаку, которую не распознал. Но замены ему они не составляют.
- Останавливают ли эти настройки объёмную атаку?
- Нет. Если атака заполняет канал перед серверами, запросы не доходят ни до фронтального слоя, ни до Undertow, и ни один атрибут не применяется. Всё здесь защищает от исчерпания соединений и потоков на прикладном уровне. Объём выше пропускной способности канала — это задача сетевого уровня, и в подсистеме Undertow она не решается.
Опубликовано: август 2026 г.
Руководство обновляется по мере выхода новых моделей и условий лицензирования. Как мы сравниваем производителей