Страница 11 из 14

Re: Два провайдера: отказоустойчивость и распределение нагрузки

Добавлено: 28 окт 2016, 16:16
algerka
KARaS'b писал(а):а дальше "нетвоч" с пингом например до 8.8.8.8

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

Re: Два провайдера: отказоустойчивость и распределение нагрузки

Добавлено: 25 ноя 2016, 21:47
KARaS'b
Последнее время стали часто спрашивать про балансировку или переключение каналов, поэтому думаю стоит поделиться своим решением по переключению на резервный канал. Местных и залетных бывалых прошу меня не пинать, знаю что не очень элегантно, даже знаю некоторые конкретные места, но как говорится, чем богаты... А если вдруг кто-то укажет на то, что можно поправить и сделать все симпатичней и самое главное покажет как, то как минимум буду безгранично благодарен!

И так, что ниже? А ниже плод моего желания отказоустойчивого интернета.
Что у меня было? Один микротик, уже полностью настроенный и работающий и 2 конца витухи от разных провайдеров. Основной провайдер отдавался по PPPoE (будет упоминаться и именоваться как isp1), запасной по DHCP (будет упоминаться как isp2). isp1 воткнут в ether3 (но это вроде не пригодится), isp2 в ether2.
Опустим настройку самих интерфейсов для подключения в соответствии с выданными провайдером настройками, она есть в тонне других мануалов. Но отдельно отмечу, что при настройке клиентов избавляемся от опции "add default route", точнее выставляем ее в положение "no" на обоих интерфейсах, включение этой опции противопоказано, так как нам нужны созданные вручную маршруты, которые будут редактироваться скриптами, с автоматически созданными маршрутами это невозможно.

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

Код: Выделить всё

/ip route add comment=GW1 distance=1 gateway=isp1
/ip route add comment=GW2 disabled=yes distance=2 gateway=1.1.1.1

Т. к. PPPoE в моем случае основной канал, я даю ему минимально возможный distance, а маршруту резервного канала указываю больший, этим мы подстрахуемся если по каким-то причинам оба маршрута окажутся включенными при рабочем основном канале. Для упрощения и сокращения кол-ва скриптов, в маршруте с pppoe клиентом указываем само pppoe соединения, микротик это нормально проглатывает, по крайней мере на момент написания в актуальных прошивках так было. "gateway=" для dhcp клиента можно указывать вообще любой адрес, скоро его подставит скрипт, но лучше подсмотреть сразу что выдал провайдер и подставить правильным.

Т.к. второй провайдер отдается по dhcp, создадим скрипт по проверке и замене гетвея в маршруте резервного канала и назовем его check_isp2_gw.

Код: Выделить всё

:local isp2gw [ip dhcp-client get [/ip dhcp-client find interface=ether2] gateway];
:local isp2gwstat [ip route get  [/ip route find comment="GW2"] gateway];
#:log info ("$isp2gw")
#:log info ("$isp2gwstat")
:if ($isp2gw != $isp2gwstat) do={ip route set [/ip route find comment="GW2"] gateway=$isp2gw;  :log info ("Update ISP2 GW complete")}

Если на предыдущем шаге вы поленились указать актуальный гетвей, то можно уже запустить скрипт и он все поправит :-):

Теперь запихнем в шедулер выполнение этого срипта, частоту выполнения указываем по вкусу, я выставил 30 сек.

Код: Выделить всё

/system scheduler add interval=30s name=check_isp2_GW on-event="/system script run check_isp2_gw" policy= ftp,reboot,read,write,policy,test,password,sniff,sensitive start-date=jan/01/1970 start-time=00:00:00


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

И так, для верности хорошо бы пинговать хотя бы пару хостов и хотя бы по два каунта, 1 из 4х точно долетит, если все хорошо.
Так что создаем еще два скрипта. Первый (назовем его check_isp1_down) пингует два хоста...

Код: Выделить всё

