Биллинговая система Nodeny

Главная категория => Курилка => Тема начата: Efendy от 25 Ноября 2011, 20:47:53



Название: 2 канала в инет. Показываю.
Отправлено: Efendy от 25 Ноября 2011, 20:47:53
Хочу рассказать как настроить 2 канала в инет в совместной работе.

Сначала отмазки:

Занимался этим вопросом всего 1 сегодняшний день, а не администрировал несколько лет (2 года так вообще не прикасался), поэтому могу многих новых штуковин не знать. Мне нужно время чтобы наверстать упущенное. Я планирую, что данную тему со временем дополню до полноценной.

Имеем 2 канала в инет:
1) tun0 с адресом 1.1.1.1 и гетвеем 1.1.1.2
2) tun1 с адресом 2.2.2.1 и гетвеем 2.2.2.2
гейтвей по умолчанию: 1.1.1.2
Клиенты на интерфейсах nfe0 и ng* 10.0.0.0/8

cat /etc/pf.conf
Код:
lan_net = "10.0.0.0/8"
int_if  = "nfe0"
ext_if1 = "tun0"
ext_if2 = "tun1"
ext_gw1 = "1.1.1.2"
ext_gw2 = "2.2.2.2"

set limit states 128000
set optimization aggressive

nat on $ext_if1 from $lan_net to any -> ($ext_if1)
nat on $ext_if2 from $lan_net to any -> ($ext_if2)

pass quick on lo0 all

pass in quick proto tcp from any to self port { 22 80 }  flags S/SA keep state

pass in quick on { $int_if ng } from $lan_net to self

pass in on { $int_if ng }  route-to { ($ext_if1 $ext_gw1), ($ext_if2 $ext_gw2) } round-robin proto tcp from $lan_net to any flags S/SA modulate state
pass in on { $int_if ng }  route-to { ($ext_if1 $ext_gw1), ($ext_if2 $ext_gw2) } round-robin proto { udp, icmp } from $lan_net to any keep state

pass out on $ext_if1 route-to ($ext_if2 $ext_gw2) from $ext_if2 to any
pass out on $ext_if2 route-to ($ext_if1 $ext_gw1) from $ext_if1 to any

Что мы сделали?

1) Подняли на каждом интерфейсе по нату
2) Приняли трафик идущий от клиентов к серверу (если это правило убрать, то трафик от клиентов к самому NoDeny пойдет на шлюз прова, я не пробовал, но по логике так):
pass in quick on { $int_if ng } from $lan_net to self
3) по очереди роутим пакеты то на gw1 то на gw2, причем такого, что одна и та же сессия разделится на пару каналов не произойдет т.к. keep state создает в таблице состояний правило, по которому весь последующий трафик пойдет мимо фаервола.
4) последние 2 правила нужны для того, чтобы при заходе на внешний интерфейс, ответы отправлялись на гетвей соответствующего прова (иначе повалят на гейтвей по умолчанию, т.е на 1.1.1.2)

Естественно эта схема не является равномерной балансировкой нагрузки т.к.она балансирует не трафик, а соединения. Но на 1й раз пойдет.

Еще нужно модифицировать ipfw т.к у нас теперь 2 внешних соединения:
Код:
200 skipto 500 ip from any to any { via tun0 or via tun1 }
400 skipto 450 ip from any to any { recv tun0 or recv tun1 }
2050  deny ip from any to any  { via tun0 or via tun1 }


Название: Re: 2 канала в инет. Показываю.
Отправлено: Efendy от 25 Ноября 2011, 23:01:50
Как показали первые полевые испытания: есть серьезные проблемы. route-to от pf форвардит пакет мимо ipfw, так что ни проверка на входе, ни подсчет исходящего трафика не работает.

Подсказывайте решение проблемы.


Название: Re: 2 канала в инет. Показываю.
Отправлено: smallcms от 25 Ноября 2011, 23:49:42
http://forum.nodeny.com.ua/index.php?topic=34.msg2103#msg2103
Делал давно. Даже без модных setfib-ов. Работало, но точно не скажу был ли подсчёт.
А сейчас уже и не воспроизведу (по причине отсутствия сети) ;D.

А так ваще да, правильное направление - вкомпилить штук 8 таблиц, завести интерфейсы в нужные, пнуть mpd-соединение к настоящему (не серому) провайдеру сторонним set iface up-script'ом в нужную таблицу.
Тема сложная, вариантов уйма, а ветераны форума 6-тью строчками обычно не делятся, поясняя, а барыжат ими. :)


Название: Re: 2 канала в инет. Показываю.
Отправлено: Efendy от 26 Ноября 2011, 12:09:34
Придумал интересный вариант. Пока тестирую на одном клиенте (счасливчик), вроде все работает отлично:

