Routing in Linux

One of the most important tasks of the network layer of the OSI model is routing. Devices that connect subnets to each other in a single composite network are called routers. Inside the network, segments are not shared by routers, otherwise it would not be one network, but several networks. The router will connect several networks to the internetwork or internet.

Данные, которые поступают на сетевой уровень и которые необходимо передать через составную сеть, снабжаются заголовком сетевого уровня. Данные вместе с заголовком образуют пакет. Заголовок пакета сетевого уровня имеет унифицированный формат, не зависящий от форматов кадров канального уровня тех сетей, которые могут входить в объединенную сеть, и несет наряду с другой служебной информацией данные о номере сети, которой предназначается этот пакет. Явная нумерация сетей позволяет протоколам сетевого уровня составлять точную карту межсетевых связей и выбирать рациональные маршруты при любой их топологии, в том числе альтернативные маршруты, если они имеются, что никак не умеют делать мосты и коммутаторы.

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

Резюмируем.

построение неоднородных сетей реализуют с помощью сетевого уровня.
сетевой уровень использует собственную адресацию, которая обеспечивает каждому узлу подсети составной сети свой универсальный сетевой адрес, который состоит из номера сети и номера узла. Благодаря такой системе адресации сетевой уровень может пересылать информации к узлу получателю “не обращая внимания” на внутреннюю структуру подсетей, с другой стороны для непосредственного продвижения пакетов к адресату, он использует технологию передачи данных конкретной подсети, через которую следуют эти пакеты.
поиск наилучшего пути следования пакетов в сети – маршрутизация – это основная задача сетевого уровня.
сети соединяются между собой с помощью маршрутизаторов. Маршрутизаторы занимаются сбором информации о топологии межсетевых соединений, и на ее основании пересылают данные в пункт назначения.

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

iproute также известна как iproute2.

Пакет iproute состоит из нескольких утилит управления трафиком:

ip – управление собственно маршрутизацией;
tc – управление очередями маршрутизации;
ss — утилита для просмотра текущих соединений и открытых портов, аналог утилиты netstat.

Увидеть IP и MAC-адрес, аналог ARP -a

# ip neighbour show

Поиск маршрута для удаленного ip

ip route get 192.168.35.55
192.168.35.55 via 192.168.35.254 dev tun1 src 10.26.95.254
cache ipid 0xf0ea

Для все MAC задает состояние failed, в дальнейшем ядро Ос удалит помеченные так MAC записи из arp таблицы.

# ip neigh flush all

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

# ip r | grep default

Просмотр сетевых карт

# ip link list

Сбросить кеш маршрутизатора

# ip route flush cache

blackhole. Добавить «зануленный» маршрут (аналог «ip route … null0» в Cisco). Пакеты в сеть с таким маршрутом будут удалены с причиной «No route to host». Может быть полезно для подавление DoS-атака-атаки с хоста

# ip route add blackhole 10.56.50.0/27

C помощью команды ip addr add можно установить на сетевом интерфейсе как основной IP адрес, так и несколько дополнительных адресов. Удалить IP адрес

ip addr del 10.90.91.254 dev eth4
или удалить все с интерфейса wlan1
ip addr flush wlan1

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

Вывести таблицы маршрутизации. Ядро принимает решение о применении той или иной таблицы на основании адреса источника пакета. Эти таблицы применимы для всех пакетов.

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

Вывести содержимое таблицы local.

# ip route show table local

Таблица local. Пакет при выборе пути к месту назначения проверяется правилом с наименьшим приоритетом. Правило 0 отправит поиск маршрута в таблицу “local”.

Таблица local проверяет не адресован ли пакет локальной машине (широковещательный или сетевой адреса интерфейсов). Таблицу local автоматически заполняют команды конфигурации сетевых интерфейсов.

Таблица main – является основной и именно она используется, если в команде, связанной с маршрутизацией, не указано какую таблицу использовать. При поднятии интерфейсов в неё прописываются маршруты к подсетям интерфейсов, стартовые скрипты также заносят в эту таблицу значение шлюза по-умолчанию. Использование команды route add администратором также может дополнить таблицу маршрутами. В общем случае, таблица main всегда содержит подходящий для пакета маршрут (например шлюз по-умолчанию).
Таблица default изначально пуста.

Модификация таблицы маршрутизации:

Добавление маршрута через шлюз: ip route add 172.16.10.0/24 via 192.168.1.1
Добавление маршрута через интерфейс: ip route add 172.16.10.0/24 dev eth0
Маршрут с метрикой: ip route add 172.16.10.0/24 dev eth0 metric 100

Кроме add также поддерживаются и другие действия: del — удалить маршрут; replace — заменить маршрут другим; change — изменить параметры маршрута.

5 декабря 2010 в 12:39
Роутинг и policy-routing в Linux при помощи iproute2
Настройка Linux*
Речь в статье пойдет о роутинге сетевых пакетов в Linux. А конкретно – о типе роутинга под названием policy-routing (роутинг на основании политик). Этот тип роутинга позволяет маршрутизировать пакеты на основании ряда достаточно гибких правил, в отличие от классического механизма маршрутизации destination-routing (роутинг на основании адреса назначения). Policy-routing применяется в случае наличия нескольких сетевых интерфейсов и необходимости отправлять определенные пакеты на определенный интерфейс, причем пакеты определяются не по адресу назначения или не только по адресу назначения. Например, policy-routing может использоваться для: балансировки трафика между несколькими внешними каналами (аплинками), обеспечения доступа к серверу в случае нескольких аплинков, при необходимости отправлять пакеты с разных внутренних адресов через разные внешние интерфейсы, даже для отправки пакетов на разные TCP-порты через разные интерфейсы и т.д.
Для управления сетевыми интерфейсами, маршрутизацией и шейпированием в Linux служит пакет утилит iproute2.

