AWS VPC 流量集中检测系列--(3)AWS GWLB集成FortiGate防火墙
一、背景
之前在《AWS GWLB集成paloalto防火墙》里面提到过,AWS GWLB集成FortiGate防火墙的官方博客[1]缺少一些配置,导致无法实现防火墙的高可用。这篇文档来介绍一下AWS GWLB如何集成FortiGate防火墙。
FortiGate防火墙集成AWS GWLB需要注意:
- FortiGate防火墙建议使用6.4.10版本。经过测试目前使用7.0.7版本无法正常工作,但是从6.4.10升级到7.0.7版本,流量是可以正常转发的。另外,不建议对防火墙执行降级操作,防火墙会丢配置,并且图形化界面可能遇到无法切换VDOM的Bug。所以目前生产环境建议使用6.4.10,7.2.2版本可以用于测试。
- FortiGate防火墙建议配置VDOM,Fortigate默认没有带外管理接口,也就是所有接口默认都会转发数据流量,通过配置VDOM可以将管理流量与数据流量分离,从而简化路由配置。
二、Fortigate VDOM
FortiGate 中有两种类型的 VDOM 模式——Split VDOM 和 Multi-VDOM 。你可以将一个VDOM理解成一个虚拟的防火墙,不同的VDOM之间,默认情况下路由表、流量等都是隔离的。
**Split VDOM:**启用Split VDOM 模式[2]后,FortiGate 会产生两个 VDOM,一个root VDOM 和 FG-Traffic VDOM。在Split VDOM 模式下,不能添加新的 VDOM。
这个非常实用的一个模式,激活这个模式能快速的将防火墙的管理平面和数据平面进行分离。但是在7.0.8版本之后,FortiGate取消了Split VDOM模式。
- Root:只能允许管理工作,并且有分离的条目。
- FG-Traffic:可以提供单独的安全策略并允许流量通过 FortiGate,它仅用于数据流量。
激活split-vdom命令:
config system global
set vdom-mode split-vdom
end

Multi-VDOM :在7.0.8版本之后,只有Multi-VDOM模式[3]。Split VDOM模式更加适合小型网络,快速的分离管理和数据平面。Multi-VDOM更加适合ISP,可以划分多个租户并进行隔离,或者需要进行流量细分的大型网络。
激活Multi-VDOM模式之后,所有的VDOM配置都会迁移到root VDOM下,root VDOM用于管理防火墙,无法删除。一次只能存在一个管理 VDOM。建议管理 VDOM 具有 Internet 访问权限,否则与管理相关的服务(例如 FortiGuard 更新和查询)将无法工作。
激活multi-vdom命令:
config system global
set vdom-mode multi-vdom
end

三、实验环境介绍
这里实验环境与之前的《AWS GWLB集成paloalto防火墙》是一样的,只是替换了防火墙产品。
这里AppVpc模拟业务的VPC,APP进出互联网的流量会被引导到SecVpc内的防火墙做安全检测,防火墙允许通过后,流量才能正常通信。
这次实验的核心组件:
GWLB:Gateway Load Balancer与防火墙建立GENEVE[4]隧道,使用UDP 6081来转发数据,这种封装方式让防火墙不用关闭源/目的地址检查,也不用做源/目的NAT的转换。GWLB会在子网创建一个弹性接口,流量通过这个弹性接口来转发。
GWLBe:Gateway Load Balancer endpoint 是由AWS PrivateLink提供的VPC终端节点,可以作为路由表中的下一跳存在,流量送到GWLBe后,会继续送往GWLB背后的实例。
Ingress Route Table:这个路由表关联在IGW上,路由表一般都是关联在子网,这里是AWS 2019年发布的一个功能VPC Ingress Routing[5],让路由表可以关联到IGW上,用于控制入向的流量。

