Маршрутизація site-to-site VPN: чому тунель «вверх», але нічого не працює (і як це виправити)

Було корисно?

Тунель «увімкнений». Панель показує зелений стан. Phase 1 встановлено, Phase 2 інстальовано, пір «підключений».
І все ж: немає ping, немає SSH, немає підключень до бази даних, немає трафіку додатків. Ви досягли класичного корпоративного
етапу: криптографія працює, мережа — ні.

Цей режим відмови настільки поширений, що заслуговує на власний рунабук. Те, що тунель увімкнений, означає лише, що пристрої домовилися про
спосіб шифрування. Це майже нічого не говорить про те, чи пакети можуть знайти тунель, пережити його й з’явитися з іншого боку так, щоб
пункт призначення прийняв і відповів.

Що «тунель увімкнений» насправді означає (і чого це не означає)

Більшість site-to-site VPN мають два окремі поняття «увімкнено»:

  • Контрольна площина увімкнена: IKE/рукостискання завершене, ключі погоджені, SA встановлено. Саме це люблять панелі керування.
  • Данна площина працює: пакети маршрутизуються в тунель, відповідають селекторам, проходять фаєрвол/NAT, переживають MTU, і зворотний трафік повертається тим же шляхом.

Проблема майже завжди в данній площині. Конкретно:

  • Маршрутизація: пакети ніколи не потрапляють у тунель (невірні маршрути, відсутні маршрути, неправильне політичне маршрутизування, неправильний VRF).
  • Селектори / політика: пакети доходять до пристрою, але не відповідають селекторам VPN (policy-based IPsec) або AllowedIPs (WireGuard).
  • NAT / фаєрвол: пакети відповідають тунелю, але їх NAT-ять у щось, чого інша сторона не очікує, або блокуються станозалежними правилами.
  • Шлях/MTU: пакети зникають через фрагментацію, PMTUD-блекхоли або через неналаштований MSS.
  • Асиметрія: пакети йдуть через VPN, а повертаються через інтернет (або інший WAN), що тригерить фаєрволи, rp_filter або просто «немає маршруту назад».

Єдиний надійний тест простий: надішліть пакет від хоста за Site A до хоста за Site B і доведіть — за допомогою знімань та лічильників — де він зупиняється.

Цікаві факти та історичний контекст (що й досі створює проблеми)

Трохи історії пояснює, чому сучасна маршрутизація VPN нагадує археологію: різні епохи мереж залишили по собі різні припущення, а ваша поточна конфігурація — це викопний мікс.

  1. IPsec передував «хмарним мережам»: основні специфікації формувалися, коли мережі були статичними й приватними. Сьогодні ми прив’язуємо його до NAT, оверлеїв і динамічної маршрутизації.
  2. Policy-based VPN були першими в багатьох фаєрволах: замість «маршрувати трафік в інтерфейс», ранні рішення порівнювали пакети з селекторами і шифрували їх. Легко для малих налаштувань, боляче в масштабі.
  3. NAT-Traversal (NAT-T) існує тому, що NAT зламав IPsec: ESP не виживав за звичайних NAT-пристроїв, тому UDP-инкапсуляція на порті 4500 стала стандартним виходом.
  4. PMTUD-блекхоли старіші за більшість команд розробки: ICMP «Fragmentation Needed» блокували «з міркувань безпеки» давно, і інкапсуляція VPN робить це гірше.
  5. «Split tunnel» колись був дебатами клієнтських VPN: тепер той самий концепт з’являється в site-to-site у вигляді селективної маршрутизації, кількох тунелів і політик трафіку.
  6. BGP поверх IPsec став популярним, бо люди ненадійні: статичні маршрути працюють, поки не з’явиться третій сайт — тоді ви на один spreadsheet від відмови.
  7. Reverse path filtering (rp_filter) в Linux — реакція на спуфінг: це добре… поки ваша маршрутизація асиметрична, тоді воно починає скидати легітимний VPN-трафік.
  8. WireGuard навмисно мінімалістичний: він дає тунель і ключі, а не політичні рамки. Неправильне AllowedIPs — сучасний еквівалент невідповідності селекторів.
  9. Перекриття адрес RFC1918 — корпоративна традиція: 10.0.0.0/8 був приватним простором, а не універсальним. Злиття компаній зробило його універсальним у реальному житті.

Швидкий план діагностики (знайти вузьке місце швидко)

Коли хтось каже «VPN увімкнений, але нічого не працює», не починайте з зміни криптографічних налаштувань. Так ви перетворите баг маршрутизації на довгу ніч. Почніть з короткого циклу: доведіть шлях, доведіть політику, доведіть зворотний шлях.

