LINUX.ORG.RU
ФорумAdmin

подскажите про 2 провайдера на одном шлюзе


1

2

Есть 1 комп, на нем centos, служит он шлюзом сети(натит исходящий и DNATит некоторые входящие порты на что-то внутри). Подключено 2 провайдера.

Подскажите простое как табуретка решение, чтобы

1. Все что приходило на eth0 только с него же и уходило в ответ

2. сеймшит и для второго eth1

3. Весь роутинг хочу строить на основании порта назначения или просто ipшника получателя по принципу - если явно не задано, что в eth1, то в маршрут по умолчанию.

С ip route я знаком, также как и fwmark. Алсо неплохо бы знать как это сделать на центосе «культурно» т.е. без костыльных скриптов, используя конфиги типа ifcfg-eth*, rule-eth*, sysconfig/iptables

Первое и второе решается через «ip rule from x.x.x.x ...» Третий пункт не понял, но раз знаете про «ip rule fwmark», наверное, осилите сделать что желаете.

В route-eth* пишите нужные маршруты с указанием таблицы, в rule-eth* нужные правила. Правите sysconfig/iptables или командами iptables добавляете нужные правила и делаете «service iptables save».

Это всё при условии, что адреса статические.

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

ты читаешь вообще что тебе пишут?

/usr/share/doc/initscripts-version*/sysconfig.txt

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

from x.x.x.x ...

Каждая строка из этого файла добавляется аргументами к команде «ip rule add» и в строке может быть что угодно.

mky ★★★★★ ()

Есть проблема - трафик со второго интерфейса идёт с айпишником от первого(он же дефлтный дял всего кроме), как это лечить?

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

Сложно ответить на твой вопрос, не видя твоих настроек iproute + iptables

Вот так будет работать:

#!/bin/bash

# iproute2 configuration
ip route flush table T1
ip route flush table T2

ip route add 172.16.0.0/24 dev eth0  src 172.16.0.2 table T1
ip route add 172.16.1.0/24 dev eth2  src 172.16.1.2 table T2

ip rule add fwmark 10 table T1 priority 100
ip rule add fwmark 20 table T2 priority 101

ip rule add from 172.16.0.2 table T1 priority 200
ip rule add from 172.16.1.2 table T2 priority 201

ip r add 192.168.2.0/24 dev eth1  proto kernel  scope link  src 192.168.2.1             table T1
ip r add 192.168.2.0/24 dev eth1  proto kernel  scope link  src 192.168.2.1             table T2

ip route add default via 172.16.0.1 table T1
ip route add default via 172.16.1.1 table T2

# Теперь файрвол
iptables -F
iptables -X

iptables -F -t nat
iptables -X -t nat

iptables -F -t mangle
iptables -X -t mangle

iptables -t mangle -A PREROUTING -m connmark --mark 0 -i eth0 -j CONNMARK --set-mark 10
iptables -t mangle -A PREROUTING -m connmark --mark 0 -i eth2 -j CONNMARK --set-mark 20

iptables -t mangle      -A PREROUTING -d $PROV1_LAN -j CONNMARK --set-mark 10
iptables -t mangle      -A PREROUTING -d $PROV2_LAN -j CONNMARK --set-mark 20

# NAT для всех. Редактировать отсюда и ниже!
iptables -t nat -A POSTROUTING -s 192.168.2.0/24 -o eth2 -j MASQUERADE
iptables -t nat -A POSTROUTING -s 192.168.2.0/24 -o eth0 -j MASQUERADE



# Восстанавливаем метки:
iptables -t mangle      -A FORWARD      -j CONNMARK --restore-mark
iptables -t mangle      -A PREROUTING   -j CONNMARK --restore-mark
exit 0

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

Это справедливо только для собственного(non-forwarded) трафика сервера. Здесь проблема идеалогического характера, а именно в том, что приложение не биндится к rt(routing table), т.е. когда приложение начинается слать что-либо на адрес x.x.x.x, то ip.src выбирается на основе grt(в линуксе она называется main) и лишь когда пакет уже «создан» он проходит через правила netfilter fwmark и ip rule from и выходят через интерфейс в соотвествии с rt, отличной от grt. Самое простое решение - прибиндить приложение к ip(типовые - ping, wget и т.п. поддерживают такую фичу), если приложение это умеет, то такой вариант наилучший. Второй вариант iptables SNAT(!-s XXX -j SNAT --to-source XXX) - требует conntrack(опасно для высоконагруженных систем). И 3ий вариант - найти/написать типа такого http://www.r1ch.net/stuff/forcebindip/

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

