IPsec через NAT

IPsec через NAT — пример реализации работы IPsec через NAT с использованием устройств CISCO и  S-Terra Gate 4.2

До этого ранее выкладывал материал CISCO IPsec, поучилось "длинно и нудно" 🙂 При этом не всё удалось подробно разобрать, хотя на самом деле много интересных практических моментов было обозначено.

Одним из "скомканных кусков" стала работа IPsec через NAT.  Решил вынести данный материал в отдельную запись.

Кроме этого продолжаю изучать интересный отечественный продукт S-Terra Gate, которое выпускается уже порядка 10 лет, но мне оно попалось в продакшене только сейчас. Первое знакомство было в статье S-Terra VPN.


Проблема NAT

Речь пойдёт конечно же про PAT (Port Address Translation), он же NAT с перегрузкой, он же маскарадинг. Когда множество частных IPv4 адресов хостов внутренней сети сопоставляется одному публичному IPv4 адресу роутера. Самая распространённая форма NAT.

Роутер с PAT подменяет IPv4 адреса в пакетах хостов на свой адрес, переписывая заголовок пакета. Поэтому когда приходят ответные пакеты, то у них у всех IPv4 адрес назначения — это адрес роутера. Как роутеру определить какой пакет какому хосту внутри сети предназначен? Сделать это можно только по порту назначения в заголовке транспортного уровня.

Но как быть если для разных хостов в заголовке транспортного уровня используется один и то же порт? Когда придут ответные пакеты, роутер просто не сможет определить для какого хоста они предназначаются. В таком случае PAT подменяет и номер исходного порта источника, ведя таблицу преобразований NAT:

If the original source port is already used, PAT assigns the first available port number starting from the beginning of the appropriate port group 0–511, 512–1023, or 1024–65535.

CCNA R&S: Connecting Networks

При работе туннеля шифрованная нагрузка ESP цепляется сразу к IP заголовку. В таком пакете нет заголовка транспортного уровня и значит нет номера порта. Нет номера порта, PAT не может правильно функционировать:

IPsec через NAT

По этой причине ESP будет не ходить через PAT без дополнительных инструментов. В статье CISCO IPsec таким инструментом являлось исключение трафика для IPsec VPN из ACL, который отбирает трафик для преобразования NAT.

Нет проблем это сделать, если NAT и VPN-шлюз на одном устройстве. Но что делать, если NAT встречается где-то ещё по пути следования пакета?

Обход NAT

В этом случае используется обход NAT (NAT-Traversal, NAT-T). Что говорит CISCO? Читаем тут:

NAT Traversal is a feature that is auto detected by VPN devices. There are no configuration steps for a router running Cisco IOS Release 12.2(13)T. If both VPN devices are NAT-T capable, NAT Traversal is auto detected and auto negotiated.

То есть сами VPN пиры должны уметь NAT-T на уровне прошивки. При этом согласовывание NAT-T происходит автоматически. Принцип работы NAT-T такой: пакет ESP обёртывается в UDP с номером порта 4500. Это позволяет нормально пропускать пакеты с ESP через PAT.

Согласование NAT-T имеет свои накладные расходы, заголовок UDP весит 8 байт и настолько же уменьшается полезная нагрузка:

Топология

Соберём следующую топологию в EVE-NG: два роутера CISCO, на одном будет настроен NAT и за этим роутером S-Terra. Топология несколько "притянута за уши", так как S-Terra полноценный роутер, а не просто VPN-шлюз.

Другое дело что для настройки NAT и фаервола на S-Terra придется использовать iptables. На классическом роутере CISCO такая настройка более прозрачна. Хотя не удивлюсь, если подобная схема "S-Terra за роутером" используется где-то в продакшене:

IPsec через NAT

В качестве образов использую старые-добрые Dynamips c3725-adventerprisek9-mz.124-15.T14. Версия IOS 12.4>12.2 и значит NAT-T данная прошивка умеет.

