GRE (Generic Routing Encapsulation) — проприетарный протокол Cisco для организации VPN соединений. Работает он по такому же принципу, что и IPSec, то есть к исходному пакету данных добавляет свой заголовок, за которым следует новый IP заголовок с новыми IP адресами. Выглядит этот так:

Однако есть существенное отличие между IPSec и GRE. IPSec изначально разрабатывался для осуществления шифрованной связи, GRE не использует никакого алгоритма шифрования и аутентификации.
GRE прост в настройке и используется там, где нужно организовать простую туннельную связь, не обременяя при этом процессор сложным алгоритмом шифрования.
GRE также идеален для передачи IPv6 поверх IPv4 и наоборот.
При настройке GRE туннеля следует учитывать тот факт, что при добавлении GRE заголовка увеличивается MTU всего пакета. Это может привести к тому, что некоторые маршрутизаторы уничтожат пакеты, если не настроены на передачу с увеличенным MTU. Фрагментация GRE пакетов также запрещена, поэтому в идеале лучше уменьшить MTU в самом начале туннеля.
Итак, приступим к настройке протокола. Схема сети выглядит так:

В данном примере мы рассматриваем конфигурацию GRE типа IPv4-over-IPv4 с использованием NAT.
Настраиваем туннельный интерфейс:
Headquarter(config)# interface Tunnel 10
Теперь нужно указать IP адрес данного интерфейса. Делается это для того, чтобы указать GRE какой сетевой протокол будет инкапсулироваться, IPv4 или IPv6 либо какой-нибудь другой протокол:
Headquarter(config-if)# ip address 100.0.0.1 255.255.255.0
Указываем начало туннеля:
Headquarter(config-if)# tunnel source 1.1.1.1
А также конец туннеля:
Headquarter(config-if)# tunnel destination 2.2.2.1
Осталось теперь пустить весь трафик, идущий в сеть 192.168.2.0/24 в наш туннель:
Headquarter(config)# ip route 192.168.2.0 255.255.255.0 interface tunnel 10
То же самое с учетом адресов проделываем и на противоположном конце. Вот как выглядят настройки на обоих маршрутизаторах:


Убедимся в работе туннеля запустив Ping на одном из компьютеров:

Взглянем как выглядит инкапсулированный пакет:
Keepalive
Что произойдет с туннелем, если интерфейс на конечном маршрутизаторе отключится интерфейс либо оборвется кабель на промежуточном участке связи?
Отключим интерфейс Tunnel 10 на маршрутизаторе Branch:

Если запустим Ping с главного офиса, то результат будет отрицательный. Взглянем на состояние интерфейсов на Headquarter:

Все интерфейсы и линейные протоколы связи в состоянии UP. Проверим сам интерфейс Tunnel в деталях:

Здесь тоже все в порядке. Попробуем “пингануть” туннельный интерфейс на противоположном конце с роутера Headquarter:

Данная информация косвенно подтверждает тот факт, что на противоположном конце не все гладко, конечно, при условии, что маршрутизация в целом и WAN интерфейс на Branch работают как надо.
Чтобы избежать такой ситуации в GRE предусмотрена отправка пакетов Keepalive. Давайте настроим ее на интерфейсе Tunnel 10:
Headquarter(config-if)# keepalive 10 3
Здесь мы указываем отправлять пакеты keepalive каждые 10 с. Если ответ не будет получен после 3-х попыток, то перевести туннель в состояние Down.
Loopback или реальный интерфейс
В официальной документации сказано, что качестве начала и конца туннеля можно указывать либо реальный интерфейс либо Loopback. Давайте разберемся в чем разница. Добавим к нашей сети еще один роутер для резервирования маршрута:

Если мы отключим роутер ISP, то туннель автоматически перекинется через резервный маршрутизатор и будет прекрасно работать. Однако, если мы отключим интерфейс Fa0/1 на Headquarter, то туннель перейдет в состояние Down. Это связано с тем, что в качестве начала туннеля указан адрес интерфейса Fa0/1 и теперь при отключении данного порта отключается и сам туннель.
Чтобы избежать подобной ситуации рекомендуется использовать Loopback интерфейс в качестве начала и конца туннеля, причем он должен иметь маршрутизируемый адрес. То есть порт должен быть доступен по сети.
Конечно, если у вас один uplink, то достаточно указать реальный WAN интерфейс, но если 2 и более, то лучше воспользоваться Loopback.
Настройка GRE over IPSec
GRE не поддерживает шифрование, однако, если необходимо организовать защищенный канал связи, то можно построить туннель GRE поверх IPSec. Организация защищенного канала IPSec состоит из 2-х фаз. В первой фазе мы определяем политику безопасности (ISAKAMP IKE) для создания служебного туннеля, а во второй — параметры туннеля (IPSec) для передачи данных.
Для начала настроим политику безопасности ISAKMP на маршрутизаторе Headquarter:
Headquarter(config)# crypto isakmp policy 1
Headquarter(config-iakmp)# encryption aes — метод шифрования aes
Headquarter(config-isakmp)# authentication pre-share — метод аутентификации pre-share
Headquarter(config-isakmp)# group 2 — метод обмена секретными ключами (метод Диффи-Хеллмана)
Headquarter(config-isakmp)# lifetime 10000 — время жизни сессии 10 000 с
Определим IP адрес конечной точки туннеля, то есть IP адрес Branch, а также их общий ключ pre-share для аутентификации:
Headquarter(config)# crypto isakmp key 6 PASSWORD address 2.2.2.1
Настроим параметры туннеля IPSec:
Headquarter(config)# crypto ipsec transform-set GRE-IPSEC esp-3des esp-sha-hmac
Теперь создадим профиль подключения и назовем его GRE. В нем мы укажем параметры туннеля:
Headquarter(config)# crypto ipsec profile GRE
Headquarter(ipsec-profile)# set security-association lifetime seconds 10000
Headquarter(ipsec-profile)# set transform-set GRE-IPSEC
И наконец заключительный этап — мы привяжем наш профиль к туннельному интерфейсу:
Headquarter(config-if)# tunnel protection ipsec profile GRE
Теперь запустим Ping и проверим работоспособность туннеля. Однако почему-то он не работает. Дело в том, что у нас включена отправка Keepalive. Маршрутизатор отправляет keepalive пакеты по незащищенному каналу и поэтому IPSec туннель не устанавливается. Если отключить keepalive, то туннель сразу установится и начнет работать.
Приветствую всех читателей Хабра!
Несколько месяцев назад компания, в которой я работаю начала снова расширяться, следствием чего было появление двух новых офисов. Руководством была поставлена задача обеспечить доступ новых сотрудников к серверам компании. Ниже представлено описание того, как я подошел к решению данной задачи, черпая информацию в Google, man-командах FreeBSD и встроенной помощи в Cisco IOS.
Смотрим, что из этого получилось.
Исходные данные и постановка задачи
- Три офиса компании, между которыми необходимо настроить связь через общественные сети. Внутри туннелей запустить протокол динамической маршрутизации для обмена маршрутами к локальным сетям.
- Между двумя филиалами есть прямой оптоволоконный канал.
- Топология должна быть полносвязной, для наличия резервных маршрутов.
- Связь с внешним миром обеспечивают: маршрутизаторы Сisco 2821, Сisco 2811, и сервер на базе FreeBSD 8.1. Маршрутизаторы подключены к внешнему миру по Ethernet каналу, а FreeBSD 8.1 через ADSL. В маршрутизаторы вставлены модули Ethernet коммутации на 4ре порта, таким образом шлюзом по умолчанию для подсетей, за которые ответственны маршрутизаторы, является интерфейс Vlan1.
Данные по подсетям:
- офис A — подсеть 192.168.20.0/24, шлюз 192.168.20.254 (FreeBSD 8.1), внешний адрес A.A.A.A
- офис B — подсеть 192.168.19.0/24, шлюз 192.168.19.254 (Cisco 2821), внешний адрес B.B.B.B
- офис C — подсеть 192.168.18.0/24, шлюз 192.168.18.254 (Cisco 2811), внешний адрес C.C.C.C
Итак, между двумя филиалами уже есть прямой оптоволоконный канал, который находится в собственности организации. Таким образом, один канал уже присутствует и практически не нуждается в конфигурировании. Осталось организовать два туннеля: первого (А) с третьим (С) и второго (В) с третьим (С) филиалами — через общественные сети (Интернет). Для организации защиты данных туннелей предполагается использовать стандарт IPsec. Раз топология должна быть полносвязной, то встает вопрос правильной маршрутизации данных. Списки доступа для шифрования вместе со статическими маршрутами для этого плохо подходят. Поэтому было решено запустить внутри туннелей протокол динамической маршрутизации. В качестве последнего принято решение использовать OSPF, а для его запуска в туннелях — протокол GRE (Generic Routing Encapsulation). Таким образом, возникла задача построить два GRE-туннеля, защищенных протоколом IPsec.
В итоге получилась следующая схема: 
Существовало еще одно замечание. Известно, что офисы В и С имеют гораздо более качественное соединение с внешним миром нежели офис А, поэтому эффективнее весь трафик во внешний мир и на офис С (Сisco 2811) пропускать через маршрутизатор на офисе В (Сisco 2821), а Интернет-соединение офиса А (FreeBSD-8.1) использовать как резервное, т.е. связь должна происходить по схеме, представленной ниже.

