Динамическая маршрутизация по GRE over IPsec туннелям между Cisco и FreeBSD 8.1

Несколько месяцев назад компания, в которой я работаю начала снова расширяться, следствием чего было появление двух новых офисов. Руководством была поставлена задача обеспечить доступ новых сотрудников к серверам компании. Ниже представлено описание того, как я подошел к решению данной задачи, черпая информацию в Google, man-командах FreeBSD и встроенной помощи в Cisco IOS.

Смотрим, что из этого получилось.

Исходные данные и постановка задачи

  1. Три офиса компании, между которыми необходимо настроить связь через общественные сети. Внутри туннелей запустить протокол динамической маршрутизации для обмена маршрутами к локальным сетям.
  2. Между двумя филиалами есть прямой оптоволоконный канал.
  3. Топология должна быть полносвязной, для наличия резервных маршрутов.
  4. Связь с внешним миром обеспечивают: маршрутизаторы С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.
В итоге получилась следующая схема:
image
Существовало еще одно замечание. Известно, что офисы В и С имеют гораздо более качественное соединение с внешним миром нежели офис А, поэтому эффективнее весь трафик во внешний мир и на офис С (Сisco 2811) пропускать через маршрутизатор на офисе В (Сisco 2821), а Интернет-соединение офиса А (FreeBSD-8.1) использовать как резервное, т.е. связь должна происходить по схеме, представленной ниже.

image

Непосредственно настройка

Оптика подключена. Для связи по оптике сделана подсеть с двумя адресами 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 вписывается:

cloned_interfaces="gre0"
ifconfig_gre0="192.168.23.1 192.168.23.2 netmask 255.255.255.252 link0 tunnel A.A.A.A C.C.C.C"
Этими строками создается и настраивается интерфейс gre0, который и ответственнен за работу GRE туннеля. После добавления данных строк в файл, команда: ifconfig gre0 create — создаст интерфейс gre0 с нужными настройками. Подсеть 192.168.23.0/30, в пределах которой назначены адреса для интерфейса, является той виртуальной сетью, через которую будет проходить туннельный трафик, она же будет отображаться в таблице маршрутизации. Параметр link0 в команде говорит о том, что необходимо использовать инкапсуляцию GRE.

В /boot/loader.conf вписывается:

if_gre_load="YES"
Эта настройка загружает драйвер gre при загрузке системы.

Офис B — Cisco 2821
configure terminal            #режим глобального конфигурирования
interface tunnel0            #режим конфигурирования интерфейса
ip address 192.168.22.1 255.255.255.252    #адрес внутри туннеля
tunnel source gi0/0                        #интерфейс источник
tunnel destination C.C.C.C                #IP назначения
tunnel mode gre ip                        #режим работы туннеля
Офис C — Cisco 2811
configure terminal
interface tunnel0
ip address 192.168.22.2 255.255.255.252
tunnel source fa0/0
tunnel destination B.B.B.B
tunnel mode gre ip

interface tun1
ip address 192.168.23.2 255.255.255.252
tunnel source fa0/0
tunnel destination A.A.A.A
tunnel mode gre ip
После этих настроек должны начать проходить пинги по туннелям.

Настройка защиты туннелей с помощью IPsec
Офис А — FreeBSD 8.1
Для включения поддержки IPsec во FreeBSD необходимо собрать ядро со следующими опциями:

options IPSEC
device crypto
Также необходимо установить порт ipsec-tools:

/usr/ports/security/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).

Содержание файлов.

ipsec.conf

spdflush;
spdadd A.A.A.A/32 C.C.C.C/32 gre -P out ipsec esp/tunnel/A.A.A.A-C.C.C.C/require;
spdadd C.C.C.C/32 A.A.A.A/32 gre -P in ipsec esp/tunnel/C.C.C.C-A.A.A.A/require;
Построчно:
  • очистка базы данных политик;
  • добавление политики для исходящего 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

Здесь редактировались следующие опции/разделы:

path pre_shared_key "/usr/local/etc/racoon/key.txt"; #путь к файлу с разделяемыми ключами
    #раздел:
    remote C.C.C.C {
        my_identifier address A.A.A.A;
        peers_identifier address C.C.C.C;
        lifetime time 86400 sec;    
#при несовпадении значений соединение может не установиться, на Cisco текущее значение lifetime #можно посмотреть командой show crypto isakmp policy

        proposal {
#в этом разделе параметры должны совпадать с таковыми на Cisco для isakmp политики, например #следующие
            encryption_algorithm aes;
            hash_algorithm md5;
            authentication_method pre_shared_key;
            dh_group 2;
        }
    }

    #раздел:
sainfo anonymous
    {
#следующие ниже опции должны совпадать в параметрами transform-set на Cisco
        encryption_algorithm aes;
        authentication_algorithm hmac_md5;
        compression_algorithm deflate;
        # pfs_group 2; # как видно закомментировано       
    }

key.txt
Содержит строку вида:

адрес_удаленного_сервера ключ
C.C.C.C    password

На данный файл устанавливается право на чтение только для root, остальные права запрещаются.

Для запуска при загрузке системы в /etc/rc.conf вписываются следующие строки:

ipsec_enable="YES"
ipsec_program="/usr/local/sbin/setkey"
ipsec_file="/usr/local/etc/racoon/ipsec.conf"
racoon_enable="YES"
racoon_flags="-f /usr/local/etc/racoon/racoon.conf"
После этого запустить соответствующие службы можно командами:

/etc/rc.d/ipsec start
/usr/local/etc/rc.d/racoon start
Офис В — Cisco 2821
  1. Cоздается политика isakmp.

    configure terminal
    crypto isakmp policy 10    # последняя цифра — ID
    encryption aes
    group 2
    auth pre-share
    hash md5
  2. Cоздается keyring – связка хост-ключ, к которой можно обращаться по имени.

    crypto keyring Ckey
    pre-shared-key address C.C.C.C key 6 password
    в дальнейшем можно обращаться к этой связке по имени Ckey
  3. Создается isakmp профиль.

    crypto isakmp profile BCisakmp
    keyring Ckey                # имя созданного keyring
    match identity address C.C.C.C 255.255.255.255
  4. Cоздается ipsec transform-set – параметры шифрования в туннеле.

    crypto ipsec transform-set EXAMPLE esp-aes esp-md5-hmac
  5. Cоздается профиль ipsec

    crypto ipsec profile BCipsec
    set isakmp BCisakmp
    set transform-set EXAMPLE
  6. Последнее — защищается GRE туннель

    interface tunnel0
    tun protection ipsec profile BCipsec
Офис С — Cisco 2811
Действия аналогичны предыдущим. Только необходимо создать по два keyring, isakmp и ipsec профиля, одну политику isakmp и один ipsec transform-set.
  1. crypto isakmp policy 10
    encryption aes
    group 2
    auth pre-share
    hash md5
  2. crypto keyring Bkey
    pre-shared-key address B.B.B.B key 6 password
    crypto keyring Akey
    pre-shared-key address A.A.A.A key 6 password
  3. crypto isakmp profile CBisakmp
    keyring Bkey               
    match identity address B.B.B.B 255.255.255.255
    crypto isakmp profile CAisakmp
    keyring Akey               
    match identity address A.A.A.A 255.255.255.255
  4. crypto ipsec transform-set EXAMPLE esp-aes esp-md5-hmac
  5. crypto ipsec profile CBipsec
    set isakmp CBisakmp
    set transform-set EXAMPLE
    crypto ipsec profile CAipsec
    set isakmp CAisakmp
    set transform-set EXAMPLE
  6. interface tun0
    tun protection ipsec profile CBipsec
    interface tun1
    tun protection ipsec profile CAipsec
Несколько команд show для демонстрации.

image

image

После успешного применения всех этих настроек, должна появится связь. Проверить можно естественно пропинговав адреса туннельных интерфейсов. А признаком защищенности канала будут установленные Security Association (SA), которые можно просмотреть:
  • на Cisco:
    show crypto ipsec sa
  • на FreeBSD:
    setkey -D
Настройка динамической маршрутизации 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_enable="YES"
quagga_daemons="zebra ospfd"
Стартуем quagga.

/usr/local/etc/rc.d/quagga start
Настраиваем.

Соединяемся на демон quagga – ospfd. Процесс конфигурирования почти аналогичен Сisco'вскому:

telnet localhost 2604
enable
conf t
router ospf
network 192.168.20.0/24 area 0
network 192.168.21.0/30 area 0
network 192.168.23.0/30 area 0
Ctrl+z
write memory
Настройка на Сisco
Cisco 2821:

configure terminal
router ospf 10
network 192.168.19.0 0.0.0.255 area 0
network 192.168.21.0 0.0.0.3 area 0
network 192.168.22.0 0.0.0.3 area 0
Cisco 2811:

configure terminal
router ospf 10
network 192.168.18.0 0.0.0.255 area 0
network 192.168.22.0 0.0.0.3 area 0
network 192.168.23.0 0.0.0.3 area 0
После этого должно состояться согласование и построены таблицы маршрутизации. Вспомним об еще одной задаче. Как было оговорено ранее — ADSL канал является медленным и нестабильным. Лучше ходить через один маршрутизатор, чем отправлять пакеты напрямую по ADSL каналу. Для решения данной задачи необходимо подредактировать стоимости маршрутов OSPF. Подстраивать будем стоимости маршрутов во FreeBSD под Cisco. Тем более шлюз является виртуальной машиной под Vmware ESXi и когда настроили OSPF на шлюзе получилось явное несоответствие стоимостей на разных концах соединений. Маршрутизаторы Cisco установили cost на туннельных интерфейсах в 11111, гигабитные и стомегабитные интерфейсы в 1.