Сначала настраиваем сетевую связность, чтобы все устройства видели друг-друга:

  • Конфигурация R1:
!
ip route 0.0.0.0 0.0.0.0 1.1.1.2
ip route 192.168.1.0 255.255.255.0 10.10.10.1
!

Маршрут по умолчанию на R2 и маршрут в сеть 192.168.1.0/24.

  • S-Terra:
ip route 0.0.0.0 0.0.0.0 10.10.10.2
  • R2:
ip route 0.0.0.0 0.0.0.0 1.1.1.1

Проверяем, всё отовсюду пингуется, PC1 пингует PC2 и наоборот.

Настройка PAT

Добавляем на R1:

interface FastEthernet0/0
ip address 1.1.1.1 255.255.255.0
ip nat outside
ip virtual-reassembly
duplex auto
speed auto
!
interface FastEthernet0/1
ip address 10.10.10.2 255.255.255.252
ip nat inside
ip virtual-reassembly
duplex auto
speed auto
!
ip route 0.0.0.0 0.0.0.0 1.1.1.2
ip route 192.168.1.0 255.255.255.0 10.10.10.1
!
ip nat inside source list 1 interface FastEthernet0/0 overload
!
access-list 1 permit 192.168.1.0 0.0.0.255
access-list 1 permit 10.10.10.0 0.0.0.3

Под NAT должен подпадать трафик из сети 192.168.1.0/24 наружу и трафик из подсети 10.10.10.0/30 наружу, то есть и трафик туннеля тоже.

Проверяем заработал ли NAT. Пингуем с PC2 ресурсы, всё что за 1.1.1.1 теперь недоступно, пинги не проходят.

Теперь пингуем с PC1 и S-Terra адрес R2 1.1.1.2, смотрим на R1 таблицу преобразований NAT:

NAT работает. Что по поводу туннеля?

Настройка туннеля

Далее настраиваем туннель между S-Terra и R2. Конфигурация R2:

crypto isakmp policy 1
 encr 3des
 authentication pre-share
 group 5
 lifetime 86400
crypto isakmp key Str0ngP@$$w0rd address 1.1.1.1
!
!
crypto ipsec transform-set SET1 esp-aes 256 esp-sha-hmac
!
crypto map IPsecMap 1 ipsec-isakmp
 set peer 1.1.1.1
 set transform-set SET1
 match address IPSEC
!
!
interface FastEthernet0/0
 ip address 1.1.1.2 255.255.255.0
 duplex auto
 speed auto
 crypto map IPsecMap
!
ip access-list extended IPSEC
 permit ip 192.168.2.0 0.0.0.255 192.168.1.0 0.0.0.255

Моменты которые нужно отметить:

  • Под туннель подпадает трафик из сети 192.168.2.0/24 в сеть 192.168.1.0/24;
  • Адрес S-Terra 10.10.10.1 будет подменятся на адрес R1 при проходе через NAT, поэтому в качестве пира на R2 везде указываем 1.1.1.1;
  • Из-за ограничений S-Terra, которая рассчитана на гостовые протоколы, приходится использовать несекьюрную группу 5 Диффи-Хеллмана и хеширование SHA (это настройка по умолчанию поэтому не показывается в конфигурации).

На S-Terra всё аналогично, только параметры хостов и подсетей зеркальные. Под туннель подпадает трафик из сети 192.168.1.0/24 в сеть 192.168.2.0/24. Адрес пира 1.1.1.2.

Проверка №1

Со стороны R2 туннель поднять нельзя. Если R2 первым отправит туннельный трафик, трафик будет отброшен, так как R1 не знает как обрабатывать этот трафик.

Но если S-Terra отправит туннельный трафик, то трафик уходит через PAT, попадает на R2 и далее. В таблице преобразований NAT на R1 появится запись. И когда придёт ответный трафик с R2, этот трафик подвергнется обратному преобразованию NAT и S-Terra его получит. То есть туннель поднимется и будет нормально работать в обе стороны пока существует запись в таблице преобразований.

