使用Gateway Load Balancer实现集中的网络流量深度检测

一、背景

Gateway Load Balancer(以下简称GWLB)于2020年Re-Invent上被宣布并在2021年3月发布。

大型企业的网络流量深度检测一直是一个复杂的话题,在本功能未推出之前,如果企业希望使用第三方商用防火墙和入侵检测系统扫描云上A点到B点之间的网络流量,需要使用Interface Endpoint转发流量到由AMI启动的防火墙,并自行管理多个虚拟设备之间的负载平衡和高可用。GWLB的推出使得这一配置大大简化,GWLB可将需要扫描的流量转发到一组虚拟设备上,并实现健康检查、负载调度、粘性链接等管理功能。Gateway Load Balancer在OSI模型的第三层工作,并使用Geneve协议(RFC 8926)和GWLB metadata向执行扫描的虚拟设备转发网络流量。

GWLB的主要使用场景是:

  • 与IGW搭配,负责多个VPC去往互联网方向的集中深度检测;
  • 与TGW搭配,负责多个VPC到某个共享VPC方向的深度检测。

在这两种场景下主要架构非常相似,下面以第一个场景为主进行介绍。

二、总体架构

本文构建如下网络架构:

  • 1个虚拟设备VPC负责运行虚拟防火墙,VPC具备IGW作为设备更新和管理入口;
  • 1个业务VPC运行应用系统,具备IGW作为流量出口;
  • 业务VPC为多层结构,有1个公有子网部署NAT网关(绑定EIP),2个私有子网分别部署应用EC2和GWLB Endpoint。
  • GWLB Endpoint负责流量转发到虚拟设备VPC。

架构图如下。

首先部署以上架构中所有的VPC、子网、NAT网关、路由表等。本实验中我们使用两个EC2作为虚拟安全设备接受以Geneve协议发送过来的流量,将检测通过的数据包返回给GWLB,完成网络流量的检测和传输。在生产环境中,可使用Marketplace上的NGFW防火墙的AMI代替这两个EC2。

接下创建GWLB和VPC Endpoint。

三、创建GWLB并配置目标组

进入EC2服务控制台,进入负载均衡器界面,点击创建负载均衡器。在创建界面选择Gateway Load Balancer,如下截图。

image-20210502154606282

选择架构图中运行虚拟网络设备的子网,根据前文架构图的规划,负载均衡器位于虚拟设备VPC的私有子网。如下截图。

image-20210502154723145

将页面向下滚动,在创建GWLB的页面中已经提供了可直接创建Target Group目标组的按钮。点击创建目标组链接打开新的标签页。如下截图。

image-20210502154846460

在新打开的创建目标组网页中,选择目标组类型是实例,输入名称GWLB,在协议位置选择GENEVE,在VPC位置选择放置虚拟设备的VPC。接下来向下滚动页面继续设置。如下截图。

image-20210502154953804

在健康检查位置选择TCP,选择端口为22。由于ALB无法对UDP做健康检查,因此检查虚拟防火墙设备工作状态将通过TCP 22端口来配合健康检查。最后一步点击创建。如下截图。

image-20210502155108578

在注册目标组界面,选中虚拟设备对应的EC2,点击添加按钮,将这两个EC2添加到GWLB的目标组中。点击下一步继续。如下截图。

image-20210502155402403

添加到目标组成功后,可看到虚拟安全设备实例已经关联到目标组中。如下截图。

image-20210502155700933

接下来回到前一个标签页的创建GWLB的页面,点击刷新按钮,即可看到前一步创建的目标组。选中它,然后点击创建负载均衡器。如下截图。

image-20210502155843301

创建GWLB完成。如下截图。

image-20210502155947871

四、配置GWLB需要的终端节点

1、创建终端服务(Endpoint Service)

进入VPC服务,点击左侧终端服务,点击创建终端服务。如下截图。

image-20210502160310135

选择上一步创建的GWLB,取消 需要接受终端节点 选项的选中状态,点击下一步继续。如下截图。

image-20210502160504010

随后可从终端服务界面中看到创建完成。将服务名称复制下来,后续将会使用。如下截图。

image-20210502160609312

2、在应用所在VPC内创建终端节点

进入VPC模块的终端服务界面,点击创建终端节点。如下截图。

image-20210502175830213

选择第二项使用名称查找服务,然后粘贴上一个步骤复制下来的终端节点服务名称,并按验证按钮。验证成功后应显示绿色信息。在选择VPC界面,选择应用所在VPC的公有子网。选择VPC时候请注意:

  • 请参考前文的网络架构图,GWLB的终端节点配置在应用VPC的中间子网内。其他子网无需配置终端节点;
  • 终端节点一次只能选择一个子网(可用区)创建,当需要高可用的话,请重复本步骤,再其他可用区再创建一个终端节点。

选择完毕后点击创建终端。如下截图。

image-20210502180004394

创建完成,接下来要等状态从Pending变成绿色的可用之后再继续下一步配置。此处需要等待3-5分钟。如下截图。

image-20210502180443634

终端节点配置完成。

五、调整应用子网的路由表

在一般环境下,应用程序所在的子网是通过NAT网关访问外网,在配置好GWLB Endpoint后,需要修改私有子网的路由表,将默认路由指向到GWLB Endpoint。

进入VPC的路由界面,找到应用所在子网的路由表,编辑路由。如下截图。

image-20210502181644102