Код:
ext_if1 = "tun0"
ext_if2 = "tun1"
ext_gw1 = "1.1.1.2"
ext_gw2 = "2.2.2.2"

set limit states 128000
set optimization aggressive

#  клиента-жертву натим по round-robin
nat on $ext_if1 from 10.1.1.1 to any -> { ($ext_if1) ($ext_if2) } round-robin
nat on $ext_if1 from 10.0.0.0/8 to any -> ($ext_if1)

#  route packets from any IPs on $ext_if1 to $ext_gw1 and the same for $ext_if2 and $ext_gw2
pass out on $ext_if1 route-to ($ext_if2 $ext_gw2) from $ext_if2 to any
pass out on $ext_if2 route-to ($ext_if1 $ext_gw1) from $ext_if1 to any

суть в том, что мы меняем направление трафика не на внутреннем интерфейсе (тогда пакет летит мимо ipfw), а на внешнем, когда уже занатили по методу round-robin. После чего, если видим, что занатили на 2й внешний интерфейс - на его шлюз и кидаем пакет
P.S. При таком варианте сессия может быть раскидана на несколько каналов, так что сейчас я работаю над этим)


Название: Re: 2 канала в инет. Показываю.
Отправлено: smallcms от 27 Ноября 2011, 04:10:27
P.S. При таком варианте сессия может быть раскидана на несколько каналов, так что сейчас я работаю над этим)
pass in прибить к modulate/keep state? :)
Всё же вкондагде.ру ругался помню на авторизацию при таких делах.


Название: Re: 2 канала в инет. Показываю.
Отправлено: Efendy от 27 Ноября 2011, 07:54:49
P.S. При таком варианте сессия может быть раскидана на несколько каналов, так что сейчас я работаю над этим)
pass in прибить к modulate/keep state? :)
это не изменит ситуацию т.к. решение о том в какой ip натить принимается при выходе пакета с интерфейса. route-to при входе в фаер не годится - пакеты сходу отправляются на внешний интерфейс, минуя ipfw - скорее всего  фрибсдишники решили это хаком - сделали вид, что пакет не пришел, а выходит с интерфейса, т.е не стали парится как сообщить ядру о маршрутизации. В любом случае, балансировка на уровне сессий скорее всего чревата неработой многих сервисов, например банально человек зашел на какой-нить даунлоад сайт, сайт вывел страничку "закачка начнется через 60 секунд", а дальше идет запрос с другого ip - и все, отлуп.

Короче, надо балансировать не трафик и не сессии, а ip. Тогда фаер принимает простейший вид и все работает корректно. Другой вопрос, как равномерно сбалансировать ip, чтобы примерно равномерно и трафик делился - это либо статически (сделали выборку клиентов, самых качальщиков загнали в другой канал) либо написать какой-нить модуль-анализатор, чтобы по умному перекидывал клиентов между каналами. Последнее я мог бы сделать, но игра не стоит свеч, первый вариант итак будет более-менее сносно работать


Название: Re: 2 канала в инет. Показываю.
Отправлено: Gosha от 01 Декабря 2011, 13:34:43
Очень интересная статья по этой теме.
xander.org.ua/doc/samag/02.2007_09.html


Название: Re: 2 канала в инет. Показываю.
Отправлено: Efendy от 01 Декабря 2011, 16:43:04
Очень интересная статья по этой теме.
xander.org.ua/doc/samag/02.2007_09.html
здесь ничего нового не написано. Прописывание роутов напрямую через команду route либо эмуляция через fwd фаервола ipfw известны уже сто лет. Там даже тупой пример приводится: если пакет идет в  0.0.0.0/1, то его в один канал, а если в 128.0.0.0/1, то в другой. Т.е как бы инет поделили на 2 части и разрулили двумя каналами. Это абсолютно бессмысленно т.к. украинские/российские адреса попадут в "одну часть интернета". Это не балансировка.

Балансировка через pf приводится классическая, которая копипастится с документации по pf в миллионы сайтов. Это многие пробовали и я в том числе. Эта схема с NoDeny не работает: route-to кидает пакет мимо ipfw, а это недопустимо для NoDeny т.к. он считает трафик и управляет доступом/шейпами через ipfw.

Вариант с нетграфовской нодой не рассмотрен. Тут автор поступил как обычно построены 99% русских документаций - объясняются всем известные вещи, а когда дело доходит до сложных, сообщается "ну есть такая фича, но она редко используется" либо объясняется крайне примитивно, потому что сам автор ее не осилил.

