LINUX.ORG.RU
ФорумAdmin

Замена адреса-источника при пробросе порта средствами iptables

 


2

3

Добрый день ! Прошу помощи в решении следующего вопроса : На шлюзе (debian linux) : внешняя карта : eth0 (1.2.3.4), внутренняя : eth1 (192.168.1.254) есть локальная сеть 192.168.1.0/24, в которой стоит сервер обновлений (192.168.1.155), на который проброшен на шлюзе внешний адрес , порт 80. Сервер обновлений в Log файлах фиксирует внутренний адрес шлюза (192.168.1.254), т.к. пакеты приходят от «его имени» Требуется подменить адрес в src пакетов, приходящих на сервер обновлений на внешний Ip адрес удаленного сервера из Internet’а, инициирующего обновления. Фрагмент действующего firewall'а (внешние адреса заменены на «абстрактные») :

iptables -t nat -A PREROUTING -d 1.2.3.4/32 -p tcp -m tcp --dport 80 -j DNAT --to-destination 192.168.1.155:80 iptables -t nat -A POSTROUTING -d 192.168.1.155/32 -p tcp -m tcp --dport 80 -j SNAT --to-source 1.2.3.4:80

iptables -t nat -A PREROUTING --dst 1.2.3.4/32 -p tcp --dport 80 -j DNAT --to-destination 192.168.1.155:80
iptables -I FORWARD 1 -i eth0 -o eth1 -d 192.168.1.0/24 -p tcp -m tcp --dport 80 -j ACCEPT
iptables -t nat -A POSTROUTING --dst 192.168.1.155/32 -p tcp --dport 80 -j SNAT --to-source 1.2.3.4
iptables -t nat -A OUTPUT --dst 1.2.3.4/32 -p tcp --dport 80 -j DNAT --to-destination 192.168.1.155
ving2 ()
Ответ на: комментарий от ving2

Предлагаемое решение не помогло

Упростил ситуацию :

так работает, но на локальную машину приходит адрес шлюза :

iptables -t nat -A PREROUTING -p tcp -d 1.2.3.4 --dport 10022 -j DNAT --to-destination 192.168.1.252:22
iptables -A FORWARD -i eth0 -d 192.168.1.252 -p tcp --dport 10022 -j ACCEPT

Добавляю два рекомендованных дополнительных правила :
iptables -t nat -A POSTROUTING --dst 192.168.1.252 -p tcp --dport 22 -j SNAT --to-source 1.2.3.4
iptables -t nat -A OUTPUT --dst 1.2.3.4 -p tcp --dport 10022 -j DNAT --to-destination 192.168.1.252

работает, но на локальную машину по прежнему приходит адрес шлюза (интерфейса локальной сети)

Amurzet ()
Ответ на: Предлагаемое решение не помогло от Amurzet

работает, но на локальную машину по прежнему приходит адрес шлюза

сначал толком не прочитал, что вам требуется. А для чего собственно нужно, чтоб приходил внешний ip в src пакетов. конечную цель бы понять - может и ответ придет.

ving2 ()
Ответ на: комментарий от ving2

Во внешней сети сервера обновлений, они инициируют соединение на внешний адрес маршрутизатора. Тот пробрасывает соединение на сервер во внутренней сети. Все работает, но в логах внутреннего сервера в качетстве серверов обновлений всегда фигурирует адрес карты шлюза (карты, которая смотрит во внутреннюю сетку). А нужно различать от какого из внешних серверов обновлений они пришли. Как я понимаю необходимо пакет снаружи безо всяких преобразований внешнего адреса перебрасывать на внутренний сервер.

Amurzet ()
Ответ на: комментарий от Amurzet

Задача в общем-то не экзотичная. При пробросе внешнего адреса со шлюза на внутренний ip необходимо сохранять адрес инициатора соединения. даже по соображениям безопасности знать этот адрес лучше , чем адрес шлюза.

Amurzet ()
Ответ на: комментарий от RiD

Как я понимаю, там без haproxy не обойтись ? т.е. одним iptables.

Amurzet ()

Вот енто уберите iptables -t nat -A POSTROUTING -d 192.168.1.155/32 -p tcp -m tcp --dport 80 -j SNAT --to-source 1.2.3.4:80 и будет счастье

anc ★★★★★ ()
Ответ на: комментарий от anc

Оставил так :

iptables -t nat -A PREROUTING -p tcp -d 1.2.3.4 --dport 10022 -j DNAT --to-destination 192.168.1.252:22
iptables -A FORWARD -i eth0 -d 192.168.1.252 -p tcp --dport 10022 -j ACCEPT

#iptables -t nat -A POSTROUTING --dst 192.168.1.252 -p tcp --dport 22 -j SNAT --to-source 1.2.3.4
iptables -t nat -A OUTPUT --dst 1.2.3.4 -p tcp --dport 10022 -j DNAT --to-destination 192.168.1.252