Перший крок: доведіть, що пакет потрапляє на VPN-шлюз

  1. З хоста за Site A, пропінгуйте/запустіть traceroute до конкретного хоста за Site B (не «підмережі»). Оберіть одну IP-адресу, яку ви контролюєте.
  2. На VPN-шлюзі Site A, зніміть трафік на LAN-інтерфейсі, щоб підтвердити, що пакет приходить.
  3. Перевірте рішення маршрутизатора: чи відправляє він цей пункт призначення в інтерфейс тунелю/VTI або збігається з політикою?

Другий крок: доведіть, що пакет відповідає політиці/селекторам

  1. Для IPsec, перевірте, що встановлені SA включають точні вихідні/призначені підмережі, які ви тестуєте.
  2. Для WireGuard, перевірте, що AllowedIPs включає віддалену підмережу, і що віддалий пір має маршрут назад.
  3. Подивіться на лічильники байтів SA. Якщо вони лишаються нульовими під час генерації трафіку, ваш пакет не входить у політику тунелю.

Третій крок: доведіть зворотний шлях і стан з’єднання

  1. Зніміть трафік на LAN-інтерфейсі віддаленого сайту: чи пакет з’являється декриптованим?
  2. Якщо він приходить, зніміть відповідь: чи вона маршрутизується назад у тунель?
  3. Перевірте стан фаєрволу та rp_filter з обох сторін.

Четвертий крок: перевіряйте MTU/MSS тільки після базової перевірки маршрутизації/політики

Проблеми з MTU можуть виглядати як «нічого не працює», але зазвичай проявляються як «ping працює, TCP застрягає» або «малі запити працюють, великі зависають».
Не звинувачуйте одразу MTU, бо це модно.

Жарт №1: Панель VPN, що каже «Up», як індикатор кавоварки «Ready». Це не гарантує, що ви отримаєте каву.

Ментальна модель: чотири ворота, які має пройти кожен пакет

Ось модель, якою я користуюся при налагодженні. Кожен пакет, що намагається перетнути site-to-site VPN, має пройти через чотири ворота:

Ворота 1: Чи джерельний хост може дістатися до свого шлюзу, і чи це правильний шлюз?

Дивовижна кількість «VPN»-проблем фактично виявляється «неправильним шлюзом за замовчуванням», «фаєрвол хоста» або «не та VLAN». Якщо ваш хост не
відсилає трафік на VPN-шлюз (або на маршрутизатор, що знає про VPN), ви налагоджуєте не той пристрій.

Ворота 2: Чи шлюз маршрутизує пакет у тунель?

Route-based VPN покладаються на таблиці маршрутизації (статичні, OSPF/BGP, політична маршрутизація). Policy-based VPN покладаються на селектори:
«якщо пакет відповідає цьому ACL, зашифруй його». Обидва можуть бути неправими у нудних, але фатальних випадках.

Класичний випадок «тунель увімкнений, але нічого не працює» — відсутній маршрут до віддаленої підмережі на стороні LAN, тож пакети
йдуть в інтернет замість потрапляння в політику VPN.

Ворота 3: Чи тунель приймає пакет?

IPsec має трафік-селектори (локальні/віддалені підмережі). Якщо ваш пакет не відповідає, його не зашифрує та не пропустить SA, який ви вважаєте потрібним.
WireGuard має AllowedIPs, що одночасно є крипто- та маршрутизуючою політикою: воно вирішує, що шифрувати й що приймати від піра.

Ворота 4: Чи віддалена сторона може доставити пакет і повернути його симетрично?

Навіть якщо віддалена сторона отримує пакет, вона має доставити його до хоста призначення й отримати відповідь тим самим шляхом.
Відповіді, що виходять іншим шляхом, — ворог станозалежних фаєрволів, conntrack, очікувань NAT і rp_filter.

Практичні завдання з командами: перевірити, вирішити, виправити

Наступні завдання призначені для виконання під час інциденту. Кожне містить: команду, що означає її вивід, і рішення, яке потрібно прийняти.
Команди наведено для Linux, бо це поширено для VPN-шлюзів, jump-хостів і тестових машин — навіть якщо ваш VPN-пристрій — це фаєрвол-апарат.

Завдання 1: Перевірити, чи хост відправляє трафік до правильного шлюзу

cr0x@server:~$ ip route show default
default via 10.20.0.1 dev eth0 proto dhcp src 10.20.0.55 metric 100

Значення: Хост використовує 10.20.0.1 як шлюз за замовчуванням. Якщо ваш VPN-шлюз/маршрутизатор не 10.20.0.1 (або не знає маршрутів до віддаленого сайту),
ваш пакет навіть не матиме шансів.

Рішення: Якщо шлюз за замовчуванням неправильний, виправте DHCP/статичну конфігурацію або додайте конкретний маршрут до віддаленої підмережі через правильний маршрутизатор.

Завдання 2: Підтвердити наявність маршруту до віддаленої підмережі (з погляду хоста)

cr0x@server:~$ ip route get 172.31.40.10
172.31.40.10 via 10.20.0.1 dev eth0 src 10.20.0.55 uid 1000
    cache

