Debian/Ubuntu «Підключено, але немає інтернету»: виправлення маршрутизації, шлюзу та політики маршрутизації

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

Ви можете підключитися по SSH до машини з локальної VLAN. Можете пропінгувати шлюз. Іконка Wi‑Fi запевняє, що все гаразд. Але щойно ви запускаєте apt update, відкриваєте веб‑сторінку або звертаєтеся до зовнішнього API — тиша.

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

Модель розуміння: пакети не вірять вашому інтерфейсу

«Підключено» зазвичай означає: лінк активний, ви отримали IP‑адресу і щось відповіло на базовий локальний трафік. Це не означає, що ваші вихідні пакети мають робочий маршрут за замовчуванням, що відповіді повернуться тим же шляхом або що DNS резолвить так, як потрібно вашим додаткам.

У Debian/Ubuntu «немає інтернету» зазвичай зводиться до одного з цих пунктів:

  • Відсутній придатний маршрут за замовчуванням (відсутній, вказує на неправильний шлюз або має неправильну метрику).
  • Асиметрична маршрутизація (пакети йдуть одним інтерфейсом, відповіді повертаються іншим і відкидаються rp_filter, фаєрволом або трекінгом стану).
  • Політика маршрутизації (ip rules і таблиці вибирають інший маршрут, ніж ви уявляєте).
  • Обман DNS (резолює в непрохідні адреси, captive portal, застарілі split‑horizon зони).
  • Проблеми MTU/PMTUD (TLS‑handshake зависає, ping працює, TCP стоїть).
  • Побічні ефекти VPN/тунелів (неправильний split‑tunnel — це просто повний відсутність доступу з додатковими кроками).

Будьте безжальні у розділенні шарів: лінк, IP, маршрутизація, DNS і додаток. Більшість часу витрачається, коли люди трактують це як одну купу.

Цитата, що допоможе залишатися чесним: «Надія — це не стратегія.» — Gen. Gordon R. Sullivan

Жарт №1: Якщо у вас відсутній маршрут за замовчуванням, ваші пакети фактично пишуть самі на собі «Повернути відправнику» і йдуть у прірву.

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

Перший: підтвердьте, що «немає інтернету» означає на рівні пакетів

  1. Чи досяжний локальний шлюз? Якщо ні — зупиніться. Ви не налагоджуєте «інтернет». Ви налагоджуєте суміжність L2/L3.
  2. Чи можна дістатися до публічної IP‑адреси за номером? Якщо так, але DNS не працює — це DNS. Якщо ні — це маршрутизація/фаєрвол/MTU.
  3. Який маршрут фактично обирає ядро? Не гадати. Запитайте за допомогою ip route get.

Другий: ізолюйте маршрутизацію проти політики маршрутизації проти NAT

  1. Перевірте маршрут за замовчуванням і метрики (ip route).
  2. Перевірте політичні правила (ip rule) та згадані таблиці (ip route show table X).
  3. Перевірте зворотну перевірку шляху, якщо у вас кілька інтерфейсів (sysctl net.ipv4.conf.*.rp_filter).

Третій: протестуйте «складні випадки», що вводять в оману

  1. MTU / PMTUD: якщо ICMP працює, але HTTPS зависає, тестуйте «не фрагментувати» ping‑ами та меншими payload.
  2. Налаштування проксі на рівні програми: curl працює, браузер ні — або навпаки.
  3. Маршрути VPN/WireGuard: AllowedIPs або pushed‑маршрути можуть заміняти ваш маршрут за замовчуванням.

