AWS VPC 流量集中检测系列--(3)AWS GWLB集成FortiGate防火墙

AWS VPC 流量集中检测系列--(3)AWS GWLB集成FortiGate防火墙
B站视频

一、背景

之前在《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上,用于控制入向的流量。

GWLB-Fortigate

APP访问互联网流量路径(红色箭头)

  1. AppVpc内的APP1想要访问Internet上的资源,所在子网关联的路由表将默认路由指向了GWLB Endpoint1。
  2. GWLB Endpoint1 使用 AWS PrivateLink 将流量送到到GWLB,这里流量是由AWS来控制,无需用户配置。
  3. 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、传输协议)进行转发决策。
  4. 防火墙收到GENEVE报文,需要解封装流量,然后根据防火墙的安全策略决定是否允许流量通过。
  5. 防火墙重新使用GENEVE封装流量,并发送到GWLB。
  6. GWLB根据 GENEVE TLV字段,选择转发到GWLB Endpoint1,并且发送时会去除GENEVE封装。
    • 为了支持具有重叠 CIDR 的多租户设备,设备需要知道流量的来源。GWLB 还需要跟踪流量并避免用户流量的混合。GWLB 可以通过将每个数据包的类型-长度-值 (TLV) 三元组发送到设备的额外信息(例如 GWLBE/VPCE ID、附件 ID、流 Cookie)来实现这一点。
  7. GWLB Endpoint1接受到流量,查看子网关联路由表,默认路由指向IGW,流量通过IGW访问Internet。

互联网访问APP的流量路径(蓝色箭头)

  1. 客户发起对App1公网地址的访问,流量到达AppVpc的IGW,IGW查看所关联的路由表,将流量送往GWLB Endpoint1。
  2. GWLB Endpoint1 使用 AWS PrivateLink 将流量送到到GWLB。
  3. GWLB使用GENEVE来封装原始IP流量,并通过UDP 6081转发到实例。
  4. 防火墙收到GENEVE报文,需要解封装流量,然后根据防火墙的安全策略决定是否允许流量通过。
  5. 防火墙重新使用GENEVE封装流量,并发送到GWLB。
  6. GWLB根据 GENEVE TLV字段,选择转发到GWLB Endpoint1,并去除GENEVE封装。
  7. 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,分别关联上VPCimage-20220921113918034

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 所在子网

image-20220921105143914

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 的管理接口所在子网,可以通过互联网直接访问

image-20220921105910094

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上,用于控制入向的流量。image-20220921115109559

AppVpc-Gwlbe-route-table关联两个GWLBe子网image-20220921115113783

AppVpc-App1-route-table关联AZ1的APP1的子网。image-20220921115119782

AppVpc-App2-route-table关联AZ2的APP2的子网。image-20220921115123253

SecVpc创建1个路由表

路由表名称					 备注
SecVpc-Mgt-route-table		默认路由指向IGW,用于互联网访问防火墙的管理接口

SecVpc-Mgt-route-table关联两个管理子网。防火墙的数据接口不需要单独的路由表,因为数据接口主要是和GWLB通过GENVEN隧道通信,当然为数据接口网段单独创建一个路由表也可以,不用添加任何特殊路由。image-20220921115634502

管理网络的默认路由指向IGW,为了之后从公网连接到防火墙进行初始化。其他路由之后再设置。image-20220921152230406

4.2 创建实例

4.2.1 创建FortiGate实例

在Marketplace搜索Fortigate关键词,这里图形化界面只提供最新的7.2.2版本选择。要想使用其他版本,可以使用AWS CLI或者CloudFormation启动。image-20221029161939329

实例命名为Fortigate1,实例类型保持默认。image-20221029162116208

选择放置在SecVpc,主网卡在SecVpc-GWLB1-Subnet网段,用于防火墙转发数据流量。安全组放行来自本VPC的所有流量,如果要精确放行,可以放行UDP 6081 GENEVE的流量。image-20221029163540589

再添加一块网卡,放置在AZ1的管理网段。image-20221030165324131

在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

image-20221029193353505

申请两个弹性IP,用于关联防火墙的管理接口。image-20221029164111215

关联Fortigate1的管理接口,注意不要选错接口了。image-20221029193424400

一样的步骤,关联Fortigate2,查看防火墙关联的弹性IP。image-20221029164127928

4.2.2 创建APP实例

创建App1,主要用于后续搭建一个HTTP服务,从公网访问测试,这里使用Amazon Linux AMI,保持默认的实例大小即可。image-20220921150935832

实例放置在AppVpc-App1-Subnet子网,开启自动分配公网IP,安全组放行TCP 8843,后续的HTTP使用8443端口。还可以放行ICMP,便于测试。image-20220921150942179

创建App2实例,这里使用Window AMI,为了启动速度快一些,这里使用了t3.large的实例类型。App2实例可以用于从公网RDP测试,也可以做为客户端使用浏览器测试互联网访问流量监测。image-20220921150947193

实例放置在AppVpc-App2-Subnet子网,允许自动获取公网IP地址,安全组保持默认放行3389即可。image-20220921150951645

4.3 创建GWLB并关联FortiGate

创建Gateway Load Balancer。image-20220921163436613

指定两台防火墙数据接口所在的子网,GWLB会在这两个子网创建两个弹性接口,GENEVE流量实际从这个弹性接口转发。在这个界面创建侦听组。image-20221029200311957

实例类型的target会侦听实例的主网卡,防火墙主网卡为port1。image-20221029200317879

防火墙主接口开启了TCP 443服务,所以使用这个端口来做健康监测。image-20221029200328405

将两台防火墙注册到侦听组上。image-20221029200333502

回到创建GWLB的界面,调用刚才创建的侦听组。image-20221029200338130

启用GWLB的跨区域负载均衡。image-20221029200345664

确认防火墙的健康检查正常。image-20221029200709620

4.4 创建Endpoint Service及Endpoint

创建Endpoint Service关联GWLB,测试环境取消勾选Acceptance required,这样当Endpoint发起连接时,不需要再手动确认一次。image-20221029201052078

记录Endpoint Service name。image-20221029201155632

AppVpc创建endpoint,填写刚才记录的Endpoint Service name,放置到AppVpc-GWLBe1-Subnet子网。image-20221029201718704

继续创建endpoint,放置到AppVpc-GWLBe2-Subnet子网。image-20221029201959380

查看创建的两个endpoint,记录endpoint ID,后续修改路由表需要用到。image-20221029202426360

记录GWLB弹性接口的IP,之后防火墙的配置需要用到这个IP地址。image-20221029202432030

4.5 配置路由表

修改IGW关联的路由表,控制去往App网段的流量分别送到两个endpoint上去。image-20221029203817148

修改App1所在子网的路由,默认路由指向Endpoint1。image-20221029203825201

修改App2所在子网的路由,默认路由指向Endpoint2。image-20221029203829312

修改endpoint所在子网的路由,默认路由指向IGW。image-20221029203834257

4.6 配置FortiGate

4.6.1 登录FortiGate

登录Fortigate1,Fortigate启动之后默认用户名为admin,密码为实例ID。image-20221029194914827

默认密码为实例ID信息。image-20221029194919342

首次登陆需要修改密码。image-20221029194923447

登录Fortigate2,因为在User Data里面创建了新的用户,可以直接使用用户名labuser,密码为FSr1Lliu1qiang2long3DemoZJG5登录。image-20221029194943606

4.6.2 Fortigate1图形化配置

Fortigate启用VDOM模式。image-20221029220538580

修改root VDOM的类型。image-20221029220600720

修改为Admin模式,用于对防火墙进行管理。image-20221029220607547

新建一个FG-trafficVDOM,类型为Traffic模式,用于转发数据流量。image-20221029220613028

修改port1关联的VDOM信息。image-20221029222533078

关联到FG-trafficVDOM上。image-20221029222602779

进入防火墙命令行模式,配置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

image-20221029222636973

查看创建的geneve接口信息。image-20221029220637915

创建防火墙策略,放行所有进出geneve1的流量。image-20221029222853729

同样的步骤,放行所有进出geneve2接口的所有流量。image-20221029220648831

设置日志信息,开启所有的Local Traffic Logimage-20221029220653602

配置静态路由,默认路由从两个geneve接口出去,另外设置去往本VPC CIDR网段从port1出去,网关为数据接口所在子网的网关。image-20221029220708297

因为前面配置了等价默认路由,可能造成从geneve1接口进的流量从geneve2出去。所以配置一下配置策略路由,让从geneve1进的流量从geneve1出去,从geneve2进的流量从geneve2出去。image-20221029220911653

查看策略路由配置。image-20221029220717615

4.6.3 Fortigate2命令行配置

配置激活multi-vdom模式,防火墙需要重新登录。

config system global
    set vdom-mode multi-vdom
    set timezone 08
    end
y
end

image-20221029233112317

继续刷其他配置,注意配置替换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多强制刷新几次。image-20221029233652230

查看防火墙的日志信息。image-20221029233822358

5.2 App2 Windows访问测试

通过RDP连接到App2上。image-20221029234520051

防火墙查看日志信息。image-20221029234527146

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

运行的效果如下:image-20221029235013924

自带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

抓包命令结果如下:image-20221029235212480

可以利用sniff抓包来确认流量目前走哪一台防火墙,然后stop这个防火墙实例,查看流量多长时间能够切换成功,测试防火墙的高可用切换。注意,如果是已经建立的会话,切换时间会长一点,如果是新建会话,切换时间会快一点。image-20221025233825647

六、清理实验环境步骤

到上面其实实验已经做完了,既然是实验,肯定是需要清空实验环境的。这个实验有一些依赖调用,有时候不太好删除,另外如果漏删除了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。

七、参考文档