[网络] 基于OpenSwan 在AWS上构建高可用Site to Site VPN

[网络] 基于OpenSwan 在AWS上构建高可用Site to Site VPN

自动化高可靠Openswan on AWS - IPsec VPN 解决方案 - v2

背景

VPN种类

  1. 一类是工作于客户端到服务端(Remote Access)的模式,像OpenVPN,SSL VPN,L2TP,PPTP这些都是需要客户端主动发起连接,拨到Server端在两者之间建立一个逻辑上的隧道 (tunnel)进行通信。这种方式一般适用于个人到总部场景。服务器是无法主动发起连接到客户端。
  2. 另外一种就是站点到站点(Site-to-Site)的模式,像OpenSwan,StrongSwan, Raccoon 等软件,这种情况下两端会各有一个设备负责来建立两个站点之间安全通信的隧道,任何需要到对端的通信都会触发设备来建立安全隧道通信。那么公司原有数据中心与云通信都是双向通信,所以站点到站点更合理。

IPsec VPN

IPsec VPN 通常被认为是两设备通信的最安全的方式之一,它在网络级别对通信进行签名和加密。包的签名,确保发送的信息在传输过程中没有被篡改,是由认证头(AH)加密协议处理的。数据包的加密防止了数据的窥探是由封装安全有效载荷(ESP)协议来处理的。这两个协议都使用Internet密钥交换(IKE)在两个设备之间提供相互身份验证。

IPSec实际上消除了可能的中间人攻击,即某人将自己置于两个设备之间,假装是设备a到设备B,反之亦然。通过这种方式可以解密并读取所有的通信。另外IPsec VPN 是一种工业标准,只要支持这种标准的设备都可以互相协商建立一个安全的隧道出来,支持的硬件设备有路由器,防火墙以及专业的 VPN 设备。

本解决方案主要想解决的问题是为企业用户提供 Site to Site VPN的解决方案,所以主要涉及到 IPSec VPN该类。

方案特点

  • 满足 AWS 中国区域无法提供 IPsec 托管服务
    • 由于 AWS 中国区域无法提供 IPsec 托管服务,可借助该方案满足用户的需求。
  • 自动化一键部署
    • 基于AWS CloudFormation脚本一键部署,相比手动配置,更简单,更不易出错而且速度更快。
  • 高可靠
    • 方案自带高可靠模块(Keepalived),可自动检测主节点 IPsec 进程是否正常运行,一旦IPsec 进程不能提供服务,则系统自动进行主从节点的切换,确保系统的高可用。
  • 可用作Direct Connect备份
    • 在Direct Connect出现故障时,自动切换至VPN链路。
  • 无需额外开销
    • 整个方案完全基于开源软件(OpenSwan和Keepalived)进行搭建。客户无需支付除了AWS资源以外的任何费用。
  • 可高度定制化
    • 完全基于开源软件,SA 或用户可以在此基础上进行定制化改造。
    • 在自动化部署的同时,也同时给予客户最大的控制VPN各项参数的自主权。
    • 适用于与云下数据中心中的VPN设备互通时,云下设备不能更改VPN参数配置的场景。
  • 自带验证模块
    • 本解决方案可帮助用户提前进行方案测试,在系统上线之前验证响应的功能。
    • 本方案除了带有部署实际使用的VPN场景的模块。另一个则是为如果客户希望在部署之前测试功能而部署的测试场景模块。

使用场景

场景 1:作为 DirectConnect 的备份方案

配置一个备用IPSec VPN 连接,以作为 AWS Direct Connect 连接的备份。在 AWS Direct Connect 发生故障时,用户仍旧可以使用 IPsec VPN 的方式连接到 AWS VPC。作为一种自动化的临时解决方案

场景 2: 打通AWS 云上资源和IDC云下资源

在业务场景对网络质量(延迟,稳定带宽等)要求不高时,客户往往希望可以通过一个简单快速的方式打通云下IDC资源和云上AWS VPC中的资源。不仅如此,客户还希望这种方案可以尽量的简单且具备一定的高可靠性

架构设计

架构描述

Openswan 主要提供 IPSec VPN 的功能,本解决方案中提供 Master-Slave 高可用模式。在 Master 节点出现故障时,采用 EIP 飘移的方式,让 Slave 节点接管 Master 节点,继续对外提供服务。

使用 Cloudformation 自动部署后,将创建如下资源。

  1. VPC
    1. 为了便于部署,本解决方案使用创建全新 VPC 的方式。
  2. 公有子网和私有子网
    1. 为确保系统的高可用,分别在两个可用区创建 4 个子网。其他 2 个公有子网,2 个私有子网。
    2. 公有子网和私有子网的路由表分别设置好
  3. 2 台 EC2实例,分别分布于两个公有子网
    1. 在 10.50.0.0/24 网段创建 OpenSwan Master 节点 ,私有 IP 是 10.50.0.8
      1. 同时运行 Keepalived 软件,设置为 Master 节点
      2. Keepalived 服务监控 IPsec 进程 (/usr/libexec/ipsec/pluto),如果pluto 进程丢失,则进行切换。
    2. 在 10.50.1.0/24 网段创建 OpenSwan Slave 节点 ,私有 IP 是 10.50.1.8
      1. 同时运行 Keepalived 软件,设置为 Slave 节点
      2. 如果 keepalived 接管,则升级问 Master 节点,重启 IPSec 服务,继续提供服务。

组件

