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

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

Ссылка на страницу

  • linux/routing.txt
  • Последнее изменение: 2024/05/30 12:50
  • Дмитрий