APP访问互联网流量路径(红色箭头)
- AppVpc内的APP1想要访问Internet上的资源,所在子网关联的路由表将默认路由指向了GWLB Endpoint1。
- GWLB Endpoint1 使用 AWS PrivateLink 将流量送到到GWLB,这里流量是由AWS来控制,无需用户配置。
- GWLB会使用IP数据包的5元组或者3元组哈希来选择实例。GWLB使用GENEVE来封装原始IP流量,并通过UDP 6081发送到防火墙。GENEVE封装可以将所有的IP流量送到实例上,GWLB的侦听组上不需要为每个协议和端口配置侦听器。
- 当 GWLB 接收到新的 TCP/UDP 流时,它会使用 5 元组流哈希(源 IP、目标 IP、传输协议、源端口、目标端口)从目标组中选择一个健康的设备。随后,GWLB 将该流的所有数据包(正向和反向)路由到同一设备(粘性)。对于非 TCP/UDP 流,GWLB 仍然使用 3 元组(源 IP、目标 IP、传输协议)进行转发决策。
- 防火墙收到GENEVE报文,需要解封装流量,然后根据防火墙的安全策略决定是否允许流量通过。
- 防火墙重新使用GENEVE封装流量,并发送到GWLB。
- GWLB根据 GENEVE TLV字段,选择转发到GWLB Endpoint1,并且发送时会去除GENEVE封装。
- 为了支持具有重叠 CIDR 的多租户设备,设备需要知道流量的来源。GWLB 还需要跟踪流量并避免用户流量的混合。GWLB 可以通过将每个数据包的类型-长度-值 (TLV) 三元组发送到设备的额外信息(例如 GWLBE/VPCE ID、附件 ID、流 Cookie)来实现这一点。
- GWLB Endpoint1接受到流量,查看子网关联路由表,默认路由指向IGW,流量通过IGW访问Internet。
互联网访问APP的流量路径(蓝色箭头)
- 客户发起对App1公网地址的访问,流量到达AppVpc的IGW,IGW查看所关联的路由表,将流量送往GWLB Endpoint1。
- GWLB Endpoint1 使用 AWS PrivateLink 将流量送到到GWLB。
- GWLB使用GENEVE来封装原始IP流量,并通过UDP 6081转发到实例。
- 防火墙收到GENEVE报文,需要解封装流量,然后根据防火墙的安全策略决定是否允许流量通过。
- 防火墙重新使用GENEVE封装流量,并发送到GWLB。
- GWLB根据 GENEVE TLV字段,选择转发到GWLB Endpoint1,并去除GENEVE封装。
- GWLB Endpoint1接受到流量,查看子网关联路由表,匹配到local路由,流量送到APP1。
四、 配置部署
4.1 VPC 配置
4.1.1 创建VPC
创建两个VPC
VPC名称 网段
AppVpc 10.10.0.0/16
SecVpc 10.20.0.0/16
4.1.2 创建IGW关联VPC
创建两个IGW,分别关联上VPC
4.1.3 创建子网
AppVpc 创建4个子网
子网名称 网段 备注
AppVpc-GWLBe1-Subnet 10.10.10.0/24 AZ1 的Gateway Load Balancer Endpoint所在子网
AppVpc-App1-Subnet 10.10.20.0/24 AZ1 App1 所在子网
AppVpc-GWLBe2-Subnet 10.10.30.0/24 AZ2 的Gateway Load Balancer Endpoint所在子网
AppVpc-App2-Subnet 10.10.40.0/24 AZ2 App2 所在子网

SecVpc 创建4个子网
子网名称 网段 备注
SecVpc-GWLB1-Subnet 10.20.10.0/24 AZ1 FortiGate 数据接口所在子网,GWLB的接口也在此子网
SecVpc-MGT1-Subnet 10.20.20.0/24 AZ1 FortiGate 的管理接口所在子网,可以通过互联网直接访问
SecVpc-GWLB2-Subnet 10.20.30.0/24 AZ2 FortiGate 数据接口所在子网,GWLB的接口也在此子网
SecVpc-MGT2-Subnet 10.20.40.0/24 AZ2 FortiGate 的管理接口所在子网,可以通过互联网直接访问

