Рекурсивная маршрутизация

Данная реализация поведения маршрутизации появилась из-за того, что в протоколе BGP при распространении маршрутов полученных через eBGP в iBGP next-hop по умолчанию, не меняется. Но не будем о BGP, а будем о простом.

Давайте начнём с простого, ниже я привёл таблицу маршрутизации простого маршрутизатора без каких либо излишек.

[admin@MikroTik.Me] > /ip route print                      
Flags: X - disabled, A - active, D - dynamic, 
C - connect, S - static, r - rip, b - bgp, o - ospf, m - mme, 
B - blackhole, U - unreachable, P - prohibit 
 #      DST-ADDRESS        PREF-SRC        GATEWAY            DISTANCE
 0 A S  0.0.0.0/0                          10.11.100.254             1
 1 ADC  10.11.0.0/17       10.11.101.55    ether1                    0
 2 ADC  192.168.1.0/24     192.168.1.1     Brdige-local              0
 3 ADC  192.168.2.0/24     192.168.2.1     Brdige-wifi-local         0
 4 ADC  192.168.3.0/24     192.168.3.1     Brdige-wifi-guest         0

Смотря на таблицу маршрутизации выше, ответьте на вопрос. Какой шлюз будет выбран для отправки пакета на адрес 8.8.8.8?

Я более чем уверен, что вы абсолютно правильно определили шлюз как 10.11.100.254 в маршруте 0.0.0.0/0 по номером ноль.

А теперь попробуйте ответить на следующий вопрос. Какой интерфейс будет выбран для отправки пакета на адрес 8.8.8.8? Почувствуйте разницу, в первом вопросе я спрашивал про шлюз, а в данном вопросе про интерфейс.

И вы скорее всего все ответите, что ether1 и будете правы, но вопрос почему именно так.

Задача маршрутизатора, определить не шлюз, а интерфейс выхода, так как маршрутизатору надо будет понять как передать до шлюза пакет, если тип ethernet, то необходимо будет выяснить с помощью arp mac адрес шлюза, если это какой-то тип инкапсуляции, то пакет надо обернуть в данный тип инкапсуляции и отправить, на адрес пира.

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

И так представьте у себя в голове таблицу маршрутизации в 700000 маршрутов. Представили?!

Я намеренно проигнорирую такие вещи как Кеш таблицы маршрутизации. (Представим, что его нет.)

Перед маршрутизатором стоит задача, отправить пакет на адрес 8.8.8.8

  1. Маршрутизатор ищет среди 700000 маршрутов лучший маршрут до адреса 8.8.8.8
  2. Он находит некий маршрут допустим 8.8.8.0/24 где адрес шлюза указан адрес 5.5.5.1
  3. Так как адрес шлюза, это IP адрес, а не интерфейс, поиск не останавливается.
  4. Маршрутизатор должен найти лучший маршрут до адреса 5.5.5.1
  5. Маршрутизатор ищет среди всех 700000 маршрутов лучший маршрут до адрес 5.5.5.1
  6. Он находит некий маршрут 5.5.5.0/30 где адрес шлюза указан ether1
  7. Так как адрес шлюза, это интерфейс, поиск останавливается.

В данном процесс поиска, есть одно тонкое место, при повторном поиске маршрута, уже до адреса шлюза 5.5.5.1 маршрутизатор проходит опять всю таблицу маршрутизации. Вам не кажется, что это немного излишне? Строго говоря адрес шлюза должен быть в непосредственно присоединенной сети к маршрутизатору! Так может следующий поиск осуществлять только среди connected маршрутов? да это было бы идеально. Но так как я уже написал выше, в протоколе BGP при передачи маршрута из eBGP в iBGP адрес шлюза не меняется, то шлюз уже не может быть connected. И что же делать?

Scope

В linux, а так как RouterOS основан на Linux, то также и в RouterOS введено такое понятие как scope маршрута и target-scope

Scope - текущая область маршрута.

Target-scope - область поиска

RouterOS recursive routing vasilevkirill

У любого маршрута есть, свой scope и target-scope.

Теперь давайте смотря на таблицу маршрутизации выше, попробуем ответить на вопрос. Какой интерфейс будет выбран для отправки пакета на адрес 8.8.8.8?

  1. Маршрутизатор производить поиск по всей таблицу маршрутизации лучшего маршрута для адреса 8.8.8.8
  2. Находит самый первый маршрут и узнаёт адрес шлюза 10.11.100.254
  3. Так как адрес шлюза, это не интерфейс, маршрутизатор берёт значение target-scope из маршрута в котором был найден шлюз. target-scope=10
  4. Производит поиск маршрута для адреса 10.11.100.254, но только среди маршрутов у которых scope равен или меньше значению 10 (target-scope)
  5. Находит, маршрут 10.11.0.0/17, адрес шлюза указан как ether1, поиск прекратился. Интерфейс найден.

