Debian/Ubuntu «Працює в LAN, не працює в WAN»: перевірки маршрутизації та NAT, що виявляють причину (випадок №25)

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

В LAN все працює. SSH працює, HTTP працює, DNS виглядає здоровим. А потім ви пробуєте зі «зовнішнього» боку (VPN, мобільна точка доступу, мережа партнера, інтернет) — і нічого. Або ще гірше: воно працює частково, з таймаутами, які здаються жартом.

Такий шаблон помилок рідко пов’язаний із «додатком». Майже завжди це маршрутизація, NAT, фільтрація або тихе невідповідність між тим, що ви думаєте, яким є маршрут, і тим, що пакети роблять о 2:00 ночі. Лікування не магічне. Воно методичне, засноване на захопленнях трафіку, і трохи безжальне щодо припущень.

Ментальна модель: чому успіх у LAN майже нічого не доводить

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

  • Одношаговий або з невеликою кількістю хопів (маршрутизація простіша).
  • Часто без NAT (або NAT поводиться інакше).
  • Менш імовірно проходить через stateful middlebox-и з суворими таймаутами.
  • Менш імовірно зазнає асиметричної маршрутизації (шлях назад зазвичай очевидний).
  • Менш імовірно тригерить «захищені» правила для інтернет-зовнішнього доступу.

WAN додає рівні: edge-роутери, ISP CPE, security groups, cloud load balancers і NAT — іноді кілька NAT-ів насипом, як млинці зі смутком.

Діагностична хитрість — перестати думати «клієнт не може підключитися» і почати мислити в термінах фаз пакету:

  1. Вхід: Чи доходить SYN/UDP-запит до інтерфейсу сервера, який ви очікуєте?
  2. Локальна політика: Чи приймає його Linux (фаєрвол, rp_filter, conntrack)?
  3. Прив’язка сервісу: Чи прив’язаний додаток до правильної IP/порт і доступний через цей шлях?
  4. Шлях назад: Чи виходить відповідь тією ж межею (або принаймні маршрутизованою)?
  5. Трансляція: Чи NAT правильно переписує адреси/порти і відстежує стан?

Якщо ви можете відповісти на ці п’ять питань, зазвичай можна впевнено назвати корінну причину, а не гадати на підставі вражень.

Швидкий план діагностики (перший/другий/третій)

Перший: доведіть, чи доходять пакети до коробки

Запустіть захоплення на публічно орієнтованому інтерфейсі під час спроби з WAN. Якщо ви не бачите вхідних пакетів, проблема вище по ланцюжку (edge NAT/port forward, ISP firewall, cloud security group, невірна публічна IP).

Другий: доведіть, чи відповідає коробка і куди йдуть відповіді

Якщо ви бачите, що SYN приходить, відразу дивіться, чи виходить SYN-ACK. Якщо він виходить іншим інтерфейсом, ви в країні асиметричної маршрутизації/policy routing. Якщо ніякої відповіді не виходить, це зона firewall/rp_filter/прив’язки сервісу.

Третій: доведіть стан і трансляцію

Якщо ви бачите, що відповіді виходять, але клієнт їх ніколи не отримує — дивіться стан NAT (conntrack) і проміжні пристрої. Багато випадків «WAN не працює» — це повернення трафіку з неправильним NAT, відкидання через rp_filter або проблеми MTU/MSS на WAN-шляху.

Прагматичне правило: Не «додавайте правило на око». Спочатку capture, потім зміна. Інакше ви наштовхуєтеся на накопичення виправлень, після чого систему важко зрозуміти.

