open atlas
↑ К треку
Linux: операционная система LIN · 09 · 02

Маршрутизация

Таблица маршрутизации — структура данных ядра, определяющая интерфейс и следующий хоп для пакета. ip route показывает её, ip route get спрашивает ядро, какой маршрут победит для конкретного адреса. Маршрут default (0.0.0.0/0) — шлюз-ловушка.

LIN Middle ◷ 20 min
Уровень
ОсновыJuniorMiddleSenior

Ты видишь, что у интерфейса есть IP — но почему машина вообще достигает интернета? Почему она достигает 10.0.0.20, но не 172.16.0.5? Ответ всегда в таблице маршрутизации. Каждый пакет, который ядро отправляет, проходит поиск: какой маршрут соответствует адресу назначения? Побеждает маршрут с самым длинным совпадающим префиксом, и он указывает egress-интерфейс и адрес следующего хопа. Когда конкретного маршрута нет — срабатывает маршрут по умолчанию 0.0.0.0/0. Когда этого маршрута нет — машина общается только с локальной подсетью. Классический инцидент: «интернет работает с ноутбука, но не с VM».

Цель

После этого урока ты сможешь читать вывод ip route и находить шлюз по умолчанию, использовать ip route get <ip> чтобы спросить ядро, какой маршрут победит для конкретного адреса, понимать правило longest-prefix match, добавлять и удалять статические маршруты, и диагностировать отсутствие маршрута по умолчанию.

1

ip route show — чтение таблицы маршрутизации.

ip route show
# default via 10.0.0.1 dev ens3 proto dhcp src 10.0.0.10 metric 100
# 10.0.0.0/24 dev ens3 proto kernel scope link src 10.0.0.10

# Разбор строк:
# default          = 0.0.0.0/0 — маршрут-ловушка
# via 10.0.0.1     = следующий хоп: отправить пакет этому шлюзу
# dev ens3         = egress-интерфейс
# proto dhcp       = маршрут установлен DHCP-клиентом
# src 10.0.0.10    = предпочтительный адрес источника для трафика по этому маршруту
# metric 100       = стоимость; меньший metric выигрывает при равных совпадениях
#
# 10.0.0.0/24 dev ens3  = для адресатов в 10.0.0.0/24 — отправить напрямую на ens3
# scope link             = шлюз не нужен — адресат на том же канале
# proto kernel           = создан автоматически при ip addr add

Маршрут 10.0.0.0/24 со scope link означает: ядро знает, что хосты в этой подсети доступны без шлюза — оно выполнит ARP и отправит кадр напрямую. Всё за пределами этого диапазона попадает на маршрут по умолчанию.

2

Longest-prefix match: правило, определяющее победителя.

При отправке пакета ядро сравнивает адрес назначения со всеми маршрутами и выбирает наиболее специфичный — с самым длинным совпадающим префиксом.

# Таблица маршрутизации на host-a (10.0.0.10):
# default via 10.0.0.1 dev ens3
# 10.0.0.0/24 dev ens3 scope link
# 192.168.5.0/24 via 10.0.0.254 dev ens3

# Отправка на 10.0.0.20:
# Кандидаты: default (0 бит), 10.0.0.0/24 (24 бита)
# Победитель: 10.0.0.0/24 — напрямую на ens3

# Отправка на 192.168.5.100:
# Кандидаты: default (0 бит), 192.168.5.0/24 (24 бита)
# Победитель: 192.168.5.0/24 → следующий хоп 10.0.0.254

# Отправка на 8.8.8.8 (интернет):
# Кандидаты: только default (0 бит)
# Победитель: default → следующий хоп 10.0.0.1 (шлюз)

/32 — самый специфичный маршрут (один хост). Хост-маршрут вроде 192.0.2.1/32 via 10.0.0.1 побеждает любой подсетевой маршрут, содержащий этот адрес.

3

ip route get <destination> — спросить ядро, какой маршрут победит.

Вместо того чтобы выполнять логику longest-prefix match в голове, спроси ядро напрямую:

# Какой маршрут использует ядро для 8.8.8.8?
ip route get 8.8.8.8
# 8.8.8.8 via 10.0.0.1 dev ens3 src 10.0.0.10 uid 1000
#     cache

# Маршрут для машины в локальной подсети:
ip route get 10.0.0.20
# 10.0.0.20 dev ens3 src 10.0.0.10 uid 1000
#     cache
# Нет "via" — прямая доставка, шлюз не нужен

# Если нет маршрута по умолчанию:
ip route get 8.8.8.8
# RTNETLINK answers: Network is unreachable
# → отсутствие default-маршрута подтверждено

ip route get — самый быстрый способ диагностировать «почему хост не может достичь X» — он показывает ровно то, что сделает ядро, включая выбор адреса источника, до отправки единого пакета.

4

Добавление и удаление статических маршрутов.

DHCP поставляет шлюз по умолчанию автоматически. Статические маршруты нужны для дополнительных подсетей, доступных через конкретный шлюз:

# Добавить маршрут: подсеть 192.168.10.0/24 через 10.0.0.254
sudo ip route add 192.168.10.0/24 via 10.0.0.254

