Решил закрыть для себя все непонятные моменты с ip route, и столкнулся с проблемой, решение которой не нашел.
Для освоения использования политик маршрутизации была создана виртуальная машина (типа тренажер) на Ubuntu Server 14.04 LTS с тремя сетевыми картами, подключенными в режиме «сетевого моста» на физическую карту хост-машины.
Хост-машина включена в подсеть 192.168.99.0\24, шлюз подсети – 192.168.99.1
Виртуальные сетевые карты имеют статические, вручную забитые адреса:
eth0: 192.168.99.160\255.255.255.0
eth1: 192.168.99.161\255.255.255.0
eth2: 192.168.99.162\255.255.255.0
cat /etc/network/interfaces
# The loopback network interface
auto lo
iface lo inet loopback
# The primary network interface
auto eth0
iface eth0 inet static
address 192.168.99.160
network 192.168.99.0
netmask 255.255.255.0
broadcast 192.168.99.255
auto eth1
iface eth1 inet static
address 192.168.99.161
network 192.168.99.0
netmask 255.255.255.0
broadcast 192.168.99.255
auto eth2
iface eth2 inet static
address 192.168.99.162
network 192.168.99.0
netmask 255.255.255.0
broadcast 192.168.99.255
Обратите внимание, что ни один из интерфейсов не создает в таблице маршрутизации маршрут по умолчанию. Это сделано сознательно, т.к. все что надо - будет добавляться вручную:
ip route show table main
192.168.99.0/24 dev eth2 proto kernel scope link src 192.168.99.162
192.168.99.0/24 dev eth0 proto kernel scope link src 192.168.99.160
192.168.99.0/24 dev eth1 proto kernel scope link src 192.168.99.161
Правила iptables отсутствуют, политика – по умолчанию, ACCEPT на все.
В ходе эксперимента я пытался принудительно направить траффик до любого хоста, доступного через шлюз – пусть будет один из IP-адресов Яндекса (213.180.204.3, свободно пингуется, проверьте сами) – через определенную сетевую карту.
Для этого в файле /etc/iproute2/rt_tables были созданы 2 пользовательские таблицы:
cat /etc/iproute2/rt_tables
#
# reserved values
#
255 local
254 main
253 default
0 unspec
#
# local
#
#1 inr.ruhep
161 usertable_1
162 usertable_2
Предполагается поиграться с правилами ip route и понаправлять траффик в эти таблицы.
Используем пока что одну из них - проверить, что многочисленные мануалы не врут, и трафик действительно будет роутиться по дополнительным таблицам в соответствии с политиками.
В таблицу usertable_1 добавляем маршрут по умолчанию через шлюз подсети:
ip route add default via 192.168.99.1 dev eth1 table usertable_1
Проверим, что он действительно добавился:
ip route list table usertable_1
default via 192.168.99.1 dev eth1
Теперь добавляем политику, принудительно заворачивающую траффик до 213.180.204.3 в пользовательскую таблицу usertable_1, которая обязана выкинуть его через интерфейс eth1:
ip rule add from 213.180.204.3 table usertable_1
Проверим, действительно ли политика добавилась:
ip rule show
0: from all lookup local
32765: from 213.180.204.3 lookup usertable_1
32766: from all lookup main
32767: from all lookup default
Теперь самое интересное – пробуем пинговать 213.180.204.3:
ping 213.180.204.3
connect: Network is unreachable
Если ради эксперимента добавить основной шлюз 192.168.99.1 в главную таблицу main (на любой из интерфейсов), то все конечно пингуется, только не через ту сетевую карту, через которую мне надо:
К примеру:
ip route add default via 192.168.99.1 dev eth0
ping 213.180.204.3
PING 213.180.204.3 (213.180.204.3) 56(84) bytes of data.
64 bytes from 213.180.204.3: icmp_seq=1 ttl=52 time=58.8 ms
Просмотр iptstate на шлюзе (который 192.168.99.1) показывает, что icmp-пакеты идут с eth0 (с адреса 192.168.99.160), а должны идти от eth1 (192.168.99.161) согласно политике.
В связи со всем изложенным, возник вопрос:
Почему ядро игнорирует политику отправки траффика в пользовательскую цепочку, стоящую выше по приоритету чем политика отправки в главную системную таблицу main?
Если комментировать детально – что я делаю не так? И что надо сделать так, чтобы собранная схема заработала.