Значения Scope

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

  • Connected - scope всегда 10. Target-scope не имеет значение, так как он connected.
  • OSPF и RIP, MME - scope = 20, а target-scope = 10.
  • Статический маршрут - scope = 30, а target-scope = 10.
  • eBGP - scope = 40, а target-scope = 10.
  • iBGP - scope = 40, а target-scope = 30.

Все типы маршрутов, кроме на iBGP, основаны на состоянии интерфейса, ну возможно eBGP немного сбоку стоит, так как по умолчанию он требует прямой связности с пиром, хотя это обходится с помощью multihop. А iBGP у него target-scope = 30, так как адрес шлюза не меняется, и нужен ещё один какой-то протокол, который бы сообщил как достичь сети nexthop-a. Например статический маршрут или зачастую ospf.

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

И так давайте переделаем дефолтный маршрут, и адрес шлюза укажем не наш шлюза, а например 8.8.8.8

[admin@MikroTik.Me] > /ip route print detail 
Flags: X - disabled, A - active, D - dynamic, 
C - connect, S - static, r - rip, b - bgp, o - ospf, m - mme, 
B - blackhole, U - unreachable, P - prohibit 
 0   S  dst-address=0.0.0.0/0 gateway=8.8.8.8 gateway-status=8.8.8.8 unreachable distance=1 
        scope=30 target-scope=10 

 1 ADC  dst-address=10.11.0.0/17 pref-src=10.11.101.55 gateway=ether1 
        gateway-status=ether1 reachable distance=0 scope=10 

 2 ADC  dst-address=192.168.1.0/24 pref-src=192.168.1.1 gateway=Brdige-local 
        gateway-status=Brdige-local reachable distance=0 scope=10 

 3 ADC  dst-address=192.168.2.0/24 pref-src=192.168.2.1 gateway=Brdige-wifi-local 
        gateway-status=Brdige-wifi-local reachable distance=0 scope=10 

 4 ADC  dst-address=192.168.3.0/24 pref-src=192.168.3.1 gateway=Brdige-wifi-guest 
        gateway-status=Brdige-wifi-guest reachable distance=0 scope=10 

Мы видим, что маршрут под номером ноль, не активен gateway-status=8.8.8.8 unreachable, естественно, так как маршрутизатором не смогу найти маршрут до адреса 8.8.8.8

Создадим маршрут до 8.8.8.8 через шлюз нашего провайдера.

[admin@MikroTik.Me] > /ip route print detail                                 
Flags: X - disabled, A - active, D - dynamic, 
C - connect, S - static, r - rip, b - bgp, o - ospf, m - mme, 
B - blackhole, U - unreachable, P - prohibit 
 0   S  dst-address=0.0.0.0/0 gateway=8.8.8.8 gateway-status=8.8.8.8 unreachable distance=1 
        scope=30 target-scope=10 

 1 A S  dst-address=8.8.8.8/32 gateway=10.11.100.254 
        gateway-status=10.11.100.254 reachable via  ether1 distance=1 scope=30 target-scope=10 

 2 ADC  dst-address=10.11.0.0/17 pref-src=10.11.101.55 gateway=ether1 
        gateway-status=ether1 reachable distance=0 scope=10 

 3 ADC  dst-address=192.168.1.0/24 pref-src=192.168.1.1 gateway=Brdige-local 
        gateway-status=Brdige-local reachable distance=0 scope=10 

 4 ADC  dst-address=192.168.2.0/24 pref-src=192.168.2.1 gateway=Brdige-wifi-local 
        gateway-status=Brdige-wifi-local reachable distance=0 scope=10 

 5 ADC  dst-address=192.168.3.0/24 pref-src=192.168.3.1 gateway=Brdige-wifi-guest 
        gateway-status=Brdige-wifi-guest reachable distance=0 scope=10 

Создали, маршрут но маршрут по умолчанию, до сих пор не активен. Так как маршрутизатор всё также не смогу найти, маршрут до 8.8.8.8, так как target-scope дефолтного маршрута равен 10, и именно среди таких scope будет производится поиск до адреса 8.8.8.8. Нам необхоидимо установить scope маршрута 8.8.8.8, так чтобы он попадал под поиск, а это значит установить scope либо 10 или меньше. Сделаем.

[admin@MikroTik.Me] > /ip route set scope=10 numbers=1

И наблюдаем, то что поднялся рекурсивный маршрут. gateway-status=8.8.8.8 recursive via 10.11.100.254