Идея такая - комп должен DNATтить на вход, пересылая траффик на нужный комп во внутренней сети. Комп должен SNATить любой траффик исходящий из локалки по любому интерфейсу, на который траффик перенаправлен. Я решил дял этого совместить 2 рецепта- через fwmark я буду решать какой ИСХОДЯЩИЙ траффик мне направить на второй канал, а при помощи Source routinga будут ответы на входящий трафик на том интерфейсе, на котором я поставлю DNAT . Все что не оговорено через Fwmark Должно идти в шлюз по умолчанию.

Локалка - 192.168.0
Провайдер 1 он же дефолтный 194.186.163.233
Провайдер 2, на него пернаправлять FwmarkНутое 31.28.6.1

Вот конфиг Iproute

ip rule add fwmark 1 table 201
ip route add default via 31.28.6.1 dev eth1 src 31.28.6.190 table 201
ip route add default via 194.186.163.233 dev eth0 src 194.186.163.234 table 202
ip route add 194.186.163.232/30 dev eth0 src 194.186.163.234
ip route add 31.28.6.0/24 dev eth1 src 31.28.6.190
ip route add default via 194.186.163.233
ip rule add from 31.28.6.190 table 201
ip rule add from 194.186.163.234 table 202

В Iptables интересует, как правильно fwmarкать чтоб работало, хочу чего то такого

*mangle

-A PREROUTING -d <Нужный ип в интернете> -j CONNMARK Или MARK --set-mark 1

И чтобы все шло по второму провайдеру. Или через --dport Тоже нужно бывает.

При этом сейчас юзается нат локалки таким образом

-A POSTROUTING -s 192.168.1.0/24 -j MASQUERADE

То есть я хочу чтобы ЛЮБОЙ исходящий траффик натился тем внешним айпишником, который годится для этого маршрута.

Мне уже удалось сделать ответ с того интерфейса, к которому обращаешься, но еще непонятно, как правильно перенаправлять траффик исходящий, что я сделал не так?

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

тебе же fernir типовое решение привёл ужо. смысл в том, чтобы было 2 таблицы - по одной для разных внешних IP с шлюзом по уомлчанию. у тебя же я вижу только 1 ip route add default via со всеми вытекающими.

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

Почему один, вот же.

p route add default via 31.28.6.1 dev eth1 src 31.28.6.190 table 201 ip route add default via 194.186.163.233 dev eth0 src 194.186.163.234 table 202

А тот который на таблицу Main Он как бы по умолчанию, то есть все что не указано туда. В его решении мне не хватает Fwmark, чтобы не проосто Ответ на тот с которого пришло, но и самому выбирать что куда.

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

Во первых, добавь в таблицы маршруты для локалки. Ни в 201 ни в 202 таблице у тебя НЕТ маршрута для локалки. Куда отправить ответ из интернета?

Дальше, где для 202 таблицы fwmark 2 ???

В моем примере: Для проходящего траффика:

iptables -t mangle -A PREROUTING -m connmark --mark 0 -d 8.8.8.8 -j CONNMARK --set-mark 10 Проверить на пустоту метки (mark 0), и отправить по 1 провайдеру. Иначе будут проблемы с ответами.

Для трафика от локальных приложений нужно трогать mangle-OUTPUT.

fernir ()

Вклинюсь-ка и я

А вот такой вопрос: можно ли, имея двух провайдеров со скоростями A и B, увеличить общую скорость до A+B за счет того, что часть пакетов будет забираться по линии первого провайдера, а часть - по линии второго, прозрачно для конечного пользователя?

Т.е. если у меня есть местный интернет (~50кБ/с) и я подключу ростелеком (128кБ/с), смогу ли я получить скорость 178кБ/с при yaourt -Syua?

Eddy_Em ☆☆☆☆☆ ()
Ответ на: комментарий от fernir

Дальше, где для 202 таблицы fwmark 2 ???

Таблица 202 это для дефолтного соединения, я не хочу маркировать на него, я хочу наоборот - все что НЕ промаркировано - на него.

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

Сделал так. нормально?

ip route flush table 201
ip route flush table 202
ip rule add fwmark 1 table 201
ip route add default via 31.28.6.1 dev eth1 src 31.28.6.190 table 201
ip route add default via 194.186.163.233 dev eth0 src 194.186.163.234 table 202
ip route add 194.186.163.232/30 dev eth0 src 194.186.163.234
ip route add 31.28.6.0/24 dev eth1 src 31.28.6.190
ip route add 192.168.1.0/21 dev eth2 src 192.168.1.2 table 201
ip route add 192.168.1.0/21 dev eth2 src 192.168.1.2 table 202
ip route add default via 194.186.163.233
ip rule add from 31.28.6.190 table 201
ip rule add from 194.186.163.234 table 202

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