Цікавинки та історичний контекст (9 швидких пунктів)

  1. NAT не був первісним планом. Він став популярним у 1990-х, коли дефіцит IPv4 зустрів споживчий broadband.
  2. Linux netfilter з’явився в еру ядра 2.4. Він замінив старі ipchains і зробив stateful firewalling повсякденним у Linux.
  3. conntrack — це пам’ять станів. NAT покладається на connection tracking; якщо conntrack заповнений, з’являються «випадкові» відмови, які не є випадковими.
  4. rp_filter існує для боротьби зі спуфінгом. Reverse path filtering відкидає пакети, які «не повинні» приходити на інтерфейс — це добре, поки ви не використовуєте асиметричну маршрутизацію або policy routing.
  5. Path MTU Discovery крихкий роками. Блокування ICMP «Fragmentation Needed» ламає PMTUD, викликаючи зависання тільки на WAN і загадкові помилки MSS/MTU.
  6. Hairpin NAT — це особливий вид незручності. Доступ до сервісу через його публічну IP зсередини того ж NAT може не працювати, якщо роутер не підтримує reflection/hairpinning.
  7. nftables не вбив iptables миттєво. Багато дистрибутивів запускають iptables як сумісний шар поверх nftables, що може плутати при відладці, якщо ви не перевіряєте, що дійсно активне.
  8. Маршрути за замовчуванням — це політика. Multi-homed хости (два uplink-и) потребують явної політики; інакше Linux обирає «найкращі» маршрути, які хороші лише в його власній уяві.
  9. UDP «в LAN працює» — не те ж саме, що «в WAN працює». Таймаути NAT і stateful фаєрволи ставляться до UDP як до тимчасового гостя.

Практичні завдання: команди, виводи та рішення (14 завдань)

Всі завдання передбачають Debian/Ubuntu на стороні сервера, якщо не вказано інше. Замініть імена інтерфейсів, IP та порти на свої. Суть — у формі доказів.

Завдання 1: Підтвердити, що сервіс слухає на правильному IP і порту

cr0x@server:~$ sudo ss -lntup | grep -E '(:80|:443|:22)\b'
tcp   LISTEN 0      4096         0.0.0.0:80        0.0.0.0:*    users:(("nginx",pid=1432,fd=6))
tcp   LISTEN 0      4096         0.0.0.0:22        0.0.0.0:*    users:(("sshd",pid=911,fd=3))
tcp   LISTEN 0      4096            [::]:443          [::]:*    users:(("nginx",pid=1432,fd=7))

Що це означає: Якщо ви бачите 127.0.0.1:80 або приватну адресу, WAN не працюватиме (додаток не прив’язаний до публічного шляху). Якщо ви бачите тільки [::]:443 і ваш WAN-тест по IPv4, можливо, ви слухаєте лише IPv6 або навпаки.

Рішення: Спочатку виправте прив’язки. Не чіпайте NAT, поки сервіс не буде доступний на очікуваному інтерфейсі/IP.

Завдання 2: Перевірити локальну політику фаєрволу (nftables/iptables/UFW) без здогадок

cr0x@server:~$ sudo nft list ruleset | sed -n '1,140p'
table inet filter {
  chain input {
    type filter hook input priority 0; policy drop;
    ct state established,related accept
    iif "lo" accept
    tcp dport { 22, 80, 443 } accept
    ip protocol icmp accept
    counter drop
  }
}

Що це означає: Політика drop за замовчуванням з явними дозволами — нормально. Відсутність порту вашого сервісу — ненормально. Якщо ви використовуєте UFW, він може управляти правилами під капотом, але nft показує те, що реально активне.

Рішення: Якщо WAN напряму б’є по цьому хосту — відкрийте порт тут. Якщо трафік DNAT-иться на внутрішній хост — відкрийте порт на цільовому хості теж.

Завдання 3: Перевірити, чи iptables справді не приховує nftables

cr0x@server:~$ sudo iptables -V
iptables v1.8.9 (nf_tables)

Що це означає: Ваші команди iptables можуть маніпулювати backend-ом nftables. Це нормально, але змішування «legacy» і «nf_tables» інструментів може створити правила, які ви не бачите там, де шукаєте.

Рішення: Оберіть один вигляд (рекомендовано nft list ruleset) і дотримуйтеся його під час відладки.

