Linux kernel ip routing table

Routing Tables

This section describes the way to setup routing table as well as it explains the logic used to prioritize interfaces.

The routing table is stored in the kernel which merely acts upon it. The route itself is set by the user-space tools. There is no preference as any tool created for this reason will do. It can be either a DHCP client, ip command or route command.

It is important to understand that NetworkManager changes the routing table whenever it creates a new connection.

Routing table acts as a junction and is there to show where the different network subnets will be routed to. An example of a routing table is shown below.

$ ip route \ default via 10.0.0.1 dev wlp3s0 proto static metric 600 \ 10.0.0.0/24 dev wlp3s0 proto kernel scope link src 10.0.0.73 metric 600 \ 10.0.1.0/24 dev lxcbr0 proto kernel scope link src 10.0.1.1 \ 169.254.0.0/16 dev docker0 scope link metric 1000 linkdown \ 172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1 linkdown \ 192.168.122.0/24 dev virbr0 proto kernel scope link src 192.168.122.1 linkdown 

The first column is the subnet with the “default” being a wildcard for everything else. The “via” fragment points to the however when it is missing it indicates that that network is connected directly and instead it describes a source address.

The metric field/column translates to the number of hops required to reach the destination and is used to determine which route shall be preferred when there are more than one route available for a specific destination. Since this value is related to the concept of distance, the lower it’s value is the better.

The metric value can be set manually however when NetworkManager creates a connection the following defaults are applied:

Editing the routing tables

The routing table can be added or modified using the standard ip command which is available on Ubuntu Core. You can find more information on its man page.

Separately it is possible to modify routing information per single connection using the nmcli tool. The parameters such as: gateway, routes and metrics can be modified.

The following options are responsible:

ipv4.gateway: ipv4.routes: ipv4.route-metric: ipv6.gateway: ipv6.routes: ipv6.route-metric: 

These options can be modified in a following way:

$ nmcli connection modify +ipv4.routes ipv4.gateway $ nmcli connection modify ipv4.route-metric

Where is the connection name. You can obtain it by listing available connections on the system:

  • is the destination network provided as a static IP address, subnet or “default”.
  • is the new gateway information. is the new metric information.

Note that this kind of changes can be made separately for each connection thus it is possible to provide a fine grained control over how the packets directed to different networks are routed.

Читайте также:  Низкое разрешение экрана linux

It is also important to understand that bringing up and down connections with different values set for these options is in fact changing the routing table.

Источник

Роутинг и policy-routing в Linux при помощи iproute2

Речь в статье пойдет о роутинге сетевых пакетов в 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 – мы уже рассматривали выше, это проверка отправителя пакета.
  • to – получатель пакета.
  • iif – имя интерфейса, на который пришел пакет.
  • oif – имя интерфейса, с которого уходит пакет. Это условие действует только для пакетов, исходящих из локальных сокетов, привязанных к конкретному интерфейсу.
  • tos – значение поля TOS IP-пакета.
  • fwmark – проверка значения FWMARK пакета. Это условие дает потрясающую гибкость правил. При помощи правил iptables можно отфильтровать пакеты по огромному количеству признаков и установить определенные значения FWMARK. А затем эти значения учитывать при роутинге.

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

Теперь рассмотрим простой пример. У нас есть некий шлюз, на него приходят пакеты с 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

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

Читайте также:  Linux с поддержкой kvm

Балансировка трафика между аплинками

# ip route replace default scope global \ nexthop via 11.22.33.1 dev eth0 weight 1 \ nexthop via 55.66.77.1 dev eth1 weight 1

Эта запись заменит существующий default-роутинг в таблице main. При этом маршрут будет выбираться в зависимости от веса шлюза ( weight ). Например, при указании весов 7 и 3, через первый шлюз будет уходить 70% соединений, а через второй – 30%. Есть один момент, который при этом надо учитывать: ядро кэширует маршруты, и маршрут для какого-либо хоста через определенный шлюз будет висеть в таблице еще некоторое время после последнего обращения к этой записи. А маршрут до часто используемых хостов может не успевать сбрасываться и будет все время обновляться в кэше, оставаясь на одном и том же шлюзе. Если это проблема, то можно иногда очищать кэш вручную командой ip route flush cache .

Использование маркировки пакетов при помощи iptables

Допустим нам нужно, чтобы пакеты на 80 порт уходили только через 11.22.33.1. Для этого делаем следующее:

# iptables -t mangle -A OUTPUT -p tcp -m tcp --dport 80 -j MARK --set-mark 0x2 # ip route add default via 11.22.33.1 dev eth0 table 102 # ip rule add fwmark 0x2/0x2 lookup 102

Первой командой маркируем все пакеты, идущие на 80 порт. Второй командой создаем таблицу маршрутизации. Третьей командой заворачиваем все пакеты с указанной маркировкой в нужную таблицу.
Опять же все просто. Рассмотрим также использование модуля iptables CONNMARK. Он позволяет отслеживать и маркировать все пакеты, относящиеся к определенному соединению. Например, можно маркировать пакеты по определенному признаку еще в цепочке INPUT, а затем автоматически маркировать пакеты, относящиеся к этим соединениям и в цепочке OUTPUT. Используется он так:

# iptables -t mangle -A INPUT -i eth0 -j CONNMARK --set-mark 0x2 # iptables -t mangle -A INPUT -i eth1 -j CONNMARK --set-mark 0x4 # iptables -t mangle -A OUTPUT -j CONNMARK --restore-mark

Пакеты, приходящие с eth0 маркируются 2, а с eth1 – 4 (строки 1 и 2). Правило на третьей строке проверяет принадлежность пакета к тому или иному соединению и восстанавливает маркировки (которые были заданы для входящих) для исходящих пакетов.
Надеюсь изложенный материал поможет вам оценить всю гибкость роутинга в Linux. Спасибо за внимание 🙂

Источник

Оцените статью
Adblock
detector