URL: https://www.opennet.me/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID1
Нить номер: 82450
[ Назад ]

Исходное сообщение
"2 провайдера и DNAT"

Отправлено zejron , 17-Окт-08 15:04 
Доброго времени суток!
Вот собственно задача:
Есть 2 провайдера с реальными IP, роутер на генту, локалка.
В локалке есть виндовые серваки..
Нужно чтобы они были доступны по любому внешнему IP.

Вод что сделано:
eth0 - Local0
eth1 - Local1
eth2 - Prov1
eth3 - Prov2

kordon my # ip r ls
$NET_PROV2 dev eth3  proto kernel  scope link  src $IP_PROV2
$NET_PROV1 dev eth2  proto kernel  scope link  src $IP_PROV1
192.168.110.0/24 dev eth1  proto kernel  scope link  src 192.168.110.254
192.168.111.0/24 dev eth0  proto kernel  scope link  src 192.168.111.254
127.0.0.0/8 dev lo  scope link
default via $GW_PROV1 dev eth2

kordon my # ip r ls t Osn
$NET_PROV1 dev eth2  scope link  src $IP_PROV1
192.168.110.0/24 dev eth1  scope link
192.168.111.0/24 dev eth0  scope link
127.0.0.0/8 dev lo  scope link
default via GW_PROV1 dev eth2

kordon my # ip r ls t Rez
$NET_PROV2 dev eth3  scope link  src $IP_PROV2
192.168.110.0/24 dev eth1  scope link
192.168.111.0/24 dev eth0  scope link
127.0.0.0/8 dev lo  scope link
default via GW_PROV2 dev eth3

kordon my # ip ru ls
0:      from all lookup local
32762:  from all fwmark 0x20 lookup Rez
32763:  from all fwmark 0x10 lookup Osn
32764:  from $IP_PROV2 lookup Rez
32765:  from $IP_PROV1 lookup Osn
32766:  from all lookup main
32767:  from all lookup default

kordon my # iptables -t nat -L -nv
Chain PREROUTING (policy ACCEPT 817K packets, 93M bytes)
pkts bytes target     prot opt in     out     source               destination
    3   144 DNAT       tcp  --  eth3   *       0.0.0.0/0            $IP_PROV2       tcp dpt:3390 to:192.168.111.1:3389
    2    96 DNAT       tcp  --  eth2   *       0.0.0.0/0            $IP_PROV1       tcp dpt:3390 to:192.168.111.1:3389
   56  2688 DNAT       tcp  --  eth3   *       0.0.0.0/0            $IP_PROV2       tcp dpt:3389 to:192.168.111.2
   19   912 DNAT       tcp  --  eth2   *       0.0.0.0/0            $IP_PROV1       tcp dpt:3389 to:192.168.111.2
139K 8119K Mac        all  --  eth0   *       0.0.0.0/0           !192.168.111.0/24

Chain POSTROUTING (policy ACCEPT 162K packets, 11M bytes)
pkts bytes target     prot opt in     out     source               destination
7172  412K SNAT       all  --  *      eth2    192.168.0.0/16      !192.168.0.0/16      to:$IP_PROV1
    0     0 SNAT       all  --  *      eth3    192.168.0.0/16      !192.168.0.0/16      to:$IP_PROV2

Chain OUTPUT (policy ACCEPT 161K packets, 11M bytes)
pkts bytes target     prot opt in     out     source               destination

Вообщем все работает через того провайдера, который дефолтный шлюз, а через второго нет.. Ну собственно если меняется шлюз, то и IP через который работает...
А надо чтоб всегда работало через оба..
После втыкания во все, пришел к заключению, что ответ от виндового сервака идет не на тот интерфейс с которого пришел запрос, на дефолтный гейт.
Хотя должен был по таблице соединений и таблицам маршрутизации уйти правильно (ну как я думаю :) )
Что я не так сделал? Что исправить?


Содержание

Сообщения в этом обсуждении
"2 провайдера и DNAT"
Отправлено PavelR , 17-Окт-08 17:07 
На форуме часто задается вопрос по поводу маршрутизации сети, подключенной к двум провайдерам.
На этот вопрос уже есть масса ответов, чтобы их найти достаточно воспользоваться поиском.

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

Проблема усугубляется тем, что обратное преобразование адресов выполняется уже после принятия решения о маршрутизации,
т.е. примерно в районе цепочки POSTROUTING, но скрытно от пользователя.

Решить эту нерешаемую проблему поможет модуль CONNMARK, который позволяет маркировать каждое проходящее через маршрутизатор соединение, и маршрутизация ответных пакетов в зависимости от значения маркера.

Принцип работы маршрутизатора для решения описанной задачи будет выглядеть примерно так:

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


В нижеописанном примере обеспечение доступности сервиса по двум каналам/провайдерам делалось для локального сервиса маршрутизатора. Также описаны отличия конфигурации для проброса сервиса в DMZ.

Изначально сервис был доступен через канал первого провайдера first на адресе first_ip. Возникла задача обеспечить его доступность по каналу второго провайдера.  

Поскольку сервис расположен на реальном айпи, то для входящих соединений с порта первого провайдера DNAT применяться не будет.
Входящие пакеты/соединения с порта второго провайдера (destination <second_ip>) будут помечены маркером и к ним будет применен DNAT.
Пакеты с порта первого провайдера мы маркировать не будем, поскольку провайдеров всего два и первый является шлюзом по умолчанию для сервиса.
(Фактически эти соединения промаркированы флажком 0x00)