Завдання 4: Підтвердити таблицю маршрутизації та маршрут за замовчуванням на сервері

cr0x@server:~$ ip route
default via 203.0.113.1 dev eth0 proto dhcp src 203.0.113.20 metric 100
10.10.0.0/24 dev eth1 proto kernel scope link src 10.10.0.10
203.0.113.0/24 dev eth0 proto kernel scope link src 203.0.113.20

Що це означає: Сервер думає, що відповіді в інтернет йдуть через eth0 через 203.0.113.1. Якщо ваш WAN-шлях насправді через інший інтерфейс — це основна проблема.

Рішення: Якщо ви multi-homed, готуйте policy routing (ip rule), замість того щоб сподіватися, що Linux вибере потрібний інтерфейс.

Завдання 5: Переглянути правила політики маршрутизації (тихі королі)

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

Що це означає: Трафік з 10.10.0.0/24 використовує таблицю 100. Це може викликати збої WAN, якщо трафік назад для WAN-з’єднання використовує неправильний source IP або неправильний uplink.

Рішення: Якщо сервіс з WAN DNAT-иться на 10.10.0.10, переконайтесь, що відповіді повертаються через інтерфейс, до якого клієнт може достукатися, зазвичай той самий NAT-шлюз.

Завдання 6: Перевірити rp_filter (reverse path filtering), класичний «вбивця WAN»

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

Що це означає: Режим strict (1) відкидає пакети, якщо ядро вважає, що шлях повернення не буде використовувати той же інтерфейс. Асиметрична маршрутизація або policy routing можуть викликати відхилення ще до того, як фаєрвол отримає слово.

Рішення: Якщо асиметрична маршрутизація — це дизайн (multi-uplink, VRF, policy routing), встановіть rp_filter у loose (2) на відповідних інтерфейсах, або обережно вимкніть (0) там, де потрібно.

Завдання 7: Доведіть, що пакети приходять: tcpdump на WAN-інтерфейсі

cr0x@server:~$ sudo tcpdump -ni eth0 'tcp port 443 and (tcp[tcpflags] & (tcp-syn) != 0)'
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
12:44:10.101010 IP 198.51.100.88.50122 > 203.0.113.20.443: Flags [S], seq 1234567890, win 64240, options [mss 1460,sackOK,TS val 101 ecr 0,nop,wscale 7], length 0

Що це означає: SYN приходить. Upstream маршрутизація і публічна IP — в порядку. Тепер м’яч на вашому полі: локальна політика, NAT або шлях назад.

Рішення: Якщо ви не бачите пакети — припиніть редагувати сервер. Виправляйте edge NAT, security groups, upstream firewall або ситуацію з «непотрібною публічною IP».

Завдання 8: Доведіть, що відповіді йдуть: захоплення SYN і SYN-ACK разом

cr0x@server:~$ sudo tcpdump -ni eth0 'host 198.51.100.88 and tcp port 443'
listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
12:44:10.101010 IP 198.51.100.88.50122 > 203.0.113.20.443: Flags [S], seq 1234567890, win 64240, options [mss 1460,sackOK,TS val 101 ecr 0,nop,wscale 7], length 0
12:44:10.101200 IP 203.0.113.20.443 > 198.51.100.88.50122: Flags [S.], seq 987654321, ack 1234567891, win 65160, options [mss 1460,sackOK,TS val 202 ecr 101,nop,wscale 7], length 0

Що це означає: Сервер відповідає коректно на правильному інтерфейсі. Якщо клієнт все ще не може підключитися, щось між сервером та клієнтом відкидає відповіді (edge firewall, ISP, DDoS-захист, неправильний стан NAT).

Рішення: Зсунути фокус назовні: perimeter device, NAT gateway, cloud firewall або шлях назад за межами цього хоста.

Завдання 9: Виявити асиметричну маршрутизацію (відповідь йде не тим інтерфейсом)

