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

2 ISP, NAT и доступность внутреннего сервера по двум провайдерам - помогите разобраться с багом

 ,


1

2

Вирт. машина (далее linux-роутер) предназначенная для агрегации ISP и проброса подключений к внутреннему серверу подключена к двум «железным» роутерам через коммутатор и получает от них интернет. Оба роутера в одной подсети (192.168.1.1, 192.168.1.2).

linux-router:

eth0: address 192.168.1.111 (получает интернет от первого ISP)
eth1: address 192.168.1.112 (получает интернет от второго ISP)
eth2: address 10.0.0.1 (подключена к целевому серверу в локальной сети)

Что я делаю:

1. Забочусь о том, чтобы пакеты уходили на через тот же интерфейс на который пришли.

ip rule add from 192.168.1.111 lookup t1
ip rule add from 192.168.1.112 lookup t2

ip route add default via 192.168.1.1 dev eth0 table t1
ip route add 192.168.1.0/24 dev eth0 table t1
ip route add default via 192.168.1.2 dev eth0 table t2
ip route add 192.168.1.0/24 dev eth1 table t2

На этом этапе мне доступны службы работающие на linux-router по двум IP (например, первый «железный» роутер пробрасывает порт 22 на 192.168.1.111, а второй на 192.168.1.112, в итоге получаю доступ из интернета к SSH по двум белым IP).

2. Пробрасываю порт 80 к IIS'у висящему на 10.0.0.2 и подключенному к eth2.

- мечу пакеты:

iptables -t mangle -N in-marking
iptables -t mangle -A PREROUTING -m conntrack -ctstate NEW -j in-marking
iptables -t mangle -A in-marking -i eth0 -j CONNMARK --set-xmark 0x1/0x3
iptables -t mangle -A in-marking -i eth1 -j CONNMARK --set-xmark 0x2/0x3

На этом этапе, если посмотреть connmark -L -p tcp --dport 22 (для подключений к SSH lunux-роутера), то видно, что пакеты получают нужные метки (для 80-го порта в дальнейшем какая-то ерунда).

Когда порт 80 будет проброшен и веб-сервер даст ответ, надо восстановить метку и направить ответ туда откуда он пришёл:

iptables -t mangle -N out-marking
iptables -t mangle -A PREROUTING -m connmark ! --mark 0x0/0x3 -j out-marking
iptables -t mangle -A out-marking -i eth2 -j CONNMARK --restore-mark --mask 0x3
ip rule add fwmark 0x1/0x3 lookup t1
ip rule add fwmark 0x2/0x3 lookup t2

И наконец самое загадочное. NAT'им подключения на 80-й порт внутреннего сервера.

NAT'им:

iptables -t nat - A PREROUTING -m connmark --mark 0x1/0x3 -i eth0 -p tcp --dport 80 -j DNAT --to-destination 10.0.0.2
iptables -t nat - A PREROUTING -m connmark --mark 0x2/0x3 -i eth1 -p tcp --dport 80 -j DNAT --to-destination 10.0.0.2
(Метки в критерии я добавил для того, чтобы убедиться, что они работают).

Проблема. Веб-сервер доступен только по одному интерфейсу, причём выбирается он кажется случайно.

С помощью iptables -vL -t nat я вижу, что оба правила применяются в зависимости от того на какой интерфейс (eth0 или eth1) пришёл запрос, но до моего веб-сервера доходят пакеты лишь с одного интерфейса, в этом я убеждаюсь с помощью tcpdump -i eth2 -t tcp (в одном случае он всегда молчит).

Помогите пожалуйста!

P.S. использовать iproute на веб-сервере и решить проблему не могу, т.к. сервер виндовый, а там с этим не понятно. К тому же хотелось бы иметь универсального агрегатора ISP, чтобы к нему подключать нужные внутренние машины.
P.P.S. Идея взята из http://habrahabr.ru/post/117620/



Последнее исправление: lemix (всего исправлений: 3)

Вирт. машина (далее linux-роутер) предназначенная для агрегации ISP и проброса подключений к внутреннему серверу подключена к двум «железным» роутерам через коммутатор и получает от них интернет

