用 openswan 实现VPC之间的通信

目标

在AWS上,我们希望将不同的VPC或者不同region连接起来,使其看似在一个内网之内。在这种情况下,可以使用 openswan 来建立 VPN 通道实现这个效果。这个做法不仅适用于AWS,还能用于需要打通内网的VPN场景。

环境

https://aws.amazon.com/articles/connecting-multiple-vpcs-with-ec2-instances-ipsec/
https://aws.amazon.com/articles/connecting-multiple-vpcs-with-ec2-instances-ipsec/

这个实验中,在AWS宁夏区域创建两个VPC,VPC0 10.0.0.0/16, VPC1 172.16.0.0/16. 在 VPC0 创建一个子网 10.0.0.0/24,VPC1 创建一个子网 172.16.1.0/24. 两个VPC都添加一个 Internet Gateway,并在 Route table 把 0.0.0.0/0 指向 Internet Gateway.

步骤

1. 在 VPC 的页面,创建两个VPC. VPC0 10.0.0.0/16, VPC1 172.16.0.0/16.
2. 在 VPC 的 Subnets 页面,为每个 VPC 分别创建一个 Public subnet 和一个 Private subnet.
3. 在 VPC 的 Internet Gateways 页面,为每个 VPC 创建一个 Internet Gateway. 关联到相应的 VPC 上。
4. 在 EC2 的页面,在每个VPC的public subnet中,分别创建一个Instance, 这里用的名字是 VPC0-vpn, VPC1-vpn. Security group 如图。

vpc0-sg

vpc1-sg

5. 将 VPC0 和 VPC1 的 Route Table 修改成如图。把 VPC0 到 VPC1 的流量转向 VPC0 中的VPN instance, 由这个instance里面的 openswan (ipsec) 进行转发。

vpc0-rt

vpc1-rt

6. 为每个 VPC 分别分配一个 EIP (Elastic IP), 在这个例子中, VPC0 的 EIP 是 52.83.144.128, VPC1 的 EIP 是 52.83.161.140, 将这两个 EIP 分别 associate 到 VPC0-vpn 和 VPC1-vpn 这两个 instances 上。

7. 登入 VPC0 的 instance (VPC0-vpn), 安装 openswan 并进行配置。

$ sudo yum install openswan

确保 /etc/ipsec.conf 里包含

include /etc/ipsec.d/*.conf

创建 /etc/ipsec.d/vpc0-to-vpc1.conf 文件,写入以下配置。

conn vpc0-to-vpc1
        type=tunnel
        authby=secret
        left=10.0.0.5
        leftid=52.83.144.128
        leftsubnet=10.0.0.0/16
        right=52.83.161.140
        rightsubnet=172.16.0.0/16
        pfs=yes
        auto=start

设置一个密码 /etc/ipsec.d/vpc0-to-vpc1.secrets, 这里的密码是 "redhat".

52.83.144.128 52.83.161.140 : PSK "redhat"

在 VPC1 的 instance (VPC1-vpn) 中,安装 openswan, 并写入如下配置。
/etc/ipsec.d/vpc1-to-vpc0.conf

conn vpc1-to-vpc0
        type=tunnel
        authby=secret
        left=172.16.0.5
        leftid=52.83.161.140
        leftsubnet=172.16.0.0/16
        right=52.83.144.128
        rightsubnet=10.0.0.0/16
        pfs=yes
        auto=start

创建 /etc/ipsec.d/vpc1-to-vpc0.secrets, 使用相同的密码。

52.83.144.128 52.83.161.140 : PSK "redhat"

启动 IPsec,并重启网络。

$ sudo systemctl restart ipsec
$ sudo systemctl restart network

在两个 VPN instance 上调整以下系统参数。
修改 /etc/sysctl.conf

net.ipv4.ip_forward = 1
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
net.ipv4.conf.all.rp_filter = 0
net.ipv4.conf.default.rp_filter = 0
net.ipv4.conf.eth0.rp_filter = 0

使之生效

$ sudo sysctl -p

8. 测试 ping 对方网络的 instance.

在 VPC0-vpn 这个 instance 上,尝试ping VPC1-vpn.

[ec2-user@ip-10-0-0-5 ~]$ ping 172.16.0.5
PING 172.16.0.5 (172.16.0.5) 56(84) bytes of data.
64 bytes from 172.16.0.5: icmp_seq=1 ttl=255 time=0.525 ms

反过来,可以从 VPC1-vpn 尝试 ping VPC0-vpn,可以看到两个不同的内网被打通了。

9. 在 VPC0 和 VPC1 中,分别创建两个新的 instances, 测试这两个 instances 之间能否 ping 通。

[ec2-user@ip-10-0-0-10 ~]$ ping 172.16.0.21
PING 172.16.0.21 (172.16.0.21) 56(84) bytes of data.
From 10.0.0.5: icmp_seq=1 Redirect Host(New nexthop: 10.0.0.1)
64 bytes from 172.16.0.21: icmp_seq=1 ttl=253 time=1.77 ms

参考文档

https://aws.amazon.com/articles/connecting-multiple-vpcs-with-ec2-instances-ipsec/
https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/security_guide/sec-securing_virtual_private_networks