linux:routing

Это старая версия документа!


Роутинг в Linux

Есть два инструмента ip и route, это я взял из одного из источников в интернете.

  • route - Устаревшая утилита, входящая в состав пакета net-tools. Служит для отображения таблицы маршрутизации и построения статических маршрутов.
  • ip route - Обновленный инструмент, призванный заменить Route. Имеет большую функциональность, по сравнению со своим предшественником.

Если честно, ни разу не пользовался route и всегда использовал ip.

Я давно знаком с ip route, но до недавнего времени редко им пользовался и почти все свои хотелки, настраивал в iptables или nftables, а зря некоторые вещи лучше делать именно в ip route и ip rule.
Утилита ip дополняет, упрощает и облегчает управление трафиком в Linux, но раньше я им пользовался только для управления двумя и более белыми адресами например на VDS.

У меня не получится рассказать тут всё про утилиту ip, возможно в будущем буду дополнять.
Тема большая и я дам пару ссылок для самостоятельного изучения, а так же постараюсь показать основные моменты для быстрого понимания что к чему.

Синтаксис ip на OpenNET (на Русском)
Ubuntu manuals - ip-route (на Английском)
ip route Man Page - Linux-SS64 (на Английском)

Очень понравились статьи, чем больше читаете, тем больше понимаете).
Маршрутизация на основе политик. Часть первая
Маршрутизация на основе политик. Часть вторая
Маршрутизация на основе политик. Часть третья
Маршрутизация на основе политик. Часть четвертая

Приведу один пример, пока просто описание ситуации, практика позже.
Вам потребовалось изолировать некоторые сети или отдельные адреса (направления), от всех участников сети и пропускать туда только некоторые (админов к примеру).

  1. Делаем отдельную таблицу маршрутов (admin)
  2. Добавляем в таблицу (admin) нужные нам адреса и сети
  3. Выше таблицы (main) одно или несколько правил для конкретного или для нескольких адресов с перенаправлением в таблицу (admin).

Получается, что указанные адреса выше таблицы (main), будут сначала попадать в таблицу (admin) и уже потом возвращаться в таблицу (main), а все остальные адреса,
пропустят это правило и сразу попадут в таблицу (main).

Что бы подобное решить в iptables или nftables, в принципе так же не сложно, можно просто не разрешать прохождение трафика в определённом направлении, но это уже дополнительные правила в файерволе,
что может затруднить администрирование файервола и повлечёт за собой лишнюю нагрузку на устройство.
Иногда, правил файервола настолько много, что порой сложно потом разобраться как же всё таки у вас проходит трафик по ним, а тут вы в два правила, можете решить похожую задачу.

К сожалению, данный пример не всегда хорошее решение хоть и рабочее, тут есть один подвох, просто описание было простым.
В дальнейшем я разберу его по полочкам и объясню в чём тут подвох.

  1. Управление трафиком с нескольких белых адресов
  2. Управление трафиком для разных адресов в локальной сети и направить их в разные направления (распределение по провайдерам к примеру)
  3. Управление маркированным трафиком, например вы поставили метки в файерволе и вам требуется отправить разные метки по разным направлениям

Вы наверняка сами делали или слышали, что надо добавить какой-то маршрут и обычно это выглядит так.

Linux

  1. ip route add 8.8.8.8 via 192.168.0.18
  2. ip route add 8.8.8.8 via 192.168.0.18 dev eth0 # С уточнением интерфейса

Windows

  1. route add 8.8.8.8 mask 255.255.255.255 192.168.0.18
  2. route add 8.8.8.8 mask 255.255.255.255 192.168.0.18 -p # Сохранить маршрут после перезагрузки

Тут я привёл пример добавления маршрута для 8.8.8.8 через 192.168.0.18, смысл тот же системы разные.

В дальнейшем по статье, я больше не буду приводить в пример Windows, с этим в Windows я практический не знаком.

В Linux, как говорится из коробки, уже есть предустановленные три таблицы local, main и default
Приведённый пример с маршрутом для 8.8.8.8, по умолчанию будет анонсирован в таблицу main

Прошу простить меня, но что бы не раздувать статью и не воровать чужие слова,
я опущу некоторые моменты, просто прочтите небольшую статью, не хочется переписывать её сюда и там всё хорошо описано).
Маршрутизация на основе политик. Часть первая

Что бы посмотреть приоритет таблиц и за одно таблицы по умолчанию.

ip rule
0:      from all lookup local
32766:  from all lookup main
32767:  from all lookup default

Обратите внимание на первую колонку, это приоритет от 0 и не знаю до сколько,
у меня получалось сделать и 1 000 000, но это лишнее обычно до 100 000 более чем достаточно).

Приоритет можно и нужно указывать когда будете составлять свои правила. Если не указывать приоритет, все ваши правила буду начитаться от 32766 и ближе к нулевому в обратном порядке, иногда вам это точно не надо.

По большому счёту, считаю таблицы local и default не интересными, если вы читали рекомендованную статью, тогда я с вашего позволения сразу перейду к таблице main.