[admin@MikroTik.Me] > /ip route print detail          
Flags: X - disabled, A - active, D - dynamic, 
C - connect, S - static, r - rip, b - bgp, o - ospf, m - mme, 
B - blackhole, U - unreachable, P - prohibit 
 0 A S  dst-address=0.0.0.0/0 gateway=8.8.8.8 
        gateway-status=8.8.8.8 recursive via 10.11.100.254 ether1 distance=1 scope=30 
        target-scope=10 

 1 A S  dst-address=8.8.8.8/32 gateway=10.11.100.254 
        gateway-status=10.11.100.254 reachable via  ether1 distance=1 scope=10 target-scope=10 

 2 ADC  dst-address=10.11.0.0/17 pref-src=10.11.101.55 gateway=ether1 
        gateway-status=ether1 reachable distance=0 scope=10 

 3 ADC  dst-address=192.168.1.0/24 pref-src=192.168.1.1 gateway=Brdige-local 
        gateway-status=Brdige-local reachable distance=0 scope=10 

 4 ADC  dst-address=192.168.2.0/24 pref-src=192.168.2.1 gateway=Brdige-wifi-local 
        gateway-status=Brdige-wifi-local reachable distance=0 scope=10 

 5 ADC  dst-address=192.168.3.0/24 pref-src=192.168.3.1 gateway=Brdige-wifi-guest 
        gateway-status=Brdige-wifi-guest reachable distance=0 scope=10 

Теперь давайте ещё раз ответим на вопрос, только изменим адрес назначения. Какой интерфейс будет выбран для отправки пакета на адрес 4.4.4.4?

  1. Маршрутизатор ищет в таблице лучший маршрут до 4.4.4.4.
  2. Маршрутизатор находит маршрут номер ноль. dst-address=0.0.0.0/0 target-scope у которого значение равно 10.
  3. Так как шлюз не интерфейс, маршрутизатор ищет маршрут, для шлюза 8.8.8.8 среди маршрутов у который scope равен или меньше target-scope из предыдущей итерации.
  4. Маршрутизатор находит маршрут под номером один dst-address=8.8.8.8/32 target-scope у которого значение равно 10.
  5. Так как шлюз не интерфейс, маршрутизатор ищет маршрут, для шлюза 10.11.100.254 среди маршрутов у который scope равен или меньше target-scope из предыдущей итерации.
  6. Маршрутизатор находит маршрут под номером два dst-address=10.11.0.0/17
  7. Так как шлюза интерфейс, поиск останавливается.

А теперь мы можем сделать следующее, мы можем указать, использовать check-gateway и тем самым проверять доступность 8.8.8,8, и если будут недоступны, маршрут умрёт, и станет активным какой-нибудь другой маршрут с худшей дистанцией, например через LTE интерфейс.

Вы можете сделать рекурсивно, друг за другом, но это не имеет значение не в каких целях.

Одними 8.8.8.8 сыт не будешь

Да конечно, если упадёт 8.8.8.8, то мало не поздоровиться, будете переделывать. Можно поступить следующим образом.

Например взять три хоста высокой доступности 1.1.1.1, 8.8.8.8 и 77.88.8.8, можете любые свои, главное чтобы они действительно максимально всегда были доступны.

Создать три маршрута, через нашего провайдера. Таким образом

/ip route
add distance=1 dst-address=1.1.1.1/32 gateway=10.11.100.254 scope=10
add distance=1 dst-address=8.8.8.8/32 gateway=10.11.100.254 scope=10
add distance=1 dst-address=77.88.8.8/32 gateway=10.11.100.254 scope=10

Далее создать три дефолтных рекурсивных маршрута, разной дистанцией.

/ip route
add check-gateway=ping distance=10 gateway=77.88.8.8
add check-gateway=ping distance=20 gateway=8.8.8.8
add check-gateway=ping distance=30 gateway=1.1.1.1

В итоге, у вас будет такая картина в Winbox.

RouterOS recursive routing vasilevkirill

Если от 77.88.8.8 перестанет приходить ответы icmp, но при этом 8.8.8.8 будет приходить, то маршрут через шлюз 77.88.8.8 выпадет из процесса маршрутизации и его место займет следующий дефолтный маршрут по дистанции.

PPP

Часто слышу вопрос, а как сделать так, чтобы можно сделать через PPPoE рекурсивный маршрут? Тут всё дело в понимании, как таковой адрес шлюза не используется, кроме как в ethernet сетях, так как в ethernet нам нужен его mac адрес, в любых типах инкапсуляции в том числе и PPPoE адрес шлюза не используется, в виду того, что маршрутизатору просто надо запихнуть пакет в другой протокол и отправить на другую сторону.

Естественно мы можем этим воспользоваться.

Создайте отдельный PPP Profile и укажите абсолютно любой IP адрес в поле remote-address, главное чтобы этот адрес не пересекался с вашими внутренними сетями. Далее укажите этот профиль в настройках вашего PPPoE клиента, и вы можете использовать указанный адрес в поле remote-address, как адрес шлюза, для настройки рекурсивной маршрутизации.

Рассказать друзьям

Чатик телеграм

@mikrotikme