Перейти до вмісту
EuroVPSEuroVPS

Арифметика таблиці станів: розмір firewall під атаки, а не під середні значення

Чому stateful firewall вичерпує стани раніше за смугу, як підібрати розмір таблиці і таймаути, коли UDP робити stateless і як HA-пари зберігають сесії.

Автор EuroVPS Engineering

5 хв читання
State table arithmetic: sizing a firewall for floods, not averages

Запитайте більшість людей, наскільки великим має бути firewall, і вони відповідять у смузі пропускання. Під атакою смуга рідко є тим, що вичерпується першим. Першою вичерпується таблиця станів: список з’єднань, які firewall відстежує, що має фіксований розмір, заповнюється зі швидкістю надходження нових з’єднань і спорожнюється лише так швидко, як дозволяють таймаути. Зрозумійте цю арифметику, і ви зможете підібрати розмір firewall під день, коли це має значення, а не під середній день.

Чому стани вичерпуються раніше за смугу

Коли таблиця заповнена, нові з’єднання відкидаються, легітимні чи ні, навіть якщо лінки майже простоюють.

Два види трафіку швидко заповнюють таблицю:

  • SYN flood. Кожен підроблений SYN створює напіввідкритий запис, який ніколи не завершиться.
  • UDP до публічних сервісів. DNS, NTP, ігрові сервери, VoIP і подібні сервіси бачать величезну кількість коротких обмінів з багатьох джерел, і кожен може створити власний запис.

Арифметика

Усталена кількість записів у таблиці, з хорошим наближенням, становить:

entries  =  new flows per second  x  seconds each entry lives

Це закон Літтла, і в ньому вся гра. Припустімо, атака надходить зі швидкістю 50 000 нових SYN за секунду, а напіввідкриті записи TCP живуть 30 секунд. Таблиці потрібно 1 500 000 записів лише для атаки, перш ніж прийде хоч один справжній користувач. Скоротіть цей таймаут до 5 секунд під час атаки, і та сама атака потребує 250 000. Той самий firewall, та сама пам’ять, шестикратна різниця, зроблена одним таймером.

Тож є лише три важелі: більша таблиця (пам’ять), коротші часи життя (таймаути) і менше записів на потік (взагалі не відстежувати стан там, де він не потрібен). Використовуйте всі три.

Важіль перший: задайте розмір таблиці свідомо

З’ясуйте, скільки пам’яті платформа виділяє на запис стану, вирішіть, яку частину RAM firewall ви готові віддати під стани, і задайте максимум виходячи з цього, замість жити зі значенням за замовчуванням, обраним для малого офісу. Потім налаштуйте тривогу задовго до заповнення таблиці.

На OPNsense і firewall на базі pf живі числа за одну команду:

pfctl -si | grep -A4 "State Table"
pfctl -sm | grep states

Важіль другий: адаптивні таймаути і SYN cookies

Статичні таймаути є компромісом між добротою до повільних клієнтів і виживанням під атакою. Адаптивні таймаути прибирають компроміс: коли таблиця заповнюється понад початковий поріг, усі таймаути лінійно зменшуються, досягаючи нуля на кінцевому порозі. У звичайні дні таймери залишаються щедрими; під тиском записи спливають швидко. Мовою pf:

set limit states 2000000
set timeout { adaptive.start 1200000, adaptive.end 2200000 }

Додайте SYN cookies, в ідеалі в адаптивному режимі, який вмикається лише тоді, коли таблиця перетинає поріг. З cookies firewall відповідає на SYN, не створюючи стану, і будує запис лише після того, як клієнт завершить handshake, чого підроблене джерело ніколи не робить. Це перетворює найефективнішу атаку на stateful firewall на трафік, який firewall ледве помічає.

Важіль третій: не відстежуйте те, що не потребує відстеження

Для UDP-сервісів з великим обсягом відстеження кожного обміну майже нічого не дає: сервіс відповідає з відомого порту, і правила прості. Пара stateless-правил (дозволити вхідне на порт сервісу, дозволити вихідне з нього) не створює записів узагалі, тож UDP flood не може вичерпати таблицю від імені сервера DNS чи NTP. Залиште stateful-обробку для TCP і для всього, де зворотний трафік має бути строго прив’язаний до вихідного запиту.

Збережіть стани під час відмови

Підбір розміру є половиною роботи; інша половина полягає в тому, щоб не втратити все при відмові вузла. У парі active і standby CARP переносить віртуальні адреси на standby, а pfsync безперервно реплікує таблицю станів між вузлами, по можливості через виділений лінк. Коли активний вузол гине, standby уже знає кожне встановлене з’єднання, тож сесії тривають замість того, щоб кожен користувач перепід’єднувався. Протестуйте це: почніть довге завантаження або SSH-сесію через пару, вимкніть живлення активного вузла і дивіться, як вона триває.

Допомагають дві практичні звички. Застосовуйте зміни налаштувань спочатку на standby, перевіряйте, потім робіть failover і змінюйте інший вузол; і розподіляйте обробку пакетів між ядрами CPU з кількістю потоків, підібраною під кожен appliance, щоб одне зайняте ядро не стало справжньою межею.

Упорядкуйте набір правил для дешевих рішень

Атаку дешевше відкинути рано. Ставте грубі, дешеві рішення першими: об’єднаний блок-список threat intelligence, потім блокування країн, потім відомі зловживані діапазони хостингу, і лише потім правила дозволу для кожного хоста. Називайте кожен alias і правило за хостом, який воно захищає, щоб набір правил документував сам себе і старі правила можна було впевнено прибирати.

Перевірте власний firewall

  • Яка межа таблиці станів і який сьогоднішній пік у відсотках від неї?
  • Чи є тривога значно нижче межі?
  • Чи налаштовані адаптивні таймаути і чи доступні SYN cookies під навантаженням?
  • Чи обробляються UDP-сервіси з великим обсягом як stateless?
  • У HA-парі, чи синхронізуються стани, і чи тестували ви failover з живими сесіями?
  • Чи знаєте ви, що зробить з таблицею атака з десятикратною швидкістю ваших звичайних з’єднань? Зробіть множення.

Наші периметрові firewall в Афінах працюють як stateful-пари, побудовані й налаштовані саме так, і змінюються лише через їхній API. Якщо вам потрібна допомога з арифметикою для ваших власних, ми радо сядемо з вами.

Поговоріть з інженером

Related (rows[1])

Пов’язане: Managed периметрові firewall · Як ми змінюємо речі: дисципліна змін у мережі · Моніторинг мережі та докази

Опубліковано 14 жовтня 2026 р..

Усі нотатки з практики