Привет, коллеги. Почему-то не срабатывает правило ip rule, если пакет предварительно обработан NAT-маскарадингом (на этом же компьютере).
Что хотелось бы получить: принимать входящие на 192.168.8.252:2023 и 192.168.8.254:2023; DNAT-ить их во внутреннюю сеть на 10.0.0.241.
Фишка в том, что 192.168.8.10 и 192.168.8.12, с которых приходят входящие - это тоже роутеры, они тоже DNAT-ят снаружи. 192.168.8.10 перенаправляет на 192.168.8.254, а 192.168.8.12 - на 192.168.8.252. Ответ, естественно, должен уходить на тот же роутер, с которого пришёл запрос.
Вот что написано в правилах:
# ip rule show
0: from all lookup local
32762: from 192.168.8.252 lookup 3
32763: from 192.168.8.254 lookup 1
32766: from all lookup main
32767: from all lookup default
# ip route show table 3
default via 192.168.8.12 dev br0
# ip route show table 1
default via 192.168.8.10 dev br0
# ip route show table main
default via 192.168.8.10 dev br0 src 192.168.8.254
В IPTABLES всё просто:
*nat
-A PREROUTING -p tcp -d 192.168.8.252 --dport 2023 -j DNAT --to 10.0.0.241
-A POSTROUTING -o br0 -j MASQUERADE
И вот что получается:
# tcpdump -enni br0 port 2023
12:15:25.821772 b8:a3:86:65:a3:0f > 00:1e:8c:8b:bc:aa, ethertype IPv4 (0x0800), length 66: 178.93.15.150.62250 > 192.168.8.252.2023: Flags [S], seq 4294154921, win 64240, options [mss 1260,nop,wscale 2,nop,nop,sackOK], length 0
12:15:25.822038 00:1e:8c:8b:bc:aa > b8:a3:86:65:a2:3d, ethertype IPv4 (0x0800), length 66: 192.168.8.252.2023 > 178.93.15.150.62250: Flags [S.], seq 2354228401, ack 4294154922, win 14600, options [mss 1460,nop,nop,sackOK,nop,wscale 6], length 0
# arp -a
? (192.168.8.12) at b8:a3:86:65:a3:0f [ether] on br0
? (192.168.8.10) at b8:a3:86:65:a2:3d [ether] on br0
То есть, по MAC-адресам видно, что запрос приходит с b8:a3:86:65:a3:0f (192.168.8.12), а ответ на него отсылается на b8:a3:86:65:a2:3d (192.168.8.10), несмотря на правило «from 192.168.8.252 lookup 3», в котором указан маршрут «default via 192.168.8.12». Вместо него, видимо, используется маршрут из table main, несмотря на то, что там явно указано «src 192.168.8.254», что не совпадает с содержимым пакетов.
Интересно, что такого не проиходит с локальными портами, т.е. открытыми непосредственно на роутере, а не транслируемыми через DNAT внутрь сети. Там ответ чётко уходит на нужный роутер в зависимости от адреса, на который пришёл запрос.
Вопрос: чего я не понимаю в этой кухне?
Я знаю ещё один способ - маркировать пакеты в iptables и правила писать в зависимости от метки fwmark, но описанный здесь способ мне кажется красивее и правильнее, хотелось бы довести его до конца.