LINUX.ORG.RU
решено ФорумAdmin

помогите понять SNAT, DNAT

 


0

1

Здравствуйте.

Роутер с 2 провайдерами и 1 интерфейс в локальную сеть.

# uname -a
Linux alpine-eng 4.4.27-0-grsec #1-Alpine SMP Tue Oct 25 08:14:42 GMT 2016 i686 Linux
eth0 -> 87.237.35.52
eth1 -> ppp0 --> 214.222.204.212
eth2 -> 192.168.3.1

Правила для таблиц

# ip ru
0:      from all lookup local
19993:  from all fwmark 0x14 lookup 102
20000:  from 87.237.35.52 lookup 101
20000:  from 214.222.204.212 lookup 102
32766:  from all lookup main
32767:  from all lookup default

#ip r
default via 87.237.35.1 dev eth0
default via 96.51.138.1 dev ppp0  metric 300
87.237.35.0/24 dev eth0  proto kernel  scope link  src 87.237.35.52
96.51.138.1 dev ppp0  proto kernel  scope link  src 214.222.204.212
192.168.3.0/24 dev eth2  proto kernel  scope link  src 192.168.3.1

#ip r show table 101
default via 87.237.35.1 dev eth0
87.237.35.0/24 dev eth0  proto kernel  scope link
#ip r show table 102
default via 96.51.138.1 dev ppp0  metric 300
96.51.138.0/24 dev ppp0  proto kernel  scope link

правила в iptables

$IPTABLES -t nat -A POSTROUTING -o $INET_IFACE_1 -s 192.168.3.0/24 -j SNAT --to-source $INET_IP_1
$IPTABLES -t nat -A POSTROUTING -o $INET_IFACE_2 -s 192.168.3.0/24 -j SNAT --to-source $INET_IP_2

$IPTABLES -t mangle -A INPUT -i $INET_IFACE_1 -j CONNMARK --set-mark 10
$IPTABLES -t mangle -A INPUT -i $INET_IFACE_2 -j CONNMARK --set-mark 20

$IPTABLES -t mangle -A OUTPUT -j CONNMARK --restore-mark

Весь трафик идет в основного провайдера (таблица 101, адрес 87.237.35.52), если он падает - успешно переключается на второго (таблица 102). Это работает. Теперь, я хочу добавить проброс порта через резервного провайдера на машину в локальной сети 192.168.3.25

$IPTABLES -t nat -A PREROUTING -p TCP -i $INET_IFACE_2 -s $Dwork -d $INET_IP_2 --dport 2221 -j DNAT --to-destination 192.168.3.25:22

Пытаюсь подключиться, (ssh user@214.222.204.212 -p2221) трафик до 192.168.3.25 доходит, улетает обратно в роутер и там я смотрю

#tcpdump -i eth0 port 2221
12:30:33.415601 IP 214.222.204.212.2221 > 215.212.87.83.58468: Flags [S.], seq 911496099, ack 1279645560, win 28960, options [mss 1460,sackOK,TS val 2912775030 ecr 375318023,nop,wscale 7], length 0
Но ведь входящий трафик поступил на ppp0 и уйти обратно должен через ppp0, но уйти обратно он пытается с eth0. Как заставить трафик уходить с того же интерфейса откуда он пришел? В данном случае с ppp0

Но ведь входящий трафик поступил на ppp0 и уйти обратно должен через ppp0, но уйти обратно он пытается с eth0.

Так и должно быть - ведь согласно Вашим настройкам, маршруты через ppp0 активируется только при падении eth0.

Попробуйте принудительно поместить трафик машины 192.168.3.25 в таблицу 102.

Serge10 ★★★★★ ()
$IPTABLES -t mangle -A INPUT -i $INET_IFACE_1 -j CONNMARK --set-mark 10
$IPTABLES -t mangle -A INPUT -i $INET_IFACE_2 -j CONNMARK --set-mark 20

это только для пакетов адресованных роутеру. На транзитные пакеты оно не влияет.

Перенеси их в PREROUTING

PS я уже задолбался повторять, что прямые маршруты должны проверятся сразу после локальных. default route (комментарий)

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

Так и должно быть - ведь согласно Вашим настройкам, маршруты через ppp0 активируется только при падении eth0