本解决方案的架构主要依赖于两个核心组件

  1. OpenSwan
  2. Keepalived

组件 1:Openswan

使用开源的openswan搭建Host_to_Host基于Ipsec RSA加密的Tunnel,用于保障主机之间数据传输的机密性。 openswan由2个组建构成:KLIPS和Pluto。KLIPS是执行加密解密数据的内核级代码,同时管理SPD(Security Policy Databases,安全策略数据库);Pluto是用户登录守护进程,控制IKE(Internet Key Exchange,因特网密钥交换)协商。

为什么选择 Openswan? 另外经过测试,OpenSwan在宁夏 Region及 北京 Region很容易安装。而用对于同类的 IPSec VPN 软件,例如 Strongswan,你不能简单的使用 yum的方式来进行安装。同时相比于 Strongswan,OpenSwan 则更容易使用, 因为不会像Strongswan必须在Linux中配置额外的路由表。

组件 2:Keepalived

Keepalived是一个免费开源的,主要提供loadbalancing(负载均衡)和 high-availability(高可用)功能,负载均衡实现需要依赖Linux的虚拟服务内核模块(ipvs),而高可用是通过VRRP协议实现多台机器之间的故障转移服务。

VRRP协议

网络在设计的时候必须考虑到冗余容灾,包括线路冗余,设备冗余等,防止网络存在单点故障,那在路由器或三层交换机处实现冗余就显得尤为重要,在网络里面有个协议就是来做这事的,这个协议就是VRRP协议,Keepalived就是巧用VRRP协议来实现高可用性(HA)的。

AWS中VRRP协议的组播被禁止,也就是说keepalived需要调整心跳的通知方式,修改/etc/keepalived/keepalived.conf配置文件中的通知为单播模式。

配置文件/etc/keepalived/keepalived.conf 如下:

1unicast_src_ip ${OpenSwanMasterPrivateIP}
2
3                unicast_peer 
4                {
5                    ${OpenSwanSlavePrivateIP}
6                }

KeepAlived切换原理

  1. OpenSwan 的 Master和 Slave 节点都分别运行 Keepalived 服务。
  2. Maste 节点监控 /usr/libexec/ipsec/pluto 进程,如果该进程不存在,说明 IPsec 服务不正常,需要进行切换
  3. Master 节点调用/etc/keepalived/failover.sh的脚本进行 EIP 地址飘移。把 EIP 赋给 Slave 节点, 并发送 SNS 消息
  4. /etc/keepalived/failover.sh 代码如下
 1#!/bin/bash
 2TYPE=$1
 3NAME=$2
 4STATE=$3
 5
 6case $STATE in
 7        "MASTER")
 8            sudo /usr/sbin/service ipsec start
 9            sudo echo "master state and start ipsec vpn"
10            exit 0
11            ;;
12        "BACKUP") EIP=52.83.187.14
13            INSTANCE_ID=i-03c47cd693eac6dd8
14            echo "********************************"
15            sudo aws sns publish  --topic-arn "arn:aws-cn:sns:cn-northwest-1:880019753204:OpenSwanHAStatusSNS"  --message "OpenSwanVPN Master server Down and switched to Slave server."  --region cn-northwest-1
16            sudo aws ec2 disassociate-address --public-ip 52.83.187.14 --region cn-northwest-1
17            sudo aws ec2 associate-address --public-ip 52.83.187.14 --instance-id i-03c47cd693eac6dd8 --region cn-northwest-1
18            exit 0
19            ;;
20esac

系统部署

创建本地数据中心模拟环境

为了方便大家测试,特提供两种模拟环境。

模拟环境 1:使用自动化脚本创建基于Openswan的数据中心模拟环境

如果客户希望测试VPN对接的是开源产品,或者客户的测试团队是开发团队,对传统网络设备并不是很熟悉。那么客户可能会需要我们提供一个一键化配置的VPN测试环境。这部分就是专门针对这种需求的客户准备的

为了在云端搭建和测试 OpenSwan 高可用,首先需要先获得本地数据中心或者对端的IPSec VPN设备信息。为了方便演示,模拟环境在 BJS Region创建,该模拟环境是为了模拟本地数据中心的环境。当然,您也可以使用1.2部分提供的传统网络VPN设备来进行测试 模拟场景如下图所示。在 public subnet 10.100.0.0/24的网段创建一台 EC2, 该 EC2 已经安装好 Openswan 用于模拟本地数据中心的网络设备。在真实的环境中,请使用本地数据中心网络设备的实际信息。

本解决方案提供了一个Cloudformation yaml 文件方便搭建测试环境。 https://cn-north-1.console.amazonaws.cn/cloudformation/home?region=cn-northwest-1#/stacks/create/template?stackName=openswanonpremtest&templateURL=https:%2F%2Faws-industry-solutions-reference.s3.cn-north-1.amazonaws.com.cn%2Fopenswan-on-aws%2Fv1.0.0%2Fopenswan-on-prem-test.yaml

具体 cloudformation 操作步骤可参考 创建 AWS 端 OpenSwan HA 环境 部分。

如上图所示,测试环境是右半部分(在 BJS Region搭建,仍旧使用两个 AZs)。该测试环境模拟本地数据中心的网络环境。 本地数据中心的 CIDR 为 10.100.0.0/16

输入参数:

<b><f textcolor="#16191f">键</f></b> <b><f textcolor="#16191f">值</f></b> <b><f textcolor="#16191f">已解析的值</f></b>
AvailabilityZones cn-north-1a,cn-north-1b 为了确保系统高可用,所以需要选择两个可用区。分别在两个可用区中创建公有子网及私有子网。
--- --- ---
CustomIdentifier OpenSwan -
IPSECPhaseIImodp modp1024 -
IPSECSALifeTime 3600s -
IPSecIKE aes256-sha1 -
IPSecIKELifeTime 86400s -
IPSecIKEmodp modp1024 -
IPSecPhaseII esp -
IPSecPhaseIIAlg aes256-sha1 -
IPSecSharedSecret psk123 -
KeypairName awskey -
LocalSubnet 10.100.0.0/16 -
OpenSwanInstanceType t2.medium -
OpenSwanMasterPrivateIP 10.100.0.8 指定测试 Openswan 节点的内网 IP 地址
OpenSwanMasterSubnetCIDR 10.100.0.0/24 -
OpenSwanSlaveSubnetCIDR 10.100.1.0/24 -
PrivateSubnet1CIDR 10.100.2.0/24 -
PrivateSubnet2CIDR 10.100.3.0/24 -
RemoteDataCenterServerIP 13.114.8.208 这里的 IP 地址,其实是 IPsec 对端的公网 IP地址。由于对端尚未创建,所以先使用 13.114.8.208 作为占位符。等待两端联调时再进行修改。(一般情况下,如果对端是IDC数据中心,VPN设备的外网地址是确认好的)
RemoteDataCenterSubnet 10.50.0.0/16 -
VPCCIDR 10.100.0.0/16 -

在 BJS 创建完堆栈后,相关的资源如下图所示。 可以看到EIP是 52.81.173.204,该地址将被作为 OpenSwan HA 环境的输入变量,该用于模拟本地数据中心用于承接 IPsec网络设备的公网 IP 地址。

模拟环境 2: Cisco CSR1000v模拟数据中心VPN设备

使用AWS Marketplace上的 Cisco CSR1000v模拟数据中心VPN设备。具体配置信息见: 参考文档及配置:VPN Backup for DX Maintenance

如果客户希望测试VPN对接的是商用产品,或者客户测的VPN配置人员是一个负责传统厂商的网络工程师,具备很强的网络厂商设备的配置能力。那么客户可能会需要我们提供一个网络设备的配置参考手册。这部分就是专门针对这种需求的客户准备的

模拟IDC的VPN设备上选择的是Cisco的虚拟路由器(CSR 1000v)。之所以选择思科路由器作为模拟IDC数据中心设备的首选,首先是因为业界现在的网络工程师绝大部分是学习思科配置出身,只要有思科路由器的标准配置,那么他们就可以方便的对照出其他厂家产品的配置。其次,因为Cisco CSR1000v已经在AWS中国区的marketplace上可以进行部署,在性能不超过100Mbps的情况下可以免license进行测试(EC2的使用还是需要付费)。

故而这里选择了思科的虚拟路由器作为非开源VPN产品的模拟器。 在AWS上选择测试机型时,在AWS Marketplace中选择Cisco Cloud Service Router(CSR 1000V)作为模拟IDC的VPN设备 下面是Cisco CSR1000v关于VPN的基本配置。(其配置依照默认CloudFormation模板进行部署,如果有参数上的差异,可以参考下面的配置直接修改相关的内容)

CSR1000v的IPSec Tunnel配置一共分为4个步骤

  1. **配置 ISAKMP profile **(IKE Phase 1)
  2. **配置 IPSec profile **(IKE Phase 2)
  3. 配置感兴趣流
    1. 即配置AWS云端和本地数据中心要访问的网段,当数据包的源和目的IP符合感兴趣流的定义时,即会触发IPSec VPN。否则VPN设备会按照正常流量从非VPN通道发送处理
  4. 在接口上启用IPSec

I****KE Phase 1 (Configure ISAKMP) Internet密钥交换(IKE)建立共享的安全策略和已认证的密钥。 Internet安全协会和密钥管理协议(ISAKMP)是用于指定密钥交换机制的协议。 ISAKMP生成一个哈希值,并在另一端共享它,以检查它是否相同。 两个密钥应匹配以启动连接。

IKE Phase 2 (Configure IPSec) IPsec是在IP层设置的,通常用于允许对网络的安全远程访问。 IPsec主要利用隧道模式来创建VPN隧道。 IPsec通过在VPN的网络级别提供身份验证,加密和压缩服务,默认情况下在VPN连接上提供了增强的安全级别。 对于每个传出IP数据包,将使用IPsec数据包对其进行封装和保护。

参考配置 1. Configure IPSec VPN

 1`$ config t`
 2`Enter configuration commands, one per line. End with CNTL/Z`
 3
 4`crypto isakmp policy 100`
 5`encr aes 256`
 6`authentication pre-share`
 7`group 2`
 8`lifetime 86400`
 9
10`crypto isakmp key psk123 address 52.80.75.132`
11
12`crypto ipsec transform-set TRAN esp-256-aes esp-sha-hmac`
13`mode tunnel`
14
15`crypto map OpenSwan 10 ipsec-isakmp`
16`set peer 52.80.75.132`
17`set transform-set TRAN`
18`match address 100`

2. Configure Access list for tag VPN traffic

1`access-list 100 permit ip 10.100.0.0 0.0.255.255 10.50.0.0 0.0.255.255`

3. enable IPSec in interface