Вариант, на котором я остановился - простой: маршрутизация по источнику, т.е. говорим так: этих клиентов пускаем через этот канал, этих - через другой. Балансировка так себе, но зато корректно работает. Вместо route-to при pass in используются nat, а route-to юзается при pass out т.к. пакет там оказывается уже будучи пройденным ipfw.


Название: Re: 2 канала в инет. Показываю.
Отправлено: kuhar от 04 Декабря 2011, 03:29:26
Придумал интересный вариант. Пока тестирую на одном клиенте (счасливчик), вроде все работает отлично:

Код:
ext_if1 = "tun0"
ext_if2 = "tun1"
ext_gw1 = "1.1.1.2"
ext_gw2 = "2.2.2.2"

set limit states 128000
set optimization aggressive

#  клиента-жертву натим по round-robin
nat on $ext_if1 from 10.1.1.1 to any -> { ($ext_if1) ($ext_if2) } round-robin
nat on $ext_if1 from 10.0.0.0/8 to any -> ($ext_if1)

#  route packets from any IPs on $ext_if1 to $ext_gw1 and the same for $ext_if2 and $ext_gw2
pass out on $ext_if1 route-to ($ext_if2 $ext_gw2) from $ext_if2 to any
pass out on $ext_if2 route-to ($ext_if1 $ext_gw1) from $ext_if1 to any

суть в том, что мы меняем направление трафика не на внутреннем интерфейсе (тогда пакет летит мимо ipfw), а на внешнем, когда уже занатили по методу round-robin. После чего, если видим, что занатили на 2й внешний интерфейс - на его шлюз и кидаем пакет
P.S. При таком варианте сессия может быть раскидана на несколько каналов, так что сейчас я работаю над этим)

Ребята, а подскажите как организовать по этому способу, если на сервак идет два входа одного и того же провайдер, у которого при каждом переподключении меняется на интерфейсах tun0 и tun1 gateway, после последних махинаций, которые я деала получилось только, что если  клиент берет инет от tun1 у него все гуд, а если от tun1 то нсы не резолвятся, а пинг по ip прходит...


Название: Re: 2 канала в инет. Показываю.
Отправлено: Efendy от 04 Декабря 2011, 21:17:00
если шлюз меняется, то красиво это не разрулишь - сам столкнулся с этой проблемой. Выхода 2:

1) в pppoe конфиге, по которому идет подключение к прову, явно указать NAS, тогда будет идти коннект всегда к одним и тем же серверам, т.е. шлюзы будут постоянными. Лишаемся возможности подключения к менее нагруженному NAS-у.
2) пишем скрипт, который после коннекта переделывает pf.conf  и перезапускает pf


Название: Re: 2 канала в инет. Показываю.
Отправлено: kuhar от 05 Декабря 2011, 12:56:53
если шлюз меняется, то красиво это не разрулишь - сам столкнулся с этой проблемой. Выхода 2:

1) в pppoe конфиге, по которому идет подключение к прову, явно указать NAS, тогда будет идти коннект всегда к одним и тем же серверам, т.е. шлюзы будут постоянными. Лишаемся возможности подключения к менее нагруженному NAS-у.
2) пишем скрипт, который после коннекта переделывает pf.conf  и перезапускает pf

А можете, пожалуйста, подсказать по первому варианту.
У меня настроено подключение к прову через ppp.conf, указаны параметры для соединения. Это можно реализовать в файле ppp.conf или только при помощи mpd?
Если можно подскажи, какой параметр для этого нужно использовать?


Название: Re: 2 канала в инет. Показываю.
Отправлено: Efendy от 05 Декабря 2011, 15:11:30
ppp.conf:

set device PPPoE:rl0:nas_name


Название: Re: 2 канала в инет. Показываю.
Отправлено: kuhar от 06 Декабря 2011, 10:22:32
ppp.conf:

set device PPPoE:rl0:nas_name

А не нужно в ppp.conf указывать что-то типо:
Код:
enable nas

Так как при указании
set device PPPoE:rl0:nas_name
не работает, присваивается другой гетвей.
Имя nas проверял nslookup-ом


Название: Re: 2 канала в инет. Показываю.
Отправлено: Rico-X от 20 Марта 2012, 08:59:29
Придумал интересный вариант. Пока тестирую на одном клиенте (счасливчик), вроде все работает отлично:

Код:
ext_if1 = "tun0"
ext_if2 = "tun1"
ext_gw1 = "1.1.1.2"
ext_gw2 = "2.2.2.2"

set limit states 128000
set optimization aggressive

