本文介绍了多云场景下如何实现多云云服务器的 Mesh 网络,以搭建 Amazon Elastic Compute Cloud(Amazon EC2) 与其他公有云云服务器之间的跨云 Mesh 网络,可以应用于:
场景一:云主机全互联模式
云主机全互联模式即所有跨云云主机之间直接内网互联,无需通过第三方节点来中转流量,相对中转模式可以提供更高的转发效率,可以应用于跨云云服务器之间传输文件、同步数据,以及实现基于云服务器搭建的中小规模数据库的在线同步、迁移或者离线迁移,如下图所示:
场景二:跨云打通容器网络
应用于多云或者混合云场景下,借助云服务器 Mesh 网络,Flannel、Kilo 等 Kubernetes CNI Overlay 网络插件可以实现跨云容器网络,以搭建跨云的容器集群。
通过 graph 生成的多云 Kilo 网络的拓扑图如下图所示:
Mesh 网络如何工作?
WireGuard 介绍
WireGuard 使用先进的加密技术,它旨在比 IPsec 更快、更简单、更精简和更有用,比 OpenVPN 具有更高的性能,适用于许多不同的环境。最初是为 Linux 内核发布的,现在是跨平台的(支持 Windows、macOS、BSD、iOS、Android)并且可以广泛部署。
WireGuard 工作原理
WireGuard 的工作原理是添加一个(或多个)网络接口,如 eth0 或 wlan0,称为 wg0(或 wg1、wg2、wg3 等),然后可以使用 ifconfig 或 ip-address 配置此网络接口,使用 route 或 ip-route 添加和删除路由,像使用所有普通网络实用程序类似,依此类推。WireGuard 方面特定的接口是使用 wg 工具配置的,此接口充当隧道接口。
WireGuard 将隧道 IP 地址与公钥和远程端点相关联,当接口将数据包发送到对等方时,它会执行以下操作:
- 此数据包发往 192.168.30.8。那是哪个对等方?这是为对等方 ABCDEFGH 准备的。
- 使用对等方 ABCDEFGH 的公钥加密整个 IP 数据包。
- 对等方 ABCDEFGH 的远程端点是什么?端点是主机 216.58.211.110 上的 UDP 端口 53133。
- 使用 UDP 通过 Internet 将步骤 2 中的加密字节发送到 216.58.211.110:53133。
当接口收到数据包时,会发生以下情况:
- 我刚从主机 98.139.183.24 上的 UDP 端口 7361 收到一个数据包。让我们解密吧!
- 为对等方 LMNOPQRS 进行正确解密和验证 。让我们记住对等方 LMNOPQRS 最近的 Internet 端点是使用 UDP 的 98.139.183.24:7361。
- 解密后,明文数据包来自 192.168.43.89。是否允许对等方 LMNOPQRS 通过 192.168.43.89 向我们发送数据包?
- 如果是,则在接口上接受数据包。如果没有,丢弃它。
WireGuard 基本配置
WireGuard 的客户端和服务端基本是平等的,双方都会监听一个 UDP 端口,比如 51820,谁主动发起连接请求,谁就是客户端。WireGuard 的核心是一个称为 Cryptokey Routing 的概念,它通过将公钥与隧道内允许的隧道 IP 地址列表相关联来工作。每个网络接口都有一个私钥和一个对等点列表。每个对等点都有一个公钥。公钥简短而简单,由对等方用来相互验证。
例如,对等节点的 conf 文件可能具有以下配置:
[Interface]
PrivateKey = yAnz...fBmk
ListenPort = 51820
[Peer]
PublicKey = xTIB...p8Dg
AllowedIPs = 10.192.124.0/24, 10.192.122.3/32
[Peer]
PublicKey = TrMv...WXX0
AllowedIPs = 192.168.0.0/16, 10.192.122.4/32
[Peer]
PublicKey = gN65...z6EA
endpoint: 192.95.5.70:54421
AllowedIPs = 10.10.10.230/32
基于前面的 conf 配置文件,手工配置本地 WireGuard 对等节点的过程如下:
#Adding the wg0 interface
$ ip link add dev wg0 type wireguard
$ ip address add dev wg0 10.192.122.3/24
$ ip route add 10.0.0.0/8 dev wg0
$ ip address show
1: lo: <LOOPBACK> mtu 65536
inet 127.0.0.1/8 scope host lo
2: eth0: <BROADCAST> mtu 1500
inet 192.95.5.69/24 scope global eth0
3: wg0: <POINTOPOINT,NOARP> mtu 1420
inet 10.192.122.3/24 scope global wg0
#Configuring the cryptokey routing table of wg0
$ wg setconf wg0 configuration-1.conf
$ wg show wg0
interface: wg0
public key: HIgo...8ykw
private key: yAnz...fBmk
listening port: 51820
peer: xTIB...p8Dg
allowed ips: 10.192.124.0/24, 10.192.122.3/32
peer: TrMv...WXX0
allowed ips: 192.168.0.0/16, 10.192.122.4/32
peer: gN65...z6EA
allowed ips: 10.10.10.230/32
endpoint: 192.95.5.70:54421
$ ip link set wg0 up
$ ping 10.10.10.230
PING 10.10.10.230 56(84) bytes of data.
64 bytes: icmp_seq=1 ttl=49 time=0.01 ms
接下来将介绍如何将多个对等节点的配置自动化。
如何自动化搭建云服务器 Mesh 网络
Architecture Overview – Multi-Cloud 云服务器 Mesh 网络
以亚马逊云科技宁夏区域、北京区域和其他公有云的 3 台云服务器为例,介绍如何搭建 Multi-Cloud 云服务器的 Mesh 网络,其中 WireGuard conf 配置文件可以通过 wg-meshconf 自动产生。
Mesh 网络配置自动化 – Bastion Host 环境配置
准备一台 Amazon EC2 实例作为 Bastion Host,用来运行 Terraform 脚本,以在宁夏、北京区域自动创建 VPC 和云服务器 Amazon EC2,以及生成多个 WireGuard Peer 节点的配置文件,并推送到 Peer 节点。
安装 wg-meshconf,用于生成多个 peer 节点的配置文件:wg0.conf
$ sudo apt install python3-pip -y
$ sudo -u ubuntu pip install --user -U wg-meshconf -i https://pypi.tuna.tsinghua.edu.cn/simple
安装 Terraform for Ubuntu,其他系统版本可以参考:https://developer.hashicorp.com/terraform/tutorials/aws-get-started/install-cli。
$ sudo apt-get update && sudo apt-get install -y gnupg software-properties-common
$ wget -O- https://apt.releases.hashicorp.com/gpg | \
gpg --dearmor | \
sudo tee /usr/share/keyrings/hashicorp-archive-keyring.gpg
$ echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] \
https://apt.releases.hashicorp.com $(lsb_release -cs) main" | \
sudo tee /etc/apt/sources.list.d/hashicorp.list#Add the official HashiCorp repository to your system.
$ sudo apt update #Download the package information from HashiCorp
$ sudo apt-get install terraform#Install Terraform from the new repository
$ export AWS_ACCESS_KEY_ID=AKI....FWL
$ export AWS_SECRET_ACCESS_KEY=axc.....ay2
Mesh 网络配置自动化 – Terraform
Clone Terraform 及 Shell 自动配置脚本,其中 TF 配置文件主要包括:main.tf,outputs.tf,variables.tf,versions.tf。
$ git clone https://github.com/nwcd-samples/terraform-wgmesh.git
$ ls terraform-wgmesh
bootstrap.sh clean.sh main.tf outputs.tf README.md variables.tf versions.tf
其中 main.tf 定义了 VPC,security groups,EC2,用于分别在宁夏、北京区域创建 VPC,Amazon EC2 实例,并安装 WireGuard。variables.tf 定义了配置使用的变量,例如区域、CIDR 块、子网数、实例类型等。
以下为 main.tf 部分内容:
.........................................................
resource "aws_instance" "wg_peer_zhy" {
ami = data.aws_ami.ubuntu_region_1.id
instance_type = var.ins_type
key_name = var.key_region_1
vpc_security_group_ids = [aws_security_group.wgsg_zhy.id]
subnet_id = module.vpc_zhy.public_subnets[0]
associate_public_ip_address = true
monitoring = true
user_data = <<EOF
#!/bin/bash
sudo apt-get update
sudo apt install wireguard -y
sudo echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
sudo sysctl -p
EOF
root_block_device {
volume_type = "gp3"
volume_size = 8
}
tags = {
Name = "wg_peer_zhy"
}
}
.........................................................
resource "aws_instance" "wg_peer_bjs" {
provider = aws.bjs
ami = data.aws_ami.ubuntu_region_2.id
instance_type = var.ins_type
key_name = var.key_region_2
vpc_security_group_ids = [aws_security_group.wgsg_bjs.id]
subnet_id = module.vpc_bjs.public_subnets[0]
associate_public_ip_address = true
monitoring = true
user_data = <<EOF
#!/bin/bash
sudo apt-get update
sudo apt install wireguard -y
sudo echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
sudo sysctl -p
EOF
root_block_device {
volume_type = "gp3"
volume_size = 8
}
tags = {
Name = "wg_peer_bjs"
}
}
.........................................................
Mesh 网络配置自动化 – wg-meshconf
前面 clone 到本地的 bootstrap.sh 脚本主要用于实现:
- apply terraform 配置(初次执行的时候,还需要先运行 terraform init 进行初始化)
- 通过 wg-meshconf 产生 3 个 wireguard peer 的 conf 配置文件,具体 wg-mesh 介绍可以参考:https://github.com/k4yt3x/wg-meshconf
- 将 conf 配置文件分别复制到 3 个 peer 节点的相关路径:/etc/wireguard/wg0.conf,然后启动 WireGuard 服务
#/bin/bash
terraform apply -auto-approve
sleep 10s
# Add peers
wg-meshconf addpeer zhy --address 192.168.10.1/24 --allowedips $(terraform output -raw public_subnet_cidr_zhy) --endpoint $(terraform output -raw public_ip_addr_zhy) --postup "iptables -A FORWARD -i wg0 -j ACCEPT; iptables -A FORWARD -o wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o ens5 -j MASQUERADE" --postdown "iptables -D FORWARD -i wg0 -j ACCEPT; iptables -D FORWARD -o wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o ens5 -j MASQUERADE"
wg-meshconf addpeer bjs --address 192.168.20.1/24 --allowedips $(terraform output -raw public_subnet_cidr_bjs) --endpoint $(terraform output -raw public_ip_addr_bjs) --postup "iptables -A FORWARD -i wg0 -j ACCEPT; iptables -A FORWARD -o wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o ens5 -j MASQUERADE" --postdown "iptables -D FORWARD -i wg0 -j ACCEPT; iptables -D FORWARD -o wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o ens5 -j MASQUERADE"
wg-meshconf addpeer pub --address 192.168.30.1/24 --allowedips 10.7.1.209/24 --endpoint x.x.x.x --postup "iptables -A FORWARD -i wg0 -j ACCEPT; iptables -A FORWARD -o wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE" --postdown "iptables -D FORWARD -i wg0 -j ACCEPT; iptables -D FORWARD -o wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE"
# Generate wg peer configuration files
wg-meshconf genconfig
# Copy wg peer configuration files to peer hosts & start wg
scp -i ~/zhy.pem output/zhy.conf ubuntu@$(terraform output -raw public_ip_addr_zhy):~
ssh -i ~/zhy.pem ubuntu@$(terraform output -raw public_ip_addr_zhy) "sudo cp zhy.conf /etc/wireguard/wg0.conf & sudo systemctl start wg-quick@wg0"
scp -i ~/bjs.pem output/bjs.conf ubuntu@$(terraform output -raw public_ip_addr_bjs):~
ssh -i ~/bjs.pem ubuntu@$(terraform output -raw public_ip_addr_bjs) "sudo cp bjs.conf /etc/wireguard/wg0.conf & sudo systemctl start wg-quick@wg0"
scp -i ~/pub.pem output/pub.conf ubuntu@x.x.x.x:~
ssh -i ~/pub.pem ubuntu@x.x.x.x "sudo cp pub.conf /etc/wireguard/wg0.conf & sudo systemctl start wg-quick@wg0"
Mesh 网络配置验证
通过 wg-meshconf 可以查看多个 Peer 的相关配置,然后 3 个 peer 都可以 ping 通其它 2 个 Peer 的内网 IP,实现了对等节点内网 IP 之间的互联互通。
参考资料
What is Infrastructure as Code with Terraform?
wg-meshconf to generate peer configuration files for WireGuard mesh networks
本篇作者