Ну, в конце скрипта еще «ip route flush cache», а так вроде да. Цель достигнута? Трафик со второго интерфейса перестал с другим IP выходить? Если нет, то выкладывай правила iptables. А вообще я бы метил метками оба потока - отслеживать удобно.

To Eddy_Em: Можно, для многопоточных закачек и торрентов. В один поток работать не будет. Вариант раз: http://www.opennet.ru/tips/info/2236.shtml Вариант два: гуглить по «route default nexthop weight»

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

iptables такой

*mangle
#-A INPUT -i eth1 -j CONNMARK --set-mark 1
#-A FORWARD -j CONNMARK --restore-mark
#-A PREROUTING -j CONNMARK --restore-mark
COMMIT

*nat
-A POSTROUTING -s 192.168.1.0/24 -o eth0 -j SNAT --to 194.186.163.234
-A POSTROUTING -s 192.168.1.0/24 -o eth1 -m connmark --mark 1 -j SNAT --to 31.28.6.190
-A POSTROUTING -s 192.168.1.0/24 -o eth1 -p udp -m mark --mark 1 -j SNAT --to 31.28.6.190
COMMIT

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

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

*mangle
-A PREROUTING -d 8.8.8.8 -j MARK --set-mark 1

*nat
-A POSTROUTING -s 192.168.1.0/24 -o eth0 -j SNAT --to 194.186.163.234
-A POSTROUTING -s 192.168.1.0/24 -o eth1 -m connmark --mark 1 -j SNAT --to 31.28.6.190
-A POSTROUTING -s 192.168.1.0/24 -o eth1 -m mark --mark 1 -j SNAT --to 31.28.6.190

например

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

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

У тебя путаница с метками и правилами. Я у себя ее избежал простым способом - ставил метки на все исходящие каналы, а метку «0» использовал как маркер что пакет не обработан и для него нет правил.

У тебя 2 провайдера (A,B) и 2 внешних IP (a,b). У провайдеров есть свои локальные сети, к которым желательно иметь доступ через родной канал (у меня например МТС-ный веб кабинет не дает менять параметры, если внешний IP не из его подсетей). Дефолтный провайдер - А, Провайдеру B ты ставишь метку «1».

Допустим из сети провайдера B приходит запрос на внешний IP «а» (т.е. на адрес другого провайдера). Пакет не получит метки, сходит по DNAT до твоего серера в DMZ, а при попытке ответа (отвечаем то мы в сеть B!) ему дадут метку «1» и отправят через IP-b.

Вот ты в Mangle строго прописал что доступ к DNS-гугла через канал b (mark 1). Вот та ситуация что я описал у тебя будет если к тебе на внешний адрес а постучится гугл с 8.8.8.8.

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

Если использовать метки для каждого канала:

Пусть у тебя есть сервис (80 - http), на компьютере в локалке (192.168.1.20), и ты хочешь открыть его наружу, по обеим IP. В тоже время, хочется ходить на локальные ресурсы разных провайдеров, а траффик к гуглу (8.8.8.8) пускать через канал B.

iptables -t nat -A PREROUTING  -p tcp -d $IPa --dport 80 -j DNAT --to-destination 192.168.1.20:80
iptables -t nat -A PREROUTING  -p tcp -d $IPb --dport 80 -j DNAT --to-destination 192.168.1.20:80

# В мангл прероутинге, если коннмарк не восстановил нам из отслеживания соединений (connmark) метки пакетов, пометить их. Так мы пометим все входящие соединения меткой канала через который они вошли.
iptables -t mangle	-A PREROUTING -m connmark --mark 0 -i eth1 -j CONNMARK --set-mark 10
iptables -t mangle	-A PREROUTING -m connmark --mark 0 -i eth2 -j CONNMARK --set-mark 20 

# Расписываем все маршруты, куда к кому. Здесь важно, что мы проверяем на пустоту метки. Если метки нет, то для пакета будет изменено правило, куда ему идти. Если какая то метка уже есть - правила не сработают.
iptables -t mangle      -A PREROUTING  -m connmark --mark 0 -d 8.8.8.8 -j CONNMARK --set-mark 20
iptables -t mangle      -A PREROUTING  -m connmark --mark 0 -d $PROV1_LAN -j CONNMARK --set-mark 10
iptables -t mangle      -A PREROUTING  -m connmark --mark 0 -d $PROV2_LAN -j CONNMARK --set-mark 20
# И на последок, говорим, что по личным нуждам 192.168.1.20 должен ходить через второго провайдера, а вся остальная локалкма через первого.
iptables -t mangle      -A PREROUTING  -m connmark --mark 0 -s 192.168.1.20  -j CONNMARK --set-mark 20
iptables -t mangle      -A PREROUTING  -m connmark --mark 0 -s 192.168.1.0/24  -j CONNMARK --set-mark 10