не помогло - tcpdump упорно показывает тоже самое - коннект с карточки шлюза, смотрящей в локалку. :(

Amurzet ()
Ответ на: комментарий от Amurzet

так при обычном nat/PREROUTING/DNAT так все и происходит.

А вот если виден адрес шлюза на котором выполнен нат - значит для этого соединения зачем-то применен еще и SNAT. Это можно избежать если проверять статус соединения "-m conntrack ! --ctstate DNAT" в nat/POSTROUTING

Для проброса порта через DNAT во внутрь нужно только одно правило.

iptables -t nat -A PREROUTING -p tcp -d x.x.x.x --dport yyy -j DNAT --to-destination z.z.z.z:n
Чтоб оно работало только для внешних коннектов, можно добавить "-i eth0", что будет более корректно. Либо добавить исключение адресов локально сети через "! -s 192.168.1.0/24"

Какой вариант нравится больше - выбирай сам.

vel ★★★★★ ()
Ответ на: комментарий от Amurzet

1. Значит где-то еще есть правила nat. При наличии первых двух, все работает как вам надо. DNAT source адрес не подменяет, что собственно следует от его названия.
2. А в OUTPUT -то нафейхуа правило?

anc ★★★★★ ()
Ответ на: комментарий от vel

Для проброса порта через DNAT во внутрь нужно только одно правило.

Ну если не рассматривать полное раздолбайство в написании правил, таки forward тоже будет нужен.

anc ★★★★★ ()
Ответ на: комментарий от vel

Я в полнейшем отчаянии. Сократил файрфол до минимума :

iptables -F

iptables -P INPUT DROP
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT

iptables -t nat -i eth0 -A PREROUTING -p tcp -d 1.2.3.4 --dport 10022 -j DNAT --to-destination 192.168.1.252:22

после старта (надеюсь обнуляю файволл правильно) он работает но на сервере 192.168.1.252 адрес источник по прежнему локальный адрес шлюза : 192.168.1.254

Система - Debian
файрволл ни в какие стартовые скрипты не вписывал. Просто запускаю сам после старта.

Amurzet ()
Ответ на: комментарий от Amurzet

Вру я вам все. проверил свою мысль - find'ом по /etc/networks прошелся - нашел хвосты старого файрвола. Удалил. Запускаю скрипт из предыдущего поста.
Стало намного лучше - локальный сервер регистрирует вторжение из интернета !!! как надо. Но до приглашения не доходит - висит все на логине. Видимо обратно пакеты что-ли не возвращаются.

Amurzet ()
Ответ на: комментарий от Amurzet

Выполнил iptables-save сразу после перезагрузки - пусто

после скрипта из предпоследнего поста :

# Generated by iptables-save v1.4.21 on Thu Nov 17 23:25:22 2016 *nat
:PREROUTING ACCEPT [22:3292]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
-A PREROUTING -d 1.2.3.4/32 -i eth0 -p tcp -m tcp --dport 10022 -j DNAT --to-destination 192.168.1.252:22
COMMIT
# Completed on Thu Nov 17 23:25:22 2016
# Generated by iptables-save v1.4.21 on Thu Nov 17 23:25:22 2016
*filter
:INPUT DROP [22:3292]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A FORWARD -d 192.168.1.252/32 -i eth0 -p tcp -m tcp --dport 10022 -j ACCEPT
COMMIT
# Completed on Thu Nov 17 23:25:22 2016-A PREROUTING -p tcp -d 1.2.3.4 --dport 10022 -j DNAT --to-destination 192.168.1.252:22

Amurzet ()
Ответ на: комментарий от Amurzet

Теоретически в таблицу filter, но если опираться на дамп из предыдущего поста, то добавлять нет смысла, даже лишнее правило из filter-FORWARD можно убрать.

Но до приглашения не доходит - висит все на логине.

В текущем виде помех со стороны iptables для прохождения транзитного трафика нет.
Ограничение может присутствовать на уровне самого сервиса, который слушает порт, либо фаервола конечного хоста.

ArcFi ()
Ответ на: комментарий от Amurzet

conntrack -L -p tcp --dport 10022 должен показать это соединение. Обрати внимание на адреса соединения.

Ну и tcpdump -ni eth1 tcp and port 22 должен показывать настоящий адрес источника соединения и адрес назначения 192.168.1.252

на сервере посмотри tcpdump -npi ethXXX port 22

vel ★★★★★ ()
Ответ на: комментарий от Amurzet

Похоже на мистику. Но все-таки, именно при этих правилах покажите что говорит tcpdump на хосте 192.168.1.252 при обращении из инета на 1.2.3.4:10022 достаточно просто телнета.

anc ★★★★★ ()
Ответ на: комментарий от anc

Спасибо большое, все заработало. Вернее,понимание пришло. Дело в том, что шлюз 2 функции выполняет : проброс портов снаружи и NAT для станций из локалки.

Выходит, что одно другому мешает. Если убрать второе - первое работает как надо. А теперь задача подружить обе функции.

Было так (это то,что я из старых скриптов накопал) :

iptables -A FORWARD -i eth1 -o eth0 -s 192.168.0.0/28 -j ACCEPT
iptables -A POSTROUTING -t nat -j MASQUERADE
iptables -A INPUT -i eth0 -p icmp --icmp-type 8 -j ACCEPT

Amurzet ()
Ответ на: комментарий от Amurzet

за iptables -A POSTROUTING -t nat -j MASQUERADE нужно больно бить по рукам!

Маскарадить нужно только то, что выходит через внешний интерфейс (-o eth0) с адресами из локальной сети (-s 192.168.1.0/24)

vel ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.