IPRoute2

ВВЕДЕНИЕ

Этот документ расскажет, как повысить эффективность управления трафиком в системах маршрутизации, построенных на базе Linux с помощью пакета iproute2.

 

1 ОГРАНИЧЕНИЯ И ЛИЦЕНЗИОННЫЕ СОГЛАШЕНИЯ

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

Короче говоря, если ваша магистраль STM-64 была взломана и по ней стала распространяться порнография вашим самым уважаемым клиентам – это не наша вина. Уж простите.

Держателями авторских прав на этот документ являются: Bert Hubert, Gregory Maxwell, Martijn van Oosterhout, Remco van Mook, Paul B. Schroeder и другие. Этот материал может распространяться только на условиях Open Publication License, v1.0 или более поздней (самую последнюю версию текста лицензии вы найдете по адресу http://www.opencontent.org/openpub).

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

Если вы опубликовали твердую копию этого HOWTO, просим вас передать авторам документа несколько экземпляров в “ознакомительных целях”.

2 ПРЕДВАРИТЕЛЬНЫЕ СВЕДЕНИЯ

Данный документ рассчитан на подготовленного читателя.
Для того, чтобы было возможно использовать данный документ в полном объёме, необходимо прочитать и понимать документ, опубликованный в глобальной сети интернет по адресу или расположенному на локальной машине /usr/doc/HOWTO/NET3-4-HOWTO.txt.

3 ЗАДАЧИ, КОТОРЫЕ МОГУТ БЫТЬ РЕАЛИЗОВАНЫ С ПОМОЩЬЮ LINUX

Вот далеко неполный список из того, что может может быть реализовано с помощью операционной системы Linux:

  • управление пропускной способностью НА отдельных компьютерах.
  • управление пропускной способностью к общим информационным ресурсам
  • управление шириной канала доступа в зависимости от источника
  • защита информационных ресурсов от DoS-атак
  • предотвращение сетевого трафика ботнет
  • организация балансировки сетевой нагрузки на информационный ресурс, с целью равномерного распределения нагрузки.
  • ограничения доступа к сетевым ресурсам
  • ограничение доступа пользователей к другим узлам сети.
  • Выполнять маршрутизацию на основе UID, MAC-адресов, исходящих IP-адресов, номеров портов, типа обслуживания, времени суток и содержимого.

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

4 ДОПОЛНИТЕЛЬНЫЕ ЗАМЕЧАНИЯ

Данный материал является попыткой сделать вполне читабельным руководство HOWTO Любые исправления и дополнения по данному материалу не будут лишними.
В текст материала могут быть внесены любые дополнения и исправления предоставленные со стороны.

5 СТРУКТУРА ДОКУМЕНТА

Структура документа строится по принципу “от простого – к сложному”.
В начале основные понятия и простые настройки, после этого более сложные понятия и настройки.

6 ВВЕДЕНИЕ В IPROUTE2

Пакет iprote2 предназначен для полноценного управления всеми сетевыми компонентами и настройками.
Работает на уровне ядра операционный системы.
Программный код пакета оптимизирован в большей мере, чем программный код других сетевых утилит.
Средствами iproute2 реализованы функции управления сетевыми компонентами и настройками, которых не было раньше.

7 КРАТКИЙ ОБЗОР IPROUTE2

Linux обладает довольно сложной системой управления пропускной способностью, названной Traffic Control (Управление Трафиком). Она поддерживает различные методы классификации, деления по приоритетам, совместного использования, и ограничения как входящего, так и исходящего трафика.
Мы начнем обсуждение проблемы с краткого обзора iproute2 и ее возможностей.

8 НЕОБХОДИМЫЕ УСЛОВИЯ

Установленный пакет iproute2. На сегодняшний момент этот пакет включён практически в любой дистрибутив Linux. При правильно настроенном репозитории программного обеспечения установка пакета iproute2 не составляет труда.
В ядре операционной системы должна быть включена поддержка netlink

9 ТЕКУЩАЯ КОНФИГУРАЦИЯ

Утилита ip является основной в пакете.

9.1. ПРОСМОТР СПИСКА СЕТЕВЫХ ИНТЕРФЕЙСОВ С ПОМОЩЬЮ УТИЛИТЫ IP

 ip link list
1: lo: <LOOPBACK,UP> mtu 3924 qdisc noqueue 
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: dummy: <BROADCAST,NOARP> mtu 1500 qdisc noop 
    link/ether 00:00:00:00:00:00 brd ff:ff:ff:ff:ff:ff
3: eth0: <BROADCAST,MULTICAST,PROMISC,UP> mtu 1400 qdisc pfifo_fast qlen 100
    link/ether 48:54:e8:2a:47:16 brd ff:ff:ff:ff:ff:ff
4: eth1: <BROADCAST,MULTICAST,PROMISC,UP> mtu 1500 qdisc pfifo_fast qlen 100
    link/ether 00:e0:4c:39:24:78 brd ff:ff:ff:ff:ff:ff
3764: ppp0: <POINTOPOINT,MULTICAST,NOARP,UP> mtu 1492 qdisc pfifo_fast qlen 10
    link/ppp

Здесь приведен результат работы команды ip link list на моем домашнем маршрутизаторе ( с “поднятым” NAT), у вас он может несколько отличаться. Я поясню часть того, что вы видите, но не все, а только то, что нас интересует в данный момент.

Первым в списке находится локальный (loopback) интерфейс. В принципе, при конфигурировании ядра, можно отключить поддержку этого интерфейса, но я бы не советовал этого делать. Размер максимального блока передачи данных (MTU – Maximum Transfer Unit) для этого интерфейса составляет 3924 октета, и для него отсутствует очередь, поскольку он не соответствует никакому физическому устройству и существует только в “воображении” ядра.

Пропускаем фиктивный (dummy) интерфейс, так как он может отсутствовать на вашем компьютере. Дальше идут два физических сетевых интерфейса, один – со стороны модема, другой – обслуживает домашнюю локальную сеть. И наконец последним в списке стоит интерфейс ppp0.

Обратите внимание на отсутствие IP-адресов в листинге. iproute отделяет понятие “интерфейса” от понятия “IP-адреса”. При назначении нескольких IP-адресов одному интерфейсу (IP-алиас), понятие IP-адреса становится достаточно расплывчатым.

Зато показываются MAC-адреса – аппаратные идентификаторы сетевых интерфейсов.

9.2. ПРОСМОТР СПИСКА IP-АДРЕСОВ С  ПОМОЩЬЮ УТИЛИТЫ IP

ip address show        
1: lo: <LOOPBACK,UP> mtu 3924 qdisc noqueue 
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 brd 127.255.255.255 scope host lo
2: dummy: <BROADCAST,NOARP> mtu 1500 qdisc noop 
    link/ether 00:00:00:00:00:00 brd ff:ff:ff:ff:ff:ff
3: eth0: <BROADCAST,MULTICAST,PROMISC,UP> mtu 1400 qdisc pfifo_fast qlen 100
    link/ether 48:54:e8:2a:47:16 brd ff:ff:ff:ff:ff:ff
    inet 10.0.0.1/8 brd 10.255.255.255 scope global eth0
4: eth1: <BROADCAST,MULTICAST,PROMISC,UP> mtu 1500 qdisc pfifo_fast qlen 100
    link/ether 00:e0:4c:39:24:78 brd ff:ff:ff:ff:ff:ff
3764: ppp0: <POINTOPOINT,MULTICAST,NOARP,UP> mtu 1492 qdisc pfifo_fast qlen 10
    link/ppp 
    inet 212.64.94.251 peer 212.64.94.1/32 scope global ppp0

Этот листинг содержит более подробную информацию. Здесь показаны все IP-адреса, и каким интерфейсам они принадлежат. Здесь “inet” соответствует термину “Internet (IPv4)”. Существует целый ряд типов сетевых адресов, но нас они пока не интересуют.

Взглянем поближе на интерфейс eth0. Из листинга видно, что ему назначен адрес “inet”  10.0.0.1/8, где “/8” определяет число бит, соответствующих адресу сети. Таким образом, для адресации хостов в сети у нас остается 32 – 8 = 24 бита, что соответствует адресу сети 10.0.0.0 и маске сети 255.0.0.0.

Это говорит о том, что любой хост в этой сети, например 10.250.3.13, будет непосредственно доступен через наш интерфейс с IP-адресом 10.0.0.1.

Для ppp0 применима та же концепция, хотя числа в IP-адресе отличаются. Ему присвоен адрес 212.64.94.251, без маски сети. Это означает, что он обслуживает соединение типа”точка-точка” (point-to-point), и что каждый адрес, за исключением 212.64.94.251, является удаленным. Но и это еще не все. Для этого интерфейса указывается адрес другого конца соединения 212.64.94.1. Здесь число “/32” говорит о том, что это конкретный IP-адрес и он не содержит адреса сети.
Вы наверняка обратили внимание на слово “qdisc”. Оно обозначает дисциплину обработки очереди (Queueing Discipline). Позднее мы коснемся этой темы подробнее.

9.3. ПРОСМОТР СПИСКА МАРШРУТОВ С ПОМОЩЬЮ УТИЛИТЫ IP

Итак, мы теперь знаем, как можно отыскать адреса 10.x.y.z, и как обратиться к адресу 212.64.94.1. Однако этого недостаточно, поскольку нам необходимо иметь возможность общения с внешним миром. Интернет доступен нам через ppp-соединение, которое объявляет, что хост с адресом 212.64.94.1, готов передать наши пакеты во внешний мир и вернуть результаты обратно.

      
[ahu@home ahu]$ ip route show
212.64.94.1 dev ppp0  proto kernel  scope link  src 212.64.94.251 
10.0.0.0/8 dev eth0  proto kernel  scope link  src 10.0.0.1 
127.0.0.0/8 dev lo  scope link 
default via 212.64.94.1 dev ppp0

Этот листинг достаточно “прозрачен”. Первые 3 строки сообщают сведения, которые нами уже обсуждались выше. Последняя строка говорит о том, что внешний мир доступен через 212.64.94.1 шлюз, заданный по-умолчанию. То что это шлюз, видно благодаря наличию слова “via” (англ. “через“). Этот шлюз (с адресом 212.64.94.1) готов перенаправлять наши пакеты в Интернет и возвращать обратно результаты наших запросов.

Для примера, более “старая” утилита route, дает такой результат на моей машине:

      
[ahu@home ahu]$ route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use
Iface
212.64.94.1     0.0.0.0         255.255.255.255 UH    0      0        0 ppp0
10.0.0.0        0.0.0.0         255.0.0.0       U     0      0        0 eth0
127.0.0.0       0.0.0.0         255.0.0.0       U     0      0        0 lo
0.0.0.0         212.64.94.1     0.0.0.0         UG    0      0        0 ppp0

10 ARP

ARP – Address Resolution Protocol (Протокол Определения Адреса) описан в RFC 826. Он используется для определения ethernet-адреса по IP-адресу. Машины в Интернет более известны под именами, которые преобразуются в IP-адреса, благодаря чему узел сети, скажем с именем foo.com, имеет возможность связаться с другой машиной, например с именем bar.net. Но в ethernet-сетях для адресации используется не IP-адрес, а ethernet-адрес и здесь на сцену выходит протокол ARP.

Рассмотрим простой пример. Предположим, что имеется сеть из нескольких компьютеров. В ней находятся компьютеры foo, с адресом 10.0.0.1 и bar, с адресом 10.0.0.2. Пусть fooхочет послать пакет ICMP Echo Request (ping) компьютеру bar, чтобы проверить работает ли он, но увы, foo не знает ethernet-адрес компьютера bar. Таким образом, прежде чем выполнить ping barfoo должен отослать ARP-запрос. Этот запрос очень похож на то, что обычно кричит человек, пытаясь отыскать в толпе своего товарища: “Bar (10.0.0.2)! Ты где?”. В результате все машины в сети услышат “крик” foo, но только bar (10.0.0.2) откликнется на него, послав обратно ARP-ответ, который можно трактовать как: “Foo (10.0.0.1)! Я – здесь! Мой адрес 00:60:94:E9:08:12.”. После этой “переклички” foo будет знать ethernet-адрес компьютера bar и сможет связаться с ним, пока опять не “забудет” (в кэше ARP) адрес компьютера bar (обычно записи в ARP-кэше удаляются через 15 минут).

Содержимое ARP-кэша можно просмотреть так:

[root@espa041 /home/src/iputils]# ip neigh show
9.3.76.42 dev eth0 lladdr 00:60:08:3f:e9:f9 nud reachable
9.3.76.1 dev eth0 lladdr 00:06:29:21:73:c8 nud reachable

Как видите, мой компьютер espa041 (9.3.76.41) “знает”, как найти компьютер espagate (9.3.76.1). А теперь добавим еще один адрес в наш кэш:

[root@espa041 /home/paulsch/.gnome-desktop]# ping -c 1 espa043
PING espa043.austin.ibm.com (9.3.76.43) from 9.3.76.41 : 56(84) bytes of data.
64 bytes from 9.3.76.43: icmp_seq=0 ttl=255 time=0.9 ms

--- espa043.austin.ibm.com ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.9/0.9/0.9 ms

[root@espa041 /home/src/iputils]# ip neigh show
9.3.76.43 dev eth0 lladdr 00:06:29:21:80:20 nud reachable
9.3.76.42 dev eth0 lladdr 00:60:08:3f:e9:f9 nud reachable
9.3.76.1 dev eth0 lladdr 00:06:29:21:73:c8 nud reachable

В результате попытки взаимодействия компьютера espa041 с espa043, ethernet-адрес последнего был добавлен в кэш. По истечении некоторого тайм аута (если между этими двумя компьютерами больше не было передано ни одного пакета), espa041 “забудет” адрес компьютера espa043 и для того чтобы что-то сообщить ему, опять потребуется послать ARP-запрос.

Удалим адрес компьютера espa043 из кэша:

[root@espa041 /home/src/iputils]# ip neigh delete 9.3.76.43 dev eth0
[root@espa041 /home/src/iputils]# ip neigh show
9.3.76.43 dev eth0  nud failed
9.3.76.42 dev eth0 lladdr 00:60:08:3f:e9:f9 nud reachable
9.3.76.1 dev eth0 lladdr 00:06:29:21:73:c8 nud stale

Теперь espa041 “забыл” адрес компьютера espa043. Если espa041 опять “захочет” что-то сообщить espa043, он будет вынужден вновь послать ARP-запрос. В этом листинге также видно, что в записи для espagate (9.3.76.1), состояние reachable (доступно) изменилось на stale (устарело). Это означает, что ethernet-адрес все еще является допустимым, но он должен быть подтвержден при первой же попытке обмена.

11 ПРАВИЛА МАРШРУТИЗАЦИИ. ПОЛИТИКИ МАРШРУТИЗАЦИИ.

Если ваш маршрутизатор обслуживает сложную сеть, то нужно удовлетворять нужды разных людей, обслуживание которых, вероятно, должно отличаться. База политик маршрутизации позволяет реализовать это с помощью набора таблиц маршрутизации.
Если вы хотите использовать эту возможность, убедитесь что ядро собрано с поддержкой “IP: advanced router” и “IP: policy routing”.
Когда ядру необходимо выбрать маршрут, оно определяет в соответствии с какой таблицей это нужно делать. По-умолчанию, определены три таблицы. Старая утилита route изменяет таблицы main и local, как и утилита ip (по-умолчанию).
Правила маршрутизации по-умолчанию:

[ahu@home ahu]$ ip rule list
0:	from all lookup local 
32766:	from all lookup main 
32767:	from all lookup default

В этом листинге приведены приоритеты всех правил. Мы видим, что правила применяются ко всем пакетам (from all). Мы уже видели таблицу ‘main’, она выводится командой ip route ls , но таблицы ‘local’ и ‘default’ для нас новые.
Если мы хотим сделать что-то интересное, то нужно задать правила, использующие разные таблицы маршрутизации. Это позволит нам переопределить общесистемную таблицу маршрутизации.
(За точной семантикой происходящего в ядре, когда есть несколько подходящих правил, обратитесь к документации ip-cref Алексея Кузнецова.)

11.1 ПРОСТАЯ МАРШРУТИЗАЦИЯ ПО ИСТОЧНИКУ

Давайте опять рассмотрим реальный пример. Два  кабельных модема, подключенны к маршрутизатору Linux с NAT (‘masquerading’). Люди с которыми я живу в одном доме, платят мне за использование Internet. Допустим одни из моих соседей ходит только на hotmail и хочет платить меньше. Мне это подходит, но при этом будет использоваться медленный канал.

Быстрое соединение имеет с моей стороны адрес 212.64.94.251, а с другой — 212.64.94.1. Медленное соединение получает динамический адрес, в данном примере это 212.64.78.148, адрес провайдера — 195.96.98.253.

Таблица local:

[ahu@home ahu]$ ip route list table local
broadcast 127.255.255.255 dev lo  proto kernel  scope link  src 127.0.0.1 
local 10.0.0.1 dev eth0  proto kernel  scope host  src 10.0.0.1 
broadcast 10.0.0.0 dev eth0  proto kernel  scope link  src 10.0.0.1 
local 212.64.94.251 dev ppp0  proto kernel  scope host  src 212.64.94.251 
broadcast 10.255.255.255 dev eth0  proto kernel  scope link  src 10.0.0.1 
broadcast 127.0.0.0 dev lo  proto kernel  scope link  src 127.0.0.1 
local 212.64.78.148 dev ppp2  proto kernel  scope host  src 212.64.78.148 
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

Много очевидных вещей, но они должны быть где-то указаны. Вот здесь они и заданы. Таблица default пустая. Посмотрим теперь на таблицу main:

[ahu@home ahu]$ ip route list table main 
195.96.98.253 dev ppp2  proto kernel  scope link  src 212.64.78.148 
212.64.94.1 dev ppp0  proto kernel  scope link  src 212.64.94.251 
10.0.0.0/8 dev eth0  proto kernel  scope link  src 10.0.0.1 
127.0.0.0/8 dev lo  scope link 
default via 212.64.94.1 dev ppp0

Создадим новое правило для нашего гипотетического соседа, которое будет называться ‘John’. Хотя мы можем работать просто с числами, намного проще и понятней если мы определим названия наших таблиц в файле /etc/iproute2/rt_tables.

# echo 200 John >> /etc/iproute2/rt_tables
# ip rule add from 10.0.0.10 table John
# ip rule ls
0:	from all lookup local 
32765:	from 10.0.0.10 lookup John
32766:	from all lookup main 
32767:	from all lookup default

Теперь нам нужно лишь сгенерировать таблицу John и очистить кэш маршрутов:

# ip route add default via 195.96.98.253 dev ppp2 table John
# ip route flush cache

Вы можете добавить это в скрипт ip-up.

11.2 ОРГАНИЗАЦИЯ МАРШРУТИЗАЦИИ ЧЕРЕЗ НЕСКОЛЬКО ВНЕШНИХ КАНАЛОВ

Раздельный доступ

Организация маршрутизации, чтобы ответы на запросы, приходящие через провайдера 1, уходили через того же провайдера.

Определим переменные.
$IF1 имя первого интерфейса (if1 на рисунке)
$IF2 имя второго интерфейса (if2 на рисунке).
$IP1 будет IP адресом $IF1
$IP2 будет IP адресом $IF2 .
$P1 это IP-адрес шлюза провайдера 1
$P2 это IP адрес шлюза провайдера 2.
$P1_NET это IP сеть, к которой принадлежит $P1
$P2_NET сеть, к которой принадлежит $P2 .

Создадим две дополнительные таблицы маршрутизации, скажем T1 и T2. Добавим их в файл /etc/iproute2/rt_tables. Теперь можно настроить эти таблицы следующими командами:

ip route add $P1_NET dev $IF1 src $IP1 table T1
ip route add default via $P1 table T1
ip route add $P2_NET dev $IF2 src $IP2 table T2
ip route add default via $P2 table T2

В таблице описаны маршрут к шлюзу и маршрут по-умолчанию через этот шлюз. Точно так же, как и в случае одного провайдера, но по таблице на каждого провайдера.
Заметьте, что маршрута к сети, в которой находится шлюз достаточно, потому что он определяет как найти все хосты в этой сети, включая сам шлюз.Теперь нужно настроить главную таблицу маршрутизации. Хорошо бы маршрутизировать пакеты для сетей провайдеров через соответствующие интерфейсы. Обратите внимание на аргумент `src’, который обеспечивает правильный выбор исходного IP-адреса.

ip route add $P1_NET dev $IF1 src $IP1
ip route add $P2_NET dev $IF2 src $IP2

Задаём маршрут по умолчанию:

ip route add default via $P1

Зададим правила маршрутизации. Они будут отвечать за то, какая таблица будет использоваться при маршрутизации. Вы хотите, чтобы пакет с определенным адресом источника маршрутизировался через соответствующий интерфейс:

ip rule add from $IP1 table T1
ip rule add from $IP2 table T2

Эти команды обеспечивают маршрутизацию ответов через интерфейс, на котором был получен запрос.

 

‘ Если $P0_NET это локальная сеть, а $IF0 — соответствующий ей интерфейс, желательно задать следующие команды:

ip route add $P0_NET     dev $IF0 table T1
ip route add $P2_NET     dev $IF2 table T1
ip route add 127.0.0.0/8 dev lo   table T1
ip route add $P0_NET     dev $IF0 table T2
ip route add $P1_NET     dev $IF1 table T2
ip route add 127.0.0.0/8 dev lo   table T2

Пример, который мы рассмотрели, будет работать для всех процессов, выполняющихся на маршрутизаторе и для локальной сети, если настроено преобразование адресов (NAT/masquerading). В противном случае, вам будет необходим диапазон IP адресов обоих провайдеров, или выполнять маскирование для одного из провайдеров. В любом случае, вы можете задать правила выбора провайдера для каждого конкретного адреса вашей локальной сети.

Распределение нагрузки.

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

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

ip route add default scope global nexthop via $P1 dev $IF1 weight 1 \
nexthop via $P2 dev $IF2 weight 1

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

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

Задать вопрос