1`interface GigabitEthernet1`
2`ip mtu 1400`
3`ip tcp adjust-mss 1360`
4`crypto map OpenSwan`

在CSR1000v上验证 IPSec 的状态 直接在CSR1000v上ping对端的私网地址。如果VPN tunnel成功建立,那么两端的IP私网网段也是互通的 show crypto isakmp sa show crypto ipsec sa

方案部署

部署前提

  1. 本地数据中心端:需要确定好本地数据中心或IPsecvpn 对端设备的相关网络信息
    1. 数据中心相关
      1. 数据中心路由器公网 IP 地址
      2. 数据中心路由器后端私有网络CIDR
      3. IPSecSharedSecret

参数说明

CloudFormation 参数

参数 说明
AvailabilityZones cn-northwest-1a,cn-northwest-1b 为了确保系统高可用,所以需要选择两个可用区。分别在两个可用区中创建公有子网及私有子网
--- --- ---
CustomIdentifier OpenSwan 本解决方案创建资源的前缀,标志资源。
IPSECPhaseIImodp modp1024 -
IPSECSALifeTime 3600s -
IPSecIKE aes256-sha1 -
IPSecIKELifeTime 86400s -
IPSecIKEmodp modp1024 -
IPSecPhaseII esp -
IPSecPhaseIIAlg aes256-sha1 -
IPSecSharedSecret psk123 -
KeypairName ningxia -
LocalSubnet 10.50.0.0/16 -
OpenSwanInstanceType t2.micro -
OpenSwanMasterPrivateIP 10.50.0.8 -
OpenSwanMasterSubnetCIDR 10.50.0.0/24 -
OpenSwanSlavePrivateIP 10.50.1.8 -
OpenSwanSlaveSubnetCIDR 10.50.1.0/24 -
PrivateSubnet1CIDR 10.50.2.0/24 -
PrivateSubnet2CIDR 10.50.3.0/24 -
RemoteDataCenterServerIP 52.81.173.204 该 IP 地址是创建本地数据中心模拟环境时所输出的对端 Openswan 的公网 IP 地址。
RemoteDataCenterSubnet 10.100.0.0/16 -
SNSEmail test@amazon.com 该邮件地址用于接收 Openswan master 及 slave 节点在发生故障时用于接收通知
VPCCIDR 10.50.0.0/16 -

AWS 端实际部署架构图

使用 CloudFormation创建资源

使用该 Cloudformation 进行,可以点击该按钮进行直接部署。默认情况下,该模板将在 AWS (宁夏)区域启动。 若需在其他AWS区域中启动该解决方案,请使用控制台导航栏中的区域选择器。

1. 点击链接直接部署 https://cn-northwest-1.console.amazonaws.cn/cloudformation/home?region=cn-northwest-1#/stacks/create/template?stackName=openswan&templateURL=https:%2F%2Faws-industry-solutions-reference.s3.cn-north-1.amazonaws.com.cn%2Fopenswan-on-aws%2Fv1.0.0%2Fopenswan-main-china.yaml
  1. 创建堆栈

指定堆栈详细信息

配置堆栈选项 (保持默认值)

审核堆栈

确保勾选 如下两个 checkbox 我确认,AWS CloudFormation 可能创建具有自定义名称的 IAM 资源。 我确认,AWS CloudFormation 可能需要以下功能: CAPABILITY_AUTO_EXPAND 等待 6 分钟左右,堆栈创建完成。如下的资源会被创建。

相关的输出如下

<b><f textcolor="#16191f">键</f></b> <b><f textcolor="#16191f">值</f></b> <b><f textcolor="#16191f">描述</f></b> <b><f textcolor="#16191f">导出名称</f></b>
EC2OpenSwanMasterInstanceEIP 161.189.168.31 Public IP address of the vpn server -
--- --- --- ---
EC2OpenSwanMasterInstancePrivateIP 10.50.0.8 Private IP address of the vpn server -
EC2OpenSwanSlaveInstancePrivateIP 10.50.1.8 Private IP address of the vpn server -
IPSecSharedSecret psk123 The shared key for the VPN connection (IPSec)

现在已经得到 Openswan HA 的 EIP 地址。由于该 EIP 地址关联到 Master Node (该 Node 的 Private IP 地址是 10.50.0.8)

SNS 确认订阅

为了便于及时收到消息,该解决方案会创建 SNS 主题。在堆栈创建成功后,会收到 SNS的确认订阅邮件。 点击 Confirm subscription 链接。订阅确认。只有确认 SNS 订阅后,才能收到响应的邮件通知。

确认后,在 AWS Console 中的 主题状态如下图所示已确认。

更改本地数据中心模拟环境Openswan 设置

在使用 Cloudformation 在 AWS 中创建好 Openswan on AWS HA 的环境后,需要得到AWS 端的 Openswan 集群的 EIP, 并需要在本地数据中心IPsec端进行响应的配置。 主要需要修改 如下文件。

修改 /etc/ipsec.d/ipsec.conf

假设 EIP 是 161.189.168.31,则修改 /etc/ipsec.d/ipsec.conf 文件 行 right=xxx.xxx.xxx.xxx 为 right=161.189.168.31

 1config setup
 2        dumpdir=/var/run/pluto/
 3        nat_traversal=yes
 4        virtual_private=%v4:10.0.0.0/8,%v4:192.168.0.0/16,%v4:172.16.0.0/12,%v4:25.0.0.0/8,%v6:fd00::/8,%v6:
 5fe80::/10
 6        oe=off
 7        protostack=netkey
 8        nhelpers=0
 9        interfaces=%defaultroute