#  клиента-жертву натим по round-robin
nat on $ext_if1 from 10.1.1.1 to any -> { ($ext_if1) ($ext_if2) } round-robin
nat on $ext_if1 from 10.0.0.0/8 to any -> ($ext_if1)

#  route packets from any IPs on $ext_if1 to $ext_gw1 and the same for $ext_if2 and $ext_gw2
pass out on $ext_if1 route-to ($ext_if2 $ext_gw2) from $ext_if2 to any
pass out on $ext_if2 route-to ($ext_if1 $ext_gw1) from $ext_if1 to any

суть в том, что мы меняем направление трафика не на внутреннем интерфейсе (тогда пакет летит мимо ipfw), а на внешнем, когда уже занатили по методу round-robin. После чего, если видим, что занатили на 2й внешний интерфейс - на его шлюз и кидаем пакет
P.S. При таком варианте сессия может быть раскидана на несколько каналов, так что сейчас я работаю над этим)
Как я понимаю при такой схеме, если один из аплинков упадет, то примерно половина запросов уйдут в никуда, то-есть сайты будут работать через раз? Можно ли как-то предусмотреть выход одного их аплинков из строя?
Да и по последним 2м правилам, н еперепутаны ли $ext_if в первом вхождении местами?
pass out on $ext_if1 route-to ($ext_if2 $ext_gw2) from $ext_if2 to any
pass out on $ext_if2 route-to ($ext_if1 $ext_gw1) from $ext_if1 to any


Название: Re: 2 канала в инет. Показываю.
Отправлено: Efendy от 20 Марта 2012, 13:37:40
pass out on $ext_if1 route-to ($ext_if2 $ext_gw2) from $ext_if2 to any
pass out on $ext_if2 route-to ($ext_if1 $ext_gw1) from $ext_if1 to any
Нет, не перепутаны, это обработка ситуации, когда пакет идет в инет с интерфейса №1, но у него src интерфейса №2 и наоборот.

Как я понимаю при такой схеме, если один из аплинков упадет, то примерно половина запросов уйдут в никуда, то-есть сайты будут работать через раз? Можно ли как-то предусмотреть выход одного их аплинков из строя?

Я вообще отказался от такой схемы т.к. у клиента могут некоторые сервисы не работать (там, где идет привязка по ip  и работа через несколько соединений). Поскольку у меня нет проблем с каналом, то я просто поделил сеть на 2 части и пускаю один через один канал, других через другой. Эффективность этого, конечно, ниже чем нормальная балансировка, но, поскольку, повторюсь, пока запас в каналах есть, работает сносно. Нормальная балансировка требует ухищрений, простой настройкой фаервола не добиться. Так что я забил. Люди юзают для балансировки еще одно звено - Микротик. Спрашивай их


Название: Re: 2 канала в инет. Показываю.
Отправлено: Rico-X от 22 Марта 2012, 15:48:04
Спасибо, понял, тоже поделил статически по каналам и забил, не в своей сети делал, у меня BGP и нах микротики, а вот в мелкой сети договориться с вышестоящими провайдерами о динамике почти не реально :(


Название: Re: 2 канала в инет. Показываю.
Отправлено: Rico-X от 28 Марта 2012, 18:12:15
Вот еще странность заметил, есть конфиг
Код:
set limit states 128000
set optimization aggressive
ext_if1="vlan666" #Vnutrenni
ext_if2="vlan64" #Vneshni
ext_gw1="xxx.xxx.xxx.xxx"
ext_gw2="yyy.yyy.yyy.yyy"
table <no_nat> const { 192.168.0.0/16}
scrub in all

nat on $ext_if1 from 192.168.4.0/24 to !<no_nat> -> $ext_if2
nat on $ext_if1 from 192.168.5.0/24 to !<no_nat> -> $ext_if2
nat on $ext_if1 from 192.168.7.0/24 to !<no_nat> -> $ext_if2
nat on $ext_if1 from 192.168.9.0/24 to !<no_nat> -> $ext_if2
nat on $ext_if1 from 192.168.0.0/16 to !<no_nat> -> $ext_if1

pass out on $ext_if1 route-to ($ext_if2 $ext_gw2) from $ext_if2 to !<no_nat>
pass out on $ext_if2 route-to ($ext_if1 $ext_gw1) from $ext_if1 to !<no_nat>
Пользователи вин7 при pppoe через  $ext_if1 - ходят нормально, а через  $ext_if2 нет интернета, при этом на линухах и вин XP все в норме, куда смотреть?


Название: Re: 2 канала в инет. Показываю.
Отправлено: Sis от 12 Июня 2012, 02:46:33
Вот здесь инструкция

wiki.mikrotik.com/wiki/PCC

если все по ней делать. То балансировка работает на ура.