Немає нічого, що б сильніше змушувало сумніватися у виборі професії, ніж «просто» IPsec‑VPN, який працює з однієї мережі, а потім перестає працювати в той же момент, коли клієнт опиняється за домашнім роутером, у готельному Wi‑Fi або в корпоративній фермі NAT. Логи кажуть, що тунель «вгорі». Користувачі кажуть, що додаток «не працює». Ваш фаєрвол каже, що «дозволяє все». І все одно: трафіку немає.
IPsec за NAT зазвичай виходить з ладу певними передбачуваними способами. Трюк у тому, щоб перестати гадати, який саме варіант у вас. NAT‑Traversal (NAT‑T) мав зробити це нудним. Коли це не нудно, відмова зазвичай голосна — просто не там, де ви дивитесь.
Що насправді робить NAT з IPsec (і чому це незручно)
Упорядкуємо словник, бо збої IPsec часто починаються зі збою в термінології з додатковими кроками.
IKE — це контрольна площина; ESP — це площина даних
У сучасному світі зазвичай маємо справу з IKEv2. Він узгоджує ключі та параметри по UDP порті 500. Коли пірси домовилися, фактичний зашифрований трафік потікає через:
- ESP (Encapsulating Security Payload): IP протокол 50 (не TCP/UDP). Це класичний режим, ворожий до NAT.
- NAT‑T інкапсульований ESP: ESP, загорнутий всередині UDP/4500. Так IPsec виживає за NAT.
Отже, потрібно дві речі для успіху: IKE має завершитися, і площина даних має переносити трафік. Ви можете мати IKE «вгорі», але з мертвою дорогою передачі даних. Це не парадокс. Це вівторок.
Чому NAT ламає «нативний» ESP
NAT‑пристрої переписують IP‑адреси (і часто порти). ESP не має портів. Багато NAT‑боксів не можуть підтримувати стабільний стан для протоколу, який не надає їм 5‑туплів (src IP, dst IP, src port, dst port, protocol). Деякі вміють «ESP passthrough» — маркетинговий термін, що означає «ми спробували».
Ще гірше: цілісність IPsec покриває частини пакета, які NAT охоче змінює. Тому якщо ви використовуєте AH (Authentication Header, протокол 51), переписування NAT робить перевірку цілісності недійсною. AH і NAT по суті несумісні за дизайном. ESP може вижити за NAT, якщо пристрій NAT його відстежує і не чіпає захищені поля, але на це не варто ставити продукцію в промисловому середовищі.
Основний трюк NAT‑T
NAT‑T змінює зовнішній транспорт на UDP, щоб NAT‑пристрої могли відстежувати потік, замаплений по порту. Після виявлення NAT обидва пірси переходять на UDP/4500. Зашифрований корисний вміст (ESP) стає корисним навантаженням UDP. NAT‑пристрій задовольняється, бо тепер може робити те, що робить весь день: підтримувати UDP‑стан.
Але NAT‑T додає оверхед. Це має значення для MTU і фрагментації. І воно залежить від таймаутів стану NAT та keepalive. Саме тому буває «підключається, а потім помирає через 30 секунд».
Одна перефразована ідея, часто приписувана Вернеру Фогельсу, підходить до роботи з надійністю: «Усе ламається; проектуйте так, щоб воно ламалося передбачувано і відновлювалося автоматично.» Проблеми NAT‑T стають передбачуваними, коли ви знаєте кілька стандартних пасток.
Три найтиповіші архітектури «за NAT»
- Road warrior: ноутбук/телефон за споживчим NAT до VPN‑шлюзу. Зазвичай найпростіше — якщо дозволені UDP/500 і UDP/4500.
- Site‑to‑site з однією NAT‑стороною: філія за роутером ISP, що робить NAT. Працює, але треба планувати динамічну публічну IP і відображення NAT.
- Подвійний NAT / CGNAT: ви за двома NAT (домашній роутер + carrier‑grade NAT). NAT‑T може працювати, але ви потрапляєте у царину агресивних таймаутів, переписування портів і думок на кшталт «можна вже використовувати WireGuard».
NAT‑T на практиці: порти, інкапсуляція та стан
Виявлення NAT і перехід на UDP/4500
IKEv2 виконує виявлення NAT шляхом хешування IP/порт триплетів і порівняння того, що кожна сторона вважає зовнішніми адресами/портами. Якщо хеші не збігаються, десь на шляху є NAT. Тоді пірси зазвичай домовляються використовувати UDP‑инкапсуляцію на порті 4500.
Якщо ви бачите IKE‑повідомлення на UDP/500, але ніколи не бачите UDP/4500, то або NAT не був виявлений (рідко), NAT‑T не ввімкнено/не погоджено (поширена помилка конфігурації), або фаєрвол скидає UDP/4500 (дуже поширено).
Keepalives: бо UDP‑стан випаровується
NAT‑пристрої швидко вичерпують відображення UDP—іноді за 30 секунд, іноді за кілька хвилин. NAT‑T використовує періодичні keepalive (часто близько 20 секунд), щоб тримати відображення активним. Якщо keepalive вимкнені або блокуються, тунель піднімається, трафік проходить коротко, а потім помирає до переключення ключів або перепідключення.
Короткий жарт №1: NAT схожий на золоту рибку: він забуває, що ваш UDP‑потік існує, щойно ви перестаєте махати пакетами перед ним.
MTU, фрагментація та чому «пінг працює» нічого не означає
NAT‑T додає оверхед: зовнішній IP‑заголовок + UDP‑заголовок + маркер non‑ESP + оверхед ESP. Якщо ви це не врахуєте, отримуєте проблеми з path MTU. Тунель «працює» для малих пакетів (пінги, банери SSH), але великі пакети вилітають в чорну діру. Ви побачите завислі TCP‑сесії, ретрансми або «сайт завантажився, але завантаження файлу не працює».
PMTUD часто не працює через IPsec + NAT, бо ICMP «Fragmentation Needed» може блокуватися або некоректно відображатися назад. Тому можливо доведеться обмежити MSS або явно встановити менший MTU.
NAT‑T з кількома клієнтами за одним NAT
Кілька клієнтів за одним NAT, які підключаються до того самого шлюзу — звичне явище. NAT‑пристрій використовує різні вихідні порти для кожного UDP/4500 потоку клієнта. Якщо VPN‑шлюз або проміжні пристрої припускають «один пірс на публічну IP», ви отримаєте флапінг тунелів, неправильний вибір SA або один користувач перехоплює сесію іншого. Це майже завжди поломка політичного пошуку (policy lookup) або надто суворе очікування peer ID.
Вибір політик IPsec і «rightid/leftid»
Коли є NAT, IP‑адреси стають менш стабільними ідентифікаторами. Використовуйте ідентифікації IKE (FQDN, email‑подібні ID, subjectAltName у сертифікаті) замість «peer має приходити з IP X». Site‑to‑site за динамічним IP? Використовуйте агресивне, але контрольоване співпадіння ідентичностей та обмежуйте доступ сертифікатами/PSK плюс звуженими пропозиціями.
Швидкий playbook діагностики (перший/другий/третій)
Ось порядок, який справді економить час у продакшні. Не починайте з читання кожного лог‑рядка з 2019 року.
Перший: доведіть, що пакети існують (UDP/500 і UDP/4500) на обох кінцях
- Захопіть трафік на боці клієнта: ви відправляєте UDP/500? Потім відправляєте UDP/4500?
- Захопіть на WAN‑інтерфейсі шлюзу: чи отримуєте ви їх?
- Якщо ви бачите UDP/500, але не бачите UDP/4500 після виявлення NAT, вважайте, що UDP/4500 заблоковано, поки не доведено протилежне.
Другий: підтвердіть, який стан думає кожен пірс (IKE SA vs CHILD SA)
- Чи встановлено IKE SA, але немає CHILD SA? Зазвичай це невідповідність пропозицій або невідповідність селекторів трафіку.
- Чи встановлено CHILD SA, але трафік не проходить? Зазвичай це маршрутизація, фаєрвол або MTU/фрагментація.
- Чи проходить він 30–120 секунд, а потім помирає? Зазвичай це таймаут відображення NAT / keepalives.
Третій: перевірте MTU/MSS і асиметричну маршрутизацію
- Запустіть DF‑пінг (або tracepath) через тунель і знайдіть реальний придатний MTU.
- Обмежте TCP MSS на інтерфейсі тунелю або на шлюзі, якщо потрібно.
- Перевірте зворотний шлях: IPsec не любить асиметричну маршрутизацію, коли задіяні станозберігаючі фаєрволи.
Якщо ви виконали ці три кроки, ви вирішите велику частину інцидентів «за NAT» без кризової кімнати.
Цікаві факти та коротка історія (трохи контексту для сьогоднішнього бардаку)
- IPsec проєктували з оптимізмом щодо IPv6. Первісно передбачалося, що end‑to‑end адресація буде звичною; NAT тоді не був центральним актором.
- AH (IP протокол 51) фактично не виживає за NAT. NAT змінює заголовки, які AH автентифікує. ESP — практичний вибір у NAT‑середовищах.
- NAT‑T став стандартом, бо «ESP passthrough» був ненадійним. Вендори випускали хаки; сумісність була… амбітною.
- UDP/4500 — конвенція для NAT‑T. Це тепер широко розпізнається фаєрволами як «порт IPsec NAT‑T», що корисно, але й дає відбиток.
- NAT‑T використовує non‑ESP маркер. В інкапсульованих ESP‑пакетах 4‑байтовий нульовий маркер відрізняє IKE‑трафік від ESP‑в‑UDP.
- Ранні чернетки NAT‑T конкурували. Існували різні реалізації до стандартизації; старе обладнання іноді поводиться дивно.
- Таймаути UDP у NAT змінюються кардинально. Побутові роутери, корпоративні фаєрволи та CGNAT вибирають різні дефолти; ваші налаштування keepalive мають відповідати найгіршому випадку.
- Мобільні мережі зазвичай агресивні. Деякі оператори та точки доступу обмежують або переробляють UDP‑потоки; IPsec через NAT‑T може виглядати як «рандомний UDP» для них.
- IKEv2 підвищив стійкість. Порівняно з IKEv1, станова машина IKEv2 і підтримка MOBIKE краще обробляють зміну адрес — за умови, що це ввімкнено та підтримується.
Практичні завдання: команди, очікуваний вивід і рішення
Нижче наведені практичні завдання, які можна виконати на клієнтах/шлюзах на базі Linux. Команди реалістичні; адаптуйте імена інтерфейсів і IP. Кожне завдання містить: команду, що означає вивід, і рішення.
Завдання 1: Підтвердіть, що в шляху є NAT (на боці клієнта)
cr0x@server:~$ ip -br addr
lo UNKNOWN 127.0.0.1/8 ::1/128
wlan0 UP 192.168.1.50/24 fe80::a00:27ff:fe4e:66a1/64
Значення: Ваш клієнт має приватну RFC1918 адресу (192.168.1.50). Ви за NAT.
Рішення: Припускайте, що потрібен NAT‑T, якщо VPN не використовує чистий UDP‑базований транспорт. Для IPsec вам потрібна досяжність UDP/4500.
Завдання 2: Перевірте маршрут за замовчуванням і інтерфейс виходу (на боці клієнта)
cr0x@server:~$ ip route show default
default via 192.168.1.1 dev wlan0 proto dhcp metric 600
Значення: Трафік виходить через 192.168.1.1 на wlan0. Це ваш NAT‑шлюз.
Рішення: Якщо VPN не працює лише в цій мережі, підозрюйте цей NAT‑пристрій або його upstream‑політику.
Завдання 3: Перевірте, що UDP/500 і UDP/4500 не блокуються локально (фаєрвол клієнта)
cr0x@server:~$ sudo nft list ruleset | sed -n '1,120p'
table inet filter {
chain input {
type filter hook input priority 0; policy accept;
}
chain output {
type filter hook output priority 0; policy accept;
}
}
Значення: Локальний фаєрвол ліберальний (policy accept). Якщо у вас політика «drop», шукайте явні дозволи.
Рішення: Якщо ви бачите drop для UDP/500 або UDP/4500, виправте локально перед тим, як звинувачувати мережу.
Завдання 4: Доведіть, що клієнт відправляє IKE‑пакети (tcpdump)
cr0x@server:~$ sudo tcpdump -ni wlan0 udp port 500 or udp port 4500
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on wlan0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
12:10:41.102345 IP 192.168.1.50.55612 > 203.0.113.10.500: isakmp: parent_sa ikev2_init[I]
12:10:41.256789 IP 203.0.113.10.500 > 192.168.1.50.55612: isakmp: parent_sa ikev2_init[R]
Значення: IKEv2 INIT відбувається на UDP/500. Отже, базова досяжність є.
Рішення: Переходьте до перевірки, чи виникає перехід на NAT‑T (UDP/4500).
Завдання 5: Підтвердіть, що перехід на NAT‑T (UDP/4500) фактично відбувається
cr0x@server:~$ sudo tcpdump -ni wlan0 udp port 4500
listening on wlan0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
12:10:42.001122 IP 192.168.1.50.4500 > 203.0.113.10.4500: UDP-encap: NONESP-encap: isakmp: parent_sa ikev2_auth[I]
12:10:42.140055 IP 203.0.113.10.4500 > 192.168.1.50.4500: UDP-encap: NONESP-encap: isakmp: parent_sa ikev2_auth[R]
12:10:43.000211 IP 192.168.1.50.4500 > 203.0.113.10.4500: UDP-encap: ESP(spi=0xc1a2b3c4,seq=0x1)
Значення: У вас є NAT‑T (UDP/4500) і ви бачите ESP‑in‑UDP пакети. Це правильна форма.
Рішення: Якщо UDP/4500 відсутній, виправляйте фаєрвол/ACL/NAT у шляху. Якщо вони є, але трафік не працює — дивіться CHILD SA, маршрутизацію та MTU.
Завдання 6: Якщо ніколи не бачите UDP/4500, перевірте, чи мережа його блокує
cr0x@server:~$ sudo nmap -sU -p 4500 203.0.113.10
Starting Nmap 7.94 ( https://nmap.org ) at 2025-12-28 12:12 UTC
Nmap scan report for 203.0.113.10
Host is up.
PORT STATE SERVICE
4500/udp open|filtered nat-t-ike
Значення: UDP‑скани не завжди можуть розрізнити «open» від «filtered». Але якщо повертається «closed», це сильний сигнал, що щось відкидає пакети.
Рішення: Якщо середовище сумнівне (готель/кафе), спробуйте іншу мережу або перемістіть IPsec на більш ліберальний транспорт (або використайте IKEv2 over TCP, якщо підтримується, але це вендорно‑залежно і не завжди розумно).
Завдання 7: На VPN‑шлюзі підтвердіть, що пакети приходять на WAN
cr0x@server:~$ sudo tcpdump -ni eth0 udp port 500 or udp port 4500
listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
12:10:41.103111 IP 198.51.100.25.55612 > 203.0.113.10.500: isakmp: parent_sa ikev2_init[I]
12:10:42.001901 IP 198.51.100.25.4500 > 203.0.113.10.4500: UDP-encap: NONESP-encap: isakmp: parent_sa ikev2_auth[I]
Значення: Шлюз бачить клієнта як 198.51.100.25 (публічна IP‑адреса NAT), а не приватну 192.168.1.50. Це очікувано.
Рішення: Якщо шлюз бачить UDP/500, але не UDP/4500, блок між клієнтом і шлюзом (часто сам NAT, upstream‑фаєрвол або ISP).
Завдання 8: Перевірте стан IKE/CHILD SA на strongSwan‑шлюзі
cr0x@server:~$ sudo swanctl --list-sas
ikev2-vpn: #12, ESTABLISHED, IKEv2, 3c4d5e6f7a8b9c0d_i* 9f8e7d6c5b4a3210_r
local 'vpn-gw.example' @ 203.0.113.10[4500]
remote 'roadwarrior' @ 198.51.100.25[4500]
AES_GCM_16-256/PRF_HMAC_SHA2_256/ECP_256
established 62s ago, rekeying in 51m
ike CHILD_SA: net-traffic{24} ESTABLISHED
local 10.10.0.0/16
remote 10.50.20.0/24
AES_GCM_16-256/ECP_256, 12345678_i 9abcdef0_o, rekeying in 47m
bytes_i 10492, bytes_o 8891, packets_i 120, packets_o 97
Значення: IKE SA встановлено і існує CHILD SA. Лічильники ростуть. Площина даних рухається.
Рішення: Якщо CHILD SA відсутній або застряг у «INSTALLING», діагностуйте невідповідність пропозицій, PSK/сертифікатів і селекторів трафіку. Якщо лічильники залишаються нульовими — перевіряйте маршрути, фаєрвол і MTU.
Завдання 9: Виявити «тунель вгорі, але трафік відсутній» через xfrm state/policy (Linux‑шлюз)
cr0x@server:~$ sudo ip xfrm state | sed -n '1,60p'
src 203.0.113.10 dst 198.51.100.25
proto esp spi 0x12345678 reqid 1 mode tunnel
replay-window 32 flag af-unspec
aead rfc4106(gcm(aes)) 0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 128
src 198.51.100.25 dst 203.0.113.10
proto esp spi 0x9abcdef0 reqid 1 mode tunnel
replay-window 32 flag af-unspec
aead rfc4106(gcm(aes)) 0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb 128
Значення: Kernel SAs існують. Якщо їх немає, переговори не встановили їх.
Рішення: Якщо стан існує, але політика не відповідає вашим підмережам — маєте невідповідність селекторів. Якщо обидва є — переходьте до перевірки маршрутизації і MTU.
Завдання 10: Перевірте NAT‑T keepalive, спостерігаючи періодичні малі пакети
cr0x@server:~$ sudo tcpdump -ni eth0 udp port 4500 and host 198.51.100.25
listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
12:15:00.000100 IP 198.51.100.25.4500 > 203.0.113.10.4500: UDP-encap: ESP(spi=0xc1a2b3c4,seq=0x35)
12:15:20.002210 IP 198.51.100.25.4500 > 203.0.113.10.4500: UDP-encap: ESP(spi=0xc1a2b3c4,seq=0x36)
Значення: Трафік триває. Якщо ви бачите сплеск, потім тишу, потім перепідключення — пахне таймаутом UDP‑стану.
Рішення: Увімкніть/налаштуйте NAT keepalives (на клієнті та/або шлюзі) і скоротіть інтервали DPD/keepalive, щоб витримати агресивні NAT‑пристрої.
Завдання 11: Знайти ефективний path MTU за допомогою tracepath
cr0x@server:~$ tracepath -n 10.10.1.10
1?: [LOCALHOST] pmtu 1500
1: 10.50.20.1 2.145ms
2: 10.10.1.10 5.621ms reached
Resume: pmtu 1380 hops 2 back 2
Значення: Path MTU виглядає як 1380. Це менше за Ethernet 1500 через оверхед інкапсуляції і, можливо, обмеження upstream.
Рішення: Встановіть MTU тунелю/інтерфейсу близько 1380 (або трохи нижче) і/або обмежте TCP MSS. Якщо PMTUD ненадійний — будьте консервативні.
Завдання 12: Підтвердіть симптоми PMTUD/фрагментації за допомогою DF‑пінгу
cr0x@server:~$ ping -M do -s 1400 10.10.1.10 -c 3
PING 10.10.1.10 (10.10.1.10) 1400(1428) bytes of data.
ping: local error: message too long, mtu=1500
ping: local error: message too long, mtu=1500
ping: local error: message too long, mtu=1500
--- 10.10.1.10 ping statistics ---
3 packets transmitted, 0 received, +3 errors, 100% packet loss
Значення: Ваш локальний інтерфейс MTU 1500, але ефективний MTU тунелю менший. DF‑пакет не може бути відправлений як є.
Рішення: Знизьте MTU на VPN‑інтерфейсі і/або обмежте TCP MSS (зазвичай до ~1360–1380 залежно від інкапсуляції).
Завдання 13: Обмежити TCP MSS через nftables (шлюз)
cr0x@server:~$ sudo nft add table inet mangle
cr0x@server:~$ sudo nft add chain inet mangle forward '{ type filter hook forward priority -150; }'
cr0x@server:~$ sudo nft add rule inet mangle forward tcp flags syn tcp option maxseg size set 1360
cr0x@server:~$ sudo nft list table inet mangle
table inet mangle {
chain forward {
type filter hook forward priority -150; policy accept;
tcp flags syn tcp option maxseg size set 1360
}
}
Значення: Нові TCP‑з’єднання, що проходять через шлюз, отримують MSS, обмежений до 1360.
Рішення: Якщо проблема у MTU‑чорній дірі, це зазвичай виправляє «деякі сайти працюють, інші зависають» без зміни кожного клієнта.
Завдання 14: Перевірити, що фаєрвол дозволяє UDP/500 і UDP/4500 на шлюзі
cr0x@server:~$ sudo nft list ruleset | grep -E 'udp dport (500|4500)'
udp dport 500 accept
udp dport 4500 accept
Значення: Фаєрвол шлюзу дозволяє IKE і NAT‑T.
Рішення: Якщо ці правила відсутні (або йдуть після drop), додайте їх. Якщо вони є — блок знаходиться upstream або на боці клієнта.
Завдання 15: Перевірити conntrack‑стан для UDP/4500 (NAT‑пристрій / шлюз, що робить NAT)
cr0x@server:~$ sudo conntrack -L -p udp --dport 4500 | head
udp 17 28 src=192.168.1.50 dst=203.0.113.10 sport=4500 dport=4500 src=203.0.113.10 dst=198.51.100.25 sport=4500 dport=4500 [ASSURED] mark=0 use=1
Значення: Є NAT/conntrack‑мапінг із 28 секундами в запасі (приклад). Якщо він падає до нуля і швидко зникає — ваш таймаут надто агресивний.
Рішення: Збільшіть UDP‑таймаут, якщо ви контролюєте NAT, або зменшіть інтервал keepalive, якщо не контролюєте.
Завдання 16: Підтвердіть, що VPN‑підмережа справді маршрутизується в тунель
cr0x@server:~$ ip route get 10.10.1.10
10.10.1.10 dev vti0 src 10.50.20.2 uid 0
cache
Значення: Кернел відправить трафік до 10.10.1.10 через vti0. Добре.
Рішення: Якщо маршрут виходить у WAN, у вас проблема з маршрутизацією/політичною маршрутизацією, а не з IPsec.
Три корпоративні міні‑історії з натівської війни
Міні‑історія №1: Інцидент через хибне припущення
Налаштування виглядало рутинним: партнеру потрібен був site‑to‑site IPsec‑тунель до стендової середовища. Інженер партнера надав одну «peer IP» і їх внутрішні підмережі. Ми внесли в білий список UDP/500 і UDP/4500 з тієї peer IP. Тунель піднявся в лабораторії. Всі оголосили перемогу.
Через два дні стенд пішов в темряву — тільки для того партнера. Наші дашборди показували, що IKE SA встановлено, а потім флапало кожні кілька хвилин. Захоплення пакетів на нашому шлюзі показало IKE‑пакети, що приходять з іншої публічної IP, ніж та, що ми внесли в білий список. Команда безпеки наполягала, що це атака, бо «peer IP змінився».
Хибне припущення було просте: що партнер має стабільну публічну IP. Ні — вони були за upstream‑NAT пулом і вихідна IP змінювалася в залежності від навантаження, а не від часу. Їх «peer IP» був адресою, яку показував їхній UI фаєрвола, а не тим, що інтернет бачив у вівторок.
Виправлення було так само просте і політичне: ми перестали зв’язувати тунель з однією вихідною IP і натомість зв’язали його з ідентичністю сертифіката, суворими пропозиціями і звуженими селекторами трафіку. Ми все ще обмежували IP по джерелу, але до невеликого діапазону провайдера, затвердженого через change control. Тунель перестав флапати. Інцидент закінчився. Всі вдавали, що так було заплановано з самого початку.
Урок: якщо ви матчите тільки по публічній IP, ви ставите надійність на чиюсь чужу NAT‑архітектуру. Це не «безпека». Це рулетка з паперами.
Міні‑історія №2: Оптимізація, що обернулася боком
Внутрішня мережна команда хотіла швидшого failover для віддалених користувачів. Їх логіка: зменшити keepalive/DPD чаттер, щоб зекономити пропускну здатність і CPU, бо «тунель переважно простоює». Вони подовжили інтервали NAT keepalive і збільшили таймаути DPD. На папері — менше пакетів, менше переривань, щасливіші фаєрволи.
Перший день все було нормально. Потім пішли тікети: «VPN підключається, але відключається, коли я припиняю друкувати». Ви могли налаштувати годинник: близько хвилини неактивності — і тунель ставав зомбі. UI клієнта ще показував «підключено», але трафік не прямував. Перепідключення допомагало — до наступної кави.
Ми зробили захоплення трафіку на шлюзі. Upstream NAT‑мапінг таймаутився на 30 секунд для UDP. Keepalive були розтягнуті далі. Мапінг просто помирав тихо, і наступний реальний пакет відкидався, бо NAT‑пристрій забув, куди його відправити. Коли клієнт зрештою ретранслював або перепереговорював ключі, він пробивав новий мапінг. Користувачі це відчували як випадкові розриви.
Ми відкотили «оптимізацію», встановили keepalive на значення, що пройшло тест на найгіршому NAT, який ми знайшли, і задокументували це як невід’ємний SLA‑параметр. Також нагадали команді гірку правду: економія трафіку за рахунок вимкнення keepalive часто повертається з відсотками в болі користувачів.
Міні‑історія №3: Нудна, але правильна практика, що врятувала день
Інша організація, інший настрій: сильно регульована, з контролем змін і алергією на героїчне тришування. Їхній IPsec‑стандарт вимагав дві речі, що здавалися надмірними, поки ними не скористалися: обов’язкові точки захоплення пакетів і письмовий «очікуваний вигляд пакета» для кожного тунелю (UDP/500 спочатку, потім UDP/4500, потім ESP‑in‑UDP).
Під час міграції ISP, підмножина віддалених сайтів перестала передавати трафік. Сторінки статусу тунелю виглядали зеленими. Власники додатків одразу ескалували, звісно.
Дежурний SRE витягнув рукопис і зробив нудні кроки. Захоплення на WAN: UDP/500 і UDP/4500 приходять. Захоплення на внутрішньому інтерфейсі: розшифрованого трафіку немає. Це звузило проблему до вибору політики, а не до досяжності. Вони порівняли встановлені селектори трафіку зі стандартом і виявили, що під час міграції ISP змінився NAT‑підхід у філії — вихідні порти переписувалися агресивніше, і фаєрвол філії матчив пірс по публічній IP і комбінації порту. Це зламалося, коли NAT вибрав інший порт.
Виправлення було конфігом, який у них вже був заздалегідь затверджений: матчити пірс за ідентичністю, а не за 5‑туплом. Застосували, перевірили, що лічильники пішли вгору, і закрили інцидент. Ніякої драми. Ніяких нічних дзвінків з вендором. Просто нудне задоволення від робочого runbook.
Типові помилки: симптом → корінна причина → виправлення
Цей розділ навмисно конкретний. Якщо ви не можете зіставити симптом з корінною причиною, ви не діагностуєте — ви збираєте відчуття.
1) Симптом: IKE SA встановлюється на UDP/500, а потім нічого; UDP/4500 не видно
Корінна причина: NAT‑T не погоджено або UDP/4500 заблоковано. Іноді через відключений NAT‑T на одній стороні або проміжний пристрій фільтрує «незнайомий UDP».
Виправлення: Увімкніть NAT‑T на обох пірсах. Дозвольте вхідний/вихідний UDP/4500. Перевірте tcpdump на обох кінцях. Якщо фаєрвол робить «IPsec helper», розгляньте вимкнення хелпера, якщо він псує пакети — хелпери прославилися тим, що допомагають як єнот на кухні.
2) Симптом: Тунель «вгорі», але трафік відсутній; CHILD SA відсутня
Корінна причина: Невідповідність пропозицій (шифр/PRF/DH) або невідповідність селекторів трафіку (підмережі не збігаються). NAT безпосередньо цього не спричиняє, але часто виявляє, коли пірси обирають різні ID.
Виправлення: Порівняйте пропозиції і селектори. Використовуйте вузькі, явні підмережі. Підтвердіть ID (leftid/rightid). Якщо одна сторона очікує публічну IP як ID, а інша шле FQDN, переговори можуть частково пройти й потім зірватися на створенні CHILD SA.
3) Симптом: Трафік проходить ~30–120 секунд, потім зупиняється до перепідключення
Корінна причина: Таймаут відображення NAT для UDP/4500; keepalive занадто рідкі або заблоковані.
Виправлення: Зменшіть інтервал NAT keepalive; увімкніть DPD з розумними таймерами. Якщо за CGNAT або мобільними мережами — налаштовуйте агресивніше. Слідкуйте за безперервністю UDP/4500 за допомогою tcpdump.
4) Симптом: Пінг працює, але великі завантаження зависають; деякі сайти відкриваються, інші зависають
Корінна причина: MTU/PMTUD збій через оверхед NAT‑T і блокування ICMP «Fragmentation Needed».
Виправлення: Обмежте MSS (найпростіше на шлюзі), або зменшіть MTU інтерфейсу тунелю/VTI. Перевірте tracepath і DF‑пінг. Не «виправляйте» це вимкненням функцій шифрування; вирішуйте розмір пакетів.
5) Симптом: Один користувач за NAT підключається; другий — не відправляється або витісняє першого
Корінна причина: Шлюз ідентифікує пірс лише по source IP, або поліс lookup колізує при наявності кількох клієнтів за однією публічною IP.
Виправлення: Співставляйте пірси за IKE‑ідентичністю, а не за IP. Забезпечте унікальні ID/сертифікати. Уникайте конфігів, що припускають «один пірс на IP».
6) Симптом: Працює з деяких мереж, не працює в готелях/кафе
Корінна причина: UDP/4500 фільтрується, обмежується або формується; captive portals і «безпечне» Wi‑Fi обладнання можуть бути агресивно дурними.
Виправлення: Забезпечте запасний варіант (інша мережа, альтернативний транспорт VPN або опції шлюзу). Як мінімум, виявляйте і повідомляйте зрозуміло: «Ваша мережа блокує UDP/4500.»
7) Симптом: IKE завершується, CHILD SA інсталюється, але зворотний трафік ніколи не приходить
Корінна причина: Асиметрична маршрутизація або відсутні маршрути; розшифрований трафік виходить неправильним інтерфейсом; станозберігаючий фаєрвол відкидає зворотні пакети.
Виправлення: Перевірте маршрути за допомогою ip route get. Забезпечте policy routing за потреби. Підтвердіть, що захищені підмережі маршрутизуються назад у тунель.
8) Симптом: Перепереговорювання (rekey) викликає вияви кожні N хвилин
Корінна причина: Несинхронні таймінги rekey, багаті NAT‑пристрої, що скидають стан під час rekey, або невідповідні часи життя, що призводять до перекриття SA і неправильної маршрутизації.
Виправлення: Вирівняйте lifetimes; використовуйте розумні межі rekey; оновіть прошивки; зменшіть складність. Якщо ви не можете оновити NAT‑пристрій, звузьте проблемне вікно більш детермінованими таймерами.
Короткий жарт №2: Якщо ваш VPN працює тільки до rekey — вітаємо: ви збудували генератор періодичних відмов з корпоративним шифруванням.
Чеклісти / покроковий план
Чекліст A: Підняти IPsec NAT‑T за NAT (site‑to‑site або road warrior)
- Визначте ідентичності першими. Використовуйте FQDN/сертифікатні ідентичності. Уникайте «peer має приходити з цієї IP», якщо тільки це не справді статично.
- Відкрийте потрібні порти. Вхідний/вихідний UDP/500 і UDP/4500 до шлюзу. Якщо ви все ж хочете дозволити ESP (протокол 50) — добре, але не покладайтеся на нього за NAT.
- Ввімкніть NAT‑T явно на обох пірсах, якщо платформа робить це опціональним.
- Підтвердіть, що пропозиції збігаються. Шифр, інтегритет, PRF, DH‑група; тримайте їх сучасними і сумісними.
- Уточніть селектори трафіку/підмережі. Ніяких накладань. Ніякого «0.0.0.0/0, якщо ви не маєте на увазі цього».
- Плануйте MTU/MSS. Почніть з консервативного MTU (наприклад, ~1380) або обмежте MSS на шлюзі.
- Встановіть keepalives/DPD для найгіршого NAT. Ви налаштовуєте під найвередливіший пристрій на шляху, а не під найкращу лабораторну мережу.
- Інструментуйте. Точки захоплення пакетів (вихід клієнта, WAN шлюзу). Логуйте стани IKE і CHILD SA та лічильники байтів.
Чекліст B: Коли воно зламалося, ізолюйте шар за шаром
- Форма пакета: Ви бачите UDP/500? Ви бачите UDP/4500? Ви бачите ESP‑in‑UDP?
- Стан: Чи IKE встановлено? Чи CHILD SA інсталювався? Чи лічильники інкрементуються?
- Політика: Чи селектори відповідають очікуваним підмережам? Чи маршрути правильні на обох сторонах?
- Транспоpт: Чи досягаєте ви MTU‑меж? Чи ICMP‑помилки блокуються? Чи UDP таймаутиться?
- Проміжні пристрої: Є ALG/IPsec helper/інспекція, що робить «розумні» речі? Розгляньте вимкнення цієї «розумності».
Чекліст C: Посилення, що робить NAT‑T менш крихким
- Віддавайте перевагу IKEv2. Краще управління станом; підтримує MOBIKE для мобільності, коли доступно.
- Використовуйте сертифікати для корпоративних випадків. PSK масштабуються погано і ведуть до неохайного матчінгу пірсів.
- Стандартизуйте таймери. DPD + NAT‑keepalives однакові між пірсами; уникайте рулетки з дефолтами вендорів.
- Базуйте MTU/MSS. Виберіть відому‑добру налаштування і задокументуйте її для кожного типу тунелю.
- Моніторьте лічильники байтів, а не «тунель вгорі». «Вгорі» — це поняття UI. Байти — це фізика.
Поширені запитання
1) Чому IPsec працює через мій мобільний хотспот, але не через офісний Wi‑Fi?
Різні проміжні пристрої. Офісний Wi‑Fi часто містить фаєрволи, проксі, IDS/IPS та «корисну» UDP‑фільтрацію. Мобільні хотспоти зазвичай дозволяють UDP/4500, бо оператори очікують використання VPN. Захопіть трафік: якщо UDP/4500 ніколи не виходить або не приходить, ви знайшли винуватця.
2) Чи потрібно дозволяти ESP (IP протокол 50), якщо я маю NAT‑T?
Не обов’язково. NAT‑T інкапсулює ESP всередині UDP/4500, тож шлях потребує лише UDP. Дозвіл ESP може допомогти, якщо NAT відсутній і обидві сторони віддають перевагу нативному ESP, але за NAT це ненадійно. Спочатку відкрийте UDP/500 і UDP/4500.
3) У логах пише «NAT detected», але переговори потім падають. Що робити?
Виявлення NAT означає лише те, що обидві сторони помітили трансляцію адреси. Помилка після цього зазвичай означає, що UDP/4500 блокується, NAT‑T вимкнено на одній стороні, або невідповідність ідентичностей/селекторів, що проявляється під час AUTH/CHILD SA. Підтвердіть перехід на UDP/4500 за допомогою tcpdump.
4) У чому різниця між DPD і NAT keepalives?
DPD (Dead Peer Detection) перевіряє, чи пірс живий на рівні IKE. NAT‑keepalives — це малі періодичні пакети, що тримають NAT‑мапінг живим. Часто потрібні обидва: keepalives, щоб уникнути тихого вимерзання NAT, і DPD, щоб виявити реальний збій пірса.
5) Чому тунель показує «підключено», але трафік не проходить?
Тому що «підключено» зазвичай відображає стан IKE SA. Дані вимагають CHILD SA плюс правильні маршрути/політики і ненарушений MTU. Перевірте лічильники CHILD SA і виконайте ip route get для захищеної IP. Якщо лічильники не рухаються, трафік навіть не входить у тунель.
6) Подвійний NAT (домашній роутер + ISP CGNAT) — чи це фатально для NAT‑T?
Не обов’язково, але це підвищує шанси на агресивні UDP‑таймаути і переписування портів. Якщо ви не контролюєте шлях, налаштуйте keepalive агресивно і розгляньте підтримку мобільності (MOBIKE) для клієнтів, що змінюють мережі.
7) Де краще знижувати MTU — на клієнті чи на шлюзі?
Краще обмежувати MSS на стороні шлюзу для TCP: одна зміна вирішує багато клієнтів. Для нет‑TCP протоколів або якщо ви контролюєте флот клієнтів, встановлення нижчого MTU на клієнті може бути чистішим рішенням. Перевіряйте DF‑пінг/tracepath.
8) Як визначити, чи UDP/4500 заблоковано без доступу до Wireshark на клієнті?
Перевірте захоплення на шлюзі: якщо ви ніколи не бачите UDP/4500 від того користувача/мережі — це upstream‑блок. Якщо ви бачите його, але клієнт каже «підключається», проблема, ймовірно, на хості клієнта або в ПЗ VPN. Також порівняйте поведінку між мережами: якщо працює на LTE, але не на Wi‑Fi — винний Wi‑Fi, поки не доведено інше.
9) Чи може «IPsec passthrough» на роутері зламати NAT‑T?
Так. Деякі пристрої реалізують helper/ALG, які намагаються відстежувати і переписувати IKE/ESP. Коли це робиться неправильно, вони псують пакети або стан, особливо при кількох клієнтах. Якщо можна — вимкніть IPsec‑хелпери та покладіться на простий UDP‑форвардинг/становий NAT.
10) Чому множинні користувачі за одним NAT викликають дивності на деяких шлюзах?
Якщо шлюз індексує сесії лише по source IP, два користувачі ділять одну IP і колізують. Правильні реалізації використовують IKE‑ідентичності і SPI для різнення. Виправлення — конфігурація (матчинг пірса за ID) або оновлення шлюзу, що все ще вважає NAT тимчасовою модою.
Висновок: що змінити в понеділок вранці
IPsec NAT‑T — це не магія; це шар сумісності для мережевого дизайну (NAT повсюди), який IPsec спочатку не передбачав. Коли VPN не піднімається за NAT, рідко трапляється щось містичне. Зазвичай це одна з чотирьох речей: UDP/4500 заблоковано, NAT‑мапінг таймаутиться, MTU‑чорні діри, або невідповідності ідентичностей/політик, ускладнені трансляцією адрес.
Практичні кроки:
- Інструментуйте захопленнями пакетів на виході клієнта і на WAN шлюзу. Доведіть наявність UDP/500 і UDP/4500 в обох напрямках.
- Припиніть довіряти «тунель вгорі». Моніторьте лічильники байтів CHILD SA і коректність маршрутів.
- Стандартизуйте таймери (DPD + keepalive) для найгіршого NAT, який ви очікуєте, а не для найкращої лабораторної мережі.
- Зробіть MTU нудним через MSS‑клапінг або явний MTU, а потім задокументуйте обране значення.
- Матчте пірси за ідентичністю (сертифікат/FQDN) замість крихких припущень про публічні IP, особливо для NAT‑філій і віддалих користувачів.
Зробіть це, і NAT‑T стане тим, чим мав бути завжди: непомітною інфраструктурою. Найкращий інцидент VPN — це той, про який ви ніколи не почуєте.