0

Маршрутизация на основе политик. Часть первая.

26.07.2023

Так будет выглядеть роутинг при использовании на интерфейсе enp0s3 ip-адреса 192.168.110.50 с маской подсети 255.255.255.0 и шлюзом по умолчанию 192.168.110.1:

# ip route show
default via 192.168.110.1 dev enp0s3
192.168.110.0/24 dev enp0s3 proto kernel scope link src 192.168.110.50Копировать

Вторая запись означает:

  • пакеты в подсеть 192.168.110.0/24 уходят через интерфейс enp0s3
  • proto kernel — маршрут был добавлен ядром при назначении интерфейсу ip-адреса
  • scope link — запись действительна только для интерфейса enp0s3
  • src 192.168.110.50 — задает ip-адрес отправителя пакетов для этого правила

Первая запись означает, что пакеты на любые хосты, не попадающие в подсеть 192.168.110.0/24 будут уходить в шлюз 192.168.110.1 через интерфейс enp0s3. Шлюз, в свою очередь, меняет ip-адрес отправителя, если используется NAT, либо просто отправляет пакет дальше.

Маршрутизация на основе политик

Существуют два механизма маршрутизации: классический destination-routing (на основе адреса назначения) и сравнительно новый policy-routing (на основе политик). Маршрутизация на основе политик применяется в случае наличия нескольких сетевых интерфейсов и необходимости отправлять определенные пакеты через определенный интерфейс. Маршрут пакета определяется не только на основе адреса назначения — есть возможность анализа практически любых полей пакета.

В основе маршрутизации с использованием политик лежат четыре понятия:

  • Адрес (address) определяет ip-адрес места назначения пакета
  • Маршрут (route) задает путь пакета, как в традиционной маршрутизации
  • Таблица маршрутизации (routing table) состоит из набора нескольких маршрутов
  • Правила (rule) позволяют отбирать нужные пакеты и направлять по заданному маршруту

Таблицы маршрутизации

Изначально предопределены таблицы мартшрутизации localmain и default:

  • В таблицу local ядро заносит записи для локальных ip-адресов (чтобы трафик на эти ip-адреса оставался локальным и не пытался уходить во внешнюю сеть), а также для бродкастов.
  • Таблица main является основной и именно она используется, если в команде ip route не указано какую таблицу использовать (в самом начале мы видели именно таблицу main).
  • Таблица default изначально пуста.

Давайте посмотрим на содержимое таблицы local:

# ip route show table local
broadcast 127.0.0.0 dev lo proto kernel scope link src 127.0.0.1
local 127.0.0.0/8 dev lo proto kernel scope host src 127.0.0.1
local 127.0.0.1 dev lo proto kernel scope host src 127.0.0.1
broadcast 127.255.255.255 dev lo proto kernel scope link src 127.0.0.1
broadcast 192.168.110.0 dev enp0s3 proto kernel scope link src 192.168.110.50
local 192.168.110.50 dev enp0s3 proto kernel scope host src 192.168.110.50
broadcast 192.168.110.255 dev enp0s3 proto kernel scope link src 192.168.110.50Копировать

Выше мы уже сталкивались с типом записи default, но здесь мы видим еще local и broadcast:

  • broadcast — для этой записи пакеты будут отправлены как широковещательное сообщение
  • local — для этой записи пакеты будут отправлены локально, без выхода во внешнюю сеть

Кроме того, типы записи могут быть unicastunreachableblackholeprohibit и так далее:

  • unicast — обычный маршрут: исходящий интерфейс + адрес следующего хопа до пункта назначения
  • unreachable — пакет выбрасывается и посылается ICMP сообщение «host unreachable»
  • blackhole — пакет просто выбрасывается без возвращения какого-либо сообщения
  • prohibit — пакет выбрасывается и посылается ICMP сообщение «administratively prohibited»

Что такое scope link мы уже знаем, но здесь еще встречается scope host:

  • scope host — эта запись действительна только для этого хоста
  • scope link — эта запись действительна только для этого интерфейса