10conn openswan
11        authby=secret
12        type=tunnel
13        auto=start
14
15        left=10.100.0.8
16        leftid=52.81.173.204
17        leftsubnet=10.100.0.0/16
18        leftnexthop=%defaultroute
19
20        right=161.189.168.31
21        rightsubnet=10.50.0.0/16
22        rightnexthop=%defaultroute
23
24        ike=aes256-sha1;modp1024
25        ikelifetime=86400s
26        phase2=esp
27        phase2alg=aes256-sha1;modp1024
28        salifetime=3600s
29        pfs=yes

修改 /etc/ipsec.d/ipsec.secrets 文件

该文件只有一行,分为 3 部分, 第一个 IP 地址是本地侧的公网 IP, 第二个 IP 地址是对端的 IP 地址。所以需要更改为161.189.168.31

152.81.173.204 161.189.168.31 : PSK "psk123"

验证IPsec VPN 服务状态

首先需要在两端执行如下命令,重新启动 IPsec 服务,确保使用最新的配置文件。

1sudo service ipsec stop
2sudo service ipsec start

检查 IPsec 服务是否正常,输入

1sudo service ipsec status

输出

 1[ec2-user@ip-10-100-0-8 ~]$ sudo service ipsec status
 2Redirecting to /bin/systemctl status ipsec.service
 3● ipsec.service - Internet Key Exchange (IKE) Protocol Daemon for IPsec
 4   Loaded: loaded (/usr/lib/systemd/system/ipsec.service; enabled; vendor preset: disabled)
 5   Active: active (running) since Thu 2020-09-24 03:19:22 UTC; 2s ago
 6     Docs: man:ipsec(8)
 7           man:pluto(8)
 8           man:ipsec.conf(5)
 9  Process: 9906 ExecStopPost=/usr/sbin/ipsec --stopnflog (code=exited, status=0/SUCCESS)
10  Process: 9902 ExecStopPost=/sbin/ip xfrm state flush (code=exited, status=0/SUCCESS)
11  Process: 9900 ExecStopPost=/sbin/ip xfrm policy flush (code=exited, status=0/SUCCESS)
12  Process: 9886 ExecStop=/usr/libexec/ipsec/whack --shutdown (code=exited, status=0/SUCCESS)
13  Process: 10196 ExecStartPre=/usr/sbin/ipsec --checknflog (code=exited, status=0/SUCCESS)
14  Process: 10193 ExecStartPre=/usr/sbin/ipsec --checknss (code=exited, status=0/SUCCESS)
15  Process: 9932 ExecStartPre=/usr/libexec/ipsec/_stackmanager start (code=exited, status=0/SUCCESS)
16  Process: 9930 ExecStartPre=/usr/libexec/ipsec/addconn --config /etc/ipsec.conf --checkconfig (code=exited, status=0/SUCCESS)
17 Main PID: 10209 (pluto)
18   Status: "Startup completed."
19   CGroup: /system.slice/ipsec.service
20           └─10209 /usr/libexec/ipsec/pluto --leak-detective --config /etc/ipsec.conf --nofork
21
22Sep 24 03:19:24 ip-10-100-0-8.cn-north-1.compute.internal pluto[10209]: "openswan" #3: STATE_MAIN_R2: sent MR2, expecting MI3
23Sep 24 03:19:24 ip-10-100-0-8.cn-north-1.compute.internal pluto[10209]: "openswan" #3: Peer ID is ID_IPV4_ADDR: '161.189.168.31'
24Sep 24 03:19:24 ip-10-100-0-8.cn-north-1.compute.internal pluto[10209]: "openswan" #3: STATE_MAIN_R3: sent MR3, ISAKMP SA established {auth=PRESHARED_KEY cipher=aes_256 integ=sha group=MODP1024}
25Sep 24 03:19:24 ip-10-100-0-8.cn-north-1.compute.internal pluto[10209]: "openswan" #3: the peer proposed: 10.100.0.0/16:0/0 -> 10.50.0.0/16:0/0
26Sep 24 03:19:24 ip-10-100-0-8.cn-north-1.compute.internal pluto[10209]: "openswan" #4: responding to Quick Mode proposal {msgid:7f120034}
27Sep 24 03:19:24 ip-10-100-0-8.cn-north-1.compute.internal pluto[10209]: "openswan" #4:     us: 10.100.0.0/16===10.100.0.8<10.100.0.8>[52.81.173.204]
28Sep 24 03:19:24 ip-10-100-0-8.cn-north-1.compute.internal pluto[10209]: "openswan" #4:   them: 161.189.168.31<161.189.168.31>===10.50.0.0/16
29Sep 24 03:19:24 ip-10-100-0-8.cn-north-1.compute.internal pluto[10209]: "openswan" #4: keeping refhim=0 during rekey
30Sep 24 03:19:24 ip-10-100-0-8.cn-north-1.compute.internal pluto[10209]: "openswan" #4: STATE_QUICK_R1: sent QR1, inbound IPsec SA installed, expecting QI2 tunnel mode {ESP/NAT=>0x21fd7fb5 <0x0d17ec...PD=passive}
31Sep 24 03:19:24 ip-10-100-0-8.cn-north-1.compute.internal pluto[10209]: "openswan" #4: STATE_QUICK_R2: IPsec SA established tunnel mode {ESP/NAT=>0x21fd7fb5 <0x0d17eced xfrm=AES_CBC_256-HMAC_SHA1_9...PD=passive}