:local PingCount 2;
:local One 8.8.8.8;
:local Too 8.8.4.4;
:local ResultOne [/ping count=$PingCount $One];
:local ResultToo [/ping count=$PingCount $Too];
:if ($ResultOne=0 && $ResultToo=0) do={/system script run isp1_down}

и если все плохо, он запускает другой скрипт (isp1_down)...

Код: Выделить всё

/system scheduler enable check_isp1_up
/system scheduler disable check_isp1_down
/ip route set [find comment="GW1"] disabled=yes
/ip route set [find comment="GW2"] disabled=no
/ip firewall connection remove [find]

Начнем с конца - видим строчку /ip firewall connection remove [find], эта прелесть шинкует все активные соединения, нужна она что бы облегчить нам жизни после переключения, что бы все не тупило, пока соединения не порвутся сами. А начинается все с непонятных строк, которых у нас еще нет (у вас нет, а у меня уже давно есть ::yaz-yk:). Это два шедулера - первый запускает уже имеющийся у нас скрипт check_isp1_down каждые 20 с., а второй будет запускать еще не существующих скрипт check_isp1_up. Создадим их и сразу все станет ясно :hi_hi_hi:
Первый шедулер (назовем его как и скрипт который он будет запускать check_isp1_down), который запускает наш скрипт check_isp1_down каждые 20 сек, время опять таки, по вкусу.

Код: Выделить всё

/system scheduler add interval=20s name=check_isp1_down on-event="/system script run check_isp1_down" policy=ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon start-date=jan/01/1970 start-time=00:00:00

Второй (назовем check_isp1_up)

Код: Выделить всё

/system scheduler add disabled=yes interval=20s name=check_isp1_up on-event="/system script run check_isp1_up" policy=ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon start-date=jan/01/1970 start-time=00:00:10

Обращаем внимание на то, что запуск второго шедулера смещен на 10 секунд, относительно первого, делал для того, что бы оба этих товарища не отработали одновременно, если вдруг они оба окажутся включенными. И самое главное, видим что этот шедулер во первых выключен, а во вторых запускает скрипт которого у нас нет, так что создадим его (назовем его check_isp1_up).

Код: Выделить всё

:local PingCount 2;
:local One 8.8.8.8;
:local Too 8.8.4.4;
:local ResultOne [/ping count=$PingCount $One];
:local ResultToo [/ping count=$PingCount $Too];
:if ($ResultOne>0 || $ResultToo>0) do={/system script run isp1_up}

Как видно, это чудо тоже пингует те же два хоста по два каунта, но в случае если ответил хотя бы один пинг, выполняет другое действие - запускает еще один скрипт, создадим и его (назовем isp1_up)

Код: Выделить всё

/system scheduler disable check_isp1_up
/system scheduler enable check_isp1_down
/ip route set [find comment="GW1"] disabled=no
/ip route set [find comment="GW2"] disabled=yes
/ip firewall connection remove [find]

И вот теперь, когда все перед глазами, расскажу как это работает - шедулер check_isp1_down каждые 20 сек запускает скрипт check_isp1_down, если все хорошо и хотя бы один пинг пролез, то не происходит ничего, если выпали все 4 пинга, то запускается скрипт isp1_down, который во первых выключает первый шедулер (check_isp1_down) и включает второй шедулер check_isp1_up, а во вторых выключает основной маршрут первого провайдера с каментом GW1 и включает второго GW2, плюс до кучи рвет все соединения.
Что происходит дальше, а дальше чудеса, второй шедулер (check_isp1_up) каждые 20 секунд пингует те же 2 хоста и хосты ему тут же отвечают! Да, да, через второго провайдера интернет-то появился и тут же происходит обратное переключение на неработающий линк, но нам же нужен интернет, а не бесконечные переключения туда сюда, поэтому ваяем костыль, да простят меня бывалые и завсегдатые! :hi_hi_hi:
Костыль будет в виде фаервольных запретов на пинги до этих хостов через второго провайдера

Код: Выделить всё