添加一条新的路由条目0.0.0.0/0,指向GWLB Endpoint。如下截图。

image-20210502181945710

系统自动加载出刚才配置好的GWLB Endpoint,添加路由条目完成。如下截图。

image-20210502182152138

至此应用VPC配置路由完成。

六、使用EC2虚拟安全设备Virtual Appliance的配置

1、Geneve协议原理

GWLB使用的协议是GENEVE协议,它将所有网络流量封装并加上本地VPC的数据报头,从GWLB发送给要处理流量的EC2。 因此当使用EC2模拟安全设备做测试时候,需要拆解GENEVE的数据包,并将源地址和目标地址调换,然后重新返回GWLB,才可以让数据包正常通过。这个过程就需要使用特定的脚本完成这一任务。

为此,可使用GENEVE proxy等第三方脚本辅助GWLB测试。本文使用如下脚本做测试:

https://github.com/sentialabs/geneve-proxy

注意:在本实验过程中:

  • EC2控制台上不需要禁用目标地址检查,模拟Virtual Appliance的EC2保持和普通应用EC2一样的网络地址检查即可;
  • 在Linux上无须启用内核转发,也就是不需要修改 /etc/sysctl.conf 配置文件。

2、安装并配置Geneve proxy

使用Amazon Linux 2系统,将补丁打到最新,系统已经预装了Python3。接下来执行如下命令安装pyyaml库:

pip3 install pyyaml

使用git clone将整个目录下载到EC2上。执行如下命令:

yum install git
git clone https://github.com/sentialabs/geneve-proxy.git

进入geneve-proxy目录,修改config.yaml配置文件,找到blocked_transport_protocols这一段,将其中的ICMP前边加上注释符号,然后在将这一行写入到allowed_transport_protocols的配置中。配置文件片段如下:

# If `allowed_transport_protocols` is set and has values, the proxy
# will drop any outbound flows using transport protocols not present in the list.
allowed_transport_protocols:
  - 0x0006 # TCP
  - 0x0011 # UDP
  - 0x0001 # ICMP

# If `blocked_transport_protocols` is set and has values, the proxy
# will drop any outbound flows using transport protocols present in the list.
blocked_transport_protocols:
# - 0x0001 # ICMP

保存退出修改状态。由此,将表示允许ICMP协议通过。

修改proxy/proxy_config.py配置文件,找到self.outbound这一段中的allowed_transport_protocols,将其从None改为True。配置文件片段如下:

      self.outbound = {
          'drop_all_traffic': False,
          'allowed_transport_protocols': True,
          'blocked_transport_protocols': None,
          'allowed_application_ports': None,
          'blocked_application_ports': None,
      }

保存退出修改状态。由此,将表示允许ICMP通过。

3、启动Geneve转发

执行如下命令:

cd geneva-proxy
python3 main.py &

出现Listening的提示表示启动正常,添加了 & 符号后出现 [1]8922 这样的进程ID表示启动成功。

至此配置完成。

七、测试流量

1、模拟访问流量

现在登陆到应用服务器上,模拟对外部互联网的访问,可执行ping等操作模拟,并保持产生流量一段时间。例如执行如下命令:

ping www.amazon.com

如果上一步配置Geneve转发正确的,这里ping应该直接正常。

2、查看流量

现在登陆到模拟虚拟安全设备的两个EC2上,执行如下命令查看流量:

tcpdump -nvv 'port 6081'

就可以在console上看到应用服务器对外网的访问的具体报文。 报文开头的地址192.168开头的就是GWLB所在的本地子网的数据包被Geneve协议封装,之下的10.2.101.47就是应用程序所在的原始EC2的报文。

  192.168.101.247.60001 > 192.168.101.235.6081: [udp sum ok] Geneve, Flags [none], vni 0x0, options [class Unknown (0x108) type 0x1 len 12 data 74a11ad9 6ec49886, class Unknown (0x108) type 0x2 len 12 data 00000000 00000000, class Unknown (0x108) type 0x3 len 8 data 39f7f1a7]
      IP (tos 0x0, ttl 254, id 29162, offset 0, flags [DF], proto TCP (6), length 40)
  10.2.101.47.48354 > 52.94.212.197.https: Flags [.], cksum 0xb792 (correct), seq 2388, ack 5780, win 356, length 0
10:58:40.778376 IP (tos 0x0, ttl 254, id 32944, offset 0, flags [none], proto UDP (17), length 1568)

如下截图。

以上过程就实现了用EC2模拟虚拟安全设备实现深度检测的过程。

3、模拟故障切换

GWLB的主要作用就是实现运行虚拟安全设备之间的流量调度,因此这里将模拟一个EC2故障流量被引导到另一个EC2上的过程。

首先进入GWLB的目标组,进入健康检查标签页,点击修改按钮。如下截图。

image-20210507174244384

将健康检查的判定为正常的标准改为连续2次,超时改为2秒,检测频率改为5秒。保存目标组设置。如下截图。

image-20210507174336738

接下来停止一个模拟NGFW防火墙的EC2,然后可以通过GWLB的目标组中看到这个EC2的状态变成了不健康。在数秒后,流量将切换到正常的EC2上。

image-20210507180603882

至此配置过程完成。

八、参考文档

参考文档:

https://aws.amazon.com/cn/blogs/networking-and-content-delivery/scaling-network-traffic-inspection-using-aws-gateway-load-balancer/
https://github.com/aws-samples/aws-gateway-load-balancer-code-samples