输出内容 “#4: STATE_QUICK_R2: IPsec SA established tunnel mode ” 标志 IPsec 隧道已经成功创建。

测试Openswan on AWS 主从节点故障切换功能

堆栈创建好后,相关的 EC2 配置如下,如果 OpenSwan 的 Master发生故障后,EIP 飘移到 OpenSwan的 Slave 的节点。 如下是模拟故障,首先在在 Master 节点执行命令,停止 IPsec 服务,模拟故障。

现在的场景是每 30 秒检测一下进程是否存在,如果连续 10 次(5 分钟)故障仍旧存在,会触发 Master 节点及 Slave 节点的切换流程。

1[ec2-user@ip-10-50-0-8 ~]$ sudo service ipsec stop
2Redirecting to /bin/systemctl stop ipsec.service

监控 /var/log/message 消息

1sudo service keepalived status -l

输出,发现经过 10 次连续的检查Ipsec 服务进程不存在, 则触发

 1Sep 24 04:40:01 ip-10-50-0-8 [ec2-user@ip-10-50-0-8 etc]$ sudo service keepalived status -l
 2Redirecting to /bin/systemctl status  -l keepalived.service
 3● keepalived.service - LVS and VRRP High Availability Monitor
 4   Loaded: loaded (/usr/lib/systemd/system/keepalived.service; enabled; vendor preset: disabled)
 5   Active: active (running) since Mon 2020-10-12 07:45:45 UTC; 58min ago
 6 Main PID: 4591 (keepalived)
 7   CGroup: /system.slice/keepalived.service
 8           ├─4591 /usr/sbin/keepalived -D
 9           ├─4592 /usr/sbin/keepalived -D
10           └─4593 /usr/sbin/keepalived -D
11
12Oct 12 08:39:45 ip-10-50-0-8.cn-northwest-1.compute.internal Keepalived_vrrp[4593]: /usr/sbin/pidof  /usr/libexec/ipsec/pluto exited with status 1
13Oct 12 08:40:15 ip-10-50-0-8.cn-northwest-1.compute.internal Keepalived_vrrp[4593]: /usr/sbin/pidof  /usr/libexec/ipsec/pluto exited with status 1
14Oct 12 08:40:45 ip-10-50-0-8.cn-northwest-1.compute.internal Keepalived_vrrp[4593]: /usr/sbin/pidof  /usr/libexec/ipsec/pluto exited with status 1
15Oct 12 08:41:15 ip-10-50-0-8.cn-northwest-1.compute.internal Keepalived_vrrp[4593]: /usr/sbin/pidof  /usr/libexec/ipsec/pluto exited with status 1
16Oct 12 08:41:45 ip-10-50-0-8.cn-northwest-1.compute.internal Keepalived_vrrp[4593]: /usr/sbin/pidof  /usr/libexec/ipsec/pluto exited with status 1
17Oct 12 08:42:15 ip-10-50-0-8.cn-northwest-1.compute.internal Keepalived_vrrp[4593]: /usr/sbin/pidof  /usr/libexec/ipsec/pluto exited with status 1
18Oct 12 08:42:45 ip-10-50-0-8.cn-northwest-1.compute.internal Keepalived_vrrp[4593]: /usr/sbin/pidof  /usr/libexec/ipsec/pluto exited with status 1
19Oct 12 08:43:15 ip-10-50-0-8.cn-northwest-1.compute.internal Keepalived_vrrp[4593]: /usr/sbin/pidof  /usr/libexec/ipsec/pluto exited with status 1
20Oct 12 08:43:45 ip-10-50-0-8.cn-northwest-1.compute.internal Keepalived_vrrp[4593]: /usr/sbin/pidof  /usr/libexec/ipsec/pluto exited with status 1
21Oct 12 08:44:15 ip-10-50-0-8.cn-northwest-1.compute.internal Keepalived_vrrp[4593]: /usr/sbin/pidof  /usr/libexec/ipsec/pluto exited with status 1

在 Console 检查 EC2 ,发现 EIP 已经飘移到 Slave 节点。 仍旧使用SSH 方式登录 EIP 地址,由于现在EIP 已经飘移到 Openswan 的 Slave 节点 (10.50.1.8)。 输入:

1[ec2-user@ip-10-50-1-8 ~]$ sudo service ipsec status

输出:IPsec VPN 服务已经成功的切换到 Slave 节点。

 1[ec2-user@ip-10-50-1-8 ~]$ sudo service ipsec status
 2Redirecting to /bin/systemctl status ipsec.service
 3● ipsec.service - Internet Key Exchange (IKE) Protocol Daemon for IPsec
 4   Loaded: loaded (/usr/lib/systemd/system/ipsec.service; enabled; vendor preset: disabled)
 5   Active: active (running) since Mon 2020-10-12 07:58:49 UTC; 1h 14min ago
 6     Docs: man:ipsec(8)
 7           man:pluto(8)
 8           man:ipsec.conf(5)
 9  Process: 23038 ExecStopPost=/usr/sbin/ipsec --stopnflog (code=exited, status=0/SUCCESS)