cr0x@server:~$ sudo tcpdump -ni any 'host 198.51.100.88 and tcp port 443'
listening on any, link-type LINUX_SLL2 (Linux cooked v2), snapshot length 262144 bytes
12:44:10.101010 eth0  IP 198.51.100.88.50122 > 203.0.113.20.443: Flags [S], seq 1234567890, win 64240, length 0
12:44:10.101300 eth1  IP 10.10.0.10.443 > 198.51.100.88.50122: Flags [S.], seq 987654321, ack 1234567891, win 65160, length 0

Що це означає: SYN прийшов на eth0 до публічної IP, але SYN-ACK виходить з приватної IP на eth1. Клієнт ніколи цього не прийме. Це підпис неправильного вибору source IP, policy routing або відсутності src в маршрутах.

Рішення: Виправити вибір адреси джерела та маршрутизацію. Типові виправлення: встановити коректний src в маршрутах, додати ip rule за джерелом або забезпечити, щоб DNAT-лені сервіси відповідали через NAT-шлюз.

Завдання 10: Перевірити правила NAT на gateway (MASQUERADE/SNAT/DNAT)

cr0x@server:~$ sudo nft list table ip nat
table ip nat {
  chain prerouting {
    type nat hook prerouting priority -100; policy accept;
    tcp dport 443 dnat to 10.10.0.10:443
  }
  chain postrouting {
    type nat hook postrouting priority 100; policy accept;
    oif "eth0" masquerade
  }
}

Що це означає: DNAT відправляє вхідний 443 на внутрішній сервер. Postrouting masquerade гарантує, що відповіді, що виходять через eth0, мають публічний джерело. Якщо masquerade відсутній, внутрішні хости можуть відповідати приватними адресами, які в інтернеті загинуть.

Рішення: Якщо клієнти WAN не можуть завершити хендшейк, перевірте і DNAT (вхід) і SNAT/MASQUERADE (вихід) для цього шляху.

Завдання 11: Підтвердити, що forwarding увімкнено (актуально для gateway/роутерів)

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

Що це означає: Якщо це NAT-шлюз і ip_forward = 0, ви можете DNAT-ити скільки завгодно, але нічого не буде форвардитись. LAN-тести можуть і надалі працювати, якщо ви обходите шлюз або потрапляєте на сервіси локально.

Рішення: Якщо ви очікуєте маршрутизації/NAT через цей хост, net.ipv4.ip_forward повинен бути 1, і ланцюжок forward повинен дозволяти трафік.

Завдання 12: Перевірити використання conntrack (проблема «працює до піку»)

cr0x@server:~$ sudo conntrack -S
cpu=0 found=120 new=42 invalid=3 ignore=0 delete=8 delete_list=8 insert=42 insert_failed=0 drop=0 early_drop=0 error=0 search_restart=0
cpu=1 found=115 new=38 invalid=1 ignore=0 delete=6 delete_list=6 insert=38 insert_failed=0 drop=0 early_drop=0 error=0 search_restart=0
cr0x@server:~$ cat /proc/sys/net/netfilter/nf_conntrack_count
51234
cr0x@server:~$ cat /proc/sys/net/netfilter/nf_conntrack_max
65536

Що це означає: Ви близькі до максимуму. Коли таблиця заповнюється, нові з’єднання відкидаються. LAN-тести можуть проходити, бо вони не проходять через NAT/conntrack, або шлях у LAN простіший.

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

Завдання 13: Виявити проблеми MTU/MSS (зависання WAN, працює маленький payload)

cr0x@server:~$ ip link show dev eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000
    link/ether 52:54:00:12:34:56 brd ff:ff:ff:ff:ff:ff
cr0x@server:~$ ping -M do -s 1472 198.51.100.1 -c 3
PING 198.51.100.1 (198.51.100.1) 1472(1500) bytes of data.
From 203.0.113.20 icmp_seq=1 Frag needed and DF set (mtu = 1492)
From 203.0.113.20 icmp_seq=2 Frag needed and DF set (mtu = 1492)
From 203.0.113.20 icmp_seq=3 Frag needed and DF set (mtu = 1492)

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