Значення: Трафік до 172.31.40.10 йде через 10.20.0.1. Той маршрутизатор має мати маршрут у VPN, інакше ви «витікаєте» в інший шлях.

Рішення: Якщо next hop не ваш очікуваний VPN-обізнаний маршрутизатор, додайте більш специфічний маршрут або виправте оголошення маршрутів.

Завдання 3: Перевірити маршрутизацію на VPN-шлюзі (route-based VPN)

cr0x@server:~$ ip route get 172.31.40.10
172.31.40.10 dev vti0 src 10.20.0.1 uid 0
    cache

Значення: Шлюз відправлятиме це призначення через vti0 (віртуальний тунельний інтерфейс). Добрий знак: маршрутизація вказує на тунель.

Рішення: Якщо маршрут виходить через WAN-інтерфейс, вам потрібні маршрути (статичні/BGP) або політична маршрутизація, щоб спрямувати його в тунель.

Завдання 4: Виявити політичну маршрутизацію або кілька таблиць (Linux-шлюзи)

cr0x@server:~$ ip rule show
0:      from all lookup local
1000:   from 10.20.0.0/24 lookup 100
32766:  from all lookup main
32767:  from all lookup default

Значення: Трафік з джерела 10.20.0.0/24 використовує таблицю маршрутизації 100. Якщо ваш VPN-маршрут знаходиться в main, але трафік використовує таблицю 100,
тунель не буде використано.

Рішення: Помістіть VPN-маршрут у правильну таблицю або відкоригуйте правило. Ставтеся до політичної маршрутизації як до продукційного коду: переглядайте, тестуйте, документуйте.

Завдання 5: Підтвердити, що IP forwarding увімкнено на Linux VPN-шлюзі

cr0x@server:~$ sysctl net.ipv4.ip_forward
net.ipv4.ip_forward = 1

Значення: Форвардинг увімкнено. Якщо 0 — шлюз декоративний маршрутизатор.

Рішення: Якщо вимкнено, увімкніть і зробіть постійним у /etc/sysctl.conf або як drop-in. Потім повторіть тест трафіку.

Завдання 6: Перевірити rp_filter (вбивця асиметрії)

cr0x@server:~$ sysctl net.ipv4.conf.all.rp_filter net.ipv4.conf.eth0.rp_filter
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.eth0.rp_filter = 1

Значення: Встановлено суворе зворотне фільтрування шляхів. Якщо зворотний трафік асиметричний (поширено при dual-WAN або кількох маршрутах),
Linux може скидати пакети як «спуфінг».

Рішення: Якщо очікується асиметрія, встановіть властивість у вільний режим (2) на відповідних інтерфейсах, або виправте симетрію маршрутизації (бажано).

Завдання 7: Перевірити WireGuard-піра і AllowedIPs (тунель увімкнений, трафік ні)

cr0x@server:~$ sudo wg show wg0
interface: wg0
  public key: v4bq6nFh1lEoC4QyM2u0n9bZ1gYpP7oGQf+XvYdW2mU=
  listening port: 51820

peer: q0P3sZtVd8l0Rk2m1yG1CwVf1mQf0Qx4lQw2uXn8G3E=
  endpoint: 198.51.100.20:51820
  allowed ips: 172.31.40.0/24
  latest handshake: 18 seconds ago
  transfer: 12.34 KiB received, 9.87 KiB sent

Значення: Рукостискання недавнє і лічильники передачі зростають. allowed ips включає 172.31.40.0/24, тож вихідне шифрування для цієї підмережі має відбуватися.

Рішення: Якщо лічильники не змінюються під час тестування, ваш трафік не відповідає AllowedIPs, або хост обходить wg0 у маршрутизації.

Завдання 8: Підтвердити створення маршрутів для WireGuard (Linux)

cr0x@server:~$ ip route show dev wg0
172.31.40.0/24 proto kernel scope link src 10.99.0.1

Значення: Ядро має маршрут до віддаленої підмережі через wg0. Якщо відсутній, можливо, ви використовуєте Table = off або кастомний дизайн маршрутизації.

Рішення: Додайте маршрут явно або налаштуйте конфігурацію WireGuard, щоб вона програмувала маршрути як передбачено.

Завдання 9: Переглянути IPsec SA і трафік-селектори (strongSwan)

cr0x@server:~$ sudo swanctl --list-sas
siteA-siteB: #3, ESTABLISHED, IKEv2, 4c2b1b3c3e5b2a6f_i* 6a8d9c0b2a1f4e3d_r
  local  '203.0.113.10' @ siteA
  remote '198.51.100.20' @ siteB
  AES_GCM_16-256/PRF_HMAC_SHA2_256/ECP_256
  established 241s ago, rekeying in 53m
  siteA-siteB-child: #5, INSTALLED, TUNNEL, ESP:AES_GCM_16-256
    local 10.20.0.0/24
    remote 172.31.40.0/24
    bytes_i 18240, bytes_o 16512, rekeying in 49m