Непосредственно настройка
Оптика подключена. Для связи по оптике сделана подсеть с двумя адресами 192.168.21.0/30.
Cisco 2821 — 192.168.21.1/30
FreeBSD 8.1 — 192.168.21.2/30
Настройка GRE туннелей
Офис А — FreeBSD 8.1
В /etc/rc.conf вписывается:
Этими строками создается и настраивается интерфейс gre0, который и ответственнен за работу GRE туннеля. После добавления данных строк в файл, команда: ifconfig gre0 create — создаст интерфейс gre0 с нужными настройками. Подсеть 192.168.23.0/30, в пределах которой назначены адреса для интерфейса, является той виртуальной сетью, через которую будет проходить туннельный трафик, она же будет отображаться в таблице маршрутизации. Параметр link0 в команде говорит о том, что необходимо использовать инкапсуляцию GRE.
В /boot/loader.conf вписывается:
Эта настройка загружает драйвер gre при загрузке системы.
Офис B — Cisco 2821
Офис C — Cisco 2811
После этих настроек должны начать проходить пинги по туннелям.
Настройка защиты туннелей с помощью IPsec
Офис А — FreeBSD 8.1
Для включения поддержки IPsec во FreeBSD необходимо собрать ядро со следующими опциями:
Также необходимо установить порт ipsec-tools:
Для хранения конфигурационных файлов был создан каталог /usr/local/etc/racoon (racoon – утилита, управляющая IPsec соединениями). В этом каталоге создано три файла: ipsec.conf, key.txt (в примерах называется psk.txt) и racoon.conf (можно скопировать из /usr/local/share/examples/ipsec-tools). В файле ipsec.conf указывается политика IPsec (SPD – Security Policy Database), т.е. какой траффик подлежит шифрованию и передаче по туннелю; в файле racoon.conf — настройки удаленных клиентов и параметры для первой и второй фаз IPSec; в файле key.txt – разделяемый ключ (pre-shared key).
Построчно:
- очистка базы данных политик;
- добавление политики для исходящего GRE трафика с A.A.A.A на C.C.C.C. При обычной настройке IPSec между двумя точками сюда пишутся адреса частных подсетей, трафик между которыми должен быть передан по туннелю. В случае, рассматриваемом в статье, подобный траффик уже завернут в протокол GRE, поэтому подлежит шифрованию весь GRE траффик, идущий между внешними адресами. Здесь необходимо соблюдать осторожность. Если написать конструкцию вида: spdadd 0.0.0.0/0 0.0.0.0/0 gre … — (которая означает весь GRE траффик), то можно получить определенные проблемы. Например, если в сети найдется Windows PPTP клиент, использующий для работы GRE протокол, то работать он не будет, т.к. его пакеты будут добросовестно упаковываться шлюзом в наш IPsec туннель;
- добавление политики для входящего GRE трафика с C.C.C.C на A.A.A.A
racoon.conf
Здесь редактировались следующие опции/разделы:
key.txt
Содержит строку вида:
На данный файл устанавливается право на чтение только для root, остальные права запрещаются.
Для запуска при загрузке системы в /etc/rc.conf вписываются следующие строки:
После этого запустить соответствующие службы можно командами:
Офис В — Cisco 2821
- Cоздается политика isakmp.
Cоздается keyring – связка хост-ключ, к которой можно обращаться по имени.
Создается isakmp профиль.
Cоздается ipsec transform-set – параметры шифрования в туннеле.
Cоздается профиль ipsec
Последнее — защищается GRE туннель
Офис С — Cisco 2811
Действия аналогичны предыдущим. Только необходимо создать по два keyring, isakmp и ipsec профиля, одну политику isakmp и один ipsec transform-set.
Несколько команд show для демонстрации.


