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-traffic
VDOM,类型为Traffic
模式,用于转发数据流量。
修改port1
关联的VDOM信息。
关联到FG-traffic
VDOM上。
进入防火墙命令行模式,配置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