Динамическая маршрутизация по GRE over IPsec туннелям между Cisco и FreeBSD 8.1
Несколько месяцев назад компания, в которой я работаю начала снова расширяться, следствием чего было появление двух новых офисов. Руководством была поставлена задача обеспечить доступ новых сотрудников к серверам компании. Ниже представлено описание того, как я подошел к решению данной задачи, черпая информацию в Google, man-командах FreeBSD и встроенной помощи в Cisco IOS.
Смотрим, что из этого получилось.
В итоге получилась следующая схема:
![image](http://habreffect.ru/files/bb9/8be6af9e1/gre_ipsec_basic_schema.jpg)
Существовало еще одно замечание. Известно, что офисы В и С имеют гораздо более качественное соединение с внешним миром нежели офис А, поэтому эффективнее весь трафик во внешний мир и на офис С (Сisco 2811) пропускать через маршрутизатор на офисе В (Сisco 2821), а Интернет-соединение офиса А (FreeBSD-8.1) использовать как резервное, т.е. связь должна происходить по схеме, представленной ниже.
![image](http://habreffect.ru/files/1f7/1446f211e/gre_ipsec_packets_flow_schema.jpg)
Cisco 2821 — 192.168.21.1/30
FreeBSD 8.1 — 192.168.21.2/30
В /boot/loader.conf вписывается:
Содержание файлов.
ipsec.conf
Здесь редактировались следующие опции/разделы:
key.txt
Содержит строку вида:
адрес_удаленного_сервера ключ
На данный файл устанавливается право на чтение только для root, остальные права запрещаются.
Для запуска при загрузке системы в /etc/rc.conf вписываются следующие строки:
![image](http://habreffect.ru/files/fdc/e73023f8f/cisco_isakmp_keyring.jpg)
![image](http://habreffect.ru/files/3fa/14ae5bd9c/cisco_tun.jpg)
После успешного применения всех этих настроек, должна появится связь. Проверить можно естественно пропинговав адреса туннельных интерфейсов. А признаком защищенности канала будут установленные Security Association (SA), которые можно просмотреть:
Для настройки необходимо изменение двух конфигурационных файлов: zebra.conf, ospfd.conf. Данные файлы были созданы в каталоге /usr/local/etc/quagga. Из настроек достаточно прописать в них параметры: hostname, password и enable password. Пример можно посмотреть в каталоге/usr/local/share/examples/quagga. Для запуска quagga при старте системы вписываем в /etc/rc.conf:
Соединяемся на демон quagga – ospfd. Процесс конфигурирования почти аналогичен Сisco'вскому:
Соединяемся на ospfd демон.
![image](http://habreffect.ru/files/97f/c51346b7c/gre_ipsec_ospf_costs_schema.jpg)
Таким образом, теперь маршрут к сети 192.168.18.0/24 будет лежать не через туннельный интерфейс напрямую на маршрутизатор Cisco 2811, а через маршрутизатор Cisco 2821 на офисе В, т.к. суммарная стоимость этого маршрута меньше стоимости маршрута, пролегающего через ADSL канал.
Еще одно замечание по настройке интерфейсов для ospf. Маршрутизаторы Сisco установили тип туннельных интерфейсов в point-to-point в то время как FreeBSD установила тип интерфейса gre0 в broadcast. По этой причине не происходило согласования между маршрутизаторами. Чтобы исправить ситуацию, необходимо изменить тип интерфейса gre0 на point-to-point.
Для настройки обмена маршрутами по умолчанию в настройках OSPF задается команда default-information originate. Например на Cisco:
![image](http://habreffect.ru/files/194/9bf2b5ddd/freebsd_default_routes.jpg)
В конечном итоге, посмотрев на таблицу маршрутизации в quagga на FreeBSD, мы должны увидеть примерно следующее:
![image](http://habreffect.ru/files/521/32a76afe1/route_finish.jpg)
Как видим, маршрут по умолчанию и маршрут к сети офиса С (192.168.18.0/24) проходит через адрес 192.168.21.1, который является адресом маршрутизатора на офисе В (Cisco 2821).
Схема заработала.
На этом я хотел бы закончить пост. Пожелания, предложения, разумная критика, комментарии спецов в соответствующих областях будут только приветствоваться.
Смотрим, что из этого получилось.
Исходные данные и постановка задачи
- Три офиса компании, между которыми необходимо настроить связь через общественные сети. Внутри туннелей запустить протокол динамической маршрутизации для обмена маршрутами к локальным сетям.
- Между двумя филиалами есть прямой оптоволоконный канал.
- Топология должна быть полносвязной, для наличия резервных маршрутов.
- Связь с внешним миром обеспечивают: маршрутизаторы С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
В итоге получилась следующая схема:
![image](http://habreffect.ru/files/bb9/8be6af9e1/gre_ipsec_basic_schema.jpg)
Существовало еще одно замечание. Известно, что офисы В и С имеют гораздо более качественное соединение с внешним миром нежели офис А, поэтому эффективнее весь трафик во внешний мир и на офис С (Сisco 2811) пропускать через маршрутизатор на офисе В (Сisco 2821), а Интернет-соединение офиса А (FreeBSD-8.1) использовать как резервное, т.е. связь должна происходить по схеме, представленной ниже.
![image](http://habreffect.ru/files/1f7/1446f211e/gre_ipsec_packets_flow_schema.jpg)
Непосредственно настройка
Оптика подключена. Для связи по оптике сделана подсеть с двумя адресами 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
Здесь редактировались следующие опции/разделы:
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
- Cоздается политика isakmp.
configure terminal crypto isakmp policy 10 # последняя цифра — ID encryption aes group 2 auth pre-share hash md5
- Cоздается keyring – связка хост-ключ, к которой можно обращаться по имени.
crypto keyring Ckey pre-shared-key address C.C.C.C key 6 password в дальнейшем можно обращаться к этой связке по имени Ckey
- Создается isakmp профиль.
crypto isakmp profile BCisakmp keyring Ckey # имя созданного keyring match identity address C.C.C.C 255.255.255.255
- Cоздается ipsec transform-set – параметры шифрования в туннеле.
crypto ipsec transform-set EXAMPLE esp-aes esp-md5-hmac
- Cоздается профиль ipsec
crypto ipsec profile BCipsec set isakmp BCisakmp set transform-set EXAMPLE
- Последнее — защищается GRE туннель
interface tunnel0 tun protection ipsec profile BCipsec
Офис С — Cisco 2811
Действия аналогичны предыдущим. Только необходимо создать по два keyring, isakmp и ipsec профиля, одну политику isakmp и один ipsec transform-set.crypto isakmp policy 10 encryption aes group 2 auth pre-share hash md5
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
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
crypto ipsec transform-set EXAMPLE esp-aes esp-md5-hmac
crypto ipsec profile CBipsec set isakmp CBisakmp set transform-set EXAMPLE crypto ipsec profile CAipsec set isakmp CAisakmp set transform-set EXAMPLE
interface tun0 tun protection ipsec profile CBipsec interface tun1 tun protection ipsec profile CAipsec
![image](http://habreffect.ru/files/fdc/e73023f8f/cisco_isakmp_keyring.jpg)
![image](http://habreffect.ru/files/3fa/14ae5bd9c/cisco_tun.jpg)
После успешного применения всех этих настроек, должна появится связь. Проверить можно естественно пропинговав адреса туннельных интерфейсов. А признаком защищенности канала будут установленные 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 0Cisco 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](http://habreffect.ru/files/97f/c51346b7c/gre_ipsec_ospf_costs_schema.jpg)
Таким образом, теперь маршрут к сети 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. Административная дистанция определяет какой из маршрутов, ведущих к одному назначению, будет инсталлирован в таблицу маршрутизации, если этот маршрут предоставлен разными протоколами маршрутизации. По правилам выбирается протокол, имеющий меньшую административную дистанцию. Таким образом, для того чтобы решить нашу задачу, необходимо:
- Настроить OSPF на обмен маршрутами по умолчанию, между маршрутизаторами офисов А и В.
- Увеличить административную дистацию статического маршрута по умолчанию на FreeBSD так, чтобы она посчитала маршрут, пришедший от маршрутизатора Cisco 2821, лучше своего собственного.
Для настройки обмена маршрутами по умолчанию в настройках OSPF задается команда default-information originate. Например на Cisco:
configure terminal router ospf 10 default-information originateАналогичная команда задается в настройках OSPF в quagga. Затем в quagga прописываем статические маршруты по умолчанию с административной дистанцией большей чем 110, мы выбрали 120. Выглядело это следующим образом:
![image](http://habreffect.ru/files/194/9bf2b5ddd/freebsd_default_routes.jpg)
В конечном итоге, посмотрев на таблицу маршрутизации в quagga на FreeBSD, мы должны увидеть примерно следующее:
![image](http://habreffect.ru/files/521/32a76afe1/route_finish.jpg)
Как видим, маршрут по умолчанию и маршрут к сети офиса С (192.168.18.0/24) проходит через адрес 192.168.21.1, который является адресом маршрутизатора на офисе В (Cisco 2821).
Схема заработала.
На этом я хотел бы закончить пост. Пожелания, предложения, разумная критика, комментарии спецов в соответствующих областях будут только приветствоваться.
1 комментарий
Не подскажете а как была решена проблема указания размера окна tcp пакетов (tcp mss)? Ведь при использовании GRE тоннелей поле data в пакете нельзя использовать в 1500 байт.