После успешного применения всех этих настроек, должна появится связь. Проверить можно естественно пропинговав адреса туннельных интерфейсов. А признаком защищенности канала будут установленные Security Association (SA), которые можно просмотреть:
- на Cisco:
- на FreeBSD:
Настройка динамической маршрутизации OSPF
Теперь необходимо обеспечить связь между подсетями офисов. Для этого настраиваем OSPF протокол для обмена маршрутами.
Настройка на FreeBSD 8.1
На FreeBSD для этого используется пакет quagga-0.99.17_3. Устанавливается из /usr/ports/net/quagga.
Для настройки необходимо изменение двух конфигурационных файлов: zebra.conf, ospfd.conf. Данные файлы были созданы в каталоге /usr/local/etc/quagga. Из настроек достаточно прописать в них параметры: hostname, password и enable password. Пример можно посмотреть в каталоге /usr/local/share/examples/quagga. Для запуска quagga при старте системы вписываем в /etc/rc.conf:
Соединяемся на демон quagga – ospfd. Процесс конфигурирования почти аналогичен Сisco’вскому:
Настройка на Сisco
После этого должно состояться согласование и построены таблицы маршрутизации. Вспомним об еще одной задаче. Как было оговорено ранее — ADSL канал является медленным и нестабильным. Лучше ходить через один маршрутизатор, чем отправлять пакеты напрямую по ADSL каналу. Для решения данной задачи необходимо подредактировать стоимости маршрутов OSPF. Подстраивать будем стоимости маршрутов во FreeBSD под Cisco. Тем более шлюз является виртуальной машиной под Vmware ESXi и когда настроили OSPF на шлюзе получилось явное несоответствие стоимостей на разных концах соединений. Маршрутизаторы Cisco установили cost на туннельных интерфейсах в 11111, гигабитные и стомегабитные интерфейсы в 1.
Соединяемся на ospfd демон.
Далее выполняются следующие команды (сетевые карты на шлюзе были определены как em0, т.к. использовалась виртуальная сетевая карта эмулирующая Intel E1000).
На последнем (туннельном gre) интерфейсе была установлена заведомо большая стоимость чем суммарная стоимость маршрута к сети офиса С через один маршрутизатор. Также была изменена стоимость туннельного соединения на маршрутизаторе Cisco 2811. Входим в режим конфигурирования интерфейса tunnel 1 и выполняем:
После этого картина распределния OSPF стоимостей интерфейсов примет следующий вид:

Таким образом, теперь маршрут к сети 192.168.18.0/24 будет лежать не через туннельный интерфейс напрямую на маршрутизатор Cisco 2811, а через маршрутизатор Cisco 2821 на офисе В, т.к. суммарная стоимость этого маршрута меньше стоимости маршрута, пролегающего через ADSL канал.
Еще одно замечание по настройке интерфейсов для ospf. Маршрутизаторы Сisco установили тип туннельных интерфейсов в point-to-point в то время как FreeBSD установила тип интерфейса gre0 в broadcast. По этой причине не происходило согласования между маршрутизаторами. Чтобы исправить ситуацию, необходимо изменить тип интерфейса gre0 на point-to-point.
Также стояла задача обеспечения прохождения траффика, идущего в Интернет от клиентов офиса А по аналогичному маршруту. Для решения этой задачи необходимо вспомнить о наличии у каждого протокола маршрутизации такой характеристики как административная дистанция. Для статических маршрутов она равна 1, для протокола OSPF – 110. Административная дистанция определяет какой из маршрутов, ведущих к одному назначению, будет инсталлирован в таблицу маршрутизации, если этот маршрут предоставлен разными протоколами маршрутизации. По правилам выбирается протокол, имеющий меньшую административную дистанцию. Таким образом, для того чтобы решить нашу задачу, необходимо:
- Настроить OSPF на обмен маршрутами по умолчанию, между маршрутизаторами офисов А и В.
- Увеличить административную дистацию статического маршрута по умолчанию на FreeBSD так, чтобы она посчитала маршрут, пришедший от маршрутизатора Cisco 2821, лучше своего собственного.
На этом этапе появилась проблема, которая состояла в том, что провайдер при пересоединении ppp сессии любит менять шлюз по умолчанию. Как заставить quagga забирать выдаваемый шлюз при пересоединении решения не нашлось, а оставить эту задачу на попечение ppp демону нельзя, т.к. необходимо изменять административную дистанцию маршрута по умолчанию. Чтобы выйти из этой ситуации, в quagga было прописано много статических маршрутов по умолчанию (для настройки статических маршрутов необходимо соединиться на демон zebra командой – telnet localhost 2601) с нужной административной дистанцией, и шлюзами в том диапазоне, из которого их выдавал провайдер (на самом деле хоть было вбито около 10ти, адрес менялся в пределах 3х постоянных значений). Quagga в зависимости от активного адреса шлюза меняет маршрут по умолчанию и инсталлирует его в таблицу маршрутизации ядра.
Для настройки обмена маршрутами по умолчанию в настройках OSPF задается команда default-information originate. Например на Cisco:
Аналогичная команда задается в настройках OSPF в quagga. Затем в quagga прописываем статические маршруты по умолчанию с административной дистанцией большей чем 110, мы выбрали 120. Выглядело это следующим образом:

В конечном итоге, посмотрев на таблицу маршрутизации в quagga на FreeBSD, мы должны увидеть примерно следующее:

Как видим, маршрут по умолчанию и маршрут к сети офиса С (192.168.18.0/24) проходит через адрес 192.168.21.1, который является адресом маршрутизатора на офисе В (Cisco 2821).
На этом я хотел бы закончить пост. Пожелания, предложения, разумная критика, комментарии спецов в соответствующих областях будут только приветствоваться.
Данная статья не подлежит комментированию, поскольку её автор ещё не является полноправным участником сообщества. Вы сможете связаться с автором только после того, как он получит приглашение от кого-либо из участников сообщества. До этого момента его username будет скрыт псевдонимом.
Возникла необходимость создать туннель IPSec+GRE между CISCO и Mikrotik, где CISCO — центральный офис, а Mikrotik — все филиалы, которых N-ое количество.
В интернете читал, что принцип "IPSec over GRE" позволяет передавать в незашифрованном GRE-туннеле зашифрованные данные IPSec, а "GRE over IPSec" позволяет инкапсулировать данные GRE заголовками ESP или AH (по-сути, незашифрованный GRE в зашифрованном IPSec).
Вопрос.
При какой из этих двух конфигураций, подсети всех филиалов смогут видеть друг друга? Например, пусть центральный офис имеет подсеть 10.10.10.0/24, а два филиала А и Б подсети 192.168.1.0/24 и 192.168.2.0/24 соответственно. При какой конфигурации из двух, указанных выше, эти две подсети (А и Б) смогут видеть друг друга и подсеть центрального офиса?
Насколько мне известно, "чистый" IPSec нельзя маршрутизировать. Т.е., NAT и правила фаерволла не применимы к пакетам IPSec.






