Настройка нескольких таблиц маршрутизации на одном сервере

2 комментария
Настройка нескольких таблиц маршрутизации на одном сервере

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

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

Предположим, у нас есть сервер с двумя физическими интерфейсами — eth0 и eth1. На каждый из них добавлено по ip-адресу. Это могут быть как адреса из одного broadcast домена (к примеру, 10.10.10.2/30 и 10.10.10.3/30), так и из разных. В данном примере рассматривается второй случай, но принципиальной разницы нет:

 Интерфейсы eth0 и eth1

Вывод команды ip address (просмотр сетевых параметров, сконфигурированных на интерфейсах сервера) для каждого из интерфейсов:

# ip address show eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:30:48:f9:c8:02 brd ff:ff:ff:ff:ff:ff
inet 10.10.1.2/24 brd 10.10.1.255 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::230:48ff:fef9:c802/64 scope link
valid_lft forever preferred_lft forever
# ip address show eth1
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:30:48:f9:c8:03 brd ff:ff:ff:ff:ff:ff
inet 172.16.1.2/24 brd 172.16.1.255 scope global eth1
valid_lft forever preferred_lft forever
inet6 fe80::230:48ff:fef9:c803/64 scope link
valid_lft forever preferred_lft forever

Маршруты на сервере:

# ip route ls
default via 10.10.1.1 dev eth0
10.10.1.0/24 dev eth0 proto kernel scope link src 10.10.1.2
172.16.1.0/24 dev eth1 proto kernel scope link src 172.16.1.2

Default маршрут настроен через интерфейс eth0 шлюз 10.10.1.1: 

default via 10.10.1.1 dev eth0

Это значит, что все ответные пакеты с данными будут отправляться через этот интерфейс eth0 и с source адресом 10.10.1.2. К примеру, если с такой конфигурацией сделать попытку подключиться по ssh к серверу по адресу 172.16.1.2, назначенному на eth1, сервер попытается ответить через eth0, и соединение не будет установлено, т.к. даже если разрешен проброс пакетов между интерфейсами, ответ будет отправлен не с тем source адресом:

 

eth0 и с source адресом 10.10.1.2

Чтобы заставить сервер отвечать с того же интерфейса, куда прилетел пакет, несмотря на default route, можно настроить несколько таблиц маршрутизации. Мы рассматриваем пример с настройкой двух дополнительных таблиц, но их количество может быть больше.

По умолчанию на сервере всегда присутствуют три стандартные таблицы:

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

Это таблицы local, main и default. Таблицы создаются в файле /etc/iproute2/rt_tables. Просмотреть содержимое конфигурационного файла можно командой:

# cat /etc/iproute2/rt_tables

Результат выполнения команды:

#
# reserved values
#
255 local
254 main
253 default
0 unspec
#
# local
#
#1 inr.ruhep

Т.е. для создания новых таблиц (назовем их table1 и table2), “привязанных” к eth0 и eth1 соответственно, добавляем в этот файл следующее:

# echo 100  table1 >> /etc/iproute2/rt_tables
# echo 101 table2 >> /etc/iproute2/rt_tables

Номер таблицы (100 и 101) нужно брать в диапазоне [2; 252]. В таком случае приоритет таблиц будет меньше, чем у таблиц main и default, и поиск маршрутов будет производиться сначала в таблицах table1 и table2. Итак, проверим, что таблицы созданы:

# cat /etc/iproute2/rt_tables

Результат выполнения команды:

#
# reserved values
#
255    local
254    main
253    default
0    unspec
#
# local
#
#1    inr.ruhep
100 table1
101 table2

Но в правилах они пока не отображены:

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

Добавляем правила и default маршруты для каждой из таблиц:

# ip rule add from 10.10.1.2 table table1
# ip route add default via 10.10.1.1 dev eth0 table table1
# ip rule add from 172.16.1.2 table table2
# ip route add default via 172.16.1.1 dev eth1 table table2

Проверяем:

# ip rule ls
0:    from all lookup local
32764:    from 10.10.1.2 lookup table1
32765:    from 172.16.1.2 lookup table2
32766:    from all lookup main
32767:    from all lookup default

При создании правила используем интересующий нас адрес, добавленный на интерфейс сервера, например, для интерфейса eth0 используется адрес 10.10.1.2, при добавлении default маршрута прописываем адрес шлюза сети (в примере выше для 10.10.1.2/24 это 10.10.1.1) и интерфейс, через который отправлять пакет.

Теперь при обращении к адресу 10.10.1.2 сервер будет отвечать через интерфейс eth0 с source адресом 10.10.1.2, а при обращении к 172.16.1.2, соответственно, через интерфейс eth1 с source адресом 172.16.1.2:

Интерфейс eth1 с source адресом 172.16.1.2

При этом для исходящих соединений с сервера ничего не изменится, они будут идти по общему default маршруту, взятому из основной таблицы main.

Для просмотра маршрутов, содержащихся в определенной таблице,к команде ip route show добавляется table table_name:

# ip route show table table1
default via 10.10.1.1 dev eth0
# ip route show table table2
default via 172.16.1.1 dev eth1

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

# ip address show eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:30:48:f9:c8:02 brd ff:ff:ff:ff:ff:ff
inet 10.10.1.2/24 brd 10.10.1.255 scope global eth0
valid_lft forever preferred_lft forever
inet 172.16.1.2/24 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::230:48ff:fef9:c802/64 scope link
valid_lft forever preferred_lft forever

Это будет выглядеть следующим образом:

# ip rule add from 10.10.1.2 table table1
# ip route add default via 10.10.1.1 dev eth0 table table1

# ip rule add from 172.16.1.2 table table2
# ip route add default via 172.16.1.1 dev eth0 table table2

В завершение необходимо внести правки в файл /etc/network/interfaces, чтобы новая конфигурация была доступна в случае, если сервер перезагрузится, либо будет перечитана сетевая конфигурация. Ниже приведен пример содержания данного конфигурационного файла с добавлением правил и default маршрутов в созданные таблицы, в примере общий default маршрут прописан через интерфейс eth0  с указанием шлюза 10.10.1.1:

# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).

# The loopback network interface
auto lo
iface lo inet loopback

# The primary network interface
auto eth0
iface eth0 inet static

address 10.10.1.2
netmask 255.255.255.0
gateway 10.10.1.1
post-up ip rule add from 10.10.1.2 table table1
post-up ip route add default via 10.10.1.1 dev eth0 table table1
post-up ip route add default via 10.10.1.1 dev eth1

auto eth1
iface eth1 inet static
address 172.16.1.2
netmask 255.255.255.0
gateway 172.16.1.1
post-up ip rule add from 172.16.1.2 table table2
post-up ip route add default via 172.16.1.1 dev eth1 table table2

Если на сервере один интерфейс, то правила для таблиц будут прописаны в секции конфигурации eth0.

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

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

VDS сервер Таймвеб

Комментарии

Сергей Рубцов +1
30 мая в 2016
Все доходчиво и понятно, без лишней воды, спасибо
Спасибо за статью!
Ошибка в файле /etc/network/interfaces при задании маршрута по-умолчанию: "post-up ip route add default via 10.10.1.1 dev eth1" следует заменить на: "post-up ip route add default via 10.10.1.1 dev eth0".
Вообще говоря, эта строка не обязательна, т.к. присутствует опция "gateway", в таком случае маршрут по-умолчанию пропишется автоматически.
И ещё один момент, в файле присутствуют две опции "gateway". Вторую нужно убрать и будет всё по фен-шую!
С помощью соцсетей
У меня нет аккаунта Зарегистрироваться
Нажимая кнопку «Зарегистрироваться», я даю согласие на обработку своих персональных данных, указанных в форме регистрации.
С помощью соцсетей
У меня уже есть аккаунт Войти
Нажимая кнопку «Зарегистрироваться», я даю согласие на обработку своих персональных данных, указанных в форме регистрации.
Инструкции по восстановлению пароля высланы на Ваш адрес электронной почты.
Пожалуйста, укажите email вашего аккаунта
Ваш баланс 10 ТК
1 ТК = 1 ₽
О том, как заработать и потратить Таймкарму, читайте в этой статье
Чтобы потратить Таймкарму, зарегистрируйтесь на нашем сайте