А нельзя проброс на самих роутерах сделать?

но до моего веб-сервера доходят пакеты лишь с одного интерфейса, в этом я убеждаюсь с помощью tcpdump -i eth2 -t tcp

Так на web тоже два интерфейса что-ли? Схему поподробнее можно?

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

Проброс на самих роутерах сделать нельзя, т.к. web в другой подсети (и я не хочу иметь на нём два сетевых интерфейса).

На web один интерфейс 10.0.0.2 gw 10.0.0.1 «воткнутый» в eth2 linux-роутера. Т.е. схема простая: у linux-роутера три интерфейса, первые два «воткнуты» в коммутатор вместе с двумя «железными» роутрами, а третий в коммутатор с веб-сервером.

В принципе я не ищу других решений, моё решение мне нравится... вот только не работает :(

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

первые два «воткнуты» в коммутатор вместе с двумя «железными» роутрами

Это как? Каждый роутер физически воткнут в отдельную сетевушку?

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

Сложно не рисуя объяснить. Есть сервер с одной сетевушкой и два роутера, всё воткнуто в один физический коммутатор.

На сервере работает hyper-v, а в нём крутиться вируталка linux-router имеющая два интерфейса которые «воткнуты» в виртуальный свич hyper-v. Т.е. два роутера, сервер, и linux-router «воткнуты» в «один» свич образованный физическим коммутатором и виртуальным коммутатором.

В этом нет проблемы, я описал, что SSH на linux-роутере прекрасно доступен по двум IP из интернета.

Проблема в том, что два правила NAT
192.168.1.111 -> 10.0.0.2
192.168.1.112 -> 10.0.0.2
работают не корректно, т.е. работает только одно правило. С одного из интерфесов пакеты просто не приходят на 10.0.0.2

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

А что там рисовать. Вот, как я понял:

digraph G {
     C1 -> SW1;
     C2 -> SW1;
     SW1 -> VirtualLin1;
     subgraph cluster_Virt {
       label="Host"
       VirtualLin1;
     }
     VirtualLin1 -> Srv1;
 }        

Посмотреть можно здесь

Выходит, что в виртуалку соединения от роутеров приходят по одному интерфейсу.

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

Вот так:

digraph G {
     C1 -> SW1;
     C2 -> SW1;
     SW1 -> VirtualSwith;
     subgraph cluster_Virt {
       label="Host"
       VirtualSwith;
       VirtualSwith -> VirtualLinux;
       VirtualSwith -> VirtualLinux;
     }
     VirtualLinux->WebServer

 }  

Можно было бы сделать алиасы:
eth0 - 192.168.1.111
eth0:1 - 192.168.1.111
но iptables с алиасами не дружит

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

eth0 - 192.168.1.111
eth0:1 - 192.168.1.112 (опечатался)

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

«Железные» роутеры, пробрасывают 80 порт.

Router1:80 -> Linux-router:192.168.1.111:80 Router2:80 -> Linux-router:192.168.1.112:80

А Linux-router уже должен пробросить дальше на 10.0.0.2, но пробрасывает только одно соединение, оба одновременно не работают.

lemix
() автор топика
Ответ на: комментарий от ziemin

В смысле?

Просто берёться и всё, путём добавления железа в вирт. машину и настройки его в /etc/network/interfaces

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

Если роутеры объединены в одну подсеть свитчем SW1, то они различаются только по IP. Соответственно одна стрелка.

А вот из VirtualLinux выходит две стрелки. Откуда и зачем вторая?

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

Если интерфейс будет один, то я не понимаю, как определять, с какого роутера пришёл запрос? Я вообще-то далеко не админ)

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

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

По-моему это разруливает уже свич, безо всяких правил. Если оба роутера подключены к свичу, то они обычные хосты, а не интерфейсы.

Когда на любой роутер приходит входящее соединение он передаёт его дальше, уже от своего ip. Соответственно на Linux-router есть один входящий интерфейс, на который сыпятся соединения от двух роутеров.

Далее надо просто перенаправлять 80 порт с единственного входящего интерфейса на машину назначения.