Соединяемся на ospfd демон.

telnet localhost 2604
Далее выполняются следующие команды (сетевые карты на шлюзе были определены как em0, т.к. использовалась виртуальная сетевая карта эмулирующая Intel E1000).

interface em0   
ip ospf cost 1
interface em2
ip ospf cost 1
interface gre0
ip ospf cost 11115
На последнем (туннельном gre) интерфейсе была установлена заведомо большая стоимость чем суммарная стоимость маршрута к сети офиса С через один маршрутизатор. Также была изменена стоимость туннельного соединения на маршрутизаторе Cisco 2811. Входим в режим конфигурирования интерфейса tunnel 1 и выполняем:

ip ospf cost 11115
После этого картина распределния OSPF стоимостей интерфейсов примет следующий вид:

image

Таким образом, теперь маршрут к сети 192.168.18.0/24 будет лежать не через туннельный интерфейс напрямую на маршрутизатор Cisco 2811, а через маршрутизатор Cisco 2821 на офисе В, т.к. суммарная стоимость этого маршрута меньше стоимости маршрута, пролегающего через ADSL канал.

Еще одно замечание по настройке интерфейсов для ospf. Маршрутизаторы Сisco установили тип туннельных интерфейсов в point-to-point в то время как FreeBSD установила тип интерфейса gre0 в broadcast. По этой причине не происходило согласования между маршрутизаторами. Чтобы исправить ситуацию, необходимо изменить тип интерфейса gre0 на point-to-point.

telnet localhost 2604
enable
conf t
interface gre0
ip ospf network point-to-point
Также стояла задача обеспечения прохождения траффика, идущего в Интернет от клиентов офиса А по аналогичному маршруту. Для решения этой задачи необходимо вспомнить о наличии у каждого протокола маршрутизации такой характеристики как административная дистанция. Для статических маршрутов она равна 1, для протокола OSPF – 110. Административная дистанция определяет какой из маршрутов, ведущих к одному назначению, будет инсталлирован в таблицу маршрутизации, если этот маршрут предоставлен разными протоколами маршрутизации. По правилам выбирается протокол, имеющий меньшую административную дистанцию. Таким образом, для того чтобы решить нашу задачу, необходимо:
  1. Настроить OSPF на обмен маршрутами по умолчанию, между маршрутизаторами офисов А и В.
  2. Увеличить административную дистацию статического маршрута по умолчанию на FreeBSD так, чтобы она посчитала маршрут, пришедший от маршрутизатора Cisco 2821, лучше своего собственного.
На этом этапе появилась проблема, которая состояла в том, что провайдер при пересоединении ppp сессии любит менять шлюз по умолчанию. Как заставить quagga забирать выдаваемый шлюз при пересоединении решения не нашлось, а оставить эту задачу на попечение ppp демону нельзя, т.к. необходимо изменять административную дистанцию маршрута по умолчанию. Чтобы выйти из этой ситуации, в quagga было прописано много статических маршрутов по умолчанию (для настройки статических маршрутов необходимо соединиться на демон zebra командой – telnet localhost 2601) с нужной административной дистанцией, и шлюзами в том диапазоне, из которого их выдавал провайдер (на самом деле хоть было вбито около 10ти, адрес менялся в пределах 3х постоянных значений). Quagga в зависимости от активного адреса шлюза меняет маршрут по умолчанию и инсталлирует его в таблицу маршрутизации ядра.

Для настройки обмена маршрутами по умолчанию в настройках OSPF задается команда default-information originate. Например на Cisco:

configure terminal
router ospf 10
default-information originate
Аналогичная команда задается в настройках OSPF в quagga. Затем в quagga прописываем статические маршруты по умолчанию с административной дистанцией большей чем 110, мы выбрали 120. Выглядело это следующим образом:

image

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

image

Как видим, маршрут по умолчанию и маршрут к сети офиса С (192.168.18.0/24) проходит через адрес 192.168.21.1, который является адресом маршрутизатора на офисе В (Cisco 2821).

Схема заработала.

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


1 комментарий

avatar
Добрый день!

Не подскажете а как была решена проблема указания размера окна tcp пакетов (tcp mss)? Ведь при использовании GRE тоннелей поле data в пакете нельзя использовать в 1500 байт.
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.