Для просмотра содержимого всех таблиц в качестве имени таблицы следует указывать allunspec или ноль. Все таблицы на самом деле имеют цифровые идентификаторы от 1 до 255, их символьные имена задаются в файле /etc/iproute2/rt_tables и используются лишь для удобства.

# ip route show table unspec
..........Копировать
# cat /etc/iproute2/rt_tables
255    local
254    main
253    default
0      unspecКопировать

Таблица unspec — это псевдо-таблица, которая содержит в себе правила всех таблиц маршрутизации системы. Именно поэтому у нее номер ноль, который не входит в диапазон с 1 по 255.

Правила маршрутизации

Как же ядро выбирает, в какую таблицу отправлять пакеты? Мы уже знаем — для этого есть правила:

# ip rule show
0:     from all lookup local
32766: from all lookup main
32767: from all lookup defaultКопировать

Число в начале строки — идентификатор правила, from all — условие, означает пакеты с любых адресов, lookup указывает, в какую таблицу направлять пакет. Если пакет подпадает под несколько правил, то он проходит их все по порядку возрастания идентификатора. Конечно, если пакет подпадет под какую-либо запись маршрутизации, то последующие записи маршрутизации и последующие правила он уже проходить не будет.

Возможные условия:

  • from — отправитель пакета.
  • to — получатель пакета.
  • iif — имя интерфейса, на который пришел пакет.
  • oif — имя интерфейса, с которого уходит пакет. Это условие действует только для пакетов, исходящих из локальных сокетов, привязанных к конкретному интерфейсу.
  • tos — значение поля TOS ip-пакета.
  • fwmark — проверка значения FWMARK пакета. При помощи правил iptables можно отфильтровать пакеты по огромному количеству признаков и установить определенные значения FWMARK. А затем эти значения учитывать при роутинге.

Условия можно комбинировать, например from 192.168.1.0/24 to 10.0.0.0/8, а также можно использовать префикc not, который указывает, что пакет не должен соответствовать условию, чтобы подпадать под это правило.

Часть вторая

Свежие комментарии

Подписка

Лучшие статьи


Fatal error: Uncaught Error: Call to a member function have_posts() on null in /home/host1867038/the-devops.ru/htdocs/www/wp-content/themes/fox/inc/blog.php:380 Stack trace: #0 /home/host1867038/the-devops.ru/htdocs/www/wp-content/themes/fox/widgets/latest-posts/widget.php(257): fox56_blog_grid(NULL, Array) #1 /home/host1867038/the-devops.ru/htdocs/www/wp-content/themes/fox/widgets/latest-posts/register.php(33): include('/home/host18670...') #2 /home/host1867038/the-devops.ru/htdocs/www/wp-includes/class-wp-widget.php(394): Wi_Widget_Latest_Posts->widget(Array, Array) #3 /home/host1867038/the-devops.ru/htdocs/www/wp-includes/widgets.php(837): WP_Widget->display_callback(Array, Array) #4 /home/host1867038/the-devops.ru/htdocs/www/wp-content/themes/fox/inc/single.php(417): dynamic_sidebar('sidebar') #5 /home/host1867038/the-devops.ru/htdocs/www/wp-content/themes/fox/inc/single.php(136): fox56_single_sidebar() #6 /home/host1867038/the-devops.ru/htdocs/www/wp-content/themes/fox/inc/single.php(7): fox56_single_inner() #7 /home/host1867038/the-devops.ru/htdocs/www/wp-content/themes/fox/single.php(23): fox56_single() #8 /home/host1867038/the-devops.ru/htdocs/www/wp-includes/template-loader.php(106): include('/home/host18670...') #9 /home/host1867038/the-devops.ru/htdocs/www/wp-blog-header.php(19): require_once('/home/host18670...') #10 /home/host1867038/the-devops.ru/htdocs/www/index.php(17): require('/home/host18670...') #11 {main} thrown in /home/host1867038/the-devops.ru/htdocs/www/wp-content/themes/fox/inc/blog.php on line 380