Про виртуальные сети (часть 18). DMVPN на виртуальных маршрутизаторах

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

Предположим, что есть некое предприятие с центральным офисом и тремя филиалами, которые нужно объединить в одну сеть. Предприятие не очень богатое (а может просто имеет широкую географию), поэтому для связи между офисами использует арендованные каналы. Это может быть сеть одного конкретного провайдера или Интернет, не важно. Важно, что предприятию выделили IP-адреса, маршрутизируемые в этой  сети, и можно с их использованием объединять сети.

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

Dynamic Multipoint Virtual Private Network – динамическая многоточечная виртуальная частная сеть, технология объединения частных сетей через публичные сети. Для объединения частных сетей, как правило, используется построение туннелей через общественные сети. В обычном варианте необходимо настраивать туннель для каждого соединения, т.е. если вы хотите получить полносвязную сеть из N узлов нужно настроить N(N-1)/2 туннелей. В определенный момент таких связей становится слишком много и приходится использовать топологию типа «звезда». В этом случае весь трафик проходит через центральный узел, что не добавляет ему производительности. Я уже не говорю о том, что в случае его отказа вся сеть рассыпается.

Вот в такой ситуации и приходит на помощь DMVPN. Суть технологии заключается в том, что на каждом узле сети настраивается только один туннельный интерфейс, который и организует затем необходимое количество туннелей автоматически, преобразуя топологию сети из «звезды» в полносвязную. Несмотря на то, что в данной технологии все-таки предусмотрено выделение центрального узла, конечные узлы также организуют между собой туннели. В конечном счете, после схождения такой сети, даже построенной по технологии «звезда», центральный узел уже не несет такой важной роли, и в случае его отказа конечные узлы могут продолжать между собой взаимодействовать по уже установленным туннелям (если, конечно же, сеть провайдера позволяет).

Из каких же составных частей состоит технология DMVPN? Ведь когда вы начинаете конфигурировать, вы не найдете в командах конфигурационного режима ключевого слова dmvpn, в команде show его тоже нет. Построение динамической многоточечной виртуальной сети происходит с использование нескольких функций IOS:

- основа всего Multipoint Generic Routed Encapsulation (mGRE) многоточечный GRE, один из самых простых протоколов туннелирования. И насколько он простой, настолько же и полезный;

- информацию о том, между какими узлами устанавливать туннели дает протокол Next Hop Resolution Protocol (NHRP), протокол похожий на ARP (ARP-like protocol), только вместо соответствия IP и MAC устанавливает соответствие между  IP физического интерфейса и IP туннельного интерфейса;

- протокола динамической маршрутизации OSPF или EIGRP (никто ведь не ждет от админа, что он будет руками прописывать все маршруты);

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

Ну и для полного винегрета, я сконфигурирую все это на виртуальных маршрутизаторах (Virtual Routing & Forwarding Instances).

Итак, вернемся к нашему предприятию. На рисунках ниже представлены физическая и логическая топологии сети.

 

DMVPN_Physic

рис.1 Физическая топология

DMVPN_Logic

рис.2 Логическая топология сети

В качестве интернета (или сети провайдера) четыре маршрутизатора, соединенные в кольцо и управляемые BGP. Для подключения центрального (Client_1)  и удаленных (Client_2-4) офисов используются относительно медленные каналы Т1 (в данной схеме это не несет никакой смысловой нагрузки, так я просто выделяю, что это клиенты, подключенные к провайдеру услуг по передаче данных). Подключение клиентов осуществляется с использованием BGP (раз уж провайдерами выделены маршрутизируемые в сети адреса). Динамическая маршрутизация по ходу статьи будет рассмотрена по протоколу OSPF, однако в конце статьи приведены ссылки и на конфиги на основе EIGRP.

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

Итак, поехали. Начнем с маршрутизатора Client_1_Branch. В целом его настройка очень проста и не должна вызвать никаких затруднений. Настраиваем loopback интерфейс, который будет изображать рабочую подсеть офиса:

Client_1_Branch#conf
Client_1_Branch(config)#int lo0
Client_1_Branch(config-if)#ip addr 192.168.10.1 255.255.255.255

Затем и интерфейс связи с CE маршрутизатором этой ветки Client_1:

Client_1_Branch(config-if)#int fa 0/0
Client_1_Branch(config-if)#ip addr 192.168.11.254 255.255.255.0