10  Process: 23035 ExecStopPost=/sbin/ip xfrm state flush (code=exited, status=0/SUCCESS)
11  Process: 23032 ExecStopPost=/sbin/ip xfrm policy flush (code=exited, status=0/SUCCESS)
12  Process: 23030 ExecStop=/usr/libexec/ipsec/whack --shutdown (code=exited, status=0/SUCCESS)
13  Process: 23312 ExecStartPre=/usr/sbin/ipsec --checknflog (code=exited, status=0/SUCCESS)
14  Process: 23309 ExecStartPre=/usr/sbin/ipsec --checknss (code=exited, status=0/SUCCESS)
15  Process: 23048 ExecStartPre=/usr/libexec/ipsec/_stackmanager start (code=exited, status=0/SUCCESS)
16  Process: 23045 ExecStartPre=/usr/libexec/ipsec/addconn --config /etc/ipsec.conf --checkconfig (code=exited, status=0/SUCCESS)
17 Main PID: 23326 (pluto)
18   Status: "Startup completed."
19   CGroup: /system.slice/ipsec.service
20           └─23326 /usr/libexec/ipsec/pluto --leak-detective --config /etc/ipsec.conf --nofork
21
22Oct 12 07:58:53 ip-10-50-1-8.cn-northwest-1.compute.internal pluto[23326]: "openswan" #1: Peer ID is ID_IPV4_ADDR: '52.81.173.204'
23Oct 12 07:58:53 ip-10-50-1-8.cn-northwest-1.compute.internal pluto[23326]: "openswan" #1: STATE_MAIN_I4: ISAKMP SA established {auth=PRESHARED_KEY cipher=aes_256 integ=sha group=MODP1024}
24Oct 12 07:58:53 ip-10-50-1-8.cn-northwest-1.compute.internal pluto[23326]: "openswan" #2: initiating Quick Mode PSK+ENCRYPT+TUNNEL+PFS+UP+IKEV1_ALLOW+IKEV2_ALLOW+SAREF_TRACK+IKE_FRAG_ALLOW+ESN_NO {using isakmp#...up=MODP1024}
25Oct 12 07:58:53 ip-10-50-1-8.cn-northwest-1.compute.internal pluto[23326]: "openswan" #2: STATE_QUICK_I2: sent QI2, IPsec SA established tunnel mode {ESP/NAT=>0x534d9a59 <0x229f2b0d xfrm=AES_CBC_256-HMAC_SHA1_9...DPD=passive}
26Oct 12 08:46:21 ip-10-50-1-8.cn-northwest-1.compute.internal pluto[23326]: "openswan" #3: initiating Quick Mode PSK+ENCRYPT+TUNNEL+PFS+UP+IKEV1_ALLOW+IKEV2_ALLOW+SAREF_TRACK+IKE_FRAG_ALLOW+ESN_NO to replace #2 ...up=MODP1024}
27Oct 12 08:46:21 ip-10-50-1-8.cn-northwest-1.compute.internal pluto[23326]: "openswan" #3: STATE_QUICK_I2: sent QI2, IPsec SA established tunnel mode {ESP/NAT=>0x99e158b0 <0x4b47a902 xfrm=AES_CBC_256-HMAC_SHA1_9...DPD=passive}
28Oct 12 08:58:53 ip-10-50-1-8.cn-northwest-1.compute.internal pluto[23326]: "openswan" #2: deleting state (STATE_QUICK_I2) and sending notification
29Oct 12 08:58:53 ip-10-50-1-8.cn-northwest-1.compute.internal pluto[23326]: "openswan" #2: ESP traffic information: in=0B out=0B
30Oct 12 08:58:53 ip-10-50-1-8.cn-northwest-1.compute.internal pluto[23326]: "openswan" #1: ignoring Delete SA payload: PROTO_IPSEC_ESP SA(0x534d9a59) not found (maybe expired)
31Oct 12 08:58:53 ip-10-50-1-8.cn-northwest-1.compute.internal pluto[23326]: "openswan" #1: received and ignored empty informational notification payload
32Hint: Some lines were ellipsized, use -l to show in full.

同时在完成节点间的切换后,会受到相应的邮件消息通知。如下图所示。

附录

如何在China Region做一个VPN备份DX的自动化方案

在AWS Global区域如何完成VPN自动备份DX

在AWS Global 区域,因为VGW支持VPN功能,所以如果希望使用VPN作为DX的备份手段,那么只需要如下图所示,将DX和VPN都终结在同一个VGW上,然后将子网路由表的propagation打开即可。EC2所在的路由表只需要将数据中心的CIDR的下一条指向VGW即可。VGW会根据选路原则,即在有相同的目的前缀时优先走DX,然后走VPN。如果DX出现故障,那么DX的路径会消失,VGW会自动切换到VPN进行转发。

在AWS China区域如何完成VPN自动备份DX

因为中国区的VGW不支持VPN属性,所以无法向Global区域那样非常简单的支持DX路由到VPN路由的自动切换。不过还是有一种简单的方法,可以快速的在DX故障时,做到自动的DX到VPN的路由切换。