# Проверить:
ip route show
# default via 10.0.0.1 dev ens3
# 10.0.0.0/24 dev ens3 scope link
# 192.168.10.0/24 via 10.0.0.254 dev ens3

# Удалить:
sudo ip route del 192.168.10.0/24 via 10.0.0.254

# С явным интерфейсом:
sudo ip route add 192.168.10.0/24 via 10.0.0.254 dev ens3

# Хост-маршрут:
sudo ip route add 192.0.2.100/32 via 10.0.0.1

Эти изменения не сохраняются. При перезагрузке таблица маршрутизации ядра пуста; сетевая инициализация (DHCP-клиент, netplan, systemd-networkd) пересоздаёт её. Для сохранения статических маршрутов используй /etc/network/interfaces со строками up ip route add ... или routes: в netplan.

5

Отсутствие маршрута по умолчанию: классический инцидент.

VM достигает 10.0.0.20, но не 8.8.8.8 и ничего за пределами подсети. Симптом: ping 10.0.0.20 работает, ping 8.8.8.8 падает с «Network is unreachable».

# Подтвердить: нет маршрута по умолчанию
ip route show | grep default
# (пусто)

# Подтвердить через route get:
ip route get 8.8.8.8
# RTNETLINK answers: Network is unreachable

# Временное исправление:
sudo ip route add default via 10.0.0.1

# Подтвердить исправление:
ip route get 8.8.8.8
# 8.8.8.8 via 10.0.0.1 dev ens3 src 10.0.0.10

# Причины:
# 1. DHCP-клиент не запустился или упал — проверь: systemctl status dhclient
# 2. Статическая конфигурация не содержит шлюза — проверь /etc/network/interfaces
# 3. Маршрут был удалён вручную и не восстановлен
Разбор примера

Диагностика: host-a не может достичь staging-подсети.

host-a (10.0.0.10) должен достигать 192.168.20.0/24 (staging). Соединения зависают.

# Шаг 1: есть ли маршрут в таблице?
ip route show | grep 192.168.20
# (пусто)

# Шаг 2: ip route get подтверждает отсутствие маршрута
ip route get 192.168.20.5
# RTNETLINK answers: Network is unreachable

# Шаг 3: добавить маршрут (шлюз 10.0.0.254 обслуживает staging)
sudo ip route add 192.168.20.0/24 via 10.0.0.254

# Шаг 4: проверить
ip route get 192.168.20.5
# 192.168.20.5 via 10.0.0.254 dev ens3 src 10.0.0.10

# Шаг 5: проверить связность
ping -c 3 192.168.20.5

# Шаг 6: сохранить в netplan (/etc/netplan/01-netcfg.yaml):
# network:
#   ethernets:
#     ens3:
#       routes:
#         - to: 192.168.20.0/24
#           via: 10.0.0.254
Частая ошибка

Добавление маршрута без проверки достижимости шлюза. Если запустить sudo ip route add 192.168.20.0/24 via 10.0.0.254, но 10.0.0.254 не находится в локальной подсети (недоступен через scope link маршрут), ядро примет команду, но каждый пакет будет недоставляемым. Симптом: ip route get 192.168.20.5 успешен, но ping зависает. Всегда проверяй достижимость шлюза через ip route get 10.0.0.254 перед добавлением маршрутов, использующих его.

Почему это работает

На macOS таблица маршрутизации читается через netstat -rn (или route -n get <ip> для конкретного адреса). Логика — longest-prefix match, шлюз по умолчанию, scope link маршруты — идентична. macOS использует BSD routing sockets, а не Linux netlink; концепции переносятся полностью, хотя команды различаются.

Проверь себя
Викторина

У host-a такие маршруты: default via 10.0.0.1 dev ens3, и 10.0.0.0/24 dev ens3 scope link. Ты запускаешь: ip route get 10.0.0.50. Какой маршрут победит и что произойдёт дальше?

Итог

Таблица маршрутизации — структура данных ядра, которую консультирует каждый исходящий пакет. Longest-prefix match выбирает наиболее специфичный маршрут — /32 бьёт /24 бьёт default 0.0.0.0/0. ip route show читает таблицу; ip route get <destination> спрашивает ядро, какой маршрут реально победит для конкретного адреса, включая выбор адреса источника. ip route add/del управляет статическими маршрутами, но изменения теряются при перезагрузке — сохраняй их через netplan или /etc/network/interfaces. Отсутствие маршрута по умолчанию оставляет хосту только доступ к локальной подсети и является наиболее частой причиной «интернет недоступен» на новых VM.

Практика

Начни сверху. Задачи идут от простого к сложному: вспомнить факт, применить к случаю, затем senior-уровень. Открой, попробуй, потом открой ответ.

вспомнитьприменитьуглубить0 из 4 завершено

Что-то непонятно?

Задай вопрос по этому уроку. Вопросы анонимны и попадают напрямую автору — урок станет лучше.

хоткеи развернуть
поиск
K
пред. пьеса
k
след. пьеса
j
тиры
t
это меню
?
sources1
expand
  1. 01

Trademarks belong to their respective owners. Editorial reference only.