Стек протоколов IPsec служит общепризнанным отраслевым стандартом защиты сетевых коммуникаций поверх недоверенных публичных сетей. Разработанный в эпоху, когда предполагалось наличие у каждого интернет-узла глобально маршрутизируемого публичного IPv4-адреса, IPsec опирается на протокол инкапсулирующей полезной нагрузки (ESP, IP Protocol 50) для обеспечения конфиденциальности, аутентификации источника и защиты от повторного воспроизведения пакетов. Однако дефицит адресного пространства IPv4 привел к повсеместному распространению механизмов трансляции сетевых адресов (NAT) и портов (PAT). Поскольку чистый протокол ESP функционирует непосредственно на сетевом уровне без портов транспортного уровня L4, маршрутизаторы NAT не могут отслеживать и маршрутизировать входящие зашифрованные ответы. Стандарты RFC 3947 («Negotiation of NAT-Traversal in the IKE») и RFC 3948 («UDP Encapsulation of IPsec ESP Packets») устраняют это фундаментальное противоречие посредством инкапсуляции пакетов ESP внутрь дейтаграмм UDP на порту 4500.

Чистый протокол ESP (сбой маршрутизации через PAT/NAT):
[Заголовок IP (Proto 50)] [Заголовок ESP: SPI (4B), Seq (4B)] [Полезная нагрузка]
                        └──> Нет портов UDP/TCP! Шлюз PAT не может адресовать ответ.

Инкапсуляция NAT-T (RFC 3948 через порт UDP 4500):
[Заголовок IP (Proto 17)] [UDP (Src 4500, Dst 4500)] [Заголовок ESP] [Данные]
                        └──> Порты L4 позволяют удерживать таблицу трансляции.

Проблема трансляции портов PAT: почему чистый протокол ESP не работает за NAT

Чтобы понять необходимость технологии прохождения NAT (NAT-Traversal, NAT-T), необходимо проанализировать логику работы шлюзов с контролем состояния соединений.

Отсутствие портов на транспортном уровне в протоколе ESP

Когда несколько частных устройств за офисным маршрутизатором или операторским шлюзом CGNAT обращаются к внешним сетевым ресурсам, транслятор подменяет их локальные адреса единым внешним публичным IP. Для сопоставления входящих пакетов с конкретными устройствами локальной сети шлюз выделяет уникальный номер порта источника для каждой исходящей сессии TCP или UDP.

Протокол ESP оперирует на сетевом уровне L3 под номером 50. В отличие от TCP (номер 6) или UDP (номер 17), у него нет концепции портов. Первые 4 байта заголовка ESP отведены под индекс параметров безопасности (Security Parameter Index, SPI) — 32-битное число, назначаемое принимающей стороной для идентификации соединения безопасности (SA):

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|               Security Parameters Index (SPI)                 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                      Sequence Number                          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                    Payload Data (Variable)                    |

При прохождении исходящего пакета ESP через шлюз PAT устройство может переписать IP-адрес источника, но не способно выделить порт. Когда от удаленного VPN-сервера возвращается ответный пакет ESP, шлюз видит отсутствие порта назначения и не имеет детерминированного способа понять, какому внутреннему клиенту адресован пакет. Некоторые домашние маршрутизаторы используют функцию «SPI passthrough», однако этот подход нарушается, если два и более внутренних устройства подключаются к одному и тому же внешнему VPN-серверу.

Модификация сетевого пути и сбой проверки контрольной суммы TCP/UDP

Вторая проблема проявляется в транспортном режиме (Transport Mode). Алгоритмы вычисления контрольной суммы псевдозаголовков TCP и UDP включают в себя IP-адреса отправителя и получателя, номер протокола и длину сегмента. Когда промежуточный транслятор изменяет IP-адрес, исходная контрольная сумма становится недействительной. Поскольку тело пакета зашифровано алгоритмом ESP, промежуточный маршрутизатор не может пересчитать контрольную сумму. При расшифровке на стороне получателя проверка целостности не проходит, и сетевой стек ядра операционной системы молча отбрасывает пакет.