步骤如下:

  1. 正确配置好DX,在EC2所在的子网路由表中开大propagation,保证客户IDC的网段正确发布到EC2的路由表中。在下图图示表示为接收到了数据中心的10.200.0.0/16的路由。
  2. 按照本文的相关内容,配置好到对端IDC的VPN连接。并在EC2所在子网的路由表中写上一个前缀大于DX的路由。如下图所示,因为IDC的数据中心路由前缀是10.200.0.0/16,那么你可以选择10.200.0.0/15。根据VPC的路由选择优先级,路由更精确的条目将会被选择,所以这个时候虽然同时存在DX和VPN两条路径,但是由于DX的路由更精确,EC2会最终选择DX的路由
  3. 当DX的线路出现故障时,IDC的路由将会因为DX出现故障而无法传递到VGW中。又由于EC2所在子网路由表开启了propagation,路由表中DX的路由将会消失。此时VPN的路由将会成为去往IDC的首选路由。此时EC2将会选择VPN到达IDC数据中心,完成切换。 VPC路由优先级参考文档:https://docs.aws.amazon.com/vpc/latest/userguide/VPC_Route_Tables.html#route-tables-priority

如何连接阿里云 VPN

【2020/11/17】感谢 SA ChenBin (binc@) 的补充信息。 阿里云提供了托管的IPSec VPN服务,也可以通过本方案建立AWS VPC与阿里云VPC之间的IPSec VPN隧道。这里,以ikev1的main模式为例,介绍其中配置的注意点。

参考:IKE V1版本的协商模式。

  • 主模式(main):协商过程安全性高。
  • 野蛮模式(aggressive):协商快速且协商成功率高。

协商成功后两种模式的信息传输安全性相同。

阿里云 IPSec VPN 介绍:https://help.aliyun.com/document_detail/65288.html

连接阿里云 VPN 前提条件

使用IPsec-VPN功能建立VPC到本地数据中心的VPN连接,确保满足以下条件:

  • 本地数据中心的网关设备必须支持IKEv1和IKEv2协议。 IPsec-VPN支持IKEv1和IKEv2协议。只要支持这两种协议的设备都可以和阿里云VPN网关互连,例如华为、华三、山石、FortiGate、深信服、Cisco ASA、Juniper、SonicWall、Nokia、IBM 和 Ixia等。
  • 本地数据中心的网关必须配置静态公网IP。
  • 本地数据中心的网段和专有网络的网段不能重叠。

修改 Openswan 配置文件

需要修改 OpenSwan 中的配置文件(ipsec.confi)进行修改,如下所示,

 1# /etc/ipsec.d/ipsec.conf
 2config setup
 3        dumpdir=/var/run/pluto/
 4        nat_traversal=yes
 5        virtual_private=%v4:10.0.0.0/8,%v4:192.168.0.0/16,%v4:172.16.0.0/12,%v4:25.0.0.0/8,%v6:fd00::/8,%v6:fe80::/10
 6        oe=off
 7        protostack=netkey
 8        nhelpers=0
 9        interfaces=%defaultroute
10conn openswan-ali
11        authby=secret
12        type=tunnel
13        auto=start     
14
15        left=172.31.0.8          # aws openswan private ip
16        leftid=54.223.106.76     # aws openswan elastic ip
17        leftsubnet=172.31.0.0/16 # aws VPC CIDR
18        leftnexthop=%defaultroute
19
20        right=40.192.2.12        # ALI VPN Gateway
21        rightsubnet=10.21.0.0/16 # ALI VPC CIDR
22        rightnexthop=%defaultroute
23
24        ikev2=no
25        ike=3des-md5;modp1024    # 加密算法-认证算法;DH Group
26        ikelifetime=3600s
27        phase2=esp
28        phase2alg=3des-md5;modp1024
29        salifetime=3600s
30        pfs=yes

注意在阿里云添加到AWS VPC CIDR的路由信息。

阿里云端 VPN 配置文件

如何连接FortiGate

下图是FortiGate的配置。 由于需要使用对端的私网地址,所以对应的Openswan配置文件需要修改。【这已经在 V2 的版本中进行了修改,需要增加 rightid 的部分】

 1# /etc/ipsec.d/ipsec.conf
 2config setup
 3        dumpdir=/var/run/pluto/
 4        nat_traversal=yes
 5        virtual_private=%v4:10.0.0.0/8,%v4:192.168.0.0/16,%v4:172.16.0.0/12,%v4:25.0.0.0/8,%v6:fd00::/8,%v6:fe80::/10
 6        oe=off
 7        protostack=netkey
 8        nhelpers=0
 9        interfaces=%defaultroute
10conn openswan-fgate
11        authby=secret
12        type=tunnel
13        auto=start     
14
15        left=172.31.0.8
16        leftid=54.223.106.76
17        leftsubnet=172.31.0.0/16           
18        leftnexthop=%defaultroute
19
20        right=104.88.27.166      # FortiGate设备ip
21        rightid=192.168.10.210   # FortiGate设备私网地址
22        rightsubnet=192.168.10.0/23
23        rightnexthop=%defaultroute
24
25        ikev2=no
26        ike=3des-md5;modp1024
27        ikelifetime=3600s
28        phase2=esp
29        phase2alg=3des-md5;modp1024
30        salifetime=3600s
31        compress=no

【2020/12/31】坑,如果需要多个网段,需要更改 rightsubnet 为 rightsubnets 【是复数,是复数,是复数,需要加 s】 例子 rightsubnets={192.168.10.0/23,192.168.20.0/23,} 另外,主要需要在ipsec.secrets文件增加一行,格式如下:【Openswan公网地址 FortiGate私有 IP : PSK “密码”】:

1# /etc/ipsec.d/ipsec.secrets
254.223.106.76 47.92.2.122 : PSK "awsomeaws"     # 阿里云托管VPN Gateway
354.223.106.76 192.168.10.210 : PSK "awsomeaws"  # FortiGate设备

配置完成后,重启IPSec 服务。