Значення: Child SA інстальовано зі селекторами 10.20.0.0/24 ↔ 172.31.40.0/24. Лічильники байтів відмінні від нуля, тож трафік проходить через SA.

Рішення: Якщо селектори не відповідають тестуваним мережам, виправте локальні/віддалені трафік-селектори. Якщо байти лишаються 0, пакети не відповідають або не досягають шлюзу.

Завдання 10: Перевірити, чи правила фаєрвол/NAT заважають (nftables)

cr0x@server:~$ sudo nft list ruleset | sed -n '1,120p'
table inet filter {
  chain forward {
    type filter hook forward priority filter; policy drop;
    ct state established,related accept
    iifname "eth0" oifname "vti0" ip saddr 10.20.0.0/24 ip daddr 172.31.40.0/24 accept
    iifname "vti0" oifname "eth0" ip saddr 172.31.40.0/24 ip daddr 10.20.0.0/24 accept
  }
}
table ip nat {
  chain postrouting {
    type nat hook postrouting priority srcnat; policy accept;
    oifname "eth1" masquerade
  }
}

Значення: Політика forward — drop; лише явні правила дозволяють LAN↔VPN. NAT masquerade застосовується до eth1 (WAN), а не до тунелю.

Рішення: Якщо NAT випадково застосовується до тунельного трафіку (masquerade на всіх інтерфейсах), виправте це. Якщо правила forward відсутні, додайте явні дозволи для VPN-підмереж.

Завдання 11: Шукати NAT на шляху VPN (legacy iptables)

cr0x@server:~$ sudo iptables -t nat -S
-P PREROUTING ACCEPT
-P INPUT ACCEPT
-P OUTPUT ACCEPT
-P POSTROUTING ACCEPT
-A POSTROUTING -o eth1 -j MASQUERADE

Значення: NAT застосований лише до WAN-інтерфейсу eth1. Добре. Якщо бачите MASQUERADE без -o eth1, можливо ви ненавмисно NAT-ите VPN-трафік.

Рішення: Звужуйте правила NAT, щоб виключити VPN-підмережі, або обмежте masquerade лише WAN-інтерфейсом.

Завдання 12: Доведіть, де пакети вмирають, за допомогою tcpdump (обидві сторони)

cr0x@server:~$ sudo tcpdump -ni eth0 host 172.31.40.10
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
14:02:11.102938 IP 10.20.0.55 > 172.31.40.10: ICMP echo request, id 3812, seq 1, length 64

Значення: Запит доходить до LAN-інтерфейсу шлюзу. Далі зніміть на інтерфейсі тунелю, щоб побачити, чи він форвардиться/шифрується.

Рішення: Якщо він з’являється на LAN, але не на тунелі — проблема в маршрутизації/політиці/фаєрволі на шлюзі. Якщо на тунелі, але не на віддалому LAN — проблема в політиці тунелю/MTU/віддалому фаєрволі.

Завдання 13: Перевірити лічильники інтерфейсу тунелю (route-based VPN)

cr0x@server:~$ ip -s link show dev vti0
7: vti0:  mtu 1436 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/ipip 0.0.0.0 brd 0.0.0.0
    RX:  bytes packets errors dropped  missed   mcast
       82912     612      0      0       0       0
    TX:  bytes packets errors dropped carrier collsns
       74488     581      0      0       0       0

Значення: Інкремент лічильників означає, що трафік надсилається/отримується на VTI. Якщо TX інкрементується, а RX стоїть на місці, повернення відсутнє або заблоковане.

Рішення: Якщо рух тільки в одному напрямку, зосередьтесь на зворотному маршруті, віддаленому фаєрволі, віддалених селекторах або NAT.

Завдання 14: Діагностувати MTU/PMTUD за допомогою ping і DF-біту

cr0x@server:~$ ping -M do -s 1400 -c 3 172.31.40.10
PING 172.31.40.10 (172.31.40.10) 1400(1428) bytes of data.
ping: local error: message too long, mtu=1436
ping: local error: message too long, mtu=1436
ping: local error: message too long, mtu=1436

--- 172.31.40.10 ping statistics ---
3 packets transmitted, 0 received, +3 errors, 100% packet loss, time 2032ms

Значення: Ваш локальний інтерфейс MTU (1436) не може відправити 1428-байтові пакети з DF. Це очікувано, якщо MTU тунелю менший через інкапсуляцію.

Рішення: Застосуйте MSS clamp для TCP, зменшіть MTU на тунельному інтерфейсі або забезпечте, щоб ICMP «frag needed» не блокувався. Якщо малі пінги працюють, а TCP застрягає — швидше за все справа в MTU.

Завдання 15: Перевірити стан MSS clamping (приклад nftables)

cr0x@server:~$ sudo nft list chain inet mangle forward
table inet mangle {
  chain forward {
    type filter hook forward priority mangle; policy accept;
    oifname "vti0" tcp flags syn tcp option maxseg size set 1360
  }
}

Значення: SYN-пакети, що виходять тунелем, мають MSS 1360. Це запобігає відправленню TCP-сегментів, що перевищують MTU тунелю.

Рішення: Якщо бачите проблеми PMTUD, реалізуйте MSS clamping на крайовому обладнанні. Це не елегантно; але ефективно.

Завдання 16: Прослідкувати шлях і виявити «неправильний вихід» маршрутизації

cr0x@server:~$ traceroute -n 172.31.40.10
traceroute to 172.31.40.10 (172.31.40.10), 30 hops max, 60 byte packets
 1  10.20.0.1  0.431 ms  0.382 ms  0.369 ms
 2  203.0.113.1  2.171 ms  2.133 ms  2.114 ms
 3  198.18.0.5  6.990 ms  6.945 ms  6.903 ms

Значення: Трафік виходить у WAN (203.0.113.1) замість тунелю. Це запах «відсутній маршрут».

Рішення: Виправте маршрути, щоб спрямувати 172.31.40.0/24 у тунель. Якщо ви покладаєтеся на BGP, перевірте, що префікс рекламовано і прийнято.

Завдання 17: Підтвердити BGP-вивчені маршрути та next-hop (FRR)

cr0x@server:~$ sudo vtysh -c "show ip route 172.31.40.0/24"
Routing entry for 172.31.40.0/24
  Known via "bgp", distance 20, metric 0, best
  Last update 00:03:12 ago
  * 10.255.255.2, via vti0

Значення: BGP надає маршрут, next hop через vti0. Це бажано для route-based VPN з динамічною маршрутизацією.

Рішення: Якщо маршрут відсутній або вказує кудись ще, перевірте стан сесії BGP, фільтри маршрутів і досяжність next-hop.

Завдання 18: Перевірити conntrack на предмет дивностей станозалежного фаєрвола

cr0x@server:~$ sudo conntrack -L -p icmp | head
icmp     1 29 src=10.20.0.55 dst=172.31.40.10 type=8 code=0 id=3812 [UNREPLIED] src=172.31.40.10 dst=10.20.0.55 type=0 code=0 id=3812

Значення: Шлюз бачить вихідні echo request, але немає відповідей. Якщо очікуєте відповіді, їх не повертають або їх скидають до того, як conntrack їх побачить.

Рішення: Зніміть трафік на віддаленій стороні, перевірте зворотний маршрут і віддалений фаєрвол. Якщо відповіді повертаються інтерфейсом іншого типу — це асиметрія.

Поширені помилки: симптоми → корінна причина → виправлення

1) Тунель показує «увімкнено», але лічильники байтів SA залишаються нульовими

Симптоми: IKE встановлено; ping/таймаути; лічильники не рухаються.

Корінна причина: Трафік ніколи не відповідає селекторам/AllowedIPs або не доходить до шлюзу через маршрутизацію.

Виправлення: Перевірте маршрути до віддаленої підмережі на хості-джерелі та шлюзі. Для policy-based IPsec переконайтеся, що точні вихідні/призначені підмережі відповідають child SA. Для WireGuard — переконайтеся, що AllowedIPs включають призначення і що ядро має маршрути до wg0.

2) Односторонній трафік: A може дістатися B, B не може дістатися A (або відповіді ніколи не приходять)

Симптоми: TCP SYN бачиться на віддаленому, SYN-ACK не повертається; ICMP request бачиться, відповідь відсутня; VTI TX зростає, а RX плоский.

Корінна причина: Відсутній зворотний маршрут на віддалому LAN/маршрутизаторі; асиметрична маршрутизація через кілька uplink; NAT на одній стороні змінює вихідну IP несподівано.

Виправлення: Додайте/рекламуйте зворотний маршрут для вихідної підмережі через VPN. Забезпечте виключення з NAT для VPN-підмереж. Якщо є кілька виходів, забезпечте симетрію за допомогою політики маршрутизації або дизайну.

3) Ping працює, але HTTPS/SSH зависає або великі передачі зупиняються

Симптоми: Малі пакети проходять; TCP-з’єднання встановлюються, але зависають під час передачі даних; окремі додатки падають дивним чином.

Корінна причина: MTU/PMTUD через накладні витрати інкапсуляції; ICMP блокується; MSS занадто велике.

Виправлення: Застосуйте MSS clamping для TCP трафіку, що йде в тунель. Встановіть MTU тунельного інтерфейсу відповідно. Дозвольте ICMP «Fragmentation Needed» на релевантних шляхах, якщо ваша політика безпеки це дозволяє.

4) Працює для однієї підмережі, не працює для іншої

Симптоми: Деякі хости можуть дістатися віддалих; інші — ні; одна VLAN працює, інша — ні.

Корінна причина: Селектори/AllowedIPs включають лише одну підмережу; відсутні маршрути для додаткових підмереж; правила фаєрволу занадто вузькі.

Виправлення: Розширте селектори/AllowedIPs симетрично з обох сторін. Додайте маршрути та правила фаєрволу для кожної підмережі. Для IPsec пам’ятайте, що обидві сторони мають погодитися на трафік-селектори.

5) Трафік працює до рекі-ї, потім помирає

Симптоми: Стабільно кілька хвилин/годин, потім раптово чорна діра після рекі-ї; панель все ще показує «тунель увімкнений».

Корінна причина: Розбіжності при рекі-ї, перев’язка NAT, таймаути станозалежного фаєрвола або відмінності у DPD, що призводять до десинхронізації child SA.

Виправлення: Узгодьте lifetimes/rekey margins; забезпечте стабільність NAT-T; перевірте налаштування DPD. Моніторьте події інсталяції/видалення SA, а не лише стан IKE.

6) Випадкові дропи під навантаженням, особливо UDP або VoIP

Симптоми: Джіттер, пропуски, сплески втрат; ping стабільний, але реальний час поганий.

Корінна причина: Відсутність QoS всередині тунелю; вузьке місце CPU на шифруванні; черги і bufferbloat; фрагментація UDP-пакетів.

Виправлення: Проведіть профілювання CPU і черг інтерфейсів. Маркуйте/формуйте трафік перед шифруванням, якщо можливо. Зменшіть MTU для UDP-насичених додатків. Розгляньте апаратне оффлоад або потужніші інстанси.

7) Все ламається лише в одному напрямку після «закріплення безпеки»

Симптоми: Після змін в політиці безпеки VPN-трафік помирає; локальний трафік у порядку.

Корінна причина: rp_filter встановлено в суворий режим, змінено політику за замовчуванням фаєрвола або глобально заблоковано ICMP.

Виправлення: Переоцініть rp_filter і правила форварду у контексті VPN-дизайну. Додайте явні правила дозволу для VPN-підмереж. Дозвольте необхідні ICMP типи для PMTUD або компенсуйте це MSS clamp.

8) Перекривання мереж: обидві сторони використовують 10.0.0.0/8

Симптоми: Трафік іде до локальних ресурсів замість тунелю; маршрути конфліктують; залежність від найдовшого префікса і локальної політики дає непослідовні результати.

Корінна причина: Перекриття адресного простору. Маршрутизація VPN не може відрізнити «їхню 10.20.0.0/24» від «нашої 10.20.0.0/24».

Виправлення: Використайте NAT (обережно) або проведіть перекладання адрес. Якщо робите NAT, робіть це послідовно та документуйте перекладені діапазони; оновіть селектори та правила фаєрволу відповідно.

Три корпоративні міні-історії з практики

Міні-історія 1: Інцидент, спричинений хибним припущенням

Середня компанія запустила «простий» site-to-site IPsec VPN між HQ і складом. Тунель піднявся. UI фаєрвола усміхався.
Команда складу намагалася дістатися inventory API в HQ. Нічого. Підвищили ескалацію. Звісно, перший крок — пересмикнути ключі і
знову запускати IKE-налагодження, бо так роблять люди, коли хвилюються.

Хибне припущення було: «Якщо тунель увімкнений, фаєрвол пропустить трафік через нього». Насправді налаштування було policy-based IPsec.
Лише трафік, що відповідав певній парі підмереж, шифрувався. Тим часом новий inventory API був розгорнутий в іншій VLAN у HQ,
з підмережею, яка не входила до phase 2 селекторів.

Хости складу могли дістатися старої підмережі без проблем. Ніхто не помітив, бо чеклист тестування був «пропінгуй будь-який хост HQ».
Нова підмережа API? Не була в селекторах, тож вона маршрутизувалася за замовчуванням в інтернет і далі відкидалася. Лічильники SA лишалися практично нульовими,
але ніхто на це не дивився, бо UI не показував їх помітно.

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

Міні-історія 2: Оптимізація, що зіграла злий жарт

Глобальне підприємство мало кілька site-to-site тунелів у центральний хаб. Латентність була важлива. Хтось запропонував оптимізацію:
підвищити MTU і дозволити PMTUD «вирішити сам» проблему. Зміни розгорнули на кількох шлюзах, і у синтетичних пінгах все було гаразд. Всі пішли додому раніше.

Два дні потому фінансовий додаток почав таймаутитись лише при завантаженні великих звітів. Аутентифікація — ок; малі сторінки — ок.
Завантаження зависли. Тунель був увімкнений; лічильники рухалися; CPU у порядку. Проблема пахла найгіршим типом: «періодична».