Механизм RFC 3947 NAT-Discovery: обнаружение промежуточных шлюзов

Для автоматического устранения несовместимости спецификация RFC 3947 (интегрированная в актуальный стандарт IKEv2 RFC 7296) регламентирует процедуру обнаружения NAT (NAT-Discovery, NAT-D) на этапе первичного согласования параметров безопасности.

Полезная нагрузка NAT-D и проверка хешей в IKE_SA_INIT

В процессе обмена IKE_SA_INIT на порту UDP 500 инициатор и ответчик обмениваются блоками данных NAT-D (NAT_DETECTION_SOURCE_IP и NAT_DETECTION_DESTINATION_IP). Каждый блок содержит дайджест SHA-1, вычисленный от значений SPI, IP-адресов и портов:

$$\text{Hash} = \text{SHA-1}(\text{SPI}_i ,|, \text{SPI}_r ,|, \text{IP} ,|, \text{Port})$$

Анализ осуществляется с двух независимых позиций:

  1. Проверка хеша источника: Инициатор хеширует свой локальный адрес и порт (500). Принимающая сторона пересчитывает хеш на основе фактического IP-адреса и порта, зафиксированных во внешнем заголовке пакета. Если хеши не совпадают, значит, исходящий пакет подвергся модификации промежуточным шлюзом.
  2. Проверка хеша назначения: Инициатор хеширует целевой IP и порт удаленного сервера. Сервер сопоставляет его со своими локальными сетевыми интерфейсами. Расхождение свидетельствует о наличии целевого NAT со стороны сервера.
Схема процедуры обнаружения NAT-Discovery:
Инициатор (Локальный IP: 192.168.1.50)              Ответчик (Публичный IP: 203.0.113.1)
  │                                                     │
  ├─ IKE_SA_INIT (UDP 500) ────────────────────────────>│ Шлюз подменяет IP источника на 198.51.100.2
  │  NAT-D (Источник: Хеш 192.168.1.50:500)             │ Ответчик вычисляет Hash(198.51.100.2:500)
  │  NAT-D (Назначение: Хеш 203.0.113.1:500)            │ Хеши не совпадают => NAT обнаружен!
  │<─ IKE_SA_INIT Response (UDP 500) ───────────────────┤
  ▼                                                     ▼
Оба узла зафиксировали наличие NAT => Немедленное переключение на UDP 4500.

Переключение портов: плавный переход с UDP 500 на UDP 4500

Как только стороны подтверждают наличие трансляции адресов, выполняется операция переключения портов:

  • Последующий этап аутентификации IKE_AUTH переносится с порта UDP 500 на UDP 4500.
  • Все создаваемые далее дочерние пакеты данных ESP упаковываются в заголовки UDP с портом назначения 4500.

Переключение портов устраняет конфликты с маршрутизаторами, применяющими жесткие статические правила к порту 500, и открывает единый маршрут для управляющего и зашифрованного пользовательского трафика.

Архитектура инкапсуляции RFC 3948: назначение 4-байтового маркера Non-ESP

Стандарт RFC 3948 определяет формат упаковки дейтаграмм, позволяющий мультиплексировать управляющие сообщения IKE и зашифрованные пакеты данных ESP на едином сокете UDP 4500.

Формат инкапсуляции UDP по стандарту RFC 3948:
+---------------------------------------------------------------+
|                       Заголовок IPv4 или IPv6                 |
+---------------------------------------------------------------+
|               Заголовок UDP (Порт источника, Порт 4500)       |
+---------------------------------------------------------------+
|                    Точка ветвления демультиплексора           |
|   [Первые 4 байта == 0x00000000]  |  [Первые 4 байта != 0x00] |
|               │                   |             │             |
|               ▼                   |             ▼             |
|        Маркер Non-ESP             |     Заголовок ESP (SPI)   |
|     (Управляющий пакет IKE)       |    (Зашифрованные данные) |
+-----------------------------------+---------------------------+

Демультиплексирование управляющего трафика IKE и данных ESP