Нет, при падении eth0, ppp0 становится default route, но это не значит что когда eth0 работает - ppp0 вобще не работает. У меня же написано

default via 96.51.138.1 dev ppp0  metric 300

Попробуйте принудительно поместить трафик машины 192.168.3.25 в таблицу 102

Это работает, но мне это не нужно. Мне нужно, чтобы если машина 192.168.3.25 инициировала какое-то подключение в интернет - трафик шел по default route, а если из интернета кто-то подключается на порт 2221 порта ppp0 роутера, этот трафик шел на 192.168.3.25 и возвращался с порта на который приходил - ppp0

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

это только для пакетов адресованных роутеру. На транзитные пакеты оно не влияет.
Перенеси их в PREROUTING

У меня возникло такое подозрение, но я не понимаю как его проверить и как исправить.
Вот я сделал после прочтения комментария

iptables -t mangle -A POSTROUTING -o ppp0 -j CONNMARK --set-mark 20
Ничего не изменилось. И я не понимаю как должно было изменится. mangle POSTROUTING ведь совершается после того как принято решение о том в какой интерфейс отправлять.

PS я уже задолбался повторять, что прямые маршруты должны проверятся сразу после локальных. default route

Что такое прямой маршрут? Сходил по ссылке.

В main не должно быть default gateway

Это наталкивает на мысли. У меня программа pingu отслеживает работоспособность интерфейсов. Пингует через eth0, если пинги не ходят - удаляет default route eth0 из таблицы main, остается только default route ppp0 metric 300. Если пинги перестали ходить через ppp0 - удаляет из таблицы main маршрут в ppp0. Остаются только таблицы 101 и 102... Как же это будет выглядеть и как переделать чтобы автоматическое переключение провайдеров осталось работать и из main убрать маршруты и правило для main перевести выше приоритетом...

GreyDjin ()
Ответ на: комментарий от GreyDjin
iptables -t mangle -A POSTROUTING -o ppp0 -j CONNMARK --set-mark 20

Извиняюсь, поправил на PREROUTING, ничего не изменилось

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

Что такое прямой маршрут

гуглить «ipv4 прямой и косвенный маршрут»

# ip ru
0:      from all lookup local
19993:  from all fwmark 0x14 lookup 102
20000:  from 87.237.35.52 lookup 101
20000:  from 214.222.204.212 lookup 102
32766:  from all lookup main
32767:  from all lookup default

Проблема в том, что если у тебя пакет с меткой 14 или src 87.237.35.52 или src 214.222.204.212, то в 192.168.3.0/24 пакет не попадет.

Нужно либо продулировать все прямые маршруты во все доп. таблицы ( и не забывать это делать после down/up любого интерфейса), либо сделать как в предыдущей ссылке, где dgw распиханы по разным таблицам.

$IPTABLES -t mangle -A OUTPUT -j CONNMARK --restore-mark

Это для локално генерируемых пакетов, а для транзитных пакетов кто будет метку восстанавливать? Пушкин? Это нужно продублировать в INPUT для eth2

Возьми бумажку, открой схему и нарисуй путь прохождения пакета туда и обратно.

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

Проблема в том, что если у тебя пакет с меткой 14 или src 87.237.35.52 или src 214.222.204.212, то в 192.168.3.0/24 пакет не попадет.

Я понял, моя ошибка что я не всю таблицу показал. Приходит пакет с src 214.222.204.212 и он успешно доходит до назначения 192.168.3.25 Ведь если бы не доходил, я бы не увидел на eth0 в tcpdump обратные пакеты, которые я показал в стартовом топике

# ip r show table 102
default via 96.51.138.1 dev ppp0  metric 300
96.51.138.1 dev ppp0  proto kernel  scope link
192.168.3.0/24 dev eth2  scope link  src 192.168.3.1

Это для локально генерируемых пакетов, а для транзитных пакетов кто будет метку восстанавливать? Пушкин? Это нужно продублировать в INPUT для eth2

Но я же не могу это сделать, если я сделаю

iptables -t mangle -A PREROUTING -i eth2 -j CONNMARK --set-mark 20
Все пакеты из этой локальной сети уйдут в ppp0, а этого быть не должно. Мне нужно не все пакеты, а только те пакеты которые изначально пришли на ppp0