Цікаві факти та історичний контекст (видання про маршрутизацію)

  • Політика маршрутизації в Linux — це не новинка. Дизайн з кількома таблицями маршрутизації (iproute2) існує з кінця 1990‑х і досі щодня неправильно розуміється.
  • «Маршрут за замовчуванням» — це просто маршрут. В ядрі це зазвичай 0.0.0.0/0 або default — жодної магії, просто найменш специфічний матч.
  • Linux обирає маршрути за довжиною префікса, потім за метрикою. Ось чому більш специфічний маршрут може перевизначити ваш default, навіть якщо ви цього не хотіли.
  • Reverse path filtering (rp_filter) створювався для анти‑спуфінгу. Він ламає multi‑homed хости, якщо його не налаштувати. Функції безпеки часто роблять це: корисно, поки не зіткнетеся зі складнішою реальністю.
  • systemd-resolved популяризував stub‑резолвер на 127.0.0.53. Коли DNS не працює, люди звинувачують «127.0.0.53», ніби це особисте осквернення. Зазвичай проблема в upstream.
  • Netplan — це генератор, а не демон. Він записує конфіг для NetworkManager або systemd‑networkd. Налагоджуйте рендерер, а не YAML‑естетику.
  • IPv6 може «виграти» несподівано. Багато клієнтів віддають перевагу IPv6; якщо у вас зламаний IPv6‑маршрут, ви отримаєте повільні відмови, що відчуваються як втрата пакетів.
  • Війни за маршрут за замовчуванням відбуваються на ноутбуках. Підключили Ethernet, залишили Wi‑Fi, додали VPN — тепер у вас три претенденти на «default». Ядро вибере один. Ваш мозок вибере неправильний.

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

Ось завдання, які я насправді виконую, коли машина каже, що вона підключена, але поводиться, ніби на безлюдному острові. Кожне завдання містить: команду, що означає її вивід, і рішення, яке ви приймаєте.

Завдання 1: Перевірте стан лінку та імена інтерфейсів

cr0x@server:~$ ip -br link
lo               UNKNOWN        00:00:00:00:00:00 <LOOPBACK,UP,LOWER_UP>
ens18            UP             52:54:00:12:34:56 <BROADCAST,MULTICAST,UP,LOWER_UP>
wlp2s0           DOWN           10:fe:ed:aa:bb:cc <NO-CARRIER,BROADCAST,MULTICAST,UP>

Значення: ens18 піднятий і має carrier. wlp2s0 адміністративно увімкнений, але без carrier (не асоційований).

Рішення: Зосередьтеся на ens18. Не вирішуйте проблеми з Wi‑Fi DNS, коли Wi‑Fi навіть не підключено.

Завдання 2: Підтвердіть IP‑адресацію та область дії

cr0x@server:~$ ip -br addr show
lo               UNKNOWN        127.0.0.1/8 ::1/128
ens18            UP             10.20.30.41/24 fe80::5054:ff:fe12:3456/64

Значення: У вас IPv4 10.20.30.41/24. Немає глобального IPv6, лише link‑local.

Рішення: Для інтернет‑тестів спочатку використовуйте IPv4, щоб зменшити кількість змінних. Якщо очікується IPv6 — це окрема проблема (RA/DHCPv6).

Завдання 3: Перевірте маршрут за замовчуванням (звичайний підозрюваний)

cr0x@server:~$ ip route show
10.20.30.0/24 dev ens18 proto kernel scope link src 10.20.30.41

Значення: Немає default via .... Ви можете спілкуватися лише з локальною підмережею.

Рішення: Відновіть налаштування шлюзу (DHCP, статична конфігурація, netplan, NM). Не чіпайте DNS поки не виправите маршрут.

Завдання 4: Запитайте DHCP, що він вважає заданим

cr0x@server:~$ sudo journalctl -u systemd-networkd --since "10 min ago" | tail -n 20
...ens18: DHCPv4 address 10.20.30.41/24 via 10.20.30.1
...ens18: Configured gateway: 10.20.30.1
...ens18: Setting route: dst: 0.0.0.0/0, gw: 10.20.30.1

Значення: networkd каже, що встановив маршрут за замовчуванням через 10.20.30.1, але ip route його не показав.

Рішення: Підозріло, що інший менеджер перезаписав його, або політика маршрутизації перемістила його в таблицю, відмінну від main.

Завдання 5: Показати маршрути в усіх таблицях (не тільки main)

cr0x@server:~$ ip route show table all | sed -n '1,120p'
default via 10.20.30.1 dev ens18 table 100
10.20.30.0/24 dev ens18 proto kernel scope link src 10.20.30.41
local 10.20.30.41 dev ens18 table local proto kernel scope host src 10.20.30.41
broadcast 10.20.30.255 dev ens18 table local proto kernel scope link src 10.20.30.41

Значення: Маршрут за замовчуванням існує, але в таблиці 100, а не в main.

Рішення: Перевірте ip rule, щоб дізнатися, коли використовується таблиця 100. Якщо жодне правило не співпадає з вашим трафіком — у вас «підключено, але немає інтернету».

Завдання 6: Огляньте політичні правила та пріоритети

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

Значення: Лише трафік з джерелом у 10.20.30.0/24 має використовувати таблицю 100. Це здається правильним — якщо тільки ваша вихідна адреса не інша (контейнери, політичні мітки, вторинні IP).

Рішення: Протестуйте реальний вибір маршруту за допомогою ip route get для зовнішньої IP і з явним from.

Завдання 7: Запитайте ядро, який маршрут воно обере

cr0x@server:~$ ip route get 1.1.1.1
1.1.1.1 dev ens18 src 10.20.30.41 uid 1000
    cache

Значення: Ядро обрало ens18 і джерело 10.20.30.41. Якщо ви побачили «unreachable» тут — все: маршрутизація зламана.

Рішення: Якщо ip route get виглядає адекватно, але ping відмовляє — дивіться в бік фаєрволу/NAT upstream. Якщо він некоректний — виправляйте маршрути локально.

Завдання 8: Перевірте досяжність шлюзу (суміжність L3)

cr0x@server:~$ ping -c 2 10.20.30.1
PING 10.20.30.1 (10.20.30.1) 56(84) bytes of data.
64 bytes from 10.20.30.1: icmp_seq=1 ttl=64 time=0.341 ms
64 bytes from 10.20.30.1: icmp_seq=2 ttl=64 time=0.305 ms

--- 10.20.30.1 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1013ms
rtt min/avg/max/mdev = 0.305/0.323/0.341/0.018 ms

Значення: Ви досягаєте шлюзу. L2/L3 до першого хопу в порядку.

Рішення: Якщо інтернет все ще недоступний, проблема в маршруті за замовчуванням, NAT або upstream‑маршрутизації — не в кабелі.

Завдання 9: Перевірте інтернет по IP (вигнати DNS із розповіді)

cr0x@server:~$ ping -c 2 1.1.1.1
PING 1.1.1.1 (1.1.1.1) 56(84) bytes of data.
64 bytes from 1.1.1.1: icmp_seq=1 ttl=56 time=12.4 ms
64 bytes from 1.1.1.1: icmp_seq=2 ttl=56 time=12.2 ms

--- 1.1.1.1 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1002ms
rtt min/avg/max/mdev = 12.2/12.3/12.4/0.1 ms

Значення: Сира доступність до інтернету працює.

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

Завдання 10: Перевірте шлях резолюції і врахування systemd‑resolved

cr0x@server:~$ resolvectl status
Global
         Protocols: -LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
  resolv.conf mode: stub
Current DNS Server: 10.20.30.53
       DNS Servers: 10.20.30.53 10.20.30.54

Значення: Ви використовуєте systemd‑resolved у режимі stub, з upstream DNS‑серверами у вашій LAN.

Рішення: Якщо резолюція не працює, тестуйте ці DNS‑сервери напряму і підтвердіть наявність маршрутів до них. Також перевірте split‑DNS, якщо активний VPN.

Завдання 11: Підтвердіть резолюцію і відрізніть SERVFAIL від таймауту

cr0x@server:~$ resolvectl query deb.debian.org
deb.debian.org: 2a04:4e42:83::644
               2a04:4e42:400::644
               151.101.130.132
               151.101.194.132
               151.101.66.132
               151.101.2.132

-- Information acquired via protocol DNS in 27.1ms.
-- Data is authenticated: no

Значення: DNS працює і повертає як AAAA, так і A записи. Якби це зависало — підозрюйте недосяжність DNS. Якщо повернулося неправильні IP — підозрюйте split‑horizon або перехоплення captive‑portal.

Рішення: Якщо DNS працює, але HTTP не працює — переходьте до MTU, проксі або перевірок фаєрволу.

Завдання 12: Прослідкуйте фактичний шлях (швидко й грубо)

cr0x@server:~$ traceroute -n 1.1.1.1 | sed -n '1,8p'
traceroute to 1.1.1.1 (1.1.1.1), 30 hops max, 60 byte packets
 1  10.20.30.1  0.410 ms  0.361 ms  0.342 ms
 2  198.51.100.1  2.103 ms  2.034 ms  2.012 ms
 3  203.0.113.9  6.821 ms  6.774 ms  6.736 ms
 4  1.1.1.1  12.504 ms  12.412 ms  12.380 ms

Значення: У вас є шлях за межі шлюзу. Якщо він помирає на хопі 1 — ваш шлюз не має upstream/NAT або блокує ICMP TTL exceeded. Якщо помирає пізніше — це upstream маршрутизація/фаєрвол.

Рішення: Якщо хоп 1 у порядку, а хоп 2+ мертвий — підніміть питання до мережної команди або виправте upstream NAT/маршрутизатор.

Завдання 13: Виявлення MTU‑чорних ям (класика «TLS зависає»)

cr0x@server:~$ ping -c 2 -M do -s 1472 1.1.1.1
PING 1.1.1.1 (1.1.1.1) 1472(1500) bytes of data.
ping: local error: message too long, mtu=1400

--- 1.1.1.1 ping statistics ---
2 packets transmitted, 0 received, +2 errors, 100% packet loss, time 1007ms

Значення: Вашому інтерфейсу MTU = 1400 (або шлях обмежує до 1400). Відправлення 1500‑байтових кадрів з DF призводить до локальної помилки.

Рішення: Встановіть коректний MTU на інтерфейсі або тунелі. Якщо є VPN — MTU тунелю зазвичай є реальним обмеженням.

Завдання 14: Перевірте reverse path filter при multi‑homed

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

Значення: Увімкнено строгий rp_filter. На multi‑homed хостах з асиметричною маршрутизацією це може відкидати дійсні відповіді.

Рішення: Якщо вам дійсно потрібна multi‑homing/policy routing, встановіть rp_filter = 2 (loose) на відповідних інтерфейсах або спроектуйте маршрути так, щоб уникати асиметрії.

Завдання 15: Підтвердіть, який менеджер контролює інтерфейс

cr0x@server:~$ networkctl status ens18 | sed -n '1,30p'
● 2: ens18
                     Link File: /usr/lib/systemd/network/99-default.link
                  Network File: /run/systemd/network/10-netplan-ens18.network
                          Type: ether
                         State: routable (configured)
                  Online state: online
                       Address: 10.20.30.41
                       Gateway: 10.20.30.1
                           DNS: 10.20.30.53

Значення: systemd‑networkd володіє цим інтерфейсом, і netplan згенерував його конфіг у /run/systemd/network.

Рішення: Не «виправляйте» це за допомогою NetworkManager, якщо не хочете двобою конфігів. Внесіть виправлення в netplan або networkd, потім застосуйте.

Збої маршрутизації, що виглядають як «немає інтернету»

1) Відсутній маршрут за замовчуванням (найпоширеніше, найменш драматичне)

Якщо ip route не містить default via, у вас немає доступу до інтернету. Крапка. Ви все ще можете дістатися локальних хостів on‑link, що підживлює ілюзію, ніби «мережа працює». Насправді — ні; вона незавершена.

Шляхи виправлення:

  • Очікується DHCP: переконайтеся, що DHCP‑клієнт запущений на правильному інтерфейсі і його не блокує щось. Перевірте логи на предмет «no DHCPOFFERS received».
  • Очікується статичний режим: вкажіть шлюз явно в netplan, ifupdown або NetworkManager, але лише в одному з них.

2) Два шлюзи за замовчуванням, один з неправильним пріоритетом

Ноутбуки це люблять. Сервери теж можуть, якщо хтось додав «тимчасовий» інтерфейс і забув. Якщо у вас два default, Linux обере на основі метрики (нижча — краща) і пріоритету протоколу. Ваш трафік може виходити через інтерфейс, який не робить NAT, не має шляху до upstream або знаходиться в карантині.

Метрики — не порада. Це вирішувач, що визначає, чи пройдуть ваші пакети через робочий інтернет або management VLAN без доступу назовні.

3) Маршрут за замовчуванням існує, але в неправильній таблиці

Це пастка політичної маршрутизації: ip route виглядає нормально в таблиці 100, але ваш трафік використовує main. Або навпаки. Машина «підключена» у сенсі наявності маршрутів десь. Але вони не використовуються для потрібного вам трафіку.

4) Асиметрична маршрутизація + rp_filter = «інколи пінгує»

Асиметрична маршрутизація не завжди неправильна. Вона неправильна, коли ваш хост або щось upstream вимагає симетрії. Linux зі строгим rp_filter=1 відкидає пакети, якщо перевірка зворотного шляху не проходить. Станові фаєрволи та NAT‑пристрої upstream також карають асиметрію.

Симптоми кумедні: вихідні SYN виходять, SYN‑ACK повертається іншим шляхом і зникає. Деякі цілі працюють, інші ні. Люди звинувачують «інтернет». Інтернет невинний.

5) MTU і PMTUD проблеми: прихований відмова

ICMP ping на 56 байт працює. DNS працює. Але HTTPS зависає. SSH інколи підключається, але передача файлів стоїть. Це часто через невдале виявлення MTU шляху — особливо через тунелі або неправильно конфігуровані jumbo кадри.

Сучасні мережі часто надто агресивно фільтрують ICMP. Це ламає PMTUD. Тоді великі пакети пропадають у чорній ямі, і TCP витрачає свій час на марні спроби.

Політика маршрутизації: мовчазний швейцар біля дверей

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

Три частини, які потрібно тримати роздільно

  • Правила (ip rule): співпадають з трафіком за джерелом, призначенням, fwmark, iif, uidrange тощо й вибирають таблицю маршрутизації.
  • Таблиці (ip route show table X): містять маршрути, включно з default. main — лише одна з них.
  • Вибір маршруту (ip route get): те, що ядро насправді робить для даного пакета.

Що йде не так у реальному світі

Правило співпадає з неправильним джерелом. Ви додаєте правило «from 10.0.0.0/24 lookup 100», припускаючи, що сервер завжди використовує 10.0.0.10. Потім Docker або вторинна IP стають джерелом для частини трафіку. Тепер половина трафіку консультує таблицю main (без default), інша половина — таблицю 100 (з default). Це часткова відмова під виглядом випадковості.

Правила перемішуються за порядком. Пріоритети мають значення. Широке правило з пріоритетом 100 може заступити специфічне правило з 1000. Завжди читайте пріоритети як «менший номер перемагає першим». Це не рекомендація; це потік керування.

Маркування без документації. Хтось використав iptables -t mangle щоб промаркувати пакети для спеціальної маршрутизації. Потім ця людина пішла з компанії. Тепер ваш хост має другу всесвіт маршрутизації, ключем до якої є шістнадцятковий номер, якого ніхто не пам’ятає.

Розумний підхід для multi‑homing

Якщо вам дійсно потрібні два uplink’и (наприклад, management і production), робіть source‑based routing навмисно:

  • Одна таблиця для кожного uplink з default-маршрутом і on‑link маршрутами.
  • Одне правило на префікс джерела, що обирає його таблицю.
  • Явні метрики маршрутів у main, щоб уникнути випадкових default.
  • rp_filter налаштований відповідно (2 часто використовується для multi‑homed, але розумійте компроміс по безпеці).

Жарт №2: Policy routing — як офісна політика: якщо ви не знаєте, що вона існує, вона вже вирішує ваше майбутнє.

Netplan, systemd-networkd, NetworkManager: хто володіє правдою?

Ubuntu (і іноді деривативи Debian) може включати три рівні «мережевої конфігурації», які люди плутають:

  • Netplan: YAML, що генерує конфіг для рендерера. Він не управляє інтерфейсами в рантаймі.
  • systemd-networkd: мережевий менеджер для серверів; конфігурується через .network файли і часто отримує дані від netplan.
  • NetworkManager: поширений на десктопах, ноутбуках і деяких серверах; може керувати Wi‑Fi, VPN та роумінгом.

Виберіть одного рендерера на інтерфейс. Не робіть спліт‑брейн. Якщо NetworkManager керує ens18, а systemd‑networkd теж вважає, що керує ens18, ви отримаєте флапінг маршрутів, що виглядає як «періодичний інтернет». Це не періодичність; це перезапис конфігурації.

Як визначити, хто активний

  • systemd‑networkd: networkctl status показує «configured» і вказує на Network File.
  • NetworkManager: nmcli dev status показує стан; маршрути часто з’являються з proto dhcp, але це не є винятковим маркером.

Netplan: дві рядки, про які люди забувають

Для статичного IPv4 потрібні адреса і маршрут. Імена полів змінюються за версіями; найбільш портативний сучасний спосіб — явно визначити default via маршрути. Приклади підходять, але в продукції вам потрібно перевірити, що netplan згенерував у /run/systemd/network і що ядро встановило в ip route.

Коли ви змінюєте netplan, застосовуйте це так, щоб не відрізати себе від віддаленої машини. netplan try існує не дарма: він дає таймер відкату, якщо ви втратите зв’язок.

Три корпоративні міні‑історії (анонімізовані, правдоподібні та дратівливі)

Міні‑історія 1: Відмова через неправильне припущення

Інцидент почався як рутинна міграція: флот Ubuntu VM переїхав з одного кластера гіпервізорів в інший. Ті самі VLAN, ті самі IP‑діапазони, ті самі security group. Всі були спокійні. Це була перша помилка.

За кілька хвилин вузли додатків почали відмовляти health check’и. Локальний моніторинг міг їх дістати. SSH працював з бастіону в тому ж підмережі. Але додатки не могли дістатися до зовнішніх платіжних кінцевих точок. «Підключено, але немає інтернету» в масштабі — окрема гідна сорому річ.

Команда припускала, що шлюз за замовчуванням роздається DHCP, бо так було в старому кластері. У новому кластери мережна команда перевела ту підмережу на статичну адресацію, а DHCP лише видавав IP (так, таке трапляється), і опція шлюзу була відсутня. VM завантажувалися з адресою, але без default route.

Діагностика була швидкою, коли хтось перестав дивитися дашборди і запустив ip route на зламаній вузлі. Немає default route. Виправлення нудне: оновити провізіювання щоб явно задати шлюз (у цьому випадку netplan) і перевідправити. Справжній висновок культурний: не припускайте, що «DHCP означає шлюз». Зазвичай так — поки ні.

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

Інженер, що дбає про продуктивність, вирішив «очистити маршрути» на multi‑homed Debian хості. У коробці було два NIC: management і production, плюс інтерфейс VPN для специфічних партнерських API. Накопичився рік маршрутного мотлоху.

Оптимізація: увімкнути строгий reverse path filtering глобально (net.ipv4.conf.all.rp_filter=1) і прибрати те, що виглядало як «дубльовані маршрути». Мета була зменшити ризик спуфінгу і зробити маршрутизацію детермінованою.

В лабораторії це спрацювало. Потім в production. Раптом деякі зовнішні виклики почали відмовляти, і лише від певних source IP. Збої виглядали як випадкові таймаути. TCP SYN йшли через production, але відповіді іноді поверталися через VPN через policy routing плюс специфічні маршрути партнерів. Зі строгим rp_filter ці відповіді відкидалися як «martians». Система не була під атакою; вона була недостатньо описана.

Постмортем був короткий і не романтичний: строгий rp_filter підходить для single‑homed систем. На multi‑homed з асиметрією — це рушниця для ноги, якщо не спроектувати все явно. Вони відкотили до rp_filter=2 на відповідних інтерфейсах і документували політику маршрутизації замість «оптимізації» у вигляді таємниць.

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

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

Це було нудно. Скрипт виводив статус інтерфейсів, default маршрути, політичні правила, статус DNS і ip route get для відомої зовнішньої IP. Також він збирає фрагменти journalctl для активного рендерера мережі. Ніхто не вихвалявся цим. Отже це було добре.

Одного дня підмножина хостів втратила інтернет після оновлення клієнта VPN. UI показував «підключено». Скрипт відразу підкреслив реальну зміну: нове ip rule з вищим пріоритетом, ніж очікувалося, що змушувало більшість трафіку в таблицю з default‑шляхом через VPN. VPN не мав бути повним тунелем і не дозволяв загальний вихід в інтернет.

