Первая схема
Казалось бы, обыденная задача - объединить два офиса шифрованным каналом. Всего-то нужно построить site-to-site VPN и зашифровать с помощью crypto map. Все так и есть, если речь идет не о государственной структуре. Нельзя использовать вражеские шифровальные алгоритмы и железо. Именно под эту задачу были выбраны маршрутизаторы ISR второго поколения 2911R. Буква R в конце названия говорит о том, что данные рутеры были произведены на территории РФ. Для шифрования трафика будем использовать модули для этих рутеров - NME RVPN, выполненные в качестве карты расширения для ISR. Они несут на борту русский софт от компании S-Terra и, конечно же, «Крипто про». По сути, платы представляют собой отдельную машинку под управлением redhat linux с несколькими кастомными софтинами. Имеет один внешний порт помимо общей коммутационной шины, которой подключаются все подобные модули в ISR.
Собрать данную схему сложности не представляет. Вопросы
начали появляться, как я взялся за настройку самого модуля.
Как добавить dot1.q интерфейс
Эта процедура описана в мануале к модулю, но после
выполнения указанных действий пакеты через созданный интерфейс у меня не
ходили. Они явно фильтровались процессом vpnserver. Еще раз, перечитав раздел мануала,
обратил внимание на следующее:
"Если командой if_mgr add был зарегистрирован новый
защищаемый интерфейс после конвертирования cisco-like конфигурации, то для
этого интерфейса будет выполняться неявное правило Drop All, так как при
конвертировании cisco-like конфигурации фильтры для каждого интерфейса
прописываются в отдельности При следующем конвертировании cisco-like конфигурации
новый интерфейс будет добавлен в эту конфигурацию и для него будут действовать
общие правила, как и для остальных интерфейсов."
Итак, добавляем драйвер на интерфейс, заходим в shell
коммандой cs_console, заходим в контекст интерфейса, делаем shutdown, выходим
из режима конфигурирования. Тут-то и происходит "конвертирование
cisco-like конфигурации". Опять заходим в режим конфигурирования, даем no
shutdown, лип-ти-ти, пакеты ходят. Единственное, что нужно знать (на что я
наткнулся) cs_console некорректно переписывает файл интерфейса, если интерфейс
DOT1.Q. После проделывания данной операции исправьте файл
/etc/sysconfig/network-scripts/ethX.X. В мануале написано, что ONBOOT должно
быть равно FALSE. Я решил сделать true. После рубута интерфейс поднялся, но
пакеты опять не ходили. Сделал по мануалу - добавил в /etc/rc.local строчку
"/sbin/ifup ethX.X"
Как зашифровать (стандартный конфиг)
Конфигурацию для пробного запуска взял из
"RVPN_Quick_Start_Guide.pdf".
В первой схеме я разбил маршрутизатор на 2 vrf: LAN и
глобальный. Связующим звеном для них, как раз, являлся модуль RVPN. IPSEC
туннель стартовал в модуле одного рутера, заканчивался, соответственно, в
модуле другого. GRE туннель стартовал с внешних интерфейсов глобальной таблицы маршрутизации
рутеров. Таким образом, получалось, что заголовки GRE не шифровались, а
полезная нагрузка уже шла в виде ESP.
Получилось так:
Не самый подходящий вариант, поэтому я не стал на нем
останавливаться.
Замечу, что в этой схеме IPSEC туннель строится без
применения NAT, поэтому модуль без проблем заработал на конфиге из стартового
мануала.
Вторая схема.
Главное отличие второй схемы от первой в том, что GRE
туннель строится внутри шифрованного IPCES туннеля. IPSEC туннель строится с
"внешних" для данной схемы интерфейсов платы RVPN. Из схемы видно,
что эти интерфейсы являются внутренними для рутера и имеют private ip адреса.
Таким образом, мы подошли к тому, что нужно использовать NAT для организации
IPSEC туннеля.
И все было хорошо, пока не пришлось применить NAT.
Конфиг NAT на маршрутизаторе:
!
interface GigabitEthernet0/1.2141
description WAN
encapsulation dot1Q 2141
ip address 10.199.1.2 255.255.255.252
ip nat outside
ip virtual-reassembly in
!
interface
Special-Services-Engine1/0.33
description RVPN-EXTERNAL
encapsulation dot1Q 33
ip address 192.168.252.254 255.255.255.0
ip nat inside
ip virtual-reassembly in
!
ip nat
inside source list 99 interface GigabitEthernet0/1.2141 overload
ip nat
inside source static udp 192.168.252.1 500 10.199.1.2 500 extendable
ip nat
inside source static udp 192.168.252.1 4500 10.199.1.2 4500 extendable
access-list
99 permit 192.168.250.0 0.0.0.255
access-list
99 permit 192.168.252.0 0.0.0.255
access-list 99 permit 192.168.141.0 0.0.0.255
Для того, чтобы понять, что вообще происходит на модуле
RVPN, нужно в режиме cisco-like дать комманду "logging trap
debugging". С этого момента все происходящее можно смотреть в файле
"/tmp/cspvpngate.log".
Первое, с чем пришлось столкнуться на второй схеме -
проблема с идентификацией пира.
Проблема с идентификацией.
Jan 16
15:19:48 cspgate vpnsvc: Partner's VPN
Agent info: product: Gate; build: 3.1.10330; OS: Linux-RHEL5; CPU: i386
Jan 16
15:19:48 cspgate vpnsvc: IKE proposals
received from 10.199.1.2:500:
Jan 16
15:19:48 cspgate vpnsvc: Transform #1: Auth:Pre-Shared Key,
Cipher:(65534), Hash:(65534), Group:MODP_1024, Life Time:86400
Jan 16
15:19:48 cspgate vpnsvc: Check proposal
#1, Protocol ISAKMP, Transform #1 for Rule "IKE_CMAP_1", Proposal #1,
Protocol ISAKMP, Transform #1 - match
Jan 16
15:19:48 cspgate vpnsvc: IKE proposals
sent to 10.199.1.2:500:
Jan 16
15:19:48 cspgate vpnsvc: Transform #1: Auth:Pre-Shared Key,
Cipher:(65534), Hash:(65534), Group:MODP_1024, Life Time:86400
Jan 16
15:19:48 cspgate vpnsvc: [ISAKMP]: NAT
detected on remote side, Partner: 10.199.1.2:500
Jan 16
15:19:48 cspgate vpnsvc: [ISAKMP]: NAT
detected on local side, Partner: 10.199.1.2:500
Jan 16
15:19:48 cspgate vpnsvc: Using preshared
key "cs_key_10_199_1_2" for partner 10.199.1.2:500
Jan 16
15:19:48 cspgate vpnsvc: [ISAKMP]:
Identity "192.168.252.1" is received from partner 10.199.1.2:4500
Jan 16
15:19:48 cspgate vpnsvc: Unable to
choose authentication rule for partner 10.199.1.2:500
Jan 16
15:19:48 cspgate vpnsvc: [ISAKMP]:
Incoming connection FAILED. [Main Mode, Responder, Packets 5,6, Pre-Shared Key]
Check IDii ERROR, Partner: 10.199.1.2:4500
Смысл в том, что изначально он видит внешний адрес пира (в
нашем случае 10.199.1.2 считаем внешним), видит привязанный к нему ключ,
применяет его. Позже пир сообщает ему, что его настоящий адрес 192.168.252.1 и
он за NAT. Этот ищет как авторизовать адрес 192.168 и не находит, в результате
отвечая "Unable to choose authentication rule for partner". Вот как я
это понял.
Поискал на форуме S-terra подобные ошибки, нашел решение.
Необходимо в cisco_like конфиге заменить строку "crypto
isakmp identity address" на "crypto isakmp identity hostname",
обозначить hostname пира двумя адресами (внешним и внутренним) строчками
"ip host gw1 10.199.1.2", "ip host gw1 additional
192.168.252.1", поменять строчку ключа с "crypto isakmp key hMV21m4H
hostname 10.199.1.2" на "crypto isakmp key hMV21m4H hostname
gw1".
В результате решение выглядит так:
Было:
crypto
isakmp identity address
crypto
isakmp key hMV21m4H hostname 10.199.1.2
Стало:
crypto
isakmp identity hostname
ip host gw1
10.199.1.2
ip host gw1
additional 192.168.252.1
crypto
isakmp key hMV21m4H hostname gw1
Более он не ругался на идентификацию, но четко дал понять,
что протокол AH не работает через NAT.
Проблема с натом (AH не натится):
Jan 16
16:04:47 gw2 vpnsvc: [ISAKMP]:
Connection request FAILED. [Quick Mode, Initiator, Packet 1] [Get Local Policy]
ERROR, Partner: 10.199.1.2:4500, Identity: gw1
Jan 16
16:04:47 gw2 vpnsvc: Connection request
FAILED, Reason: AH and NAT are not compatible, ip: 10.199.1.2, Protocol: IPsec,
Stopped at: [Quick Mode, Initiator, Packet 1] [Get Local Policy]
Jan 16
16:04:49 gw2 vpnsvc: Connection request,
packet: 192.168.142.2->192.168.141.2, proto 1, FilteringRule:
"Filter_nil_acl_CMAP_1"
Jan 16
16:04:49 gw2 vpnsvc: [ISAKMP]:
Connection request FAILED. [Quick Mode, Initiator, Packet 1] [Get Local Policy]
ERROR, Partner: 10.199.1.2:4500, Identity: gw1
Jan 16
16:04:49 gw2 vpnsvc: Connection request
FAILED, Reason: AH and NAT are not compatible, ip: 10.199.1.2, Protocol: IPsec,
Stopped at: [Quick Mode, Initiator, Packet 1] [Get Local Policy]
Jan 16
16:04:51 gw2 vpnsvc: Connection request,
packet: 192.168.142.2->192.168.141.2, proto 1, FilteringRule:
"Filter_nil_acl_CMAP_1"
Нет, так нет. Убираем AH. Заменяем строку "crypto ipsec
transform-set gost ah-md5-hmac esp-des" строкой "crypto ipsec
transform-set gost esp-des".
Решение:
Было:
crypto
ipsec transform-set gost ah-md5-hmac esp-des
Стало:
crypto
ipsec transform-set gost esp-des
После этого IPSEC туннель поднялся, но не поднялся GRE. Я
упустил небольшой нюанс при создании туннеля из vrf. Я указал, что после
создание интерфейс tu33 помещается в vrf LAN, а вот то, что создается он из
этого же vrf, я не указал, и IOS пытался строить этот туннель из глобальной
таблицы маршрутизации. После добавления строчки "tunnel vrf LAN" все
завелось.
!
interface Tunnel33
ip vrf forwarding LAN
ip address 10.199.4.1 255.255.255.0
ip mtu 1476
ip tcp adjust-mss 1436
ip ospf network broadcast
ip ospf hello-interval 30
tunnel source 192.168.250.254
tunnel destination 192.168.249.254
tunnel vrf LAN
!
Вторая схема дебаг:
C2911-RND-INT#ping
vrf AVIA-LAN-R1 192.168.142.2
Type escape
sequence to abort.
Sending 5,
100-byte ICMP Echos to 192.168.142.2, timeout is 2 seconds:
!!!!!
Success
rate is 100 percent (5/5), round-trip min/avg/max = 4/4/4 ms
C2911-RND-INT#ping
vrf AVIA-LAN-R1 10.199.2.2
Type escape
sequence to abort.
Sending 5,
100-byte ICMP Echos to 10.199.2.2, timeout is 2 seconds:
!!!!!
Success
rate is 100 percent (5/5), round-trip min/avg/max = 1/2/4 ms
--
C2911-RND-INT#traceroute
vrf AVIA-LAN-R1
Protocol
[ip]:
Target IP
address: 10.199.2.2
Source
address: 192.168.141.2
Numeric
display [n]:
Resolve AS
number in (G)lobal table, (V)RF or(N)one [G]:
Timeout in
seconds [3]:
Probe count
[3]:
Minimum
Time to Live [1]:
Maximum
Time to Live [30]:
Port Number
[33434]:
Loose,
Strict, Record, Timestamp, Verbose[none]:
Type escape
sequence to abort.
Tracing the
route to 10.199.2.2
VRF info:
(vrf in name/id, vrf out name/id)
1 192.168.141.1 0 msec 4 msec 0 msec
2 192.168.250.1 0 msec 0 msec 0 msec
3 192.168.252.254 4 msec 4 msec 0 msec
4 10.199.1.1 4 msec 4 msec 0 msec
C2911-RND-INT#traceroute
vrf AVIA-LAN-R1
Protocol
[ip]:
Target IP
address: 192.168.142.2
Source address:
192.168.141.2
Numeric
display [n]:
Resolve AS
number in (G)lobal table, (V)RF or(N)one [G]:
Timeout in
seconds [3]:
Probe count
[3]:
Minimum
Time to Live [1]:
Maximum
Time to Live [30]:
Port Number
[33434]:
Loose,
Strict, Record, Timestamp, Verbose[none]:
Type escape
sequence to abort.
Tracing the
route to 192.168.142.2
VRF info:
(vrf in name/id, vrf out name/id)
1 192.168.141.1 0 msec 4 msec 0 msec
2 10.199.4.2 4 msec 4 msec 4 msec
3 192.168.142.2 4 msec * 4 msec
Теперь получилось так:
На этом можно было бы остановиться, но мне не понравились
два лишних хопа при направлении пакета в интернет. В интернет пакеты летят
через модуль RVPN. Можно было сделать линк между vrf вланами через коммутатор и
два интерфейса рутера, либо рут мапом перекинуть пакеты куда нужно, но у
клиента коммутатор не поддерживает вланы, а рут мапом тоже не очень красиво
получается из-за NAT. Итак, в данном случае нет никакой нужды использовать
разбиение на vrf.
Третья схема.
После всех проб и ошибок образовалась простая и понятная
схема. Как оказалось, именно она рассматривается первой в одном из мануалов по
настройке site_to_site туннеля между рутерами с использованием модуля RVPN.
Но и тут небольшая проблемка. Падает ospf сессия в туннеле.
Долго думать не пришлось. Приходит маршрут на сеть, в которой лежит адрес
назначения туннеля, из-за чего ospf ругается на петлю "looped chain
attempting to stack" и кладет сессию. Все решилось добавлением запрета на
аннонс этой сети посредством использования distribute-list.
Проблема с падением ospf.
looped
chain attempting to stack
Решение: не анонсировать маршрут назначения туннеля в сам
туннель.
QOS
Остался последний штрих - настроить QOS. В одном офисе
подключение 5 mbps, в другом adsl 8/1 (1 mbps исходящий). Используем политику
для классификации на входе и иерархический шедулер на выходе.
Router1:
class-map
match-all GW1TOGW2TUN
match access-group name RVPN-IN
!
class-map
match-all TUNNEL-INET-OUT-CLASS
match access-group name TUNNEL-INET-OUT
!
policy-map
mark-input
class GW1TOGW2TUN
set ip precedence 4
!
policy-map
GW1-OUT
class TUNNEL-INET-OUT-CLASS
bandwidth percent 70
class class-default
fair-queue 32
!
policy-map
GW1-OUT-PARENT
class class-default
shape average 5000000
service-policy GW1-OUT
!
ip
access-list extended RVPN-IN
permit udp any any eq isakmp
permit udp any any eq non500-isakmp
permit esp any any
!
ip
access-list extended TUNNEL-INET-OUT
permit ip any any precedence flash-override
!
!
interface
GigabitEthernet0/1.2141
description WAN
encapsulation dot1Q 2141
ip address 10.199.1.2 255.255.255.252
ip nat outside
ip virtual-reassembly in
service-policy output GW1-OUT-PARENT
!
Debug:
C2911-GW1#show
policy-map interface gigabitEthernet 0/1.2141
GigabitEthernet0/1.2141
Service-policy output: GW1-OUT-PARENT
Class-map: class-default (match-any)
15112 packets, 6977168 bytes
5 minute offered rate 163000 bps, drop
rate 0 bps
Match: any
Queueing
queue limit 64
packets
(queue depth/total drops/no-buffer drops)
0/0/0
(pkts output/bytes output) 15112/6977168
shape (average) cir 5000000, bc 20000, be
20000
target shape rate 5000000
Service-policy :
GW1-OUT
Class-map: TUNNEL-INET-OUT-CLASS
(match-all)
15112 packets, 6977168 bytes
5 minute offered rate 163000 bps,
drop rate 0 bps
Match: access-group name
TUNNEL-INET-OUT
Queueing
queue limit 64 packets
(queue depth/total drops/no-buffer
drops) 0/0/0
(pkts output/bytes output)
15112/6977168
bandwidth 70% (3500 kbps)
Class-map: class-default (match-any)
0 packets, 0 bytes
5 minute offered rate 0 bps, drop
rate 0 bps
Match: any
Queueing
queue limit 64 packets
(queue depth/total drops/no-buffer
drops/flowdrops) 0/0/0/0
(pkts output/bytes output) 0/0
Fair-queue: per-flow queue limit 16
Maximum Number of Hashed
Queues 32
C2911-GW1#show
policy-map interface Special-Services-Engine 1/0
Special-Services-Engine1/0
Service-policy input: mark-input
Class-map: GW1TOGW2TUN (match-all)
15171 packets, 6923154 bytes
5 minute offered rate 0 bps, drop rate 0
bps
Match: access-group name RVPN-IN
QoS Set
precedence 4
Packets marked 15171
Class-map: class-default (match-any)
12079 packets, 6262861 bytes
5 minute offered rate 0 bps, drop rate 0
bps
Match: any
C2911-GW1#show
ip access-lists
Standard IP
access list 99
10 permit 192.168.35.0, wildcard bits
0.0.0.255 (8 matches)
20 permit 10.199.5.252, wildcard
bits 0.0.0.3 (2 matches)
Extended IP
access list RVPN-IN
10 permit udp any any eq isakmp (3365
matches)
20 permit udp any any eq non500-isakmp
(30482 matches)
30 permit esp any any
Extended IP
access list TUNNEL-INET-OUT
10 permit ip any any precedence
flash-override (15168 matches)
Router2:
class-map
match-all GW2TOGW1TUN
match access-group name RVPN-IN
!
class-map
match-all TUNNEL-INET-OUT-CLASS
match access-group name TUNNEL-INET-OUT
!
policy-map
mark-input
class GW2TOGW1TUN
set ip precedence 4
!
policy-map
GW2-OUT
class TUNNEL-INET-OUT-CLASS
bandwidth percent 70
class class-default
fair-queue 32
!
policy-map
GW2-OUT-PARENT
class class-default
shape average 1000000
service-policy GW2-OUT
!
ip
access-list extended RVPN-IN
permit udp any any eq isakmp
permit udp any any eq non500-isakmp
permit esp any any
!
ip
access-list extended TUNNEL-INET-OUT
permit ip any any precedence flash-override
!
interface
GigabitEthernet0/1.2142
description WAN
encapsulation dot1Q 2142
ip address 10.199.2.2 255.255.255.252
ip nat outside
ip virtual-reassembly in
service-policy output GW1-OUT-PARENT
!
Вот и всё.
пздц
ОтветитьУдалить