亚马逊AWS官方博客

搭建 Multi-Cloud 云服务器 Mesh 网络

本文介绍了多云场景下如何实现多云云服务器的 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 地址与公钥和远程端点相关联,当接口将数据包发送到对等方时,它会执行以下操作:

  1. 此数据包发往 192.168.30.8。那是哪个对等方?这是为对等方 ABCDEFGH 准备的。
  2. 使用对等方 ABCDEFGH 的公钥加密整个 IP 数据包。
  3. 对等方 ABCDEFGH 的远程端点是什么?端点是主机 216.58.211.110 上的 UDP 端口 53133。
  1. 使用 UDP 通过 Internet 将步骤 2 中的加密字节发送到 216.58.211.110:53133。

当接口收到数据包时,会发生以下情况:

  1. 我刚从主机 98.139.183.24 上的 UDP 端口 7361 收到一个数据包。让我们解密吧!
  2. 为对等方 LMNOPQRS 进行正确解密和验证 。让我们记住对等方 LMNOPQRS 最近的 Internet 端点是使用 UDP 的 98.139.183.24:7361。
  3. 解密后,明文数据包来自 192.168.43.89。是否允许对等方 LMNOPQRS 通过 192.168.43.89 向我们发送数据包?
  4. 如果是,则在接口上接受数据包。如果没有,丢弃它。

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

本篇作者

马昆

西云数据解决方案架构总监,15+ 年的开发和架构经验,加入西云数据前,拥有互联网,零售快消及 8 年的在线教育领域的工作及创业经历。擅长操作系统、数据库、数据湖、虚拟化、容器化(K8S)架构设计。

刘佳鑫

西云数据解决方案架构师,目前为泛互联网客户提供架构设计、解决方案以及技术支持,加入西云数据前,主要面向运营商、零售等行业客户提供移动无线网络、MEC、虚拟化、容器化及应用持续交付等产品及解决方案。