гуглить «ipv4 прямой и косвенный маршрут»
Маршруты для прямой маршрутизации добавляются в таблицу маршрутизации автоматически при присвоении адреса интерфейсу. Косвенные маршруты необходимо прописывать в таблицу маршрутизации вручную.

Ок, я понял.

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

iptables -t mangle -A PREROUTING -i eth2 -j CONNMARK --set-mark 20

Все пакеты из этой локальной сети уйдут в ppp0, а этого быть не должно. Мне нужно не все пакеты, а только те пакеты которые изначально пришли на ppp0

Чтобы ответы ходили через тот же канал, что пришли нужно

iptables -t mangle -A PREROUTING -i eth2 -j CONNMARK --restore-mark
А маркирровать только входящие соединения через ppp
iptables -t mangle -A PREROUTING -i ppp0 -m state NEW -j CONNMARK --set-mark 20

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

Добавил правил для PREROUTING eth2 resotr-mark

# iptables -t mangle -vnL
Chain PREROUTING (policy ACCEPT 99590 packets, 33M bytes)
 pkts bytes target     prot opt in     out     source               destination
24047 4771K CONNMARK   all  --  eth2   *       0.0.0.0/0            0.0.0.0/0            CONNMARK restore

Chain INPUT (policy ACCEPT 33215 packets, 7389K bytes)
 pkts bytes target     prot opt in     out     source               destination
 874K  264M CONNMARK   all  --  eth0   *       0.0.0.0/0            0.0.0.0/0            CONNMARK set 0xa
 108K   27M CONNMARK   all  --  ppp0   *       0.0.0.0/0            0.0.0.0/0            CONNMARK set 0x14
24143 1371K CONNMARK   all  --  vlan10 *       0.0.0.0/0            0.0.0.0/0            CONNMARK set 0x1e
   42 53660 CONNMARK   all  --  vlan123 *       0.0.0.0/0            0.0.0.0/0            CONNMARK set 0x28

Chain FORWARD (policy ACCEPT 64680 packets, 24M bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain OUTPUT (policy ACCEPT 33674 packets, 6998K bytes)
 pkts bytes target     prot opt in     out     source               destination
1115K  286M CONNMARK   all  --  *      *       0.0.0.0/0            0.0.0.0/0            CONNMARK restore

Chain POSTROUTING (policy ACCEPT 98354 packets, 31M bytes)
 pkts bytes target     prot opt in     out     source               destination

После этого сделал ip r flush cache и conntrack -F
Все равно, подключиться пытаюсь на ppp0, а ответы уходят в eth0

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

А куда пропала маркировка на PREROUTING? Вам же vel постом выше оба правила написал.

ЗЫ на будущее о таблице main еще одно пояснение от vel Маршрутизация маркированных iptables пакетов. (комментарий)

anc ★★★★★ ()
Последнее исправление: anc (всего исправлений: 1 )
Ответ на: комментарий от anc

А куда пропала маркировка на PREROUTING? Вам же vel постом выше оба правила написал.

Я подумал что мне нужно выбрать из его сообщения то что мне необходимо, я не понял что мне нужно применить оба правила.

Прям в том виде правило не сработало. Заменил модуль на conntrack

iptables -t mangle -A PREROUTING -i ppp0 -m conntrack --ctstate NEW -j CONNMARK --set-mark 20

Так заработало. Честно, я пока не понял почему при наличии двух правил

iptables -t mangle -A PREROUTING -i eth2 -j CONNMARK --restore-mark
iptables -t mangle -A POSTROUTING -o ppp0 -j CONNMARK --set-mark 20
Не работало, а при наличии трех правил заработало
iptables -t mangle -A PREROUTING -i eth2 -j CONNMARK --restore-mark
iptables -t mangle -A POSTROUTING -o ppp0 -j CONNMARK --set-mark 20
iptables -t mangle -A PREROUTING -i ppp0 -m conntrack --ctstate NEW -j CONNMARK --set-mark 20

Спасибо за помощь всем! Попытаюсь осмыслить

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

Честно, я пока не понял почему при наличии двух правил
Не работало, а при наличии трех правил заработало

Второе правило "-t mangle -A POSTROUTING -o ppp0 -j CONNMARK --set-mark 20" не нужно. С остальным надеюсь понятно :)

anc ★★★★★ ()
Последнее исправление: anc (всего исправлений: 2 )
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.