Таблица main

Если в построении правил вы не указываете таблицу, тогда маршруты всегда будут анонсированы в таблице main.
Я про пример выше.

Linux

  1. ip route add 8.8.8.8 via 192.168.0.18
  2. ip route add 8.8.8.8 via 192.168.0.18 dev eth0 # С уточнением интерфейса
ip route show table main
default via 192.168.0.14 dev eth0 
8.8.8.8 via 192.168.0.18 dev eth0 
192.168.0.0/24 dev eth0 proto kernel scope link src 192.168.0.26

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

Почему будет правильней анонсировать маршруты в таблице по умолчанию?
Тут всё просто, IPv4 как и IPv6 будут маршрутизироваться туда где меньше адресов, ну или больше больше маска сети.

Просто для справки
192.168.0.1/32 - максимально большая маска, адрес только один
192.168.0.0/24 - привычная маска, 254 адреса
192.168.0.0/22 - маска меньше адресов больше, 1022 адреса

Вот пример

Анонсируем маршруты

ip route add 192.168.0.0/24 via 192.168.0.18
ip route add 192.168.0.0/22 via 192.168.0.12

Смотрим что получилось

ip route
default via 192.168.0.14 dev eth0 
8.8.8.8 via 192.168.0.18 dev eth0 
192.168.0.0/24 dev eth0 proto kernel scope link src 192.168.0.26 
192.168.0.0/24 via 192.168.0.18 dev eth0 
192.168.0.0/22 via 192.168.0.12 dev eth0

Тут я анонсировал две сети с разными маршрутами и не смотря на то что сеть 192.168.0.0/24 по факту входит в состав сети 192.168.0.0/22, сеть 192.168.0.0/24 будет маршрутизироваться на 192.168.0.18 адрес,
а сети 192.168.1.0/24, 192.168.2.0/24 и 192.168.3.0/24 уже будет маршрутизироваться на 192.168.0.12 адрес, в данном примере.

...
192.168.0.0/24 via 192.168.0.18 dev eth0 
192.168.0.0/22 via 192.168.0.12 dev eth0

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

Давайте представим ситуацию, когда у вас адрес 192.168.8.4 является внешним DNS сервером для всех участников сети,
но вот например для бухгалтерии, внешний DNS с таким же адресом 192.168.8.4 только в другой сети, соответственно с другим маршрутом.

Давайте попробуем добавить маршруты.

ip route add 192.168.8.4 via 192.168.0.18 dev eth0
ip route add 192.168.8.4 via 192.168.0.19 dev eth0
RTNETLINK answers: File exists

И на последнем маршруте, вы получите ошибку, т.к. одна таблица не может содержать разные маршруты для одного и того же адреса.
Исключением может служить разные метрики, но тут теряется смысл и бухгалтерия всё равно не получит нужный маршрут.

Это сработает, но работать не будет как вам надо. Про метрики позже.
ip route add 192.168.8.4 via 192.168.0.19 dev eth0 metric 100

В итоге, вы получите только один маршрут.

ip route show table main
default via 192.168.0.14 dev eth0 
192.168.8.4 via 192.168.0.18 dev eth0 
192.168.0.0/24 dev eth0 proto kernel scope link src 192.168.0.26

Что бы нам правильно отправить бухгалтерию к нужному им DNS, надо добавить отдельную таблицу маршрутизации.

Давайте добавим запись о новой таблице, можно в конце файла это не важно.

nano /etc/iproute2/rt_tables

Тут мы в праве создавать нужные нам таблицы, с номерами в диапазоне от 1 по 252, обычно это 100, 101 и т.д.

...
100     buh_dns
  • buh_dns - это просто алиас к номеру 100, вы можете указывать что угодно buh1, vpn1, buhexit ну и наконец buh_dns, в обще не важно.

Теперь мы можем добавить похожий маршрут в таблицу 100 или по её алиасу buh_dns.

ip route add 192.168.8.4 via 192.168.0.19 table buh_dns
  • Таблицу можно указывать как номер так и алиас, это уже как вам будет удобнее.

Если у вас несколько сетевых интерфейсов, вам может потребоваться указать и интерфейс

ip route add 192.168.8.4 via 192.168.0.19 dev eth1 table buh_dns
  • dev eth1 - второй интерфейс, ну или просто другой.

Можно посмотреть что у нас теперь в таблице buh_dns

ip route show table buh_dns
192.168.8.4 via 192.168.0.19 dev eth0

Теперь вам нужно добавить приоритет маршрута для адресов бухгалтерии, которым требуется этот DNS и делается это через ip rule.

ip rule add from 192.168.0.30 iif eth0 table buh_dns prio 20000
  • iif eth0 - интерфейс с которого будут приходить пакеты от 192.168.0.30, можно не указывать но желательно.

