По умолчанию при наличии нескольких адресов на одном или нескольких интерфейсах на сервере он отвечает через тот интерфейс и с того адреса, через который прописан дефолтный маршрут. Если нужно, чтобы сервер отвечал с того адреса, на который прилетел пакет с данными, можно выполнить настройку нескольких таблиц маршрутизации. Для чего это может понадобиться: если на сервере есть основной и резервный адрес, то, настроив для них разные таблицы, можно подключаться к каждому из них.
Общий принцип настройки для всех систем один, мы рассматриваем настройку на примере Ubuntu.
Предположим, у нас есть сервер с двумя физическими интерфейсами — eth0 и eth1. На каждый из них добавлено по ip-адресу. Это могут быть как адреса из одного broadcast домена (к примеру, 10.10.10.2/30 и 10.10.10.3/30), так и из разных. В данном примере рассматривается второй случай, но принципиальной разницы нет:
Вывод команды 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 адресом:
Чтобы заставить сервер отвечать с того же интерфейса, куда прилетел пакет, несмотря на 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:
При этом для исходящих соединений с сервера ничего не изменится, они будут идти по общему 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-подобных систем настройка будет производиться аналогичным образом, будут отличаться конфигурационные файлы. Важно не забывать сохранять в них все внесенные изменения.
Количество таблиц не ограничено двумя. Помимо резервного доступа к серверу, несколько таблиц могут понадобиться, если на сервере поднят мониторинг, и нужно, чтобы на обращения к системе мониторинга сервер отвечал с его адреса, а все остальные пакеты шли через другой.
Комментарии
Ошибка в файле /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". Вторую нужно убрать и будет всё по фен-шую!