Этот набор утилит лишь задает настройки, реально вся работа выполняется ядром Linux. Для поддержки ядром policy-routing оно должно быть собрано с включенными опциями IP: advanced router (CONFIG_IP_ADVANCED_ROUTER) и IP: policy routing (CONFIG_IP_MULTIPLE_TABLES), находящимися в разделе Networking support -> Networking options -> TCP/IP networking.

ip route

Для настройки роутинга служит команда ip route. Выполненная без параметров, она покажет список текущих правил маршрутизации (не все правила, об этом чуть позже):

# ip route
192.168.12.0/24 dev eth0 proto kernel scope link src 192.168.12.101
default via 192.168.12.1 dev eth0

Так будет выглядеть роутинг при использовании на интерфейсе eth0 IP-адреса 192.168.12.101 с маской подсети 255.255.255.0 и шлюзом по умолчанию 192.168.12.1.
Мы видим, что трафик на подсеть 192.168.12.0/24 уходит через интерфейс eth0. proto kernel означает, что роутинг был задан ядром автоматически при задании IP интерфейса. scope link означает, что эта запись является действительной только для этого интерфейса (eth0). src 192.168.12.101 задает IP-адрес отправителя для пакетов, попадающих под это правило роутинга.
Трафик на любые другие хосты, не попадающие в подсеть 192.168.12.0/24 будет уходить на шлюз 192.168.12.1 через интерфейс eth0 (default via 192.168.12.1 dev eth0). Кстати, при отправке пакетов на шлюз, IP-адрес назначения не изменяется, просто в Ethernet-фрейме в качестве MAC-адреса получателя будет указан MAC-адрес шлюза (часто даже специалисты со стажем путаются в этом моменте). Шлюз в свою очередь меняет IP-адрес отправителя, если используется NAT, либо просто отправляет пакет дальше. В данном случае используются приватный адрес (192.168.12.101), так что шлюз скорее всего делает NAT.
А теперь залезем в роутинг поглубже. На самом деле, таблиц маршрутизации несколько, а также можно создавать свои таблицы маршрутизации. Изначально предопределены таблицы local, main и default. В таблицу local ядро заносит записи для локальных IP адресов (чтобы трафик на эти IP-адреса оставался локальным и не пытался уходить во внешнюю сеть), а также для бродкастов. Таблица main является основной и именно она используется, если в команде не указано какую таблицу использовать (т.е. выше мы видели именно таблицу main). Таблица default изначально пуста. Давайте бегло взглянем на содержимое таблицы local:

# ip route show table local
broadcast 127.255.255.255 dev lo proto kernel scope link src 127.0.0.1
broadcast 192.168.12.255 dev eth0 proto kernel scope link src 192.168.12.101
broadcast 192.168.12.0 dev eth0 proto kernel scope link src 192.168.12.101
local 192.168.12.101 dev eth0 proto kernel scope host src 192.168.12.101
broadcast 127.0.0.0 dev lo proto kernel scope link src 127.0.0.1
local 127.0.0.1 dev lo proto kernel scope host src 127.0.0.1
local 127.0.0.0/8 dev lo proto kernel scope host src 127.0.0.1

broadcast и local определяют типы записей (выше мы рассматривали тип default). Тип broadcast означает, что пакеты соответствующие этой записи будут отправлены как broadcast-пакеты, в соответствии с настройками интерфейса. local – пакеты будут отправлены локально. scope host указывает, что эта запись действительная только для этого хоста.
Для просмотра содержимого конкретной таблицы используется команда ip route show table TABLE_NAME. Для просмотра содержимого всех таблиц в качестве TABLE_NAME следует указывать all, unspec или 0. Все таблицы на самом деле имеют цифровые идентификаторы, их символьные имена задаются в файле /etc/iproute2/rt_tables и используются лишь для удобства.

ip rule

Как же ядро выбирает, в какую таблицу отправлять пакеты? Все логично – для этого есть правила. В нашем случае:

# ip rule
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, который указывает, что пакет не должен соответствовать условию, чтобы подпадать под это правило.
Итак, мы разобрались что такое таблицы маршрутизации и правила маршрутизации. А создание собственных таблиц и правил маршрутизации это и есть policy-routing, он же PBR (policy based routing). Кстати SBR (source based routing) или source-routing в Linux является частным случаем policy-routing, это использование условия from в правиле маршрутизации.

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

Теперь рассмотрим простой пример. У нас есть некий шлюз, на него приходят пакеты с IP 192.168.1.20. Пакеты с этого IP нужно отправлять на шлюз 10.1.0.1. Чтобы это реализовать делаем следующее:

Создаем таблицу с единственным правилом:

# ip route add default via 10.1.0.1 table 120

Создаем правило, отправляющее нужные пакеты в нужную таблицу:

# ip rule add from 192.168.1.20 table 120

Как видите, все просто.

Доступность сервера через несколько аплинков

Теперь более реалистичный пример. Имеется два аплинка до двух провайдеров, необходимо обеспечить доступность сервера с обоих каналов:

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

Решается это весьма просто:
Определяем таблицы:

# ip route add default via 11.22.33.1 table 101
# ip route add default via 55.66.77.1 table 102

Определяем правила:

# ip rule add from 11.22.33.44 table 101
# ip rule add from 55.66.77.88 table 102

Думаю теперь уже объяснять смысл этих строк не надо. Аналогичным образом можно сделать доступность сервера по более чем двум аплинкам.