Поскольку управляющие сигналы IKE (ротация ключей, проверки доступности, завершение SA) и зашифрованные данные пользователей передаются через единый порт UDP 4500, сетевой стек ядра должен мгновенно различать их без разбора вложенных структур.

RFC 3948 решает эту задачу с помощью элегантного правила:

  1. Маркер Non-ESP для IKE: Любое служебное сообщение IKE на порту UDP 4500 снабжается префиксом из 4 нулевых байтов (0x00000000).
  2. Прямое смещение SPI для ESP: В пакетах данных ESP 32-битный индекс параметров безопасности (SPI) размещается непосредственно за заголовком UDP.

В соответствии со спецификацией RFC 4301, значение SPI 0 (0x00000000) строго зарезервировано и никогда не назначается реальным соединениям безопасности. Сетевой стек операционной системы выполняет операцию $O(1)$ по проверке первых 4 байт после заголовка UDP:

  • Если первые 32 бита содержат 0x00000000, 4 байта маркера отсекаются, а дейтаграмма передается процессу управления IKE в пространстве пользователя.
  • Если первые 32 бита не равны нулю, пакет классифицируется как зашифрованные данные ESP. Ядро использует это значение как ключ SPI для поиска в базе данных ассоциаций безопасности (SAD) и передает пакет напрямую криптографическим модулям ядра.

Такая организация устраняет переключение контекста для основного потока данных, обеспечивая высокую пропускную способность.

Работа NAT Keepalive и таймеры состояний трансляции

Межсетевые экраны и шлюзы CGNAT хранят таблицы трансляций в оперативной памяти. При отправке исходящего пакета шлюз создает запись состояния. Если через эту запись в течение определенного времени (в мобильных сетях часто от 30 до 60 секунд) не проходит трафик, шлюз удаляет трансляцию. В результате входящие зашифрованные пакеты от VPN-сервера начинают сбрасываться.

RFC 3948 описывает стандартный пакет поддержания активности NAT Keepalive:

  • Формат: Один байт со значением 0xFF, передаваемый сразу за заголовком UDP на порту 4500.
  • Размер: Ровно 1 байт.
  • Интервал передачи: Отправляется каждые 20–25 секунд при отсутствии полезных данных.
Структура пакета Keepalive по стандарту RFC 3948:
+-----------------------------------------------+
| Заголовок IP (Протокол 17)                    |
+-----------------------------------------------+
| Заголовок UDP (Порт 4500, Длина 9 байт)       |
+-----------------------------------------------+
| 0xFF (Один октет полезной нагрузки)           |
+-----------------------------------------------+

Принимающий сервер, обнаружив дейтаграмму UDP длиной ровно 1 байт со значением 0xFF, отбрасывает ее без генерации системных предупреждений. Пакет предназначен исключительно для обновления таймера неактивности на промежуточных сетевых устройствах, поддерживая обратный канал связи.

Накладные расходы туннелирования, обнаружение Path MTU и зажим TCP MSS

Инкапсуляция пакетов ESP в протокол UDP приводит к увеличению заголовка, сокращая доступный размер полезной нагрузки.

Добавление 8-байтового заголовка UDP снижает эффективный максимальный размер пакета (MTU). На стандартном канале Ethernet с MTU 1500 байт:

  • Накладные расходы чистого ESP для IPv4 составляют от 50 до 60 байт в зависимости от выбранных криптографических алгоритмов.
  • Инкапсуляция UDP добавляет еще 8 байт, увеличивая суммарный заголовок туннеля до 62–72 байт.
  • Внутренний параметр максимального размера сегмента TCP (MSS) должен быть принудительно уменьшен со стандартных 1460 байт до 1360–1380 байт.

Без корректного зажима TCP MSS пакеты, превышающие MTU пути, подвергаются фрагментации. Поскольку многие операторские маршрутизаторы блокируют фрагментированные IP-пакеты, некорректная настройка MTU приводит к зависаниям соединений и снижению скорости передачи.

Устойчивость в сетях CGNAT: интеграция с архитектурой RiceGuard