[root@test z]# iptables -t nat -nvL PREROUTING
Chain PREROUTING (policy ACCEPT 144M packets, 9659M bytes)
pkts bytes target     prot opt in     out     source               destination
    1    52 CONNMARK   tcp  --  *      *       0.0.0.0/0            <second_ip>      tcp dpt:<port> CONNMARK set 0x1
    1    52 DNAT       tcp  --  *      *       0.0.0.0/0            <second_ip>      tcp dpt:<port> to:<first_ip>:<port>


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

В связи с тем, что сервис локальный, маркировка исходящих пакетов делается в цепочке OUTPUT таблицы mangle.
Для проброса порта к серверу в локальной сети(в DMZ)  восстановление маркера надо делать в цепочке PREROUTING таблицы mangle.

[root@test z]# iptables -t mangle -nvL OUTPUT
Chain OUTPUT (policy ACCEPT 6745M packets, 7048G bytes)
pkts bytes target     prot opt in     out     source               destination
65915 8600K CONNMARK   tcp  --  *      *       <first_ip>            0.0.0.0/0           tcp spt:<port> CONNMARK restore


Далее система принимает решение о маршрутизации пакета.

Все не маркированные пакеты будут идти по маршруту по умолчанию. В моем случае это первый провайдер first и IP интерфейса first_ip.
Все исходящие (обратные) пакеты  будут промаркированы значением маркера соединения в цепочке OUTPUT таблицы mangle.


[root@test z]# ip ru sh
0:      from all lookup local
1000:   from all lookup main
3300:   from all fwmark 0x1 lookup <second>
5000:   from <first_ip> lookup <first>
5500:   from <second_ip> lookup <second>
10000:  from all lookup default
32766:  from all lookup main
32767:  from all lookup default


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


http://www.opennet.me/openforum/vsluhforumID1/78348.html
http://www.opennet.me/openforum/vsluhforumID1/78704.html

http://www.opennet.me/openforum/vsluhforumID10/3679.html#4


"2 провайдера и DNAT"
Отправлено zejron , 17-Окт-08 17:24 
Просто огромное спасибо :)
Видать я плохо скал... Или может не совсем то :)
Буду пробывать



"2 провайдера и DNAT"
Отправлено PavelR , 17-Окт-08 18:12 
>Просто огромное спасибо :)
>Видать я плохо скал... Или может не совсем то :)
>Буду пробывать

а фиг знает как это найти. На сайте стопудово есть, я отправлял, как автор...

Найти не могу )


"два провайдера"
Отправлено Andrey Mitrofanov , 18-Окт-08 09:45 
>а фиг знает как это найти. На сайте стопудово есть, я отправлял,
>как автор...

http://www.opennet.me/tips/info/1651.shtml

>Найти не могу )

google.ru
first_ip site:opennet.ru
ENTER

:-) Спасибо!


"2 провайдера и DNAT"
Отправлено zejron , 17-Окт-08 20:24 
Все заработало :) Огормыое спасибо!

Собственно вод:
$IPT -t nat -A PREROUTING -i $I_WAN1 -d $IP_WAN1 -p tcp --dport 3389 -j CONNMARK --set-mark 0x10
$IPT -t nat -A PREROUTING -i $I_WAN1 -d $IP_WAN1 -p tcp --dport 3389 -j DNAT --to-destination 192.168.111.2:3389
$IPT -t nat -A PREROUTING -i $I_WAN2 -d $IP_WAN2 -p tcp --dport 3389 -j CONNMARK --set-mark 0x20
$IPT -t nat -A PREROUTING -i $I_WAN2 -d $IP_WAN2 -p tcp --dport 3389 -j DNAT --to-destination 192.168.111.2:3389
$IPT -t nat -A PREROUTING -i $I_WAN1 -d $IP_WAN1 -p tcp --dport 3390 -j CONNMARK --set-mark 0x10
$IPT -t nat -A PREROUTING -i $I_WAN1 -d $IP_WAN1 -p tcp --dport 3390 -j DNAT --to-destination 192.168.111.1:3389
$IPT -t nat -A PREROUTING -i $I_WAN2 -d $IP_WAN2 -p tcp --dport 3390 -j CONNMARK --set-mark 0x20
$IPT -t nat -A PREROUTING -i $I_WAN2 -d $IP_WAN2 -p tcp --dport 3390 -j DNAT --to-destination 192.168.111.1:3389

$IPT -t mangle -A -A PREROUTING -s 192.168.111.2 -p tcp --sport 3389 -j CONNMARK --restore-mark
$IPT -t mangle -A -A PREROUTING -s 192.168.111.1 -p tcp --sport 3389 -j CONNMARK --restore-mark

ip rule list
0:      from all lookup local
32762:  from all fwmark 0x20 lookup Rez
32763:  from all fwmark 0x10 lookup Osn
32764:  from $IP_WAN2 lookup Rez
32765:  from $IP_WAN1 lookup Osn
32766:  from all lookup main
32767:  from all lookup default

как сделать ip rule на 2 (более) провайдеров http://www.mgul.ac.ru/~t-alex/Linux/Traffic-Control-HOWTO/in...