Ну и, конечно же, маршрутизация:

Client_1_Branch(config-if)#router ospf 10
Client_1_Branch(config-if)#network 192.168.10.1 0.0.0.0 area 0
Client_1_Branch(config-if)#network 192.168.11.0 0.0.0.255 area 0

На этом с Client_1_Branch все.

Поправим настройки интерфейса Т1 на ISP_1.

ISP_1#conf t
ISP_1(config)#int s 2/0
ISP_1(config-if)#ip addr 192.168.13.1 255.255.255.252

Ну и собственно Client_1. Во-первых, создадим виртуальный маршрутизатор:

Client_1#conf t
Client_1(config)#ip vrf Client_1
Client_1(config-vrf)#rd 10:1

Затем настроим физические интерфейсы:

Client_1(config)#int fa0/0
Client_1(config-if)#ip vrf forw Client_1
Client_1(config-if)#ip addr 192.168.11.1 255.255.255.0
Client_1(config-if)#int s1/0
Client_1(config-if)#ip vrf forw Client_1
Client_1(config-if)#ip addr 192.168.13.2 255.255.255.252

Теперь нужно настроить BGP. По правде говоря, маршрутизатору Client_1 совершенно не нужна таблица маршрутизации интернета, с другой стороны ему выделен IP-адрес, который должен быть в этом самом интернете смаршрутизирован. Поэтому мы можем попросить провайдера, чтобы он не выдавал нам информацию обо всех маршрутах интернета, а выдал только маршрут по умолчанию, а Client_1 со своей стороны будет анонсировать свою адресацию. (В данной конфигурации на Client_1 совсем не обязательно включать BGP. ISP_1 и без этого будет анонсировать подсеть 192.168.13.0/30. Я просто продемонстрирую один из механизмов подключения сети предприятия к интернету по BGP без приема на Client Edge маршрутизатор всей таблицы маршрутизации интернета, о чем я упоминал в предыдущей статье).

На Client_1 все просто:

Client_1(config)#router bgp 10
Client_1(config-router)#address-family ipv4 vrf Client_1
Client_1(config-router-af)#neighbor 192.168.13.1 remote-as 1
Client_1(config-router-af)#neighbor 192.168.13.1 activate
Client_1(config-router-af)#network 192.168.13.0 mask 255.255.255.252

А вот на ISP_1 чуть сложнее сначала создаем запретительный список доступа:

ISP_1(config)#ip access-list ext BGP
ISP_1(config-ext-nacl)#ip access-list extended BGP
ISP_1(config-ext-nacl)#deny ip any any

Затем настраиваем маршрутизацию с Client_1:

ISP_1(config)#router bgp 1
ISP_1(config-router)#address-family ipv4 vrf Client
ISP_1(config-router-af)#network 192.168.13.0 mask 255.255.255.252
ISP_1(config-router-af)#neighbor 192.168.13.2 remote-as 10
ISP_1(config-router-af)#neighbor 192.168.13.2 activate
ISP_1(config-router-af)#neighbor 192.168.13.2 default-originate
ISP_1(config-router-af)#neighbor 192.168.13.2 distribute-list BGP out

Теперь русским языком, что сконфигурировано: мы проанонсировали подсеть 192.168.13.0/30, подключили соседа 192.168.13.2, активировали его, сказали ему, что IPS_1 для него маршрутизатор по умолчанию, и ограничили выдачу маршрутов для Client_1 списком доступа BGP, т.е. вообще запретили анонсировать туда маршруты. Посмотрим, что из этого вышло на Client_1:

Client_1#sh ip bgp vpnv4 vrf Client_1
BGP table version is 24, local router ID is 192.168.12.1
Status codes: s suppressed, d damped, h history, * valid, > best, i — internal,
r RIB-failure, S Stale
Origin codes: i — IGP, e — EGP, ? — incomplete

Network          Next Hop            Metric LocPrf Weight Path
Route Distinguisher: 10:1 (default for vrf Client_1)
*> 0.0.0.0          192.168.13.1                           0 1 i
*> 192.168.13.0/30  0.0.0.0                  0         32768 i

Как видно, в принятых маршрутах только локально анонсируемая сеть и маршрут по умолчанию, указывающий на ISP_1. И никаких проблем с лишними маршрутами.

Теперь примемся за сам DMVPN.

