Криптографічні алгоритми транспортного рівня захищають IP-датаграми від перехоплення та спотворення корисного навантаження. Сучасні шифри обчислюють значення перевірки цілісності (ICV), яке підтверджує справжність кожного окремого фрейму. Проте перевірка автентичності ізольованих пакетів не здатна захистити протоколи без встановлення з'єднання від атак повторного відтворення.
Без збереження послідовності станів супротивник на проміжному маршруті передавання може записувати дійсні зашифровані пакети та надсилати їхні дублікати до шлюзу призначення. Такі пакети успішно проходять математичну перевірку, виснажують ресурси центрального процесора, порушують роботу скінченних автоматів і спричиняють стан відмови в обслуговуванні. Для усунення цієї вразливості стандарт IPsec Encapsulating Security Payload (ESP, RFC 4303) вимагає обов'язкового використання порядкового лічильника та механізму ковзного вікна захисту від повторів.
Роль порядкових номерів у криптографічних мережевих тунелях
Тунелі без встановлення з'єднання інкапсулюють датаграми IP 3-го рівня в зовнішні заголовки IP або UDP. Оскільки проміжні маршрутизатори спрямовують пакети різними фізичними лініями, дані нерідко надходять у порушеному порядку або тимчасово дублюються під час транзиту.
У межах асоціації безпеки IPsec (Security Association, SA) відправник призначає строго монотонно зростаючий порядковий номер кожному надісланому пакету ESP. Цей номер виконує дві головні задачі:
- Забезпечує унікальний матеріал для векторів ініціалізації (IV) та псевдовипадкових чисел AEAD, запобігаючи повторному застосуванню ключових потоків.
- Дозволяє шлюзу-одержувачу виявляти дубльовані фрейми та відкидати пакети, які виходять за межі допустимого часового вікна.
+-----------------------------------------------------------------------------+
| СТРУКТУРА ІНКАПСУЛЯЦІЇ ПАКЕТА IPSEC ESP (RFC 4303) |
+-----------------------------------------------------------------------------+
| Зовнішній IP-заголовок | SPI (32 біти) | Порядковий номер (32 біти) | Дані |
+-----------------------------------------------------------------------------+
Відправник ніколи не зменшує значення лічильника протягом існування активної асоціації SA. Щойно лічильник досягає максимальної межі, система зобов'язана узгодити нову SA через протокол IKEv2 перед передаванням подальших даних.
Механіка ковзного вікна захисту від повторів IPsec ESP (RFC 4303)
Оскільки мережа може доставляти пакети не за порядком, приймальний вузол IPsec не може відхиляти кожен пакет лише тому, що його номер менший за попередній. Стандарт RFC 4303 визначає алгоритм ковзного вікна на основі бітової маски завширшки $W$, яка зазвичай налаштовується в межах від 32 до 1024 бітів.
<- Застарілі відкидаються -> | <- Ковзне вікно (Ширина W) -> | <- Майбутні ->
... ------------------------------+-------------------------------+-------------> Простір
^ ^
(M - W + 1) M (Макс. прийнятий)
Приймальний шлюз відстежує дві ключові змінні:
- $M$: найбільший порядковий номер, успішно перевірений та прийнятий.
- Бітова маска розміром $W$: відображає стан $W - 1$ номерів, які передують $M$.
Зсув вікна та відстеження стану бітової маски
Під час надходження пакета ESP із номером $S$ механізм перевірки аналізує $S$ відносно меж вікна до початку витратної операції розшифрування:
- Випадок 1 ($S > M$): Пакет новіший за всі раніше отримані. Шлюз перевіряє значення ICV. У разі успіху вікно зміщується праворуч шляхом зсуву маски ліворуч на $(S - M)$ позицій, фіксується $M = S$, а відповідний біт встановлюється в 1.
- Випадок 2 ($M - W + 1 \le S \le M$): Пакет перебуває в межах поточного вікна. Одержувач перевіряє біт за зміщенням $(M - S)$. Якщо біт уже активований, пакет відкидається як повторний дублікат. Якщо біт чистий, проводиться верифікація цілісності, і біт перемикається в 1.
- Випадок 3 ($S < M - W + 1$): Пакет розташований лівіше вікна. Шлюз негайно знищує пакет без розшифрування та збільшує лічильник відкинутих повторів.
Логіка відкидання застарілих та дубльованих пакетів ESP
Фільтрація трафіку до розшифрування забезпечує високу продуктивність. Перевіряючи актуальність порядкового номера до запуску важких обчислень, шлюз нейтралізує повторні атаки з мінімальним залученням ресурсів процесора.
Спроби перевантажити ресурси VPN-шлюзу лавиною дублікатів припиняються безпосередньо на вхідному мережевому інтерфейсі. Справжні пакети, що затрималися через коливання маршрутизації, приймаються в штатному режимі, якщо затримка не виходить за глибину $W$.
Вичерпання 32-бітного простору номерів на високих швидкостях
Початковий стандарт IPsec (RFC 2401) відводив 32 біти для поля номера ESP. Такий простір розрахований на $2^{32} - 1 \approx 4.29 \times 10^9$ пакетів до моменту переповнення. На високошвидкісних магістральних каналах цей ліміт вичерпується за лічені хвилини:
| Пропускна здатність | Розмір пакета | Інтенсивність потоку | Час вичерпання лічильника |
|---|---|---|---|
| 1 Гбіт/с | 1400 байтів | 89.2 тис. пак/с | 13.3 години |
| 10 Гбіт/с | 1400 байтів | 892.8 тис. пак/с | 80.0 хвилин |
| 40 Гбіт/с | 1400 байтів | 3.57 млн пак/с | 20.0 хвилин |
| 100 Гбіт/с | 1400 байтів | 8.92 млн пак/с | 8.0 хвилин |
| 100 Гбіт/с | 64 байти | 148.8 млн пак/с | 28.8 секунди |
Якщо асоціація SA вичерпує діапазон номерів без увімкнення розширеної нумерації, передавання призупиняється до створення нової SA через IKEv2. Часте генерування нових ключів перевантажує процесор і викликає короткочасні втрати пакетів.
Розширені порядкові номери ESN: захист 64 біт без накладних витрат
Специфікації RFC 4303 та RFC 4304 визначають розширені порядкові номери (Extended Sequence Numbers, ESN), які збільшують простір до 64 бітів ($2^{64} - 1 \approx 1.84 \times 10^{19}$ пакетів). За швидкості 100 Гбіт/с навіть для фреймів найменшого розміру лічильник забезпечує безперебійне шифрування протягом тисячоліть.
Важливо те, що структура пакета на фізичному рівні залишається незмінною. Заголовок ESP передає лінією зв'язку лише молодші 32 біти ($Seq_{low}$).
+-----------------------------------------------------------------------------+
| АРХІТЕКТУРА РОЗШИРЕНИХ НОМЕРІВ (ESN ЗГІДНО З RFC 4303) |
+-----------------------------------------------------------------------------+
| Передається лінією: [ Поле SPI 32 біти ] [ Молодші 32 біти номера ] |
| Зберігається локально: [ Старші 32 біти номера ] |
| Перевіряється в ICV: [ Неявні старші 32 біти ] + [ Повний фрейм ESP ] |
+-----------------------------------------------------------------------------+
Відновлення старших бітів через неявний стан лічильника
Оскільки мережею прямує лише $Seq_{low}$, одержувач обчислює старші 32 біти ($Seq_{high}$) на підставі поточного положення ковзного вікна:
- Якщо $Seq_{low} \ge M_{low}$, пакет належить до чинної епохи, і шлюз встановлює $Seq_{high} = M_{high}$.
- Якщо $Seq_{low} < M_{low}$ у діапазоні вікна, одержувач співвідносить $Seq_{low}$ зі значенням $M_{high}$.
- Коли $M_{low}$ наближається до межі $2^{32} - 1$, алгоритм визначає, чи пакет започаткував нову епоху $M_{high} + 1$, чи є запізнілим фреймом з епохи $M_{high}$.
Для захисту від спроб розсинхронізації підсумкове значення ICV охоплює повний 64-бітний номер. У разі підробки номера на межі циклів перевірка цілісності зазнає невдачі, і пакет негайно знищується.
Багаточергова маршрутизація NIC та неупорядкованість у багатоядерних шлюзах
Шлюзи корпоративного рівня розподіляють вхідний потік між ядрами CPU за допомогою механізму Receive Side Scaling (RSS). У разі передавання відкритого трафіку RSS використовує 5 параметрів пакета. Проте в зашифрованих пакетах IPsec ESP порти транспортного рівня приховані всередині тунелю.
Через це мережеві карти хешують пакети ESP лише за IP джерела, IP призначення та 32-бітним значенням SPI.
[ Потік пакетів ESP ] ---> [ Апаратний хеш RSS (IP + SPI) ]
|
+---------------+---------------+
v v
[ Ядро CPU 0 ] [ Ядро CPU 1 ]
(Розшифрування) (Розшифрування)
\ /
+-------------> <-------------+
|
[ Зміна черговості надходження ]
v
[ Перевірка вікна захисту від повторів ]
Конкуренція блокувань та втрати пакетів зі стандартними вікнами
Коли кілька ядер одночасно обробляють пакети однієї швидкісної SA, незначні коливання в часі виконання порушують первинний порядок. Пакет на Ядрі 1 може досягти перевірки на сотні позицій раніше за пакет на Ядрі 0.
Якщо глибина вікна $W$ залишається на застарілому рівні 32 або 64 пакети, таке розходження спричиняє масове відкидання пакетів:
- Ядро 1 зміщує $M$ уперед на 120 позицій.
- Ядро 0 доставляє наступний пакет із номером $S < M - W + 1$.
- Шлюз помилково вважає легітимний пакет застарілим і знищує його.
Ці хибні втрати активують процедуру швидкого повторного надсилання TCP та різко звужують вікно перевантаження. Інженери можуть перевіряти стан зовнішніх маршрутів за допомогою сервісу перевірки власної IP-адреси.
Масштабовані бітові карти: оптимізація RFC 6479 для високонавантажених тунелів
Традиційні алгоритми виконують лінійний зсув масиву бітової маски під час надходження кожного нового номера. Для вікон на 32 або 64 біти це виконується однією машинною операцією (bitmask <<= shift).
Однак для компенсації неупорядкованості на багатоядерних вузлах глибину $W$ необхідно розширювати до 1024 або 4096 пакетів. Зсув блоку пам'яті в 4096 бітів для кожного вхідного кадру створює значне навантаження на шину пам'яті та руйнує кеш процесора.
Стандарт RFC 6479 розв'язує цю проблему за допомогою циклічного бітового буфера без фізичного зсуву бітів:
+-----------------------------------------------------------------------------+
| ЦИКЛІЧНИЙ БУФЕР МАСКИ ЗАХИСТУ ВІД ПОВТОРІВ ЗА RFC 6479 |
+-----------------------------------------------------------------------------+
| Блок 0 (64 біти) | Блок 1 (64 біти) | ... | Блок N (64 біти) |
+-----------------------------------------------------------------------------+
^ ^
Індекс: (Seq / 64) % Кількість_блоків Вказівник поточної позиції
У рішенні RFC 6479:
- Бітова карта розбивається на фіксовані машинні слова по 32 або 64 біти.
- Номер пакета проєктується в індекс слова через взяття залишку:
index = (seq / 64) % total_banks. - Під час просування вікна стираються лише ті слова, через які пройшов вказівник, без копіювання всього масиву.
- Пошук статусу пакета виконується за сталий час $O(1)$ незалежно від глибини вікна.
Налаштування вікон захисту від повторів у стеках Linux XFRM та BSD
Сучасні платформи містять параметри для точного регулювання розміру вікон та ввімкнення ESN.
У середовищі Linux підсистема XFRM керує станами безпеки через набір утиліт iproute2. Для створення SA з циклічним вікном на 1024 пакети та 64-бітними ESN виконується команда:
# Налаштування стану XFRM із вікном 1024 пакети та прапорцем ESN
ip xfrm state add src 198.51.100.1 dst 203.0.113.1 \
proto esp spi 0x1a2b3c4d reqid 1 mode tunnel \
replay-window 1024 flag esn \
aead "rfc4106(gcm(aes))" 0x0123456789abcdef0123456789abcdef01234567 128
Для контролю кількості скинутих пакетів на шлюзі Linux:
# Перегляд лічильників помилок захисту від повторів
ip -s xfrm state show spi 0x1a2b3c4d
Виведена інформація деталізує розмір replay-window та лічильник помилок replay. Якщо це значення зростає під інтенсивним навантаженням за відсутності мережевих атак, установлений розмір вікна недостатній для компенсації затримок між ядрами.
В операційних системах FreeBSD та OpenBSD параметр коригується через змінні ядра sysctl:
# Налаштування глибини вікна прийому ESP в операційних системах BSD
sysctl net.inet.ipsec.esp_replaywindow=1024
У службах на кшталт StrongSwan прапорець ESN активується в конфігурації пропозицій Child SA фази 2 суфіксом esn (esp=aes256gcm128-esn!).
Як RiceGuard усуває неупорядкованість без ризику повторних атак
Платформа VPNRice впровадила фірмовий модуль прискорення RiceGuard на всіх глобальних серверах мережі. Замість вибору між якістю фільтрації повторів і паралельною багатоядерною швидкістю RiceGuard реалізує адаптивний конвеєр обробки.
[ Користувацький трафік ] -> [ Прив'язка потоків RiceGuard ] -> [ Ядра шифрування ]
|
v
[ Матриця вікна 4096 бітів RFC 6479 ] -> [ Стабільна доставка без втрат ]
- Прив'язка сесій до фіксованих ядер: RiceGuard розпізнає параметри потоків даних до початку інкапсуляції, скеровуючи певні сесії TCP або UDP на виділені ядра процесора. Це гарантує надходження пакетів у правильній черговості.
- Адаптивна матриця вікна на 4096 бітів: Під час нестабільності транзитних ліній BGP RiceGuard динамічно збільшує бітову маску до 4096 пакетів за алгоритмом RFC 6479, запобігаючи помилковому відкиданню даних.
- Апаратна синхронізація ESN: Сервери шлюзів координують 64-бітні лічильники безпосередньо в апаратних блоках криптографічного прискорення, усуваючи затримки узгодження на швидкості 100 Гбіт/с.
Для збереження високої стабільності та комплексного шифрування зв'язку на робочих комп'ютерах і смартфонах доступний офіційний клієнт.
Мережевим фахівцям, що проєктують масштабні канали, радимо ознайомитися з аналітикою щодо субсекундного виявлення збоїв каналів із BFD та розглянути роботу ковзних вікон у WireGuard. Також дізнайтеся про налаштування алгоритму керування перевантаженням TCP BBR.
Контрольний список впровадження для високошвидкісних шлюзів IPsec
Розгортання захисту від повторних атак на швидкісних магістральних вузлах потребує перевірки таких параметрів:
- Підтвердження узгодження ESN: Переконайтеся, що конфігурація сервісу IKEv2 містить ESN у всіх пропозиціях ESP Child SA для запобігання переповненню 32-бітного лічильника.
- Збільшення ширини вікна: Розширте вікно зі стандартного значення 32/64 щонайменше до 512 або 1024 пакетів на портах зі швидкістю 1 Гбіт/с і вище.
- Активація бітових структур RFC 6479: Перевірте, чи ядро операційної системи використовує циклічні буфери для збереження обчислювальних ресурсів CPU.
- Корекція розподілу RSS: Оптимізуйте налаштування черг мережевого адаптера або застосуйте інкапсуляцію в UDP (NAT-T RFC 3948) для рівномірного балансування симетричних потоків між чергами.
- Моніторинг лічильників відкидання: Відстежуйте показники
XfrmInReplayError(у Linux SNMP) абоnetstat -s -p espчерез Prometheus для вчасного виявлення затримок мережевого обладнання. - Збереження перевірки цілісності: У жодному разі не вимикайте захист від повторів повністю (
replay-window 0), оскільки це відкриває шлюз для руйнівних атак відмови в обслуговуванні.