Що це означає: Path MTU менша за 1500 (звично з PPPoE/VPN). Якщо ICMP блокується upstream, PMTUD ламається і TCP-сесії можуть зависати — часто тільки на WAN.

Рішення: Виправте MTU на інтерфейсі/тунелі, дозвольте ICMP «Fragmentation needed» або використайте clamp MSS на edge-фаєрволі для TCP.

Завдання 14: Переконатися, що DNS — не справжній винуватець (split-horizon, неправильні A/AAAA)

cr0x@server:~$ dig +short app.example.internal A
10.10.0.10
cr0x@server:~$ dig +short app.example.internal @1.1.1.1 A
203.0.113.20

Що це означає: Внутрішній DNS повертає приватний IP; публічний резолвер — публічний IP. Це нормально для split-horizon. Це стає проблемою, коли клієнти «WAN-але-не-дуже» (VPN-користувачі, мережі партнерів) отримують неправильний вигляд.

Рішення: Визначте, які клієнти мають бачити яку адресу. Виправте conditional forwarding для VPN-DNS або перестаньте намагатися використовувати одне ім’я для двох світів, якщо не можна контролювати резолвери.

Жарт №1: NAT як офісна політика: все працює, поки хтось не запитає, хто взагалі має право говорити з ким.

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

Міні-історія 1: Аутаж через неправильне припущення

Одна компанія тримала клієнтський портал за Debian-based reverse proxy. Внутрішньо всі заходили по імені сервісу, яке резолвилося у приватний VIP. З інтернету воно резолвилося в публічну IP на edge-фаєрволі, який форвардив 443 на той самий reverse proxy.

Команда додала другий uplink для «резервування». Сервер став multi-homed: eth0 до фаєрволу, eth1 до нового SD-WAN-пристрою. Вони припустили, що Linux «зробить правильно» і поверне трафік тим інтерфейсом, по якому він прийшов. Linux зробив те, що Linux робить: маршрутизував згідно своїх таблиць, а не чиюсь надію.

LAN-тести залишалися в порядку, бо внутрішні клієнти потрапляли на приватний VIP і трафік лишався приватним. WAN-тести падали періодично. Іноді хендшейк проходив, іноді ні, залежно від того, яка адреса джерела була вибрана і яке правило маршрутизації перемогло в той момент.

Прорив у відладці стався після tcpdump -ni any, який показав SYN-и, які приходять на eth0, але SYN-ACK-и виходять через eth1 з неправильною source-IP. Коли команда додала source-based routing rules і встановила rp_filter у loose на відповідних інтерфейсах, WAN-шлях стабілізувався.

Неправильне припущення не було «Linux зламався». Воно було в тому, що в multi-homed світі симетрична маршрутизація — це дефолт. Ні, не є.

Міні-історія 2: Оптимізація, що відкотилася

Ще одна організація хотіла зменшити латентність. Перенесли NAT і фаєрвол із виділеного апарату на Ubuntu VM «біля робочого навантаження». У синтетичних тестах виглядало чудово. VM мала достатньо CPU, і iperf в центрі даних показував фантастичні числа.

Але коли прийшов реальний трафік: багато короткоживучих HTTPS-з’єднань з інтернету й декілька UDP-моніторингових від партнерів — conntrack таблиця заповнилася під час піків. Коли вона досягла межі, нові з’єднання падали. Команда додатку відкрила баг: «WAN нестабільний, LAN нормальний». Квиток супроводжувався скриншотами й розчаруванням.

LAN був у порядку, бо внутрішні запити не проходили тим NAT-шляхом або створювали менше станів. WAN — це карнавал conntrack. Вони «оптимізували» шлях, не розрахувавши розмір state-таблиць, таймаутів і kernel-параметрів для поведінки в інтернеті.

