初始网络拓扑
公司总部网关CCR1009上有固定公网IP地址。有一办公室网关需要通过隧道访问公司总部内网资源。办公室网关的互联网连接经过运营商设备的动态NAT(PAT),网关上只能分到内网IP,并且互联网出口IP会不定期变化。
设备的基线配置如下:
RouterOS
1 2 |
/ip address add address=192.0.2.1/24 interface=ether1 network=192.0.2.0 |
IOS XE
PPPoE拨号,并且在互联网出口做一下Dynamic PAT。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
interface GigabitEthernet0/0/1 no ip address negotiation auto pppoe enable group global pppoe-client dial-pool-number 1 ! interface Dialer1 ip address negotiated ip mtu 1480 ip nat outside encapsulation ppp ip tcp adjust-mss 1432 dialer pool 1 dialer-group 1 ppp authentication pap callin ppp pap sent-username usernAme password passw0rd ip virtual-reassembly ! ip nat inside source route-map nat-pppoe interface Dialer1 overload ! ip route 0.0.0.0 0.0.0.0 Dialer1 ! ip access-list standard nat-inside-ip permit 192.168.1.1 0.0.0.255 ! route-map nat-pppoe permit 10 match ip address nat-inside-ip match interface Dialer1 |
计划
因为需要支持IPSec NAT-T,这里必须使用tunnel模式。IPSec运行在tunnel模式下时,两侧的设备各有一个tunnel内部IP;当一台设备向另一台设备的tunnel内部IP发送数据时,数据会被traffic selector选中,加密后发送至对面设备的互联网地址。RouterOS和大多数Linux系统都能手工设置tunnel内部IP;但是IOS系列设备的IPSec tunnel模式不能自由设置tunnel内部IP,当它运行在tunnel模式下时,默认的tunnel内本地IP是IPSec源interface的IP,对端IP就是对端的真实IP。也就是说,虽然IPSec运行在tunnel模式下,但是操作起来和transport模式没有区别,只是多了NAT-T功能。这样的设定虽然少了一些自由度,但是省两个IP呀。
在IOS一端的默认路由所在端口IP是动态分配的时候,这样的设定就带来了一个新问题:如果我们直接用Dialer1上拿到的IP地址作为IPSec的源地址,那么对端traffic selector的目标地址就会变,RouterOS在这种情况下很难处理其上GRE隧道的对端IP。所以我们这里要做一个简单的workaround。只要我们用一个固定的loopback地址作为源地址发起IPSec隧道连接。这样,IOS这边提交的traffic selector就会是:
- 源地址:loopback地址
- 目标地址:RouterOS公网地址
- 协议:47
而我们在RouterOS那边设置IPSec Template为:
- 源地址:RouterOS公网地址
- 目标地址:0.0.0.0/0
- 协议:47
这样就正好能match,并且IPSec tunnel内两端IP地址均固定不变。
IKEv2配置
RouterOS服务器端
一个很标准的Roadwarrior IPSec VPN配置。Traffic Selector那边需要注意的是只通过SA source address来识别对端,别的都填0.0.0.0/0让对面发。(其实用source address来识别对端也行,看具体需要怎么认证客户端。)
1 2 3 4 5 6 7 8 9 10 11 12 13 |
/ip ipsec policy group add name=vpn /ip ipsec profile add dh-group=modp3072 enc-algorithm=aes-128 hash-algorithm=sha256 lifebytes=1000000000 lifetime=1 name=vpn /ip ipsec peer add exchange-mode=ike2 name=vpn passive=yes profile=vpn /ip ipsec proposal add auth-algorithms=sha256 enc-algorithms=aes-128-cbc name=vpn pfs-group=modp3072 /ip ipsec identity add generate-policy=port-override notrack-chain=prerouting peer=vpn policy-template-group=vpn secret=passw0rd remote-id=fqdn:remote-office.contoso.com /ip ipsec policy set 0 disabled=yes add dst-address=0.0.0.0/0 group=vpn proposal=vpn protocol=gre sa-src-address=192.0.2.1 src-address=0.0.0.0/0 template=yes |
IOS XE端
IKE参数和RouterOS一侧相同即可。新的VTI语法可以自动创建Traffic Selector,只需要保证隧道源IP都存在,ISAKMP就会启动。注意:
- 新增的Loopback接口也需要配置PAT(IP需要加入PAT的access-list,接口上配置ip nat inside)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
crypto ikev2 proposal office encryption aes-cbc-128 integrity sha256 group 15 ! crypto ikev2 policy office match fvrf any proposal office ! crypto ikev2 keyring office-keys peer office address 192.0.2.1 pre-shared-key local passw0rd pre-shared-key remote passw0rd ! ! crypto ikev2 profile office match identity remote address 192.0.2.1 255.255.255.255 identity local fqdn remote-office.contoso.com authentication remote pre-share authentication local pre-share keyring local office-keys ! crypto ikev2 nat keepalive 10 crypto ikev2 dpd 10 2 periodic ! crypto ipsec transform-set office esp-aes esp-sha256-hmac mode tunnel crypto ipsec df-bit clear ! crypto ipsec profile office set security-association lifetime seconds 3600 set security-association lifetime kilobytes 1000000 set transform-set office set ikev2-profile office ! interface Loopback0 ip address 192.168.2.1 255.255.255.255 ip nat inside ! ip access-list standard nat-inside-ip permit 192.168.1.1 0.0.0.255 permit 192.168.2.1 0.0.0.255 |
如果想用老的crypto map方式配置的话,也是可以的:
- crypto map对应的access-list需要放行全部可能通过GRE隧道的流量(这里因为没有配内网路由,所以就只放行了GRE两侧的IP)
- 修改过crypto map以后,需要重启所有关联该crypto map的接口
1 2 3 4 5 6 7 8 9 10 11 12 |
crypto map office 10 ipsec-isakmp set peer 192.0.2.1 set transform-set office set ikev2-profile office match address office-ipsec ! interface Dialer1 shutdown crypto map office no shutdown ip access-list extended office-ipsec permit ip host 192.168.3.3 host 192.168.3.2 |
GRE配置
IPSec隧道建立起来以后,用IOS XE一侧的Loopback IP和RouterOS一侧的公网IP建立一个GRE隧道即可。GRE隧道内的IP就比较随意了,配成点对点或者带广播都行啦。注意RouterOS的GRE默认会开Keepalive,IOS XE则需要单独配置一下。以下写一个简单的例子:
RouterOS端
1 2 |
/interface gre add local-address=192.168.3.2 name=gre-remote remote-address=192.168.3.3 |
IOS XE端
因为我们强制设定了TS的本地侧IP是Loopback0的IP,在VTI端口上也要相应设置local-address,否则ISAKMP匹配不到东西就不会生效。
1 2 3 4 5 6 7 8 |
interface Tunnel1 ip address 192.168.3.3 255.255.255.254 ip tcp adjust-mss 1370 keepalive 10 10 tunnel source Loopback0 tunnel destination 192.0.2.1 tunnel protection ipsec profile office tunnel protection ipsec local-address Loopback0 |
验证配置
RouterOS一侧应该能看到由template生成的policy:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
> /ip ipsec policy print Flags: T - template, X - disabled, D - dynamic, I - invalid, A - active, * - default 0 TX* group=default src-address=::/0 dst-address=::/0 protocol=all proposal=default template=yes 1 T group=james src-address=192.0.2.1/32 dst-address=0.0.0.0/0 protocol=gre proposal=vpn template=yes 2 DA src-address=192.0.2.1/32 src-port=any dst-address=192.168.2.1/32 dst-port=any protocol=gre action=encrypt level=unique ipsec-protocols=esp tunnel=yes sa-src-address=192.0.2.1 sa-dst-address=192.0.2.2 proposal=vpn ph2-count=1 |
如果policy没有生成出来,但是remote peers里面能看到连接,说明crypto map或者其关联的access-list配错了。改完crypto map记得重启一下关联的interface。
IOS XE一侧检查一下SA:
1 2 3 4 5 6 7 8 9 |
Router#show crypto ikev2 sa IPv4 Crypto IKEv2 SA Tunnel-id Local Remote fvrf/ivrf Status 1 192.168.2.1/4500 192.0.2.1/4500 none/none READY Encr: AES-CBC, keysize: 128, PRF: SHA256, Hash: SHA256, DH Grp:15, Auth sign: PSK, Auth verify: PSK Life/Active Time: 86400/4036 sec IPv6 Crypto IKEv2 SA |
互相ping一下,应该就通啦。
IKEv2自恢复
这个版本的IOS XE有个bug,每一到两天它会忘记rekey一次,导致Tunnel断开。因为我在Tunnel里面跑了BFD,基本上断开以后它就会立即line-protocol down,所以我们用EEM写个脚本来自动触发rekey:
1 2 3 4 5 6 7 8 |
track 2 interface Tunnel1 line-protocol delay down 5 ! event manager applet TUNNEL1_REKEY event track 2 state down action 1 syslog priority warnings msg "auto-rekey tunnel1" action 2 cli command "enable" action 3 cli command "clear crypto sa" |
感谢某匿名CCNP玩家在本文写作过程中提供的帮助。
参考: