Почему маршрутизация ломается и как быстро понять, что дело именно в ней
Сбой маршрутизации выглядит однотипно: сервер работает, SSH отвечает, но внешние адреса недоступны. Причин обычно четыре: неверный шлюз, конфликт маршрутов, правила политики маршрутизации, которые уводят трафик не через тот интерфейс, и потеря маршрутов после перезагрузки, если они были добавлены вручную командой ip route add.
Разделить маршрутизацию, DNS и файрвол помогают три проверки: ping по IP, ping по имени и ip route get. Этого хватает, чтобы за минуту понять уровень сбоя. Если ping 8.8.8.8 не проходит, а nslookup google.com отвечает корректно, резолвер тут не при чём: пакет не доходит до адреса. Если ping по IP проходит, а по имени нет, сломано разрешение имен, и смотреть нужно systemd-resolved и /etc/resolv.conf. Разбор различий между сбоем маршрута, DNS, firewall, VPN и MTU собран в материале как диагностировать проблемы маршрутизации на сервере.
Три быстрые проверки: ping по IP, ping по имени, ip route get
Первые команды занимают несколько секунд и не требуют прав root:
ping -c 3 8.8.8.8 ping -c 3 google.com ip route get 8.8.8.8
Вывод ip route get читается построчно:
8.8.8.8 via 192.168.1.1 dev eth0 src 192.168.1.10 uid 0
cache
via 192.168.1.1 это выбранный next-hop, dev eth0 это интерфейс, с которого уйдет пакет, src 192.168.1.10 это адрес источника, который ядро подставит автоматически. Ответ Network is unreachable означает, что маршрута нет: ни default, ни более специфичного. Если интерфейс или шлюз в выводе отличаются от ожидаемых, ищите причину в таблице маршрутов или в правилах ip rule.
Проверяйте не только 8.8.8.8. Запросите маршрут до конкретной цели: ip route get 10.20.30.40. Так сразу видно, уходит ли трафик во внутреннюю сеть через ожидаемый интерфейс или его забирает туннель VPN. Для источника с двумя адресами полезен запрос с указанием адреса: ip route get 8.8.8.8 from 192.168.1.10.
Как отличить проблему маршрутизации от файрвола
Ключ к различию лежит в направлении пакетов. Смотрите дамп на всех интерфейсах и сопоставляйте входящие и исходящие флаги:
tcpdump -i any -n -c 20 icmp tcpdump -i any -n -c 20 host 8.8.8.8
Сценарии читаются так. Видите исходящие SYN и ни одного ответа: либо ответ не возвращается из-за асимметричного маршрута, либо пакет режет фильтр на удаленной стороне. Видите входящий SYN, но сервер не отправляет SYN-ACK: смотрите локальные правила, iptables -L -n -v и nft list ruleset. Правило вида iptables -A INPUT -p tcp --dport 80 -j DROP отбрасывает пакет молча, без ответа, поэтому для клиента это выглядит как недоступность узла, а не как явный отказ. Для сравнения: REJECT, в отличие от DROP, отправляет ответный пакет — для TCP это RST/ACK, для UDP это ICMP destination port unreachable, как если бы сервер был доступен, но порт не слушался. Пакеты уходят, но не достигают шлюза: проверьте L2 командой arping -I eth0 -c 3 192.168.1.1. Если arping молчит, а ping по адресу шлюза тоже не проходит, проблема на канальном уровне: VLAN, кабель, MAC-адрес или таблица ip neigh. Полезно также заглянуть в conntrack -L, чтобы увидеть, отслеживает ли ядро эти соединения как established.
Проверка таблицы маршрутов через ip route: что искать и как исправлять
Основная команда диагностики это ip route show. Вывод типичного сервера выглядит так:
default via 192.168.1.1 dev eth0 proto static metric 100 192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.10 10.0.0.0/24 via 192.168.1.2 dev eth0 proto static metric 10
Как читать ip route show: proto, metric, scope, src
| Поле | Значение | Что означает на практике |
|---|---|---|
| proto kernel | Маршрут создало ядро при назначении адреса на интерфейс | Удалять вручную бессмысленно, он вернется при поднятии адреса |
| proto static | Маршрут добавлен вручную или через конфигурацию сети | Именно его правят при смене шлюза |
| proto dhcp | Маршрут получен от DHCP-сервера | Проверяйте lease: неверный gateway часто приходит именно отсюда |
| metric | Приоритет маршрута, меньше значит приоритетнее | При двух default побеждает меньшая метрика |
| scope link | Сеть подключена напрямую | Шлюз не нужен, доставка идет по ARP |
| scope global | Доставка через шлюз | Требуется рабочий next-hop и корректный ARP |
| src | Адрес источника по умолчанию | Неверный src ломает ответы при нескольких адресах на интерфейсе |
Два default route с метриками 100 и 200 сосуществуют нормально: активен маршрут с метрикой 100, второй лежит в резерве и включается, когда первый исчезает. Если метрики одинаковые, полагаться на конкретный выбор нельзя: поведение ядра при двух default route с одинаковой метрикой не определено и может отличаться между версиями, поэтому такие конфигурации использовать не рекомендуется. При попытке добавить маршрут, конфликтующий с уже существующим, ip route возвращает ошибку RTNETLINK answers: File exists. Если же несколько путей всё-таки установлены как multipath, заранее предсказать, куда уйдет конкретное соединение, нельзя. Это уже не резервирование, а источник нестабильности.
Типичные ошибки: неверный шлюз, конфликт маршрутов, отсутствие default route
Первый случай: ip route показывает default via 192.168.1.254, а реальный шлюз в сети 192.168.1.1. Симптомы: ping 8.8.8.8 не проходит, arping -I eth0 192.168.1.254 не получает ответа, ip neigh показывает FAILED для адреса шлюза. Исправление на время сессии:
ip route replace default via 192.168.1.1 dev eth0
Второй случай: два default route от разных менеджеров сети, например от NetworkManager и от статической конфигурации. Симптом: трафик периодически уходит через неправильный интерфейс, ping то работает, то нет. Сначала определите владельца маршрута, затем уберите лишний источник. Третий случай: строка default в выводе ip route отсутствует вовсе, а ping внешнего адреса отвечает Network is unreachable. Лечится добавлением маршрута, но только после проверки, что шлюз действительно доступен по ARP. Пять частых ошибок с разбором причин и команд разобраны в статье частые ошибки в настройке маршрутизации.
Безопасное изменение маршрутов на рабочем сервере
Правка маршрутов на продакшене может оборвать сессию управления за секунду. Порядок действий, который снижает риск:
- Убедитесь, что есть резервный доступ: IPMI, KVM, консоль гипервизора или второй сетевой интерфейс.
- Запустите работу внутри screen или tmux, чтобы команда не прервалась при обрыве SSH.
- Сохраните текущее состояние: ip route show > /root/route_backup.txt и ip rule show >> /root/route_backup.txt.
- Меняйте маршрут командой ip route replace, а не парой del и add: между удалением и добавлением сервер остается без маршрута.
- Сразу проверьте результат: ip route get 8.8.8.8 и ping -c 3 8.8.8.8.
Помните, что команды ip route и ip rule изменяют состояние ядра, но не сохраняются после перезагрузки. Чтобы маршруты и правила жили постоянно, их нужно прописать в конфигурационных файлах дистрибутива. В системах с NetworkManager (RHEL, CentOS, Fedora, современные Ubuntu) статические маршруты добавляют в конфигурацию интерфейса, например командой nmcli connection modify eth0 +ipv4.routes "192.168.100.0/24 10.0.0.1". В системах с systemd-networkd (Ubuntu Server и ряд других дистрибутивов) используются файлы с расширением .network. Альтернативный подход — systemd-юнит, в котором размещаются все нужные команды; при этом важно соблюдать порядок: сначала добавлять маршруты в таблицы, затем создавать правила. Как переносить команды в постоянную конфигурацию описано в руководстве настройка маршрутизации в Linux: таблицы и статические маршруты.
Правила ip rule: когда маршрутизация управляется политиками, а не таблицей main
Бывает так: ip route get показывает верный шлюз, дамп подтверждает уход пакетов, а ответы всё равно идут не туда. В этом случае таблицу main переопределяют правила маршрутизации.
Как читать ip rule show и находить нестандартные таблицы
Базовый вывод на любом Linux выглядит так:
0: from all lookup local 32766: from all lookup main 32767: from all lookup default
Правила применяются сверху вниз, приоритет задается числом: чем меньше число, тем раньше сработает правило. Таблица local содержит адреса самого хоста, main это основная таблица из ip route show, default обычно пуста. Если появляется правило с приоритетом меньше 32766, например 100: from 10.0.0.0/24 lookup 100, то для трафика из 10.0.0.0/24 ядро пойдет в таблицу 100, а таблица main останется в стороне.
Список именованных таблиц лежит в /etc/iproute2/rt_tables. Посмотреть содержимое конкретной таблицы можно командой ip route show table 100 или ip route show table custom. Пустая таблица означает, что пакеты из этого источника либо уйдут по правилу с большим приоритетом, либо получат Network is unreachable. Отдельная тема это метки fwmark: правило вида 200: from all fwmark 0x1 lookup 100 направляет трафик, помеченный nftables или iptables, и найти такую метку без чтения правил фильтрации невозможно.
Асимметричная маршрутизация: симптомы и исправление
Классический сценарий: eth0 с адресом 192.168.1.10 смотрит в клиентскую сеть, eth1 с адресом 10.0.0.10 идет во внутреннюю сеть, а default route ведет через 10.0.0.1. Клиент из 192.168.1.0/24 отправляет SYN на 192.168.1.10, пакет приходит на eth0, но ответ ищет маршрут по таблице main и уходит через eth1. Клиент ответа не получает. В дампе это видно как пара In eth0 и Out eth1.
Лечится политикой маршрутизации: ответы с конкретного адреса источника отправляются в отдельную таблицу со своим шлюзом.
ip rule add from 192.168.1.10 table 100 ip route add default via 192.168.1.1 dev eth0 table 100 ip route get 8.8.8.8 from 192.168.1.10
Последняя команда должна показать via 192.168.1.1 dev eth0. Удалить лишнее правило можно по приоритету: ip rule del priority 100 или целиком, указав источник: ip rule del from 192.168.1.10 table 100. Правила ip rule и маршруты в нестандартных таблицах не сохраняются после перезагрузки: их нужно прописать в конфигурации сети (netplan, systemd-networkd, NetworkManager) или в скрипте, который запускается при старте.
Проверка доступности шлюза и трассировка пути с traceroute
Прежде чем искать проблему на стороне провайдера, убедитесь, что локальный шлюз вообще отвечает. Проверка идет в два уровня: L2 через arping и L3 через ping.
arping и ping: проверка шлюза на L2 и L3
arping -I eth0 -c 3 192.168.1.1 ip neigh show dev eth0 ping -c 3 192.168.1.1 ping -I eth0 -c 3 192.168.1.1
Если arping не получает ответа, а ping по адресу шлюза тоже не проходит, сбой на канальном уровне: VLAN, порт коммутатора, MAC-адрес или конфликт IP. Если arping проходит, а ping не проходит, шлюз может просто блокировать ICMP, и это не признак аварии. Когда в ip neigh для шлюза стоит FAILED или запись отсутствует, ядро не может отправить пакет дальше L2, даже при корректной таблице маршрутов. Флаг -I полезен на серверах с несколькими интерфейсами: он заставляет ping использовать конкретный интерфейс и исключает выбор неверного пути. Смежные проверки ARP, MTU и правил nft на маршрутизаторе собраны в статье диагностика Linux-маршрутизатора: команды и решение типовых проблем.
traceroute, traceroute -I, traceroute -T: какой выбрать
Классический traceroute шлет UDP-пробы на «маловероятные» порты: порт первой пробы 33434, каждая следующая проба увеличивает порт на единицу. В man-странице traceroute указано, что для UDP и TCP базовый номер порта проб по умолчанию равен 33434. В современных сетях такие пакеты часто фильтруют, поэтому вывод превращается в цепочку звездочек. Варианты по типу трафика:
- traceroute -I 8.8.8.8 использует ICMP Echo, работает там, где ICMP не заблокирован.
- traceroute -T -p 443 8.8.8.8 использует TCP-пробы: этот метод предназначен для обхода файрволов и применяет постоянный порт назначения (по умолчанию 80, http). Порт 443 выбирают, когда он разрешен в сети, но гарантий «самой достоверной картины» TCP-метод не дает.
- mtr -T -P 443 8.8.8.8 показывает потери и задержки на каждом хопе в динамике, что удобнее разового запуска.
Чтение вывода простое:
1 192.168.1.1 0.5 ms 2 10.0.0.1 1.2 ms 3 * * * 4 8.8.8.8 10.5 ms
Звездочки на третьем хопе не означают потерю пакетов: промежуточный маршрутизатор может не отвечать на пробы, пропуская трафик дальше. Тревожный признак другой: трассировка обрывается, а конечный адрес не достигается. Если последний отвечающий хоп принадлежит провайдеру, дальше ищите проблему у него, а не на сервере. И помните, что traceroute показывает путь только в одну сторону: обратный маршрут проверяется запуском трассировки с удаленной стороны.
tcpdump: подтверждаем, что пакеты уходят и возвращаются
Дамп снимает все сомнения: он показывает, покидают ли пакеты сервер, доходят ли до интерфейса и приходят ли ответы. Это самый надежный способ отделить проблему маршрутизации от проблемы приложения или удаленного фильтра.
Базовые команды tcpdump для диагностики маршрутизации
tcpdump -i any -n -c 20 icmp tcpdump -i any -n -e -c 20 host 8.8.8.8 tcpdump -i eth0 -n port 443 tcpdump -i any -n -e arp tcpdump -i eth0 -n -w /tmp/cap.pcap tcpdump -r /tmp/cap.pcap -n
Опции, которые нужны чаще всего: -i any слушает все интерфейсы, -n отключает разрешение имен и ускоряет вывод, -e добавляет MAC-адреса и метки In и Out, -c ограничивает число пакетов, -w пишет дамп в файл для разбора, -r читает сохраненный файл. Комбинация -i any и -e особенно полезна при асимметрии: строка In eth0 Out eth1 означает, что пакет пришел на один интерфейс, а ушел через другой. Фильтр arp пригодится, когда нужно понять, разрешается ли адрес шлюза и не отвечает ли на него кто-то чужой.
На высоконагруженном интерфейсе дамп без фильтров создает нагрузку и быстро забивает диск. Ограничивайте захват конкретным хостом, портом и количеством пакетов, а для длительного разбора пишите в файл с ротацией.
Как читать флаги TCP и ICMP-сообщения при проблемах маршрутизации
| Что видно в дампе | Вероятная причина |
|---|---|
| Исходящий SYN, ответа нет | Обратный маршрут уходит не туда или ответ режет фильтр |
| Входящий SYN, нет SYN-ACK | Локальный файрвол или сервис не слушает порт |
| RST в ответ на SYN | Порт закрыт либо правило reject вместо drop |
| ICMP Destination Unreachable, Network Unreachable | Нет маршрута до сети назначения |
| ICMP Host Unreachable | ARP не разрешается, хост не отвечает на L2 |
| ICMP Fragmentation needed, mtu | Проблема MTU, а не маршрутизации |
| ICMP TTL exceeded | Петля маршрутизации или слишком длинный путь |
Отдельного внимания требует сообщение ICMP need to frag с указанием mtu, например mtu 1400. Согласно RFC 1191, маршрутизатор, возвращающий ICMP-сообщение «fragmentation needed and DF set», обязан включить MTU сети следующего перехода в младшие 16 бит поля ICMP-заголовка, помеченного в RFC 792 как «unused». Это сообщение относится к технике Path MTU Discovery: PMTU равен минимуму MTU каждого перехода на пути. Маршрут при этом корректен, а крупные пакеты теряются из-за туннеля или PPPoE. Симптом проявляется так: ping проходит, SSH и мелкие запросы работают, а загрузка файлов и TLS-рукопожатия зависают. Уменьшение MTU интерфейса или MSS clamping на маршрутизаторе — распространённый способ обойти такую ситуацию, но конкретную настройку подбирайте под свою топологию.
Реальные кейсы: неверный шлюз, конфликт маршрутов, асимметрия
Кейс 1: неверный шлюз после смены DHCP
Сервер получает адрес по DHCP, и после замены DHCP-сервера в lease попадает шлюз 192.168.1.254 вместо рабочего 192.168.1.1. Признаки: ip route показывает default via 192.168.1.254 dev eth0 proto dhcp metric 100, ping 8.8.8.8 не проходит, arping -I eth0 -c 3 192.168.1.254 молчит. Немедленное исправление без перезагрузки:
ip route replace default via 192.168.1.1 dev eth0 ip route get 8.8.8.8
Постоянное исправление зависит от менеджера сети. В netplan файл /etc/netplan/01-netcfg.yaml получает явный шлюз, затем применяется netplan apply. В NetworkManager достаточно команды nmcli connection modify eth0 ipv4.gateway 192.168.1.1 и повторного поднятия соединения. Перед правкой YAML проверяйте синтаксис: ошибка в отступах и netplan apply оставит сервер без сети.
Кейс 2: конфликт маршрутов от NetworkManager и статической конфигурации
Симптом: ip route show выдает два default route, трафик уходит то через один интерфейс, то через другой, внешние сервисы отвечают с перебоями. Причина: маршруты одновременно прописывают NetworkManager и статическая конфигурация. Порядок разбора:
- Определите активный менеджер: systemctl status NetworkManager и systemctl status systemd-networkd.
- Посмотрите профили: nmcli connection show и содержимое /etc/network/interfaces.
- Уберите дублирующий источник, а не сам маршрут: иначе он вернется при следующем поднятии соединения.
- Сверьте результат: ip route show должен содержать ровно один default route.
Отключать NetworkManager на удаленном сервере без резервного доступа нельзя: после остановки службы интерфейс может потерять адрес, и сессия оборвется вместе с правами на исправление.
Кейс 3: асимметричная маршрутизация на сервере с двумя интерфейсами
Сервер: eth0 с адресом 192.168.1.10, eth1 с адресом 10.0.0.10, default route через 10.0.0.1. Клиент из сети 192.168.1.0/24 подключается к сервису на 192.168.1.10. Входящий SYN приходит на eth0, но ответ уходит через eth1, и клиент его не видит. Дамп подтверждает картину: In eth0 Out eth1.
ip rule add from 192.168.1.10 table 100 ip route add default via 192.168.1.1 dev eth0 table 100 ip route get 8.8.8.8 from 192.168.1.10
Теперь ответы с адреса 192.168.1.10 уходят через тот же интерфейс, откуда пришел запрос. Правила и нестандартные таблицы живут до перезагрузки: переносите их в netplan, systemd-networkd, NetworkManager или в скрипт запуска, иначе после maintenance-окна сбой вернется.
Чек-лист диагностики и типичные ошибки
Пошаговый алгоритм: от ping до tcpdump
- ping -c 3 8.8.8.8: проверка L3. Норма это ответы с нулевыми потерями. Network is unreachable означает отсутствие маршрута.
- ping -c 3 google.com: проверка DNS. Отказ при рабочем первом шаге указывает на резолвер, а не на маршруты.
- ip route get 8.8.8.8: какой шлюз, интерфейс и src выбрало ядро. Сравните с ожидаемыми значениями.
- ip route show: наличие одного default route, корректные метрики, отсутствие дублей.
- ip rule show: нет ли правил с приоритетом меньше 32766, уводящих трафик в другие таблицы.
- arping -I eth0 -c 3 192.168.1.1 и ip neigh show: разрешается ли адрес шлюза.
- traceroute -T -p 443 8.8.8.8 или mtr -T -P 443 8.8.8.8: где обрывается путь.
- tcpdump -i any -n -e host 8.8.8.8: уходят ли пакеты и приходят ли ответы, нет ли метки In на одном интерфейсе и Out на другом.
Такой же последовательный разбор с интерпретацией вывода ping, traceroute и mtr приведен в статье диагностика проблем маршрутизации: инструменты и методика поиска причины.
Ошибки, которые приводят к потере доступа к серверу
- ip route del default без проверки альтернативного пути. Удаляйте и добавляйте одним действием через ip route replace.
- Правка маршрутов по SSH без screen или tmux: обрыв связи означает потерю доступа к консоли.
- Остановка NetworkManager на удаленном сервере ради устранения конфликта маршрутов.
- Запуск netplan apply с ошибкой в YAML: сначала netplan generate, потом apply.
- Удаление маршрута, по которому идет управляющий трафик.
- Забыли перенести маршруты и правила в конфигурацию: после перезагрузки сбой возвращается.
Безопасная схема изменения выглядит так: получаете резервный доступ, добавляете новый маршрут с меньшей метрикой, проверяете ip route get и связь, удаляете старый маршрут, а затем переносите изменения в постоянную конфигурацию. Дополнительная страховка на критичном сервере это отложенный откат: echo 'ip route replace default via 192.168.1.254 dev eth0' | at now + 5 minutes. Если связь не пропала, задание снимается командой atrm, и сервер остается на новом маршруте.