Виправлення не було героїчним. Виміряли використання conntrack, збільшили nf_conntrack_max, зменшили конкретні UDP-таймаути, додали моніторинг насичення conntrack. Найголовніше — перестали вважати NAT безстанним. NAT — це стан, і він вимагає планування ємності.

Жарт №2: Нічого так не говорить «висока доступність», як одна conntrack-таблиця, що панікує, коли маркетинг запускає кампанію.

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

Фінансова компанія мала просте правило: кожна інтернет-орієнтована зміна включала packet capture до і після, збережений з записом зміни. Нічого новаторського. Просто достатньо, щоб показати поведінку ingress і egress.

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

On-call інженер дістав «before» capture з минулого тижня і зробив свіжий «after» capture. Новий capture показав, що TCP-сесії зупиняються після певного розміру пакета. Потім побачили справжню зміну: ICMP type 3 code 4 був заблокований «для безпеки». PMTUD зламався, і MSS не кліпалося. Класичний біль тільки на WAN.

Вони відкочували блокування ICMP, додали явний дозвіл для потрібних ICMP-повідомлень та задокументували, коли використовувати MSS clamping на VPN-лінках. Інцидент тривав хвилини, а не години, бо у них були базові докази і дисципліна порівнювати їх. Нудно, правильно, повторювано. Найкращий вид операційної роботи.

Цитата про надійність (перефразовано): «Ви не можете поліпшити те, що не вимірюєте.» — ідея, близька до W. Edwards Deming

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

1) «Працює з LAN, таймаут з WAN»

Симптом: Немає з’єднання з інтернету; клієнти LAN успішні.

Корінна причина: Вхідний трафік ніколи не досягає хосту (невірна публічна IP, відсутній port forward, cloud security group блокує, ISP блокує).

Виправлення: Зробіть capture на WAN-інтерфейсі. Якщо нічого не приходить — виправляйте upstream NAT/firewall. Не чіпайте додаток.

2) «SYN приходить, SYN-ACK не виходить»

Симптом: tcpdump показує вхідний SYN, але без відповіді.

Корінна причина: Локальний фаєрвол відкидає, сервіс не слухає на цій IP/порт, rp_filter відкидає або локальний маршрут до клієнта зламаний.

Виправлення: Перевірте ss -lntup, потім правила фаєрволу (nft), потім rp_filter, потім маршрутизацію.

3) «SYN-ACK виходить, але клієнт ніколи не завершує хендшейк»

Симптом: Сервер відповідає, але клієнт продовжує ретранслювати SYN.

Корінна причина: Повернення трафіку зламане за межами сервера, неправильний source IP у відповіді (асиметрична маршрутизація) або upstream-скиди.

Виправлення: Захопіть на any, щоб побачити, який інтерфейс використовує відповідь. Виправте policy routing або NAT на gateway. Перевірте upstream правила.

4) «VPN-користувачі не вдаються, інтернет-користувачі ок»

Симптом: Віддалені VPN-клієнти не можуть дістатися сервісу за публічним іменем; інші можуть.

Корінна причина: Невідповідність split DNS або hairpin NAT не підтримується на шляху egress VPN.

Виправлення: Виправте DNS-представлення для VPN, або дайте внутрішнім/VPN-користувачам внутрішнє ім’я/VIP, або реалізуйте hairpin NAT коректно.

5) «Малі запити працюють, великі завантаження зависають»

Симптом: Сторінка логіну завантажується, але передача файлів зупиняється на WAN.

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

Виправлення: Дозвольте ICMP fragmentation-needed, встановіть коректний MTU, або увімкніть MSS clamping на edge для TCP, де потрібно.

6) «Все ламається під час піку, потім відновлюється»

Симптом: Випадкові WAN-збої, корельовані з навантаженням.

Корінна причина: Вичерпання conntrack, вичерпання портів NAT або насичення stateful фаєрволу.

Виправлення: Виміряйте conntrack count vs max, відрегулюйте ліміти/таймаути, масштабуйтесь у NAT або зменшіть непотрібну генерацію станів.

