Приветствую.
Затык случился с задачей: пробросить порт в локалку за NAT-ом с двуххвостого (multihomed) роутера на хвост, который не по умолчанию.
То есть: есть входы ppp0 и ppp1. ppp1 — default route. Запрос приходит через ppp0, соответственно, ответ надо засунуть туда же.
Делал по http://habrahabr.ru/blogs/linux/100919/ . Для ответов с самого роутера — все замечательно: он снаружи пингуется, на него можно зайти. Для DNAT-ового сервиса (который замечательно работал при одном хвосте в роутере) — все плохо. tcpdump видит как пакетик приходит в локалку, видит ответ сервиса и видит как ответ уходит по неправильному интерфейсу (ppp1).
Роутинг делается по:
ip rule add priority 101 fwmark 0x1/0x1 lookup T1 # на ppp1
ip rule add priority 102 fwmark 0x2/0x2 lookup T2 # на ppp0
ip route add default metric 1 dev ppp1
ip route add default metric 2 dev ppp0
Правила сейчас выглядят так:
iptables -t mangle -A INPUT -i ppp0 -j CONNMARK --set-mark 0x2
iptables -t mangle -A INPUT -i ppp1 -j CONNMARK --set-mark 0x1
iptables -t mangle -A OUTPUT -j CONNMARK --restore-mark
iptables -t mangle -A FORWARD -i ppp0 -m conntrack --ctstate DNAT -j CONNMARK --set-mark 0x2
iptables -t mangle -A FORWARD -i ppp1 -m conntrack --ctstate DNAT -j CONNMARK --set-mark 0x1
iptables -t mangle -A FORWARD -j CONNMARK --restore-mark
Идея был проста: в момент -t mangle FORWARD мы еще знаем входящий интерфейс, уже знаем что оно DNAT-лено, и можем поставить CONNMARK. Который, по идее, должен подхватиться при ответе.
Но не работает. Вызывая у меня чувство, что я чего-то глобального не понимаю.
Заранее спасибо за добрый совет.