Сетевой движок RiceGuard в платформе VPNRice использует спецификации RFC 3948 NAT-T для обеспечения стабильного туннелирования через строгие мобильные сети, многоуровневые домашние маршрутизаторы и корпоративные фильтры.

Архитектура RiceGuard Zero-Trust с поддержкой NAT-T:
Мобильный клиент / Удаленный узел
  │  (За шлюзом CGNAT или двойным NAT)
  │  Инициирует сессию IKE_SA_INIT через UDP 500
  ▼
Автоматическая верификация NAT-D
  │  - Фиксирует подмену внешнего IP-адреса
  │  - Моментально переключает сессию на порт UDP 4500
  │  - Добавляет маркер Non-ESP к служебным пакетам
  ▼
Высокопроизводительный шлюз Anycast RiceGuard
  │  - Принимает инкапсулированные кадры ESP на порту 4500
  │  - Обеспечивает быстрый поиск по базе SAD ядра Linux XFRM
  │  - Адаптивно настраивает периодичность keepalive-пакетов
  ▼
Защищенная магистральная сеть / Корпоративный периметр
  1. Детерминированное переключение портов: RiceGuard автоматически распознает наличие трансляции сетевых адресов при установке туннеля и переходит на UDP 4500, защищая трафик от избирательной блокировки порта 500 на стороне интернет-провайдеров.
  2. Адаптивные таймеры активности: Отказываясь от фиксированных интервалов, RiceGuard анализирует параметры задержки мобильной сети и корректирует частоту отправки keepalive-пакетов, экономя заряд аккумулятора мобильных устройств.
  3. Аппаратное демультиплексирование в ядре: Используя интерфейс сокетов Linux XFRM с разгрузкой UDP-инкапсуляции, шлюзы RiceGuard отправляют поток зашифрованных данных непосредственно в криптографические ускорители, передавая служебные маркеры Non-ESP управляющим демонам.

Диагностика и проверка: анализ сокетов NAT-T и базы SAD ядра Linux

Сетевые администраторы могут инспектировать активные туннели NAT-T на серверах под управлением Linux при помощи стандартного набора утилит.

Проверка прослушивания портов UDP 4500

Убедитесь, что демон IPsec открыл необходимые сокеты:

# Проверка сокетов UDP для протоколов IKE и NAT-T
ss -uan '( sport = :500 or sport = :4500 )'

Пример вывода:

State    Recv-Q    Send-Q       Local Address:Port        Peer Address:Port
UNCONN   0         0                  0.0.0.0:500              0.0.0.0:*
UNCONN   0         0                  0.0.0.0:4500             0.0.0.0:*

Анализ параметров инкапсуляции в базе SAD ядра Linux

Выполните запрос к таблице ассоциаций безопасности (SAD) для проверки инкапсуляции пакетов:

# Отображение параметров IPsec SA и параметров инкапсуляции
ip xfrm state show

Фрагмент вывода:

src 198.51.100.2 dst 203.0.113.1
	proto esp spi 0xc7a41289 reqid 1 mode tunnel
	replay-window 64 flag af-unspec
	auth-trunc hmac(sha256) 0x6e7a... 128
	enc cbc(aes) 0x4f12...
	encap type espinudp sport 4500 dport 4500 addr 0.0.0.0
	sel src 0.0.0.0/0 dst 0.0.0.0/0

Строка encap type espinudp подтверждает, что ядро Linux инкапсулирует исходящие пакеты ESP в заголовки UDP порта 4500 и ожидает входящие пакеты в том же формате, обеспечивая надежную доставку трафика через любые промежуточные сетевые шлюзы.

Стандарт RFC 3948 стал ключевой вехой, сохранившей жизнеспособность протокола IPsec в современном интернете с преобладанием NAT. Упаковка дейтаграмм ESP в формат UDP 4500 и строгое разделение потоков с помощью маркеров Non-ESP обеспечивают стабильную работу защищенных корпоративных сетей поверх сложной провайдерской инфраструктуры.

Для построения отказоустойчивых сетевых туннелей Zero-Trust, способных работать через комплексные сетевые конфигурации, доступно решение Скачать VPNRice.