Маршрутизация Linux — различия между версиями

Материал из Корпоративная wiki Администрации города Волгодонски
Перейти к: навигация, поиск
(РЕШЕНИЕ:)
(РЕШЕНИЕ:)
 
Строка 130: Строка 130:
 
В этом случае для хоста 10.10.10.1 будет выбран второй маршрут, а для хоста 10.10.20.1 - первый.
 
В этом случае для хоста 10.10.10.1 будет выбран второй маршрут, а для хоста 10.10.20.1 - первый.
  
 +
Также может быть маршрут default (НЕ ТАБЛИЦА), который подразумевает направление 0.0.0.0/0
  
 +
Можно создавать дополнительные таблицы маршрутизации и обращаться к ним по номерам от 1 до 252 (0 - unspec, 253 - default, 254 - main, 255 - local) или по именам, но тогда надо прописать эти имена в файл /etc/iproute2/rt_tables.
 +
 +
Основы сказал, остальную информацию можно получить по man.
  
 
----
 
----
Строка 158: Строка 162:
 
Основная часть задачи выполняется одной командой:
 
Основная часть задачи выполняется одной командой:
  
ip route add default nexthop via 192.168.0.1 dev eth0 weight 10 nexthop via 192.168.1.1 dev eth1 weight 3
+
''ip route add default nexthop via 192.168.0.1 dev eth0 weight 10 nexthop via 192.168.1.1 dev eth1 weight 3''
  
 
После выполнения данной команды Linux будет случайным образом пропорционально указанным весам распределять маршруты. После чего они будут записываться в кэш маршрутизации. Это означает, что если первый раз на yandex.ru был выбран маршрут через первый шлюз, то дальше все запросы будут отправляться также на первый шлюз.
 
После выполнения данной команды Linux будет случайным образом пропорционально указанным весам распределять маршруты. После чего они будут записываться в кэш маршрутизации. Это означает, что если первый раз на yandex.ru был выбран маршрут через первый шлюз, то дальше все запросы будут отправляться также на первый шлюз.
 +
 +
''ip'' - собственно команда пакета iproute2
 +
 +
''route'' - работаем с маршрутами
 +
 +
''add'' - добавить
 +
 +
''default'' - направление (0.0.0.0/0)
 +
 +
''nexthop'' - следующий прыжок, т.е. какому шлюзу отправляем пакеты
 +
 +
''via a.b.c.d'' - IP шлюза
 +
 +
''dev ethX'' - через какой интерфейс
 +
 +
''weight Y'' - "вес" данного шлюза, т.е. грубо - какая часть маршрутов будет проложена через него (в нашем случае будет 10/13 и 3/13)

Текущая версия на 13:18, 6 декабря 2017

ЛинУкс, как много в этом слове

Для сердца Сисадминского слилось!

(простите за потерю ритма) :)


Учительница в школе спрашивает учеников, кем работают их родители. Обнаруживаются врачи, менеджеры по продажам, бухгалтеры… И тут встает Вовочка и заявляет: «А мой папа – тапер в борделе!». Учительница, естественно, не может закрыть на это глаза, отправляется к Вовочке домой и гневно спрашивает папу: «Какой пример вы подаете ребенку?». «Вообще-то я программист, — отвечает папа, — специализируюсь на TCP/IP в Unix. Но как объяснить это семилетнему пацану?».

(бородатый анекдот)

18+


Многие сталкивались с ситуацией, когда им надо организовать маршрутизацию по нескольким выходным каналам. У кого-то есть два канала в интернет, у кого-то есть специализированный канал для специализированной связи...

Предлагаю рассмотреть вариант, когда есть два канала интернет, один спецканал, и две локальных сети. Достаточно сложная картинка, но она позволит показать все основные возможности маршрутизации в Linux.

ДАНО:

Провайдер0:

Шлюз IP - 192.168.0.1/24

Наш IP - DHCP/24

Интерфейс - eth0

Ширина - 10Мбит/с

Провайдер1:

Шлюз IP - 192.168.1.1/24

Наш IP - 192.168.1.100/24 ("белый" IP)

Интерфейс - eth1

Ширина - 3Мбит/с

Спецканал:

Шлюз IP - 192.168.2.1/24

Наш IP - 192.168.2.100/24

Интерфейс - eth2

ЛВС0:

Наш IP - 192.168.10.1/24

Интерфейс - eth3

ЛВС1:

Наш IP - 192.168.11.1/24

Интерфейс - eth4

Дополнительно ДАНО:

Спецсеть - 10.10.10.0/24

Особые сайты: 123.145.167.189, 109.187.165.143

ЗАДАЧА:

Распределить основной интернет-трафик согласно ширине канала по провайдерам.

Обеспечить доступ в спецсеть из ЛВСх.

Обеспечить доступ к особым сайтам через "белый" IP.

Открыть некоторые порты...

РЕШЕНИЕ:

НЕОБХОДИМЫЙ ИНСТРУМЕНТ:

Windows отпал сразу, т.к. без дозакупки дополнительного ПО она мало что умеет, но, при желании, кое-что тоже сделать можно. Но не будем о чепухе!

Linux - любой современный дистр уже имеет в своем комплекте iptables и iproute2. НО! Не все функции работают в различных сборках, о чем будет сказано позже. Мною использовались Ubuntu 16.04.3 server и OpenSUSE Leap 42.3.

Теперь перейдем к теоретическому обоснованию решения.

Когда мы говорим о маршрутизации, то нужно помнить, что маршрутизацию проходят пакеты, а не соединения. Т.е. когда наш шлюз получает очередной пакет, то он проходит по всем нашим правилам (ну или не по всем... :) ). Но при этом мы можем говорить о маршрутизации на уровне маршрутов (да, тавтология), на уровне соединений и на уровне пакетов, в зависимости от того, как мы напишем правила.

Мы не можем маршрутизировать входящий трафик по нашим каналам! Мы можем только пытаться исходящим корректировать входящий.

Далее обратимся к следующему термину - правила маршрутизации.

Список правил можно получить командой:

ip rule show

Первым делом проверяется таблица local, а последними main и default.

Проход по правилам идет в порядке увеличения числа priority. Также в правиле может быть прописаны условия выполнения (исходящий/входящий адрес/интерфейс и т.д.). Более подробно всегда можно прочитать в man.

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

Каждая таблица маршрутизации состоит из направления (адреса получателя с маской), шлюза, интерфейса и метрики.

Посмотреть таблицу main можно командой:

ip route show

другие таблицы:

ip route show table ИМЯ_ТАБЛИЦЫ

В таблице local прописаны маршруты для нашего хоста и широковещательные.

main - основная рабочая таблица для всех "нелокальных" маршрутов.

default - процитирую: "reserved for post-processing" - зарезервирована для особых случаев, но ни разу еще не видел ее использования.

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

Например у нас прописаны два маршрута:

1. на 10.0.0.0/8 через 192.168.0.1

2. на 10.10.10.0/24 через 192.168.0.2

В этом случае для хоста 10.10.10.1 будет выбран второй маршрут, а для хоста 10.10.20.1 - первый.

Также может быть маршрут default (НЕ ТАБЛИЦА), который подразумевает направление 0.0.0.0/0

Можно создавать дополнительные таблицы маршрутизации и обращаться к ним по номерам от 1 до 252 (0 - unspec, 253 - default, 254 - main, 255 - local) или по именам, но тогда надо прописать эти имена в файл /etc/iproute2/rt_tables.

Основы сказал, остальную информацию можно получить по man.


Сначала балансировка:

ВАРИАНТ 1:

Можно отправлять каждый 4-ый (см. ДАНО) пакет через второй канал и надеяться, что что-то из этого выйдет (маршрутизация на уровне пакетов). Но в этом варианте внешний хост будет получать от нас пакеты в одном соединении с разных IP-адресов, что снесет ему крышу и он нас пошлет.

ВАРИАНТ 2:

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

ВАРИАНТ 3:

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

ВАРИАНТ 4:

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


Начну с третьего варианта, т.к. работать будет на любом дистре Linux.

Основная часть задачи выполняется одной командой:

ip route add default nexthop via 192.168.0.1 dev eth0 weight 10 nexthop via 192.168.1.1 dev eth1 weight 3

После выполнения данной команды Linux будет случайным образом пропорционально указанным весам распределять маршруты. После чего они будут записываться в кэш маршрутизации. Это означает, что если первый раз на yandex.ru был выбран маршрут через первый шлюз, то дальше все запросы будут отправляться также на первый шлюз.

ip - собственно команда пакета iproute2

route - работаем с маршрутами

add - добавить

default - направление (0.0.0.0/0)

nexthop - следующий прыжок, т.е. какому шлюзу отправляем пакеты

via a.b.c.d - IP шлюза

dev ethX - через какой интерфейс

weight Y - "вес" данного шлюза, т.е. грубо - какая часть маршрутов будет проложена через него (в нашем случае будет 10/13 и 3/13)