4.1.4 创建路由表
这里创建路由表之后,暂时先不修改路由,因为有些路由的下一跳是Endpoint,需要等Endpoint创建完成后再修改路由表。
AppVpc创建4个路由表
路由表名称 备注
AppVpc-Igw-Ingress-route-table 这个路由表关联AppVpcIGW,不关联子网,用于将入向流量引导到endpoint
AppVpc-Gwlbe-route-table 这个路由表关联两个GWLBe所在的子网,用于将流量从IGW出去
AppVpc-App1-route-table 这是AZ1 App的路由表,默认路由指向AZ1的endpoint
AppVpc-App2-route-table 这是AZ2 App的路由表,默认路由指向AZ2的endpoint
AppVpc-Igw-Ingress-route-table关联IGW。路由表一般都是关联子网,这里是AWS 2019年发布的一个功能VPC Ingress Routing,让路由表可以关联到IGW上,用于控制入向的流量。
AppVpc-Gwlbe-route-table关联两个GWLBe子网
AppVpc-App1-route-table关联AZ1的APP1的子网。
AppVpc-App2-route-table关联AZ2的APP2的子网。
SecVpc创建1个路由表
路由表名称 备注
SecVpc-Mgt-route-table 默认路由指向IGW,用于互联网访问防火墙的管理接口
SecVpc-Mgt-route-table关联两个管理子网。防火墙的数据接口不需要单独的路由表,因为数据接口主要是和GWLB通过GENVEN隧道通信,当然为数据接口网段单独创建一个路由表也可以,不用添加任何特殊路由。
管理网络的默认路由指向IGW,为了之后从公网连接到防火墙进行初始化。其他路由之后再设置。
4.2 创建实例
4.2.1 创建FortiGate实例
在Marketplace搜索Fortigate关键词,这里图形化界面只提供最新的7.2.2版本选择。要想使用其他版本,可以使用AWS CLI或者CloudFormation启动。
实例命名为Fortigate1,实例类型保持默认。
选择放置在SecVpc,主网卡在SecVpc-GWLB1-Subnet网段,用于防火墙转发数据流量。安全组放行来自本VPC的所有流量,如果要精确放行,可以放行UDP 6081 GENEVE的流量。
再添加一块网卡,放置在AZ1的管理网段。
在User data里面为防火墙创建一个测试账号(可选),Fortigate启动之后默认用户名为admin,密码为实例ID,但是需要重置密码。我觉得重置密码太麻烦,所以这里添加一个测试用户。
另外因为需要通过port2来对防火墙进行管理,所以禁用port1的默认路由,让默认路由从port2出去。
config system admin
edit "labuser"
set accprofile "super_admin"
set vdom "root"
set password FSr1Lliu1qiang2long3DemoZJG5
next
end
config system interface
edit "port1"
set defaultgw disable
set allowaccess ping https ssh fgfm probe-response
next
edit "port2"
set mode dhcp
set allowaccess ping https ssh fgfm probe-response
set defaultgw enable
next
end

申请两个弹性IP,用于关联防火墙的管理接口。
关联Fortigate1的管理接口,注意不要选错接口了。
一样的步骤,关联Fortigate2,查看防火墙关联的弹性IP。
4.2.2 创建APP实例
创建App1,主要用于后续搭建一个HTTP服务,从公网访问测试,这里使用Amazon Linux AMI,保持默认的实例大小即可。
实例放置在AppVpc-App1-Subnet子网,开启自动分配公网IP,安全组放行TCP 8843,后续的HTTP使用8443端口。还可以放行ICMP,便于测试。
创建App2实例,这里使用Window AMI,为了启动速度快一些,这里使用了t3.large的实例类型。App2实例可以用于从公网RDP测试,也可以做为客户端使用浏览器测试互联网访问流量监测。
实例放置在AppVpc-App2-Subnet子网,允许自动获取公网IP地址,安全组保持默认放行3389即可。
4.3 创建GWLB并关联FortiGate
创建Gateway Load Balancer。
指定两台防火墙数据接口所在的子网,GWLB会在这两个子网创建两个弹性接口,GENEVE流量实际从这个弹性接口转发。在这个界面创建侦听组。
实例类型的target会侦听实例的主网卡,防火墙主网卡为port1。
防火墙主接口开启了TCP 443服务,所以使用这个端口来做健康监测。
将两台防火墙注册到侦听组上。
回到创建GWLB的界面,调用刚才创建的侦听组。
启用GWLB的跨区域负载均衡。
确认防火墙的健康检查正常。
4.4 创建Endpoint Service及Endpoint
创建Endpoint Service关联GWLB,测试环境取消勾选Acceptance required,这样当Endpoint发起连接时,不需要再手动确认一次。
记录Endpoint Service name。
AppVpc创建endpoint,填写刚才记录的Endpoint Service name,放置到AppVpc-GWLBe1-Subnet子网。
继续创建endpoint,放置到AppVpc-GWLBe2-Subnet子网。
查看创建的两个endpoint,记录endpoint ID,后续修改路由表需要用到。
记录GWLB弹性接口的IP,之后防火墙的配置需要用到这个IP地址。
4.5 配置路由表
修改IGW关联的路由表,控制去往App网段的流量分别送到两个endpoint上去。
修改App1所在子网的路由,默认路由指向Endpoint1。
修改App2所在子网的路由,默认路由指向Endpoint2。
修改endpoint所在子网的路由,默认路由指向IGW。
4.6 配置FortiGate
4.6.1 登录FortiGate
登录Fortigate1,Fortigate启动之后默认用户名为admin,密码为实例ID。
默认密码为实例ID信息。
首次登陆需要修改密码。
登录Fortigate2,因为在User Data里面创建了新的用户,可以直接使用用户名labuser,密码为FSr1Lliu1qiang2long3DemoZJG5登录。
4.6.2 Fortigate1图形化配置
Fortigate启用VDOM模式。
修改root VDOM的类型。
修改为Admin模式,用于对防火墙进行管理。
新建一个FG-trafficVDOM,类型为Traffic模式,用于转发数据流量。
修改port1关联的VDOM信息。
关联到FG-trafficVDOM上。
进入防火墙命令行模式,配置geneve接口信息(目前图形化不支持此配置)。
config system geneve
edit "geneve1"
set interface "port1"
set type ppp
set remote-ip 10.20.10.32
next
edit "geneve2"
set interface "port1"
set type ppp
set remote-ip 10.20.30.8
next
end