В начале статьи  я перечислял, на основе каких технологий строится dmvpn, и теперь в полном соответствии с этим списком будем настраивать. Сначала туннельный интерфейс:

Client_1(config)#interface Tunnel0
Client_1(config-if)#ip vrf forwarding Client_1
Client_1(config-if)#ip address 192.168.60.1 255.255.255.0

Теперь GRE:

Client_1(config-if)#tunnel source Serial1/0
Client_1(config-if)#tunnel mode gre multipoint
Client_1(config-if)#tunnel key 0
Client_1(config-if)#tunnel vrf Client_1

Мы привязали туннель к интерфейсу Serial1/0, что обозначает, что в поле source пакета, вышедшего из туннельного интерфейса, будет значиться ip-адрес интерфейса Serial1/0. Указали режим GRE мультиточка и назначили туннельный ключ 0 (по сути это номер данной сети туннелей).

А вот последняя команда интересней. Зачем ее указывать, если при конфигурировании интерфейса Tunnel0 мы уже указывали ip vrf forwarding Client_1? А разница в следующем: команда ip vrf forwarding указывает, в какую таблицу маршрутизации включать интерфейс, т.е. на каком из виртуальных маршрутизаторов будет находиться вход в туннель. А команда tunnel vrf указывает, в какой виртуальный маршрутизатор попадет GRE пакет, уже обработанный интерфейсом Tunnel0. Если эту команду не указывать, то пакет попадет в основную таблицу маршрутизации железного маршрутизатора, и поскольку там не будет никакой информации об ip-адресе назначения, пакет будет отброшен.

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

На очереди NHRP. Именно благодаря этому протоколу мы будем узнавать ip-адреса противоположных концов туннелей и различать, где у нас hub, а где spoke (поскольку физическая топология все-таки не звезда).

Client_1(config)#interface Tunnel0
Client_1(config-if)#ip nhrp network-id 1
Client_1(config-if)#ip nhrp map multicast dynamic
Client_1(config-if)#ip nhrp server-only

Первой командой мы включаем NHRP на интерфейсе и присваиваем номер NBMA (Non-broadcast multiple-access) сети, которой является совокупность наших туннелей. Второй командой говорим, что нужно передавать мультикастовые пакеты для всех обнаруженных (именно обнаруженных, а не заданных статически) узлов NBMA сети. Это нужно, чтобы динамическая маршрутизация работала. И последняя команда (в общем-то необязательная) запрещает делать запросы на установление соответствия общесетевого и NBMA адреса, т.е. подразумевается, что Client_1 сам все должен знать. А узнает он все от маршрутизаторов в других офисах, на которых NHRP сконфигурирован немного иначе:

Client_2(config)#interface Tunnel0
Client_2(config-if)#ip nhrp network-id 1
Client_2(config-if)#ip nhrp map multicast dynamic
Client_2(config-if)#ip nhrp map 192.168.60.1 192.168.13.2
Client_2(config-if)#ip nhrp map multicast 192.168.13.2
Client_2(config-if)#ip nhrp nhs 192.168.60.1

Первое отличие в том, что мы задаем соответствие общесетевого и NBMA адресов для Client_1 вручную и следующей командой разрешаем передачу туда мультикастовых пакетов (для маршрутизации). Последней командой объявляем Client_1 NHRP сервером. Благодаря этому  Client_2 знает, куда ему обращаться за соответствием адресов и как достичь сервера. Client_1 в свою очередь, получая запросы от других маршрутизаторов, узнает о соответствии их общесетевых и NBMA адресов, после чего может предоставлять эту информацию всем участникам NBMA сети.

Ну и, собственно, какая же сеть без маршрутизации? Настраиваем OSPF на Client_1.

Client_1(config)#router ospf 10 vrf Client_1
Client_1(config-router)#network 192.168.11.0 0.0.0.255 area 0
Client_1(config-router)#network 192.168.60.0 0.0.0.255 area 0
Client_1(config-router)#default-information originate

Обратите внимание, что я не анонсирую через OSPF подсеть 192.168.13.0/30. Во-первых, это будет избыточно. И без этого анонса обработка таблицы маршрутизации на Client_1_Branch все равно укажет на Client_1, а в других офисах на соответствующий ISP. Во-вторых, и самое неприятное, что после добавления этого анонса в офисах Client_2 – Client_4 появятся маршруты, указывающие, что 192.168.13.0/30 находится не за Serial 1/0, a за Tunnel0, что в свою очередь приводит к образованию маршрутной петли, т.к. все пакеты, уходящие к 192.168.13.0/30, будут следовать в интерфейс Tunnel0, затем опять попадать на обработку в виртуальный маршрутизатор, который в свою очередь опять отправит этот пакет в Tunnel0 и так снова и снова.