/ip firewall filter add action=drop chain=output dst-address=8.8.8.8 out-interface=ether2 protocol=icmp
/ip firewall filter add action=drop chain=output dst-address=8.8.4.4 out-interface=ether2 protocol=icmp

А до кучи полечим еще одну болячку и сделаем еще один костыль...

Код: Выделить всё

/ip route add distance=1 dst-address=8.8.4.4/32 gateway=isp1
/ip route add distance=1 dst-address=8.8.8.8/32 gateway=isp1

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

И так болячки полечили, костылей навтыкали, возвращаемся к тому, что произошло после выключения основного провайдера - включился второй шедулер check_isp1_up и каждые 20 секунд он запускает скрипт check_isp1_up, тот в свою очередь пингует хосты, пока лежит основной канал пинги не пройдут, их не пустит фаервол, но как только основной канал подымется, скрипт check_isp1_up запустит другой скрипт - isp1_up, который вернет все обратно - выключит маршрут резервного канал, включит основного, выключит второй шедулер check_isp1_up и включит первый check_isp1_down и опять разорвет нам все соединения, что бы мы не мучилась в ожиданиях. Ну и на этом все =)

Re: Два провайдера: отказоустойчивость и распределение нагрузки

Добавлено: 26 ноя 2016, 10:43
algerka
Слишком сложно: несколько скриптов, файервол и нетвоч, да и логирования бы добавить. Но для новичков будет полезно, чтобы понять что и как работает.
Проделана огромная работа. Свое конечно будет ближе и понятнее чем чужое. Но, на мой взгляд, проще взять скрипт с http://mikrotikwizard.com/ и доработать под себя, если не устраивает.

PS: по коду, желательно писать команды полностью, а то может не все поймут почему после команды

Код: Выделить всё

add action=drop chain=output dst-address=8.8.8.8 out-interface=ether2 protocol=icmp

не работает

Код: Выделить всё

add distance=1 dst-address=8.8.4.4/32 gateway=isp1


PSS: совсем не рационально иметь два полноценных канала и второй только как резервный использовать. лучше их объединить.

Re: Два провайдера: отказоустойчивость и распределение нагрузки

Добавлено: 26 ноя 2016, 12:39
KARaS'b
algerka писал(а):PS: по коду, желательно писать команды полностью, а то может не все поймут почему после команды

Спасибо, поправил, но скрипты не стал править, их предпочитаю добавлять через винбокс.
PSS: совсем не рационально иметь два полноценных канала и второй только как резервный использовать. лучше их объединить.

А тут не согласен, кто говорил что они равноценны? Данное решение представлено чисто как решение по переключению на резерв причем, в принципе универсальное, за счет того, что условия не "тепличные" - две статики, как это встречалось в большинстве манов которые я находил, тут и туннель в виде pppoe и dhcp от второго провайдера и оба варианта, на мой взгляд, максимально просто обыграны.
А касаемо логирования, это уже излишества, я же не за кого-то взялся работу делать, а предоставил возможный вариант, самодостаточный. А если уж добавлять излишества, то и отсылку нотификашек о переключении на почту можно запихнуть и, поскольку оба канала динамика, ddns прикрутить, но все это излишества нужные одним и не нужные другим, так что они сюда не попали.

Re: Два провайдера: отказоустойчивость и распределение нагрузки

Добавлено: 26 ноя 2016, 13:28
algerka
KARaS'b писал(а):кто говорил что они равноценны?

Раз первый pppoe, а второй нужен только резервным, то вообще можно обойтись без всяких скриптов:
Для pppoe делаем Default route distance 1, для dhcp 2.
И все!
Это самый простой вариант, конечно же будет работать только при условии; если есть pppoe подключение, значит канал рабочий.
На своем ростелекоме дома, за несколько лет ни раз не было такого, что есть pppoe соединение, а интернета нет.

Re: Два провайдера: отказоустойчивость и распределение нагрузки

