Policy-routing на CentOS

Довольно распространённая ситуация — на моёй рабочей станции есть два интерфейса и два айпишника, скажем из подсети А и подсети Б. При обращении клиента с хоста из сети Б к моему айпишнику из подсети А ответ к нему уходит через другой интерфейс с моего айпишника из подсети Б, т.к. он из той же подсети, что и адрес клиента. Мне надо сделать, чтобы эти ответы уходили с того же адреса на который пришли.

Тут нужен policy-routing — маршрутизация на основе определённых правил. Логика получается такая: ответы на запросы из подсети Б к моему адресу из подсети А отправлять с адреса из подсети А (т.е. на шлюз подсети А).

Маркируем соединения из сети Б к нашему адресу из сети А при помощи iptables и таблицу mangle (используется для изменения пакетов):
iptables -t mangle -I INPUT -i eth0 -s 10.1.100.0/24 -d 10.2.96.3 -j CONNMARK --set-mark 1
А на выходе копируем маркировку соединения в маркировку пакетов, насколько я понимаю, это означает, что мы маркируем пакеты промаркированных ранее соединений:
iptables -t mangle -I OUTPUT -s 10.2.96.3 -d 10.1.100.0/24 -j CONNMARK --restore-mark
Вероятно, в этом правиле можно обойтись и без указания адресов источника и адресата, но мне кажется так будет правильнее, более точно чтоли )

В таблицу маршрутизации 111 добавляем маршрут для сети Б, но на шлюз из подсети А:
ip route add to 10.1.100.0/24 via 10.2.96.1 dev eth0 table 111
И, наконец, добавляем правило для перенаправления пакетов с нашей маркировкой в отдельную таблицу маршрутизации:
ip rule add fwmark 1 lookup 111

Для удобства можно назначить название для таблицы в файле /etc/iproute2/rt_tables, которое можно будет использовать вместо номера.

Так же нужно проверить не включена ли проверка обратного пути (reverse path checking):
sysctl net.ipv4.conf.eth0.rp_filter
Если включена, то система будет проверять пакеты на соответствие источника интерфейсу, с которого пакет получен. Например, если пакет пришёл с адреса, который виден через другой интерфейс (а не тот, с которого пакет пришёл), то значит этот пакет надо отбросить.

Если всё заработало как надо, то сохраняем правила iptables в файл "/etc/sysconfig/iptables", а правила для маршрутизации в файл "/etc/sysconfig/network-scripts/route-eth0".

Далее несколько вспомогательных команд, которые могут пригодиться.

Посмотреть определённую таблицу маршрутизации:
ip route show table 111
Удалить маршрут из указанной таблицы
ip route del table 111 to 10.1.100.0/24
Посмотреть правила маршрутизации:
ip rule show
Удалить правило маршрутизации:
ip rule del fwmark 1

Как посмотреть правила iptables писать не буду )