Тому що вони мали вивід скрипта до і після, команда змогла вказати на конкретну різницю в політиці маршрутизації, а не сперечатися про «DNS здається повільним». Відкат пройшов чисто. Довготривале виправлення — прив’язати маршрути VPN лише до префіксів партнерів. Нудна практика врятувала години, бо вона зводила проблему до фактів, яких ядро не могло заперечити.

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

  • Симптом: Можу пінгувати шлюз, не можу пінгувати 1.1.1.1
    Корінна причина: Відсутній маршрут за замовчуванням або неправильний IP шлюзу
    Виправлення: Додайте/відновіть default via <gateway> у правильному менеджері (netplan/NM/networkd). Перевірте за допомогою ip route get 1.1.1.1.
  • Симптом: Ping 1.1.1.1 працює, але імена не резолвляться
    Корінна причина: Недоступний DNS‑сервер, неправильний DNS або неверний split DNS від VPN
    Виправлення: Перевірте resolvectl status, запросіть через resolvectl query, впевніться, що є маршрути до DNS‑серверів, виправте опцію 6 DHCP або netplan nameservers.
  • Симптом: DNS працює, ping працює, HTTPS зависає або таймаутиться
    Корінна причина: MTU/PMTUD чорна діра (часто тунель/VPN) або ICMP блокується upstream
    Виправлення: Виявіть path MTU за допомогою DF ping; встановіть коректний MTU на інтерфейсі/тунелі; не блокувати ICMP «fragmentation needed».
  • Симптом: Працює по Wi‑Fi, відмовляє по Ethernet (або навпаки)
    Корінна причина: Два default маршрути; неправильна метрика; політика маршрутизації обирає небажаний uplink
    Виправлення: Видаліть небажаний default, налаштуйте метрики або додайте явні політичні правила. Перевірте ip route і ip route get.
  • Симптом: Лише деякі цілі відмовляють; інші — в порядку; відмови «випадкові»
    Корінна причина: Асиметрична маршрутизація + rp_filter або вибіркове upstream фільтрування на одному egress шляху
    Виправлення: Налаштуйте rp_filter для multi‑homing; забезпечте симетрію шляху або правильні політичні правила; підтвердіть через tcpdump на обох інтерфейсах.
  • Симптом: Локальна LAN доступна; інтернет недоступний після підключення VPN
    Корінна причина: VPN встановив default маршрут (full tunnel) або правило з вищим пріоритетом
    Виправлення: Налаштуйте split‑tunnel VPN так, щоб лише потрібні префікси йшли через VPN; перевірте таблиці маршрутизації і пріоритети ip rule.
  • Симптом: «Працює під root, але не як сервіс» (або навпаки)
    Корінна причина: Політична маршрутизація за UID, fwmark від iptables/nft або мережеві неймспейси сервісу
    Виправлення: Перегляньте ip rule на предмет uidrange/fwmark; перевірте ізоляцію сервісів; підтвердіть за допомогою ip route get ... uid або nsenter у неймспейс.
  • Симптом: Маршрут існує, але трафік все одно не виходить
    Корінна причина: Вибрано неправильний source IP; відсутній src в маршруті; ARP flux; множинні адреси
    Виправлення: Закріпіть джерело в маршрутах або правилах; перевірте за допомогою ip route get; перегляньте ip addr на предмет вторинних IP.

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

Чекліст A: Single‑homed хост (один NIC, один шлюз)

  1. Підтвердіть, що інтерфейс увімкнений і має carrier: ip -br link.
  2. Підтвердіть IP‑адресу та маску: ip -br addr.
  3. Підтвердіть, що default маршрут існує в main: ip route.
  4. Підтвердіть досяжність шлюзу: ping -c 2 <gw>.
  5. Підтвердіть досяжність публічної IP: ping -c 2 1.1.1.1.
  6. Підтвердіть DNS‑сервери та резолюцію: resolvectl status і resolvectl query.
  7. Якщо HTTPS відмовляє, тестуйте MTU: ping -M do -s 1472 1.1.1.1 і налаштуйте при необхідності.

Чекліст B: Multi‑homed хост (два NIC, можливо VPN)

  1. Перелічіть всі default і метрики: ip route show | grep -E '^default'.
  2. Покажіть політичні правила: ip rule. Якщо ви не очікували правил — вітаю: вони є.
  3. Покажіть усі таблиці: ip route show table all. Шукайте default в таблицях, відмінних від main.
  4. Запитайте у ядра обраний шлях: ip route get 1.1.1.1 і ip route get 1.1.1.1 from <source-ip>.
  5. Перевірте rp_filter: sysctl net.ipv4.conf.all.rp_filter. Якщо строгий і multi‑homed — розгляньте послаблення per‑interface.
  6. Якщо є VPN — перевірте, які маршрути він підштовхує/встановлює: ip route show до/після підняття VPN.
  7. Підтвердіть повернену видимість трафіку tcpdump’ом на обох інтерфейсах, якщо підозрюєте асиметрію.