Теперь нужно подровнять OSPF на туннельном интерфейсе, поскольку у нас это не обычный интерфейс, есть некоторые особенности.

Во-первых, все туннельные интерфейсы по умолчанию считаются point-to-point.

OSPF процесс ожидает, что через такой интерфейс может быть установлено только одно соседство.

Client_2#sh ip ospf 10 int tu0
Tunnel0 is up, line protocol is up
Internet Address 192.168.60.2/24, Area 0
Process ID 10, Router ID 192.168.22.1, Network Type POINT_TO_POINT, Cost: 11111
Transmit Delay is 1 sec, State POINT_TO_POINT
Timer intervals configured, Hello 10, Dead 40, Wait 40, Retransmit 5
oob-resync timeout 40
Hello due in 00:00:03
Supports Link-local Signaling (LLS)
Index 2/2, flood queue length 0
Next 0x0(0)/0x0(0)
Last flood scan length is 1, maximum is 2
Last flood scan time is 0 msec, maximum is 0 msec
Neighbor Count is 1, Adjacent neighbor count is 1
Adjacent with neighbor 192.168.12.1
Suppress hello for 0 neighbor(s)

Поэтому, когда из Tunnel0 вдруг приходят Hello-пакеты от нескольких маршрутизаторов, OSPF процесс приходит в замешательство и начинает постоянно сбрасывать и устанавливать соседство в соответствии с приходящими Hello-пакетами.

Чтобы это поправить пишем:

Client_1(config)#int tu0
Client_1(config-if)#ip ospf network broadcast

Почему broadcast? У нас ведь NBMA сеть. Потому что так удобней. OSPF при настройке point-to-multipoint интерфейса требует указания всех соседей в такой сети статически командой neighbor. К тому же возможны ситуации (и наверняка будут), когда маршруты будут построены так, что пакет пробежит между spoke’ми через hub, а то и через другой spoke.  Неудобно и неэффективно. Поэтому пишем broadcast.

Client_2(config-if)#do sh ip ospf 10 int tu0
Tunnel0 is up, line protocol is up
Internet Address 192.168.60.2/24, Area 0
Process ID 10, Router ID 192.168.22.1, Network Type BROADCAST, Cost: 11111
Transmit Delay is 1 sec, State DROTHER, Priority 0
Designated Router (ID) 192.168.12.1, Interface address 192.168.60.1
>No backup designated router on this network
Timer intervals configured, Hello 10, Dead 40, Wait 40, Retransmit 5
oob-resync timeout 40
Hello due in 00:00:07
Supports Link-local Signaling (LLS)
Index 2/2, flood queue length 0
Next 0x0(0)/0x0(0)
Last flood scan length is 1, maximum is 2
Last flood scan time is 0 msec, maximum is 0 msec
Neighbor Count is 1, Adjacent neighbor count is 1
Adjacent with neighbor 192.168.12.1  (Designated Router)
Suppress hello for 0 neighbor(s)

Во-вторых, поскольку сеть все-таки не широковещательная, ведущую роль в нем выполняет Client_1, то нужно сделать так, чтобы Client_1 всегда выполнял роль Designated Router, так как DR должен иметь постоянную связь со всеми соседями, а связь между spoke’ми устанавливается только по мере необходимости. Поэтому на Client_1 пишем:

Client_1(config)#int tu0
Client_1(config-if)#ip ospf priority 255

А на остальных:

Client_2(config)#int tu0
Client_2(config-if)#ip ospf priority 0

Если вы решаете использовать вместо OSPF EIGRP, настройка осуществляется исходя из тех же соображений. Ну и с учетом, разумеется, особенностей EIGRP.

На этом этапе сеть уже готова к использованию, все пакеты будут бегать куда нужно, динамические туннели будут устанавливаться между spoke’ми, в общем почти полный фэншуй. Вот только наша виртуальная сеть никак не может быть частной, пока не настроено шифрование. Настройка IPSec, если не вдаваться особо в подробности о том, как он вообще работает, пожалуй, одна из самых простых из настраиваемых технологий. Здесь нет никаких особенностей для hub или spoke’ов, или от того, что это mGRE — везде все одинаково. Отпечаток накладывает только то, что настраивается IPSec на виртуальном маршрутизаторе. Пишем:

Client_1(config)#crypto keyring Client vrf Client_1
Client_1(conf-keyring)#pre-shared-key address 0.0.0.0 0.0.0.0 key secretkey

Client_1(conf-keyring)#crypto isakmp policy 5
Client_1(config-isakmp)#hash md5
Client_1(config-isakmp)#authentication pre-share
Client_1(config-isakmp)#group 2

Client_1(config-isakmp)#crypto isakmp profile dmvpn
Client_1(conf-isa-prof)#vrf Client_1
Client_1(conf-isa-prof)#keyring Client
Client_1(conf-isa-prof)#match identity address 0.0.0.0

Client_1(conf-isa-prof)#crypto ipsec transform-set dmvpn_set esp-aes esp-md5-hmac

Client_1(cfg-crypto-trans)#crypto ipsec profile dmvpn_prof
Client_1(ipsec-profile)#set transform-set dmvpn_set

И применяем на туннельный интерфейс:

Client_1(ipsec-profile)#int tu0
Client_1(config-if)#tunnel protection ipsec profile dmvpn

Вот, собственно, и все. Нужно только убедиться, что все работает как нужно.

Client_2_Branch#traceroute 192.168.40.1

Type escape sequence to abort.
Tracing the route to 192.168.40.1

1 192.168.21.1 40 msec 8 msec 16 msec
2 192.168.60.4 80 msec 52 msec 28 msec
3 192.168.41.254 68 msec 76 msec 52 msec
Client_2_Branch#traceroute 192.168.10.1

Type escape sequence to abort.
Tracing the route to 192.168.10.1

1 192.168.21.1 32 msec 8 msec 12 msec
2 192.168.60.1 96 msec 52 msec 44 msec
3 192.168.11.254 68 msec * 68 msec
Client_2_Branch#traceroute 192.168.30.1

Type escape sequence to abort.
Tracing the route to 192.168.30.1

1 192.168.21.1 28 msec 28 msec 16 msec
2 192.168.60.1 84 msec 108 msec 68 msec
3 192.168.60.3 128 msec 140 msec 164 msec
4 192.168.31.254 152 msec 188 msec 104 msec
Client_2_Branch#traceroute 192.168.30.1

Type escape sequence to abort.
Tracing the route to 192.168.30.1

1 192.168.21.1 28 msec 20 msec 12 msec
2 192.168.60.3 88 msec 72 msec 48 msec
3 192.168.31.254 88 msec 64 msec 72 msec

Видно, что все конечные узлы друг друга видят напрямую. Я специально продемонстрировал, дважды выполнив traceroute на 192.168.30.1, динамический характер установления туннелей. В первом случае пакеты шли через Client_1, который у нас является hub’ом. Затем, когда Client_2 узнал через NHRP, как попасть на Client_3, пакеты слал уже по кратчайшему маршруту. Ну и IPSec:

Client_2#sh crypto isakmp sa
dst src state conn-id slot status
192.168.23.2 192.168.33.2 QM_IDLE 3 0 ACTIVE
192.168.13.2 192.168.23.2 QM_IDLE 1 0 ACTIVE
192.168.43.2 192.168.23.2 QM_IDLE 2 0 ACTIVE

Все туннели установлены и находятся в правильных состояниях.

Вот и все. Конфиги как обещал:

ISP_1, ISP_2, ISP_3, ISP_4

OSPF: Client_1.OSPF, Client_1_Banch.OSPF, Client_2.OSPF, Client_2_Branch.OSPF, Client_3.OSPF, Client_3_Branch.OSPFClient_4.OSPF, Client_4_Branch.OSPF

EIGRP: Client_1.EIGRP, Client_1_Banch.EIGRP, Client_2.EIGRP, Client_2_Branch.EIGRP, Client_3.EIGRP, Client_3_Branch.EIGRP, Client_4.EIGRP, Client_4_Branch.EIGRP.

Аверьянов Кирилл
network-lab.ru


Комментарии:

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Hide me
Получать регулярно свежие материалы, лабораторные и вебинары
Email Имя
Show me