7) «WAN IPv4 падає, а IPv6 працює» (або навпаки)

Симптом: Одна сімейство IP працює; інша — ні.

Корінна причина: Невідповідність прив’язки додатку, правила фаєрволу, відсутній AAAA/A запис або неправильний маршрут для однієї сімейства.

Виправлення: Перевірте ss на v4/v6 слухачі, перевірте правила фаєрволу по сімейству, валідуйте DNS-записи по сімейству.

8) «В LAN працює за IP, не працює за hostname»

Симптом: curl https://10.10.0.10 працює, але curl https://app.example.internal — ні.

Корінна причина: DNS вказує на іншу адресу з WAN, або сертифікат/SNI маршрутує інакше на reverse proxy.

Виправлення: Порівняйте DNS зсередини/ззовні, перевірте конфіг vhost reverse proxy і SNI, підтвердьте правильну цільову IP.

Чеклисти / покроковий план

Чеклист A: Окремий хост напряму на публічній IP (без DNAT)

  1. Підтвердити listening socket: ss -lntup. Якщо він прив’язаний до localhost/приватної адреси — виправте конфіг сервісу.
  2. Підтвердити локальний фаєрвол: nft list ruleset. Якщо політика drop — явне відкриття порту потрібне.
  3. Підтвердити, що пакети приходять: tcpdump -ni eth0 під час тесту з WAN.
  4. Якщо пакети приходять, але відповіді не йдуть: перевірте rp_filter і маршрути до підмережі клієнта.
  5. Якщо відповідь виходить, але клієнт її не бачить: залучіть upstream firewall/ISP, перевірте маршрут назад, перевірте політику DDoS scrubber.
  6. Для «великі payload зависають»: перевірте MTU/PMTUD і дозвіл ICMP.

Чеклист B: NAT gateway, що робить port forwarding (DNAT на приватний сервер)

  1. На gateway переконайтесь, що є DNAT-правило, яке відповідає інтерфейсу/порту.
  2. На gateway переконайтесь, що forward chain дозволяє трафік (stateful allow типово).
  3. На gateway переконайтесь, що SNAT/MASQUERADE для вихідних відповідей на WAN-інтерфейсі налаштований.
  4. На внутрішньому сервері переконайтесь, що він бачить вхідне з’єднання (tcpdump на приватному інтерфейсі).
  5. На внутрішньому сервері переконайтесь, що default route вказує назад на gateway (інакше відповіді обійдуть NAT і загинуть).
  6. Спостерігайте conntrack на gateway під час тестів; NAT потребує стану.

Чеклист C: Multi-homed хост (два інтерфейси, два шляхи)

  1. Захопіть на any і перевірте ingress і egress інтерфейс для одного й того ж потоку.
  2. Перевірте ip rule і всі таблиці маршрутів, що використовуються.
  3. Встановіть rp_filter у loose (2) там, де очікується асиметрична маршрутизація.
  4. Примусово вкажіть source addresses за допомогою src в маршрутах або policy routing за джерелом підмережі.
  5. Перетестуйте і підтвердьте, що відповідь постійно виходить через правильний uplink.

Чеклист D: DNS і hairpin sanity (поширено в офісах і VPN)

  1. Порівняйте DNS-відповіді зсередини і ззовні за допомогою dig з конкретними резолверами.
  2. Якщо внутрішні клієнти резолвлять публічну IP — перевірте, чи підтримує edge hairpin NAT.
  3. Якщо hairpin не підтримується — перестаньте примушувати його: дайте внутрішнім/VPN-клієнтам внутрішнє ім’я або conditional DNS.
  4. Перевірте сертифікати і SNI-маршрутизацію відповідно до імені, яким користуються користувачі.

Питання й відповіді (FAQ)

1) Якщо працює в LAN, чи не доводить це, що додаток в порядку?

Це доводить, що додаток може відповісти по якомусь шляху. WAN додає іншу маршрутизацію, NAT і політику фаєрволу. Трактуйте успіх у LAN як «додаток не зовсім мертвий», не більше.