Чекліст C: Внесіть виправлення, не відрізавши віддалений доступ

  1. При використанні netplan на Ubuntu віддавайте перевагу sudo netplan try спочатку (рекомендується локальний консоль).
  2. При зміні маршрутів на віддаленій машині додавайте нові маршрути перед тим, як видаляти старі.
  3. Тримайте постійний позаосновний шлях доступу (консоль, iLO/IPMI, cloud serial console). «Я просто знову підключусь по SSH» — це не план.
  4. Після змін перевіряйте ip route, ip rule, ip route get і реальний тест додатку (curl до зовнішньої кінцевої точки).

FAQ

1) Чому робочий стіл показує «Підключено», коли інтернету немає?

Тому що «підключено» зазвичай означає лінк + IP. Це не перевіряє маршрут за замовчуванням, DNS або upstream NAT. Ядро не цікавлять іконки.

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

ip route get 1.1.1.1. Якщо вона повертає «unreachable» або обирає дивний інтерфейс/джерело — ви знайшли категорію проблеми.

3) У мене є default маршрут, але інтернету все одно немає. Що тепер?

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

4) Чому в /etc/resolv.conf видно 127.0.0.53? Це зламалося?

Не обов’язково. Це локальний stub systemd‑resolved. Справжні upstream‑сервери дивіться в resolvectl status. Виправляйте upstream або маршрутизацію до нього.

5) Як виникають кілька default маршрутів?

DHCP на двох інтерфейсах, Wi‑Fi плюс Ethernet, клієнти VPN, що встановлюють default, або статичні конфіги поверх DHCP. Linux обирає один на основі метрик і логіки правил/таблиць.

6) У чому різниця між маршрутом main table і політичною маршрутизацією?

Main table — це стандартний пошук. Policy routing додає правила, що обирають таблиці на основі атрибутів пакета (джерело, мітка, вхідний інтерфейс, UID). Якщо є правила — main може бути неважливим для цікавого вам трафіку.

7) Чи варто вимикати rp_filter, щоб виправити це?

Не вимикайте його сліпо. Для single‑homed систем строгий rp_filter підходить. Для multi‑homed — встановіть loose (2) per‑interface, якщо асиметрія легітимна. Краще: спроектуйте симетричну маршрутизацію, де це можливо.

8) Чому ping працює, а apt/curl відмовляє?

Ping — малий і простий. apt/curl зачіпають DNS, TCP, TLS і часто більші пакети. Найпоширеніші причини — MTU/PMTUD та проблеми з DNS.

9) Чи може IPv6 викликати «немає інтернету», навіть якщо IPv4 в порядку?

Так. Багато клієнтів віддають перевагу IPv6; зламаний IPv6‑маршрут призводить до повільних відмов. Тестуйте curl -4 проти curl -6 і перевірте default маршрути IPv6 та RA/DHCPv6.

10) Я виправив вручну з ip route add default. Як зробити це постійним?

Помістіть конфіг у системний мережевий менеджер (netplan, NetworkManager, ifupdown або networkd). Ручні ip route зміни зникнуть після перезавантаження або при флапі лінку — і вони повернуться переслідувати вас.

Наступні кроки, які ви справді можете зробити

Якщо ви нічого не візьмете з цього: перестаньте довіряти «підключено» і почніть допитувати ядро. Запустіть ip route, ip rule і ip route get. Ці три покажуть вам, у що вірить хост.

Потім зробіть нудні виправлення в порядку:

  1. Переконайтеся, що для заданого класу трафіку існує саме один потрібний маршрут за замовчуванням (або кілька з явними метриками і правилами).
  2. Зробіть політику маршрутизації явною, задокументованою і мінімальною. Якщо ви не можете пояснити кожне ip rule — ви не володієте своєю маршрутизацією.
  3. Перевірте DNS через resolvectl і тестуйте по IP, щоб розділити проблеми.
  4. Якщо додатки зависають — підозрюйте MTU, доки не доведено протилежне.
  5. Збережіть зміни в правильному менеджері (netplan/NM/networkd) і уникайте роздвоєння конфігурацій.

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

← Попередня
Ariane 5 і перетворення числа, яке знищило ракету
Наступна →
Ubuntu 24.04: SSH-сеанси перериваються випадково — налаштування keepalive, що дійсно допомагають

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