В данном примере, мы добавили приоритет маршрута 20000, перед таблицей main, у которой приоритет 32766.
Теперь ПК с адресом 192.168.0.30, сначала будет искать маршруты в таблице buh_dns, там он найдёт маршрут 192.168.8.4 через 192.168.0.19
и уже потом перейдёт в таблицу main, для поиска других маршрутов, но только уже для других адресов.

Что бы добавить ещё один ПК с нужным маршрутом, указывайте всё так же, допускается указывать один и тот же приоритет.

ip rule add from 192.168.0.31 iif eth0 table buh_dns prio 20000

Так же можно указывать сеть частями. Например ваша бухгалтерия находится в диапазоне от 192.168.0.17 до 192.168.0.30,
тогда вы можете указать адрес с маской 28

ip rule add from 192.168.0.17/28 iif eth0 table buh_dns prio 20000

Тут вам в помощь, могу порекомендовать IP калькулятор, он прекрасно считает любые сети.
Онлайн IP калькулятор

Таким образом, ПК бухгалтеров на этом шлюзе будут получать такие же маршруты как и все остальные, за исключением 192.168.8.4.

Посмотрим приоритеты

ip rule
0:      from all lookup local
20000:  from 192.168.0.30 iif eth0 lookup buh_dns
20000:  from 192.168.0.31 iif eth0 lookup buh_dns
20000:  from 192.168.0.17/28 iif eth0 lookup buh_dns
32766:  from all lookup main
32767:  from all lookup default

Один и тот же ПК или виртуалка, или роутер например на OpenWRT, при наличии нескольких сетевых интерфейсов, либо с настроенными VLAN с разными тегами 802.1Q например,
может работать как два и более шлюзов для нескольких сетей.

Допустим в вашей организации несколько провайдеров и несколько сетей. Например бухгалтерия 192.168.8.0/24, а хоз. часть 192.168.9.0/24.

  • ens20 шлюз 10.10.8.1 - Провайдер 1
  • ens21 шлюз 10.10.9.1 - Провайдер 2
  • ens22 192.168.8.0/24 - Сеть бухгалтерии
  • ens23 192.168.9.0/24 - Сеть хоз. часть
  • ens20 10.10.8.26/24 - адрес интерфейса, провайдер 1
  • ens21 10.10.9.26/24 - адрес интерфейса, провайдер 2
  • ens22 192.168.8.26/24 - адрес интерфейса, сеть бухгалтерии
  • ens23 192.168.9.26/24 - адрес интерфейса, сеть хоз. часть

Давайте добавим записи о новых таблицах, как в примере выше.

nano /etc/iproute2/rt_tables
...
100     inet1
101     inet2

Давайте назначим этим таблицам маршруты по умолчанию (default)

ip route add default via 10.10.8.1 table inet1
ip route add default via 10.10.9.1 table inet2

Можно проверить

ip route show table inet1
default via 10.10.8.1 dev ens20

и

ip route show table inet2
default via 10.10.9.1 dev ens21

В текущей задаче, есть одна особенность. Если мы вспомним, что у нас в таблице main указаны маршруты до внутренних сетей,
тогда получается что мы не можем указать сетям 192.168.8.0/24 и 192.168.9.0/24 маршруты по умолчанию выше таблицы main,
внутренние сети перестанут работать и вы потеряете доступ к серверу.

В этом случае, следует указать приоритет ниже 32767 и я предлагаю указать 35000 и 35001.

ip rule add from 192.168.8.0/24 iif ens22 table inet1 prio 35000
ip rule add from 192.168.9.0/24 iif ens23 table inet2 prio 35001
ip rule
0:      from all lookup local
32766:  from all lookup main
32767:  from all lookup default
35000:  from 192.168.8.0/24 iif ens22 lookup inet1
35001:  from 192.168.9.0/24 iif ens23 lookup inet2

Но и это ещё не всё, во время настройки сервера, вы наверняка указывали какой-то шлюз, что бы сам сервер имел доступ к интернету,
в моём случае, пусть будет 10.10.8.1.

ip route show table main
default via 10.10.8.1 dev ens20
10.10.8.0/24 dev ens20 proto kernel scope link src 10.10.8.26
10.10.9.0/24 dev ens21 proto kernel scope link src 10.10.9.26
192.168.8.0/24 dev ens22 proto kernel scope link src 192.168.8.26
192.168.9.0/24 dev ens23 proto kernel scope link src 192.168.9.26

Получается, что все участники сети, так или иначе попадают в default и правила которые мы добавили ниже с приоритетом 35000 и 35001, бесполезны.
В данной ситуации, мы просто удалим маршрут по умолчанию.

ip route del default via 10.10.8.1

Но и это ещё не всё, т.к. мы удалили маршрут по умолчанию, а правила с приоритетом 35000 и 35001 будут работать только для указанных сетей,
сам сервер потеряет доступ к интернету. Исправим это положение, одним правилом и тут вы должны сами определиться какой интернет сделать доступным для сервера.

  • linux/routing.1706361728.txt.gz
  • Последнее изменение: 2024/01/27 20:22
  • Дмитрий