Повернення виявилось класичним: PMTUD покладався на ICMP-повідомлення, які блокувалися політикою безпеки десь між сайтами.
При нових MTU інкапсульовані пакети перевищували реальний MTU шляху. Мережа не могла повідомити «потрібна фрагментація», тож пакети зникали.
TCP повторював спроби до таймауту.

Виправлення — clamp MSS на виході тунелю і зменшити MTU тунеля до безпечного значення, що працює по всіх шляхах.
Також відкоригували політику фаєрволу, щоб дозволити ті ICMP-типи, які потрібні для PMTUD — де це було можливо.
«Оптимізацію» відкотили, і урок закарбувався: MTU — це спільна правда, а не персональна вподобайка.

Міні-історія 3: Нудна, але правильна практика, що врятувала день

SaaS-компанія тримала route-based VPN зі свого основного дата-центру до кількох партнерів. У них була звичка, що здавалась нудною:
кожен тунель мав односторінковий «контракт», що описував локальні/віддалені префікси, NAT-політику, MTU тунелю та очікуваний next-hop маршрутизації.
Вони також тримали базовий «відомий добрий» рецепт для знімання пакетів і перевіряли його щоквартально.

Одного дня партнер повідомив, що не може дістатися конкретної підмережі. Тунель увімкнений. Команда партнера наполягала «нічого не змінювали».
On-call з SaaS відкрив контракт, потім швидко перевірив маршрут: рекламований префікс від партнера тихо зменшився з /16 до /24.
BGP ще був вгору, але набір маршрутів не відповідав тому, що очікували їх правила фаєрволу.

Оскільки практика була нудно послідовною, on-call мав базову лінію для порівняння. Він міг сказати з доказами: «тунель у порядку,
але ваша сторона більше не рекламує агрегат; ми бачимо лише цей більш специфічний префікс». Це швидко закінчило питання про звинувачення.

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

Жарт №2: BGP — як офісна політика: всі кажуть, що діляться інформацією, але вам все одно потрібно перевірити, що саме вони сказали.

Контрольні списки / покроковий план

A. Контрольний список інциденту (15–30 хвилин, щоб ізолювати)

  1. Оберіть одну пару для тесту: конкретний хост-джерело і хост-призначення з IP-адресами, до яких ви маєте доступ.
  2. Підтвердьте локальну маршрутизацію хоста: ip route get <dest> має вказувати на VPN-обізнаний шлюз/маршрутизатор.
  3. Підтвердьте, що шлюз бачить трафік на LAN: зніміть трафік на LAN-інтерфейсі.
  4. Підтвердьте, що шлюз маршрутизує в тунель або відповідає політиці: ip route get (route-based) або лічильники SA/селектори (policy-based).
  5. Підтвердьте, що лічильники тунелю інкрементуються: лічильники VTI, байти SA, лічильники WireGuard.
  6. Підтвердьте, що віддалена сторона отримує декриптований трафік: зніміть трафік на віддалому LAN.
  7. Підтвердьте зворотний шлях: зніміть відповідь, що виходить з віддаленої сторони, і переконайтесь, що вона маршрутизується назад у тунель.
  8. Перевірте правила фаєрволу в обох напрямках: forward/ACL та виключення з NAT.
  9. Тільки потім перевіряйте MTU/MSS: якщо TCP зависає або великі пакети не проходять.
  10. Задокументуйте точку відмови: «помирає до тунелю», «помирає в політиці тунелю», «помирає після декрипту» або «зламаний зворотний шлях».

B. Контрольний список правильного побудови (перед запуском у прод)

  1. Обирайте route-based, якщо немає вагомої причини інакше: воно краще масштабується і спрощує налагодження.
  2. Визначте динамічну маршрутизацію чи статичні маршрути: якщо буде більше кількох префіксів, обирайте BGP з чіткими фільтрами.
  3. Запишіть префіксні контракти: локальні й віддалені префікси, включно з очікуваннями зростання.
  4. Явно визначте NAT-політику: виключення з NAT для VPN-трафіку й перекладені діапазони, якщо є перекриття.
  5. Встановіть MTU/MSS свідомо: не «як вийде». Виміряйте, потім clamp.
  6. Плануйте для асиметрії: один вихід найпростіший; якщо неможливо, забезпечте політику маршрутизації і перевірте rp_filter.
  7. Моніторьте сигнали данної площини: байти SA, лічильники інтерфейсу VTI, падіння пакетів, рекі-и — панелі мають показувати трафік, а не лише «підключено».
  8. Створіть тестовий набір: ping, TCP connect, HTTP-запит, велика передача і DNS — запускайте після кожної зміни.

C. Контрольний список змін (щоб не нашкодити продукції)

  1. Перед зміною: зафіксуйте базові селектори SA, маршрути і значення MTU.
  2. Робіть одну зміну за раз: спочатку маршрути, потім політику, потім фаєрвол, потім MTU.
  3. Після зміни: перевірте тим же тест-паром і порівняйте лічильники до/після.
  4. Майте відкат: тримайте попередні конфіги під рукою і знайте, як відкрутити маршрути та правила фаєрволу.

Питання та відповіді

1) Чому VPN каже «увімкнено», якщо трафік не проходить?

Тому що «увімкнено» зазвичай означає, що контрольна площина IKE встановлена. Данна площина залежить від маршрутизації, селекторів/AllowedIPs, фаєрволу/NAT і зворотних шляхів.

2) Який найшвидший доказ того, що проблема в маршрутизації?

Запустіть ip route get <remote-host> на шлюзі. Якщо він вказує на WAN-інтерфейс замість тунелю/VTI — ви знайшли проблему.
Також traceroute, що показує інтернет-хопи замість шляху через тунель, — явний сигнал.

3) Що таке «traffic selectors» в IPsec і як вони ламають систему?

Traffic selectors визначають, які вихідні/призначені підмережі child SA шифруватиме. Якщо ваш реальний трафік використовує підмережу, якої немає в селекторах,
він не співпаде і не буде зашифрований. Результат: тунель увімкнений, трафік не працює.

4) WireGuard рукопощання є, але я не можу дістатися віддаленої підмережі. Яка звичайна причина?

Неправильно налаштоване AllowedIPs або відсутні маршрути в ядрі. WireGuard може виконати рукопощання без корисної маршрутизації. Також перевірте, чи віддалий бік має маршрут назад до вашої підмережі.

5) Як визначити, що NAT ламає мій site-to-site VPN?

Якщо віддалий бік бачить трафік із транслітованою вихідною IP (не вашу реальну локальну підмережу), це може не співпасти з селекторами або правилами фаєрволу.
На Linux-шлюзах перевірте правила NAT і переконайтеся, що VPN-підмережі виключені з masquerade.

6) Чому ping працює, але TCP не працює?

Зазвичай це MTU/MSS. ICMP echo за замовчуванням використовує малі пакети; TCP може домовитися про великі сегменти, які відкидаються через накладні витрати інкапсуляції і заблокований PMTUD.
Застосуйте clamp MSS і встановіть консервативний MTU тунелю.

7) Чи потрібен мені BGP поверх VPN?

Якщо у вас кілька префіксів, кілька сайтів, резервні лінії або ви очікуєте зростання — так, BGP зменшує людські помилки. Якщо це справді одна підмережа з обох сторін і ніколи не зміниться, статичні маршрути можуть бути достатні.

8) У чому різниця між policy-based та route-based VPN для налагодження?

Policy-based: налагоджуєте селектори/ACL-матчі і лічильники SA. Route-based: налагоджуєте маршрути до тунельного інтерфейсу. Route-based зазвичай простіше для розуміння і масштабування.

9) Як може виникнути асиметрична маршрутизація, якщо є лише один тунель VPN?

Тому що решта мережі може мати кілька виходів. Вихідний пакет може йти тунелем, а відповідь — іншим WAN або іншим маршрутизатором з іншим набором маршрутів.
Станозалежні фаєрволи і rp_filter цього не люблять. Виправляйте дизайном маршрутизації, а не надією.

10) Що слід моніторити, щоб це не стало щомісячним сюрпризом?

Моніторьте лічильники байтів SA, лічильники інтерфейсу VTI, частоту рекі-їв, падіння пакетів і симптоми MTU (TCP retransmits).
«Тунель увімкнений» — це не метрика; це настрій.

Висновок: кроки, які ви можете зробити вже сьогодні

Якщо запам’ятати одне: те, що VPN-тунель увімкнений, доводить, що два кінці домовилися про шифрування. Це не доводить, що ваші пакети маршрутизуються, відбираються, форвардяться і повертаються.
Слідкуйте за VPN як за мережевим шляхом із контрольної та данної площинами і налагоджуйте його як будь-який інший маршрут.

Практичні кроки:

  1. Створіть одну тестову пару (хост-джерело і хост-призначення) і зафіксуйте її у вашому рунабуку.
  2. Додайте моніторинг данної площини: байти SA і лічильники тунельних інтерфейсів з алертами на «увімкнено, але простої під час бізнес-годин».
  3. Стандартизуйте route-based дизайни, де можливо, і документуйте префіксні контракти та NAT-правила.
  4. Встановіть MTU/MSS свідомо, потім тестуйте великими передачами — не лише пінгами.
  5. Наступного разу, коли хтось скаже «VPN увімкнений, але нічого не працює», проганяйте швидкий план діагностики і відмовляйтеся торкатися крипто-параметрів, доки маршрутизація не буде доведена.

“Everything fails, all the time.” — Werner Vogels

← Попередня
Debian 13 «Read-only file system»: найшвидший шлях до причини й відновлення
Наступна →
ZFS на Proxmox проти VMFS на ESXi: Снапшоти, продуктивність, відновлення та реальні підводні камені

Залишити коментар