Добавлено: 02 фев 2017, 09:40
Spiller
Пытаюсь настроить для каждого списка локальных адресов выход на "своего", определенного провайдера. Но что-то не получается. Прошу помочь.
Изображение

Re: Два провайдера: отказоустойчивость и распределение нагрузки

Добавлено: 02 фев 2017, 11:16
algerka
Spiller писал(а):Пытаюсь настроить для каждого списка локальных адресов выход на "своего", определенного провайдера. Но что-то не получается. Прошу помочь.

На сколько смог рассмотреть проблема в magle - не хватает правил. И, это не ошибка что группу адресов to_isp1 маркируете для isp2?
В маршрутизации я бы для маркированых сделал distance меньше, чем не для маркированных (к примеру на 2 вместо 0)

Вообще это издевательство, глаза "сломаешь" такое рассматривать

Re: Два провайдера: отказоустойчивость и распределение нагрузки

Добавлено: 02 фев 2017, 11:23
Spiller
algerka, не ошибка. Если вы заметили, интерфейс ether1, выключен, если его включить и в правила роутинг маск поставить ISP1 то все будет работать.
Но по схеме, если не работает ISP1 я должен в любой момент переключить адрес лист на ISP2, что я и сделал, но по моим настройкам не работает...

Re: Два провайдера: отказоустойчивость и распределение нагрузки

Добавлено: 02 фев 2017, 14:37
Vlad-2
Spiller писал(а):Пытаюсь настроить для каждого списка локальных адресов выход на "своего", определенного провайдера. Но что-то не получается. Прошу помочь.

Как то Вы всё просто хотите и по-быстрому. Вам правильно сказали, что мало правил.

Итак:
1) в Мангле создаём правила (INPUT)
а) mark connection (INPUT) in-interface - isp1, new connection mark: isp1_in
b) mark connection (INPUT) in-interface - isp2, new connection mark: isp2_in
Итак, Вы пометили всё входящие соединения каждого провайдера

2) в Мангле создаём правила
а.1) mark connection (FORWARD) in-interface - isp1, new connection mark: isp1_for
a.2) mark routing (PREROUTING), connection mark - isp1_for Src-Addr-List: LocalNet, new-routing mark: isp1_rout
b.1) mark connection (FORWARD) in-interface - isp2, new connection mark: isp2_for
b.2) mark routing (PREROUTING), connection mark - isp2_for Src-Addr-List: LocalNet, new-routing mark: isp2_rout

3) в Мангле создаём списки соответcтвий по провайдерам
a) mark routing (PREROUTING), connection mark - no-mark Src-Addr-List: to_ISP1, Dst-Addr-List: !LocalNet, new-routing mark: isp1_rout
b) mark routing (PREROUTING), connection mark - no-mark Src-Addr-List: to_ISP2, Dst-Addr-List: !LocalNet, new-routing mark: isp2_rout

4) в Мангле создаём правила (OUTPUT)
а) mark routing (OUTPUT) connection-mark - isp1_in, new connection mark: isp1_rout
b) mark routing (OUTPUT) connection-mark - isp2_in, new connection mark: isp2_rout

ТАКЖЕ
В таблице маршрутизации делаете каждый маршрут с меткой каждого провайдера
Потом делаете такие же правила но уже без Роутинг-Марк, но с другой дистанцией
Не забывает также описать NAT (для каждого провайдера)

И пробуйте. Правила не копировал, а показал смысл, забивать руками придёться.
Про Списки: LocalNet - в ней серые адреса моих сетей, в списки IPS1 и ISP2 помещаете нужный адрес компа в этот список и он жёстко будет работать через этого провайдера.

Re: Два провайдера: отказоустойчивость и распределение нагрузки

Добавлено: 02 фев 2017, 15:15
Spiller
Vlad-2, а в чем отличие списка !LocalNet от LocalNet ?
не понятно это в 3 правиле:
Src-Addr-List: to_ISP1, Dst-Addr-List: !LocalNet