Проверим это. Попробуем запустить пинг с PC1 на PC2. И.. ничего не работает. Включим дебаг ISAKMP на R2:

R2# debug crypto isakmp
Crypto ISAKMP debugging is on

Любая ошибка как несовпадение паролей или параметров SA и тогда вывод дебага заканчивается:

*Aug 9 14:30:00.000: ISAKMP:(0):deleting SA reason "Death by retransmission P1" state (I) MM_NO_STATE (peer 1.1.1.1) 

- MM_NO_STATE means that the VPN phase 1 (ISAKMP) is not even negotiated

Наконец все ошибки из-за невнимательности отловлены, туннель поднимается и пинг с PC1 на PC2 проходит. Смотрим таблицу трансляций NAT на R1:

IPsec через NAT

Запись 1 это согласование ISAKMP, запись 2 пакеты ESP обёрнутые в UDP. Роемся в дебаге на R2 и ищем там буквы про NAT:

*Aug 9 14:34::48.951: ISAKMP:(0): constructed NAT-T vendor-rfc3947 ID
...
*Aug 9 14:35:09.091: ISAKMP (0:0): vendor ID is NAT-T RFC 3947
...
*Aug 9 14:35:33.419: ISAKMP (0:1003): NAT found, the node outside NAT

То есть NAT-T согласовывается уже на первой фазе туннеля.

Проверим SA на S-Terra и сравним результаты с результатами из записи S-Terra VPN. Было:

Стало:

NAT-T согласовался и это указано в свойствах IPsec SA. Соответственно с PC2 пинги на PC1 тоже стали проходить:

NAT-keepalive

Но запись в таблице трансляций NAT живёт ограниченное время и если нет трафика со S-Terra, то таблица трансляций очистится, значит трафик с R2 опять будет отброшен.

Однако на самом деле траффик со S-Terra будет идти постоянно. Очистим таблицу трансляций на R1 и просто подождём, никакой трафик по туннелю в это время не запускаем:

Как видно запись пересоздалась. Это работает механизм NAT-T, называемый NAT-keepalive (не путать с ISAKMP-keepalive). Он как раз нужен чтобы предотвратить очистку таблицы трансляций.

Захватим пакеты с интерфейса S-Terra в сторону R2:

Пакеты NAT-keepalive отправляются только с устройства, которое за NAT:

The location of the NAT device is important, as the keepalives have to initiate from the peer "behind" the NAT.

Настройка связности через PAT

Тем не менее связность VPN пиров пока только в одну сторону. Что тут можно придумать?

Если дополнительно сделать на R1 статический NAT на S-Terra, то это будет взаимно-однозначное сопоставление внутреннего и внешнего адресов. А задача была чтобы S-Terra отправляла трафик именно через PAT. Не подходит.

Поэтому прокинем порты с R1 на S-Terra. Конфигурация R1:

ip nat inside source static udp 10.10.10.1 500 1.1.1.1 500 extendable
ip nat inside source static udp 10.10.10.1 4500 1.1.1.1 4500 extendable

Трафик ISAKMP это UDP порт 500, а ESP после согласования NAT-T будет работать как UDP порт 4500. А что это за параметр Extendable?

"Extendable" static translations: The extendable keyword allows the user to configure several ambiguous static translations, where an ambiguous translations are translations with the same local or global address.

Поскольку у нас 2 правила трансляции портов с одинаковыми адресами, то и нужен данный параметр.

Проверка №2

Cохраняем конфигурации и перезагружаем все устройства. Теперь пинг запускаем с PC2 на PC1. Запускаем WireShark на интерфейсе R1 в сторону R2 и смотрим что получилось:

Туннель успешно поднимается. Шифрованный трафик теперь может нормально инициироваться любой из двух сторон, что и нужно было.

Разрешение трафика через ACL

Если настраивать на R1 CBAC-файрвол, то для согласования туннеля и прохождения шифрованного трафика нужен ACL, который будет висеть на интерфейсе в сторону R2:

R1(config)# ip access-list extended firewall_acl
R1(config-ext-nacl)# permit udp host 1.1.1.2 host 1.1.1.1 eq isakmp
R1(config-ext-nacl)# permit udp host 1.1.1.2 host 1.1.1.1 eq 4500
R1(config-ext-nacl)# exit
R1(config)# interface FastEthernet 0/0
R1(config-if)# ip access-group firewall_acl in

Добавление второй S-Terra

Из вывода таблицы преобразований NAT было видно, что используется номер порта 4500 и всё замечательно. А что если за NAT будет 2 устройства с IPsec VPN? Как R1 различит трафик для каждого из устройств?

Добавим вторую S-Terra и посмотрим каким образом роутер R1 с этим разберётся:

Топология ещё более "притянута за уши" чем первая, но она нужна такая для проверки работы.

Дополнительная настройка

На R1:

interface FastEthernet1/0
ip address 10.10.11.2 255.255.255.252
ip nat inside
ip virtual-reassembly
duplex auto
speed auto
!
ip route 192.168.3.0 255.255.255.0 10.10.11.1
!
access-list 1 permit 192.168.3.0 0.0.0.255
access-list 1 permit 10.10.11.0 0.0.0.3

Делаем интерфейс Fa1/0 внутренним для NAT, добавляем маршрут в сеть 192.168.3.0/24, добавляем в ACL1 новые правила для NAT.

На S-Terra2 всё аналогично S-Terra1. На R2:

ip access-list extended IPSEC
permit ip 192.168.2.0 0.0.0.255 192.168.1.0 0.0.0.255
permit ip 192.168.2.0 0.0.0.255 192.168.3.0 0.0.0.255

Не нужно добавлять новую строчку для крипто-карты crypto map IPsecMap 2 ipsec-isakmp (хотя можно сделать и так), все параметры совпадают. Поэтому только добавляем ещё 1 строку в ACL IPSEC.

Проверка №3

Протестируем туннели. Запустим постоянный пинг с  PC1 на PC2 и с PC3 на PC2. Пинг нормально проходит. Смотрим таблицу трансляций NAT на R1:

IPsec через NAT

То есть при трансляции в пакетах порты для устройства S-Terra2 подменяются и они уже не 500 и 4500, а 1 и 1024. Стандартная работа PAT по подмене портов. Соответственно, если посмотреть ответные пакеты, то для S-Terra1 предназначены пакеты:

IPsec через NAT

А для S-Terra2 пакеты:

IPsec через NAT

И тут возникает вопрос: как тогда для S-Terra2 прокидывать порты снаружи NAT вовнутрь? Ведь при работе NAT хостами внутренней сети будет отправлено множество пакетов и комбинации портов в таблице NAT будут разными в разные моменты времени.

Значит порты, используемые для IPsec, могут быть выбраны произвольными в широком диапазоне. Ответа на этот вопрос у меня нет.

Смотрим на R2:

Хотя все параметры, включая адрес пира (1.1.1.1) совпадают, R2 видит 2 раздельных ассоциации ISAKMP.

Что ещё? Можно было бы повесить дополнительно PAT и на R2, но это полностью аналогично тому, что делалось на R1.

NAT Virtual Interface

Последнее что нужно отметить, не сильно важное для IPsec, но просто интересное: когда был настроен NAT на R1, то появился дополнительный интерфейс — NVI.

Этот виртуальный интерфейс введён в IOS 12.3(14)T:

Recall that classic NAT first performs routing and then translation when going from an inside interface to an outside interface, and vice versa when the traffic flow is reversed. 

NVI, however, performs routing, translation, and routing again; NVI performs the routing operation twice, before and after translation, before forwarding the packet to an exit interface.

Нужен NVI чтобы обходить ограничения классического NAT. Например, когда на роутере настроен PAT совместно со статическим NAT: клиенты из внутренней сети не смогут попасть на Web-сервер по его внешнему адресу.

Работа NVI позволяет устранить данное ограничение.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *