Всем привет
Надо сделать так, чтобы роутер портмаппил определенный TCP траффик одинаково прозрачно для клиентов на внутренний сервер в сети одинаково прозрачно для клиентов как из интернета так и из сети.
Постараюсь нарисовать как я себе это вижу и что не работает.
Вот такая схема работает:
iptables -t nat -A PREROUTING -p tcp --dport 8000 -j DNAT --to 192.168.1.20
iptables -t nat -A POSTROUTING -o ppp0 -j SNAT --to [Public IP]
Client -> Router -> Server
Internet [192.168.1.1] [192.168.1.20]
[to:Public IP] [DNAT->192.168.1.20]
[From:ExternalClientIP]
Тут «внешний» клиент ломится на внешний публичный адрес роутера на порт 8000 и роутер его DNATтит в сеть, там сервер видит «внешний» адрес клиента и через MASQUERADE ему получается ответить. Это проблем не вызывает.
Теперь этот же клиент делает то же самое но будучи внутри этой самой сети как локальный.
Client -> Router -> Server
Internet [192.168.1.1] [192.168.1.20]
[to:Public IP] [DNAT->192.168.1.20]
[From:LocalClientIP]
В таком случае пакеты на адрес 192.168.1.20 идут с адреса LocalClientIP (например 192.168.1.2) и сервер сопоставляя одно с другим не видит необходимости направлять трафик на свой шлюз и отвечает клиенту на прямую, что клиент конечно же не ожидает и ничего не работает. Это как бы тоже очевидно.
добавляю правило
iptables -t nat -I POSTROUTING -p tcp --dport 8000 -d 192.168.1.20 -j SNAT --to 192.168.1.1
ожидаю, что роутер сменит адрес отправителя после DNAT на свой, и сервер 192.168.1.20 уже ответит ему.
Да я понимаю, что это двойной трафик в сети. Да я понимаю что это приведёт к лишней нагрузке на роутер. Но сейчас это за скобкой.
Так вот это правило SNAT не обрабатывается (счётчик не увеличивается). Если верить tcpdump пакеты всё ещё уходят с адресом отправителя равным Клиентскому (да и сервер 192.168.1.20 их видит таковыми)
Так вот вопрос: почему не работает SNAT? Потому что нет как такового перекладывания из интерфейса в интерфейс? Можно как-то принудить к этому?
Помню был подобный случай только с REDIRECT когда напрявлял в locahost, там был sysctl ключик net.ipv4.conf.all.route_localnet. Я даже попробовал его в этом применении - непомогает :(