# Говорим файрволу сохранять метки пакетов на основе коннмарков. Т.е. отслеживать соединения, и входящим пакетам уже установленных соединений восстанавливать метки. Это правило нужно располагать в самом конце! 
iptables -t mangle	-A FORWARD	-j CONNMARK --restore-mark
iptables -t mangle	-A PREROUTING	-j CONNMARK --restore-mark

Пробегаясь сверху вниз по файрволу: Если у входящего пакета нет метки, то он новый, и мы помечаем его меткой канала. Дальше, если пакет летит на 8.8.8.8, и у него нет метки (т.е. это исходящий пакет), пометить его 20-кой. Тоже самое с локалками првайдеров (у меня на одном провайдере яндекс считается локалкой, очень удобно тянуть с mirrors.yandex.ru что нибудь тяжелое по 100 Мбит). И т.д. Для чего я это все расписывал: я везде проверяю на пустоту метки, пустая метка для меня признак необработанного пакета, к которому нужно применить кучу правил. Если я до сих пор тебя не убедил что это удобно, то я умываю руки :-)

Думаю можно описать грамотную последовательность правил файрвола, чтобы получить нужный тебе результат, без меток на дефолтном канале, но это нужно все выписывать и перепроверять tcpdump'ом. Кстати, в моем примере если у исходящего пакета не будет метки, он не попадет в выборочные таблицы (T1, T2...) и пройдет маршрутизацию согласно общей таблице маршрутов (которая просто ip r sh), и успешно выйдет через общий default route.

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

Локалок у провайдеров нет (точнее они мне не нужны и -d пров_лан использоваться не будет никогда в таком случае)Однако такое впечатление, что connmark не работает почему то, в отличии от просто mark. Само же использование или неиспользование меток не столь важно, Сервер про который речь .20 не столь однозначен, один порт с него я хочу вывести на новый канал, а весь другой траффик вообще оставить на старом. например если на нем 80ый порт, то такой командой

iptables -t mangle -A PREROUTING -m connmark --mark 0 -s 192.168.1.0/24 -j CONNMARK --set-mark 10

Я выведу весь траффик с него, что не нужно (на нем еще и почта ворочается а mx прописан на другой канал), но нужно сделать так, чтоб все что к нему пришло по каналу b на порт 80, отдавалось по каналу b обратно, не трогая все остальное.

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

Пакеты на 80й, вошедшие через IP провайдера b, и которым [CONNMARK --restore-mark] не восстановил метку, мы должны присвоить метку 20 (по моим примерам). Тогда правило [PREROUTING -m connmark --mark 0 -s 192.168.1.0/24 -j CONNMARK --set-mark 10] на него не подействует, т.к. метка у него уже будет. И ответ пойдет туда, откуда пришел запрос.

Выложи полный iptables -L -v -n -x -t mangle. Connmark у меня не работал, когда я [-restore-mark] ставил не последним правилом.

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

connmark вообще не работает, где бы ни стоял похоже.

Chain PREROUTING (policy ACCEPT 515 packets, 56348 bytes)
pkts bytes target prot opt in out source destination
0 0 CONNMARK all  — * * 0.0.0.0/0 80.247.181.146 connmark match 0x0 CONNMARK set 0x1
0 0 CONNMARK all  — eth1 * 0.0.0.0/0 0.0.0.0/0 connmark match 0x0 CONNMARK set 0x1
155 8195 CONNMARK all  — eth0 * 0.0.0.0/0 0.0.0.0/0 connmark match 0x0 CONNMARK set 0x2
0 0 CONNMARK all  — * * 192.168.1.8 !192.168.0.0/21 connmark match 0x0 CONNMARK set 0x1
514 56300 CONNMARK all  — * * 0.0.0.0/0 0.0.0.0/0 CONNMARK restore

Chain INPUT (policy ACCEPT 217 packets, 36693 bytes)
pkts bytes target prot opt in out source destination

Chain FORWARD (policy ACCEPT 288 packets, 18875 bytes)
pkts bytes target prot opt in out source destination
288 18875 CONNMARK all  — * * 0.0.0.0/0 0.0.0.0/0 CONNMARK restore

Chain OUTPUT (policy ACCEPT 224 packets, 40919 bytes)
pkts bytes target prot opt in out source destination

Chain POSTROUTING (policy ACCEPT 510 packets, 59682 bytes)
pkts bytes target prot opt in out source destination

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

В форварде у тебя restore есть, а в построутинге нету.

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