А маршрутизацией уже занимается система и настраивать её через фаервол не нужно.

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

Не совсем так. Да, соединение с любого роутера дойдёт до Linux-router, но ответ уйдёт через gw по умолчанию. Необходимы правила, чтобы направить ответ через тот-же gw.

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

правила в моём примере реализованы через iproute и любые локальные службы linux-роутера доступны, т.е. отвечают через тот gw, с которого пришёл запрос.

Глючит только дальнейшая проброска, причём глючит конкретно, не просто не отправляет ответ, а не пересылает запрос до конечно веб-сервера. Т.е. пересылает, но только с одного интерфейса, а с другого пакет просто пропадает где-то.

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

Но ведь ssh работает через оба роутера?

но ответ уйдёт через gw по умолчанию

Это если рулить на уровне пакетов. Но TCP оперирует соединениями. И в них уже есть инфа что куда отправлять.

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

Но ведь ssh работает через оба роутера?

Только брагодаря правилам:

ip rule add from 192.168.1.111 lookup t1
ip rule add from 192.168.1.112 lookup t2

ip route add default via 192.168.1.1 dev eth0 table t1
ip route add 192.168.1.0/24 dev eth0 table t1
ip route add default via 192.168.1.2 dev eth0 table t2
ip route add 192.168.1.0/24 dev eth1 table t2
lemix
() автор топика
Ответ на: комментарий от lemix

Опять опечатался:

ip route add default via 192.168.1.2 dev eth1 table t2

Но в рабочих настройках всё верно.

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

Вот. Интерфейс один и тот же.

Точнее здесь:

ip route add 192.168.1.0/24 dev eth1 table t2

он отличается, что наводит меня на мысль, что эти строки вообще никакой погоды не делают.

Да и зачем тебе шлюз, если устанавливается конкретное соединение с конкретного ip? Роутеры уже сами разбираются что куда отправлять.

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

Если у машины не указан gw, то она не сможет ответить во внешнюю сеть, т.е. мой SSH без этих правил будет доступен только из 192.168.1.0.24. Если же указать два gw, то ответ уйдёт на gw по умолчанию.

В общем проблема решилась полностью установкой Debian7 вместо Ubuntu 12.04 LTS.

В убунте есть баг связанный похоже с conntrack.

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

В общем проблема решилась полностью установкой Debian7 вместо Ubuntu 12.04 LTS.

Пометь тред как решённый же.

Ну и да:

В убунте есть баг связанный похоже с conntrack.

В этом была проблема?

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

ziemin, спасибо за вашу настойчивость, я таки отказался от двух интерфейсов, оставил один, а маркирую пакеты по MAC шлюза. Хотя и с двумя интерфейсами работало бы.

Вот рабочее решение, проверенное на Debian7, в Ubuntu 12.04 оно не работает.

ip rule add fwmark 0x1/0x3 lookup t1
ip rule add fwmark 0x2/0x3 lookup t2
ip route add default via 192.168.1.1 table t1
ip route add default via 192.168.1.2 table t2

iptables -t mangle -F
iptables -t mangle -N in-marking
iptables -t mangle -A PREROUTING -m conntrack --ctstate NEW -j in-marking
iptables -t mangle -A in-marking -m mac --mac-source 90:E6:BA:77:4E:1C -j CONNMARK --set-xmark 0x1/0x3
iptables -t mangle -A in-marking -m mac --mac-source 90:F6:52:24:03:28 -j CONNMARK --set-xmark 0x2/0x3

iptables -t mangle -N out-marking
iptables -t mangle -A PREROUTING -m connmark ! --mark 0x0/0x3 -j out-marking
iptables -t mangle -A out-marking -i eth2 -j CONNMARK --restore-mark --mask 0x3

iptables -t nat -F
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j DNAT --to-destination 10.0.0.2
iptables -t nat -A POSTROUTING -o eth2 ! -d 10.0.0.0/24 -j SNAT --to-source 192.168.1.111
lemix
() автор топика
Ответ на: комментарий от ziemin

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

если ИП клиентов в логах не критичны - должно работать.

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