查看创建的geneve接口信息。
创建防火墙策略,放行所有进出geneve1的流量。
同样的步骤,放行所有进出geneve2接口的所有流量。
设置日志信息,开启所有的Local Traffic Log。
配置静态路由,默认路由从两个geneve接口出去,另外设置去往本VPC CIDR网段从port1出去,网关为数据接口所在子网的网关。
因为前面配置了等价默认路由,可能造成从geneve1接口进的流量从geneve2出去。所以配置一下配置策略路由,让从geneve1进的流量从geneve1出去,从geneve2进的流量从geneve2出去。
查看策略路由配置。
4.6.3 Fortigate2命令行配置
配置激活multi-vdom模式,防火墙需要重新登录。
config system global
set vdom-mode multi-vdom
set timezone 08
end
y
end

继续刷其他配置,注意配置替换GWLB的私有IP地址。
end
config vdom
edit root
config system settings
set vdom-type admin
end
y
end
config vdom
edit FG-traffic
config system settings
set vdom-type traffic
end
end
config global
config system interface
edit "port1"
set vdom "FG-traffic"
set defaultgw disable
set allowaccess ping https ssh fgfm probe-response
next
edit "port2"
set vdom "root"
set mode dhcp
set allowaccess ping https ssh fgfm probe-response
set defaultgw enable
next
end
end
config vdom
edit FG-traffic
config system geneve
edit "geneve1"
set interface "port1"
set type ppp
set remote-ip 10.20.30.8
next
edit "geneve2"
set interface "port1"
set type ppp
set remote-ip 10.20.10.32
next
end
config firewall policy
edit 1
set name "1"
set srcintf "geneve1"
set dstintf "geneve1"
set srcaddr "all"
set dstaddr "all"
set action accept
set schedule "always"
set service "ALL"
set logtraffic all
set logtraffic-start enable
next
edit 2
set name "2"
set srcintf "geneve2"
set dstintf "geneve2"
set srcaddr "all"
set dstaddr "all"
set action accept
set schedule "always"
set service "ALL"
set logtraffic all
set logtraffic-start enable
next
end
config log setting
set local-in-allow enable
set local-in-deny-unicast enable
set local-in-deny-broadcast enable
set local-out enable
next
end
config router static
edit 1
set device "geneve1"
next
edit 2
set device "geneve2"
next
edit 3
set dst 10.20.0.0 255.255.0.0
set gateway 10.20.30.1
set device "port1"
next
end
config router policy
edit 1
set input-device "geneve1"
set gateway 10.20.30.8
set output-device "geneve1"
next
edit 2
set input-device "geneve2"
set gateway 10.20.10.32
set output-device "geneve2"
next
end
五、访问测试
5.1 App1 HTTP访问测试
通过SSH连接到App1上,安装HTTP服务,修改端口为8443。
yum install -y httpd
sed -i.bak 's/Listen 80/Listen 8443/g' /etc/httpd/conf/httpd.conf
echo "<h2>Hello World from $(hostname -f)</h2>" > /var/www/html/index.html
systemctl start httpd.service
systemctl enable httpd.service
访问EC2的公网8443端口测试,在浏览器界面可以使用CTRL+F5多强制刷新几次。
查看防火墙的日志信息。
5.2 App2 Windows访问测试
通过RDP连接到App2上。
防火墙查看日志信息。
5.3 防火墙冗余测试
防火墙抓包
FortiGate防火墙可以通过Debug packet flow[7]来查看防火墙对数据包执行的动作,这个抓包方法一般用于排错,输出的信息比较多。也可以通过自带的sniffer工具[8]单纯的抓包,输出的信息比较简洁。
Debug packet flow
例如:这里首先暂停了之前的抓包进程,然后抓取地址包含114.114.114.114的10个报文。
diagnose debug flow trace stop
diagnose debug enable
diagnose debug flow filter addr 114.114.114.114
diagnose debug flow show function-name enable
diagnose debug flow trace start 10
也可以通过协议来进行过滤,这里只查看icmp协议的报文。
diagnose debug flow trace stop
diagnose debug enable
diagnose debug flow filter proto 1
diagnose debug flow show function-name enable
diagnose debug flow trace start 10
运行的效果如下:
自带sniffer工具抓包
例如,这里抓取来自port1端口,端口号为6081的报文,其实就是GENVEN报文。
FGT-GWLB-1 (FG-traffic) # diagnose sniffer packet port1 'port 6081'
例如,这里抓取来所有的icmp报文。
FGT-GWLB-1 (FG-traffic) # diagnose sniffer packet any icmp 4
抓包命令结果如下:
可以利用sniff抓包来确认流量目前走哪一台防火墙,然后stop这个防火墙实例,查看流量多长时间能够切换成功,测试防火墙的高可用切换。注意,如果是已经建立的会话,切换时间会长一点,如果是新建会话,切换时间会快一点。
六、清理实验环境步骤
到上面其实实验已经做完了,既然是实验,肯定是需要清空实验环境的。这个实验有一些依赖调用,有时候不太好删除,另外如果漏删除了EIP和卷,还会持续产生费用。
按照下面步骤可以彻底清空前面所有操作创建的资源,不会有依赖报错。
1. 终止所有实例。
2. 解除AppVpc的4个路由表关联的子网和IGW。
3. 删除AppVpc的4个路由表。
4. 删除2个Endpoint。
5. 删除Endpoint Service。
6. 删除AppVpc。
7. 删除GWLB。
8. 删除SecVpc。
9. 删除Target Group。
10. 释放申请的2个EIP。
七、参考文档
-
[1] 亚马逊云科技(中国区)网关负载均衡服务集成FortiGate安全网关扩展安全服务性能:https://aws.amazon.com/cn/blogs/china/gateway-load-balancing-services-integrate-fortigate-security-gateways/
-
[2] FortiGate 6.4.10 Split-Task VDOM Mode:https://docs.fortinet.com/document/fortigate/6.4.10/administration-guide/758820/split-task-vdom-mode
-
[3] FortiGate 7.2 VDOM overview:https://docs.fortinet.com/document/fortigate/7.2.2/administration-guide/597696/vdom-overview
-
[4] RFC 8926 Geneve: Generic Network Virtualization Encapsulation:https://www.rfc-editor.org/rfc/rfc8926
-
[5] New – VPC Ingress Routing – Simplifying Integration of Third-Party Appliances:https://aws.amazon.com/cn/blogs/aws/new-vpc-ingress-routing-simplifying-integration-of-third-party-appliances
-
[6] FortiGate VDOM Configuration: Complete Guide:https://networkinterview.com/fortigate-vdom-configuration/
-
[7] FortiGate / FortiOS 7.2.1 Administration Guide Debugging the packet flow:https://docs.fortinet.com/document/fortigate/7.2.1/administration-guide/054688/debugging-the-packet-flow
-
[8] Troubleshooting Tip: Using the FortiOS built-in packet sniffer:https://community.fortinet.com/t5/FortiGate/Troubleshooting-Tip-Using-the-FortiOS-built-in-packet-sniffer/ta-p/194222