2) Який найшвидший тест, щоб не гадати?

tcpdump на WAN-інтерфейсі під час спроби з WAN. Якщо нічого не приходить — перестаньте звинувачувати сервер.

3) Чому rp_filter ламає WAN, але не LAN?

Трафік у LAN часто йде прямим симетричним шляхом. Трафік WAN на multi-homed хостах або у policy-routed мережах може виглядати «спуфнутим» для strict rp_filter, і ядро відкидає його раніше.

4) Я відкрив порт в UFW, але все одно не працює. Чому?

Або UFW не є активним шаром фаєрвола, як ви думаєте, або трафік не доходить до хоста, або ви DNAT-ите на іншу машину, яка все ще блокує. Завжди валідуйте реальні активні правила за допомогою nft list ruleset і захоплення трафіку.

5) Як зрозуміти, чи є асиметрична маршрутизація?

Захоплення на any і спостереження за одним потоком. Якщо SYN входить через один інтерфейс, а SYN-ACK виходить через інший — є асиметрія. Потім перевірте ip rule і маршрути по таблицях.

6) Чому великі завантаження падають, а сторінка логіну працює?

Це шаблон помилки MTU/PMTUD. Малі пакети проходять; більші потребують фрагментації або коректного PMTUD. Якщо ICMP «fragmentation needed» блокується, TCP зависає.

7) Чи може вичерпання conntrack виглядати як «тільки WAN»?

Так. Багато LAN-шляхів не проходять через сильно навантажені NAT/conntrack-пристрої або створюють менше станів. Інтернет-орієнтований трафік спалахоподібний і дуже вміє виявляти ваші обмеження таблиць.

8) Ми DNAT-имо на внутрішній хост. Чому внутрішньому хосту потрібен правильний default route?

Тому що відповіді мають повертатися через NAT-шлюз, щоб бути правильно трансформованими. Якщо внутрішній хост відправляє відповіді через інший шлюз, клієнт бачить приватні source IP або невідповідний стан і сесія помирає.

9) Чи стосується IPv6 проблеми «LAN працює, WAN падає»?

Звісно. Багато середовищ помилково експонують IPv6 внутрішньо, але не зовнішньо (або навпаки). Перевірте прив’язки, DNS AAAA записи і правила фаєрволу по кожній сімействі.

10) Чи варто просто включити MASQUERADE всюди?

Ні. Це створює борг у відладці і несподівані шляхи. SNAT/MASQUERADE має бути точним: правильний egress-інтерфейс, правильні source-підмережі і тільки там, де дійсно потрібна трансляція.

Висновок: наступні кроки, які варто зробити

Якщо ви візьмете лише одну звичку з цього: capture перш ніж змінювати. «Працює в LAN, не працює в WAN» — це історія про маршрутизацію/NAT/фільтрацію, поки не доведено протилежне. Ваше завдання — довести, де пакет зникає.

  1. Запустіть tcpdump на WAN-інтерфейсі під час невдалої спроби. Визначте: upstream чи локально.
  2. Якщо локально — перевірте по порядку: listening sockets → правила фаєрволу → rp_filter → маршрутизацію/policy routing.
  3. Якщо це DNAT — перевірте обидва напрямки: DNAT вхід, SNAT/MASQUERADE вихід і коректний default route на внутрішньому хості.
  4. Якщо це нестабільно під навантаженням — виміряйте conntrack і межі state-таблиць і перестаньте вважати NAT безкоштовним.
  5. Якщо «великі payload-и зависають» — виправте MTU/PMTUD і не блокуйте довільно ICMP, якого не розумієте.

Зробіть це — і «працює в LAN, не працює в WAN» стане не загадкою, а чеклистом з доказами.

← Попередня
Excel керує світом: моторошні історії, які повторюються
Наступна →
Docker: Повільні записи на overlay2 — коли переходити на томи і чому

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