- 方案概述:
AWS-Fortinet关键应用联合防御解决方案通过整合AWS资源和Fortinet产品的优势,可以为客户量身打造既有针对性又满足适用性的个性化安全防护解决方案。作为安全威胁综合防御场景里的最佳实践之一,本方案使用集中式部署架构,通过自动化部署快速完成整套AWS云上基础设施搭建以及Fortinet产品开箱即用,展示如何使用FortiGate和FortiWeb协同防护API Gateway + Lambda的关键应用威胁防御和响应。
- 适配场景:
- 支持多可用区部署。灵活适配单可用区、双可用区和三个可用区的不同业务需求;
- 解决方案符合并支持“信息安全技术:网络安全等级保护基本要求”(GB/T 22239-2019) (等保);
- 支持FortiGate-VM防火墙、FortiWeb-VM应用防火墙的灵活部署。可两者联合组网,也可每种产品独立提供解决方案。
- 不但支持对VPC内业务实例的威胁综合防御,而且提供对API Gateway + Lambda等SaaS服务的威胁防护与响应。
- 方案特点:
- 前置防御:FortiGate-VM防火墙 + AWS Gateway Load Balancer (GWLB),在流量入站时,进入VPC的第一时间进行南北向安全检查;
- 分层防御:FortiGate-VM作为出口防火墙,应对入侵检测、恶意软件/病毒等安全威胁;FortiWeb-VM作为WEB应用防火墙,提供全面的关键业务防护;
- 重点防御:FortiWeb-VM应用防火墙拥有机器学习引擎,能够防御OWASP Top10攻击、机器人威胁,提供API防护,可以灵活定制、适配应用场景;
- 南北防护:入站业务流量通过边缘关联拦截进入防火墙做流量清洗,出站返回流量、出站实例流量通过VPC路由表引流至防火墙做安全检查;
- 东西检查:无论是同VPC,还是同账号下的不同VPC,可以按实际业务要求,分别采用Transit Gateway (TGW) 或者自定义路由引流至防火墙做流量检查;
- 紧密聚合:FortiGate-VM防火墙、FortiWeb-VM应用防火墙共同部署在业务VPC中,使业务流量的调度更加紧凑
- 自动化:通过Terraform自动化部署脚本,可以轻松快速的实现按需配置整套AWS云上基础设施以及Fortinet产品的开箱即用。
- 方案架构示意图:
- 方案资源规划:
- VPC Prod SecOps的子网概述
名称 | CIDR | 说明 |
subnet-natgw-az1 | 172.25.211.0/24 | 部署有AZ1的NAT Gateway (natgw-az1),用于本方案中的AZ1实例的出站 |
subnet-natgw-az2 | 172.25.212.0/24 | 部署有AZ2的NAT Gateway (natgw-az2),用于本方案中的AZ2实例的出站 |
subnet-nlb-public-az1 | 172.25.201.0/24 | 部署有nlb-public在AZ1的弹性网卡eni-nlb-az1 |
subnet-nlb-public-az2 | 172.25.202.0/24 | 部署有nlb-public在AZ2的弹性网卡eni-nlb-az2 |
subnet-gwlbe-az1 | CIDR无须展示,请自行定义 | 部署有GWLB在AZ1的Endpoint,对应的弹性网卡为gwlbe-hub-az1 |
subnet-gwlbe-az2 | 部署有GWLB在AZ2的Endpoint,对应的弹性网卡为gwlbe-hub-az2 | |
subnet-fgt-port1-az1 | CIDR无须展示,请自行定义 | 部署有FortiGate-VM的port1网卡,用于FortiGate的许可激活、特征库更新等,仅有管理流量,不承载业务流量。 |
subnet-fgt-port1-az2 | ||
subnet-fgt-port2-az1 | CIDR无须展示,请自行定义 | 部署有FortiGate-VM的port2网卡,用于通过GENEVE协议与AWS的GWLB连接;同时图1中的GWLB也部署并关联这两个subnets |
subnet-fgt-port2-az2 | ||
subnet-fwb-az1 | CIDR无须展示,请自行定义 | 部署有FortiWeb-VM |
subnet-fwb-az2 | ||
subnet-app-az1 | CIDR无须展示,请自行定义 | 部署有WEB服务器实例,以及DVWA靶场服务器 |
subnet-app-az2 | 部署有WEB服务器实例 | |
subnet-faz-az1 | CIDR无须展示,请自行定义 | 部署有Fortinet的日志分析产品FortiAnalyzer-VM |
- VPC Prod SecOps的路由表概述
名称 | 关联的SUBNETs | 说明 |
VPC Edge Association | N/A | 控制VPC Connect的入站路由,即当有目标是natgw-az1 (172.25.211.0/24)、nagw-az2 (172.25.212.0/24)、nlb-public-az1 (172.25.201.0/24)、nlb-public-az2 (172.25.202.0/24)的入站流量时,流量会被转发到对应AZ的GWLB Endpoint (gwlbe-az*) |
rtb-natgw-az1 | subnet-natgw-az1 | 控制subnet-natgw的出站路由表,默认路由指向gwlbe |
rtb-natgw-az2 | subnet-natgw-az2 | |
rtb-nlb-public-az1 | subnet-nlb-public-az1 | 控制subnet-nlb-public的出站路由表,subnet-nlb-public部署有AWS NLB,默认路由指向gwlbe |
rtb-nlb-public-az2 | subnet-nlb-public-az2 | |
rtb-gwlbe | subnet-gwlbe-az1 subnet-gwlbe-az2 | 控制GWLB endpoint的出站路由表,默认路由指向IGW |
rtb-nva-mgmt | subnet-fgt-port1-az1 subnet-fgt-port1-az2 subnet-fwb-az1 subnet-fwb-az2 subnet-faz-az1 | 控制网络虚拟设备(NVA)的出站路由表,FortiGate-VM防火墙、FortiWeb-VM应用防火墙、FortiAnalyzer-VM日志分析的EIP弹性公网IP均使用该路由表出站,默认路由指向IGW |
rtb-app-az1 | subnet-app-az1 | 控制应用服务实例的出站,默认路由指向各可用区的NAT网关(natgw) |
rtb-app-az2 | subnet-app-az2 |
- 方案部署说明:
- Terraform概述
可以通过Github Fortinet 中国区的仓库获取Fortinet 中国区工程师已经编写完成的Terraform自动化部署工程,解决方案对应的Terraform工程,在Github上terraform-fortinet-china/terraform-awschina/fgtvm-gwlb-with-fwb/的目录找到,如下图:
- 红色圈出的文件:表示将要部署的AWS的云上资源。文件名中的数字不代表Terraform部署的顺序,仅作为逻辑上梳理架构的提示。云上资源的部署顺序由Terraform代码和AWS共同决定。这些AWS的云上基础设施资源包括:VPC (可使用已有VPC)、子网、安全组、Internet网关(可使用已有IGW)、GWLB、Endpoint Service、VPC路由表。
- 蓝色圈出的文件:代表Terraform模块,感兴趣的朋友可以查看modules目录,观察到FortiGate-VM,FortiWeb-VM,NLB和用于测试的Ubuntu实例均实现了模块部署,不但方便对上述资源的大规模部署,也方便这部分代码移植到其它的工程项目中。
- 绿色圈出的文件:代表需要修改的部分,terraform.tfvars文件中包括了VPC和Subnet的CIDR,可用区信息,需要自定义的资源名称,Fortinet产品的管理信息等等。
-
- Terraform部署
- 初始化工程项目
确保进入fgtvm-gwlb-with-fbw工程目录后,再运行下列命令;
如果您已经按照Github Fortinet 中国区的仓库的说明指导完成了初始化,请忽略这一步。
terraform init |
- 修改terraform.tfvars以适配您的项目需求
ProjectName = "fgtvm-gwlb-with-fwb" | # 您的项目名称 |
CompanyName = "FTNT" | # 您的公司名称 |
enableNewVpcNgfw = true | # 是否新建VPC和Internet网关。如果false,请参照文件中的指导,在DryRun时传入ID |
enableNlbPreserveClientIp = true | # 是否开启NLB的保持ClientIP功能 该功能在本工程配置下,后续仅能通过CLI控制 |
enableDemoBastion = false | # 是否部署用于演示用途的堡垒机 (VNC) |
该堡垒机不支持GB/T 22239-2019 | |
regionName = "cn-northwest-1" | # 您项目部署的AWS Region |
# azList = ["a"] # azList = ["b"] # azList = ["c"] azList = ["a", "b"] # azList = ["a", "c"] # azList = ["b", "c"] # azList = ["a", "b", "c"] | # 您将要使用的可用区,以及可用区数量 选择单AZ,双AZ,三AZ,其余保持注释状态即可 |
vpcName = "VPC-NGFW" | # 您的VPC名称,当上方enableNewVpcNgfw为false时,仅需要修改VPC的CIDR,与您实际的CIDR保持一致即可 |
cidrVpcNgfw = "172.25.0.0/16" | |
cidrSubnetFgtPort1 | # cidrSubnetFgtPort1为FortiGate-VM防火墙Port1对应3个可用区的子网。如果仅有1个可用区,则实际仅第一组IP会生效。其它的子网以此类推。 |
cidrSubnetFgtPort2 | |
cidrSubnetFwbPort1 | |
cidrSubnetNlbPublic | |
cidrSubnetNatgwVpcNgfw | |
cidrSubnetGwlbeNgfw | |
cidrSubnetApp | |
cidrSubnetBastionVncAz1 | # 演示用VNC堡垒机的子网 |
cntFgtByol = 0 | # FortiGate-VM BYOL许可的部署数量 |
licenseFiles | # BYOL的许可文件,请copy到本目录下 |
cntFgtPayg = 1 | # FortiGate-VM PAYG的部署数量 |
instanceTypeFgtFixed = "c5.large" | # BYOL和PAGY实例的类型。对于BYOL许可,请确保许可vCPU数量与实例类型匹配 |
portFgtHttps = "8443" | # FortiGate-VM防火墙的GUI管理端口 |
versionFgt = "fgtvm70" | # FortiGate-VM防火墙部署的版本,可后续升级 |
cntFwbByol = 1 | # FortiWeb-VM应用防火墙的部署数量 |
instanceTypeFwbFixed = "m5.large" | # FortiWeb-VM应用防火墙的实例类型 |
portFwbHttps = "8443" | # FortiWeb-VM应用防火墙的GUI管理端口 |
portsNlb | # NLB的监听、业务、健康检查端口定义 |
versionUbuntu = "bionic1804" | # 测试Ubuntu实例的版本, 18.04, 20.04, 22.04 |
keynameUbuntu = "kpc_ubuntu" | # 测试Ubuntu实例的KeyPair名称 |
- DryRun
当您完成上步,即Terraform工程与您AWS环境的适配后,您就可以执行下面的命令,测试Terraform是否满足部署条件。
terraform plan -out=tfplan |
[注] 期间可能会弹出Warning或者Error,主要是由于镜像市场Marketplace订阅导致的,如上图,请点击进入FortiGate-VM的产品,选择订阅即可。
请针对FortiWeb-VM重复同样的订阅操作。
- 部署
如果上步的DryRun通过,您可以观察到terraform输出的FortiGate-VM、FortiWeb-VM登录信息以及业务NLB的访问URL,取决于您是否选择部署堡垒机,输出会有不同。
terraform apply tfplan |
-
- FortiWeb配置
FortiWeb,简称为FWB,是Fortinet的WAF产品。可保护托管的Web应用免受针对已知和未知漏洞的攻击。FortiWeb使用人工智能增强的多层次和关联检测方法,为应用程序提供针对已知漏洞和零日威胁的防护。下面的配置过程,请登录FWB的WEB-GUI界面后从WEB-CLI控制台发起,或者通过SSH远程登录FWB的CLI。
-
-
- 配置FWB的“虚拟服务器”(Virtual Server)
-
config server-policy vserver | # 进入Virtual Server的配置 |
edit "vsrv" | # 创建名为'vsrv'的Virtual Server |
config vip-list | |
edit 0 | |
set interface port1 | # 对于云上的FWB实例,通常建议使用主弹性网卡对应的port1 |
set use-interface-ip enable | # 使用实例主弹性网卡,而非VIP |
next | |
end | |
next | |
end |
-
-
- 配置FWB的“服务器池”(Server Pool)
-
- 创建针对Terraform中WEB服务器实例的Server Pool
当上节Terraform创建时,terraform.tfvar文件中的变量enableSimpleWebSrv = true 时,即表示部署一组简单的WEB应用实例,其中位于可用区1的subnet-app的IP为192.168.251.72 (请根据您Terraform部署后的实例实际IP填写),当从浏览器发起访问,如http://nlb-public-98bfxxxx3f4exxxx.elb.cn-northwest-1.amazonaws.com.cn时,请求将由FWB反向代理发送至这个192.168.251.72的WEB实例。
config server-policy server-pool | # 进入Server Pool的配置 |
edit "websrv" | # 创建名为'websrv'的Server Pool |
config pserver-list | |
edit 0 | |
set ip 192.168.251.72 | # 为便于理解,此处仅配置可用区1的WEB实例 |
next | |
end | |
next | |
end |
- 创建针对Terraform中DVWA靶场的Server Pool
当上节Terraform创建时,terraform.tfvar文件中的变量enableDemoDvwa = true 时,即表示部署一个DVWA靶场实例,其中位于可用区1的subnet-app的IP为192.168.251.112 (请根据您Terraform部署后的实例实际IP填写),当从浏览器发起访问,如http://nlb-public-98bfxxxx3f4exxxx.elb.cn-northwest-1.amazonaws.com.cn/DVWA/login.php时,请求将由FWB反向代理发送至这个192.168.251.112的DVWA实例。
config server-policy server-pool | # 进入Server Pool的配置 |
edit "DVWA" | # 创建名为'DVWA'的Server Pool |
config pserver-list | |
edit 0 | |
set ip 192.168.251.112 | # 此即为DVWA的内网IP |
next | |
end | |
next | |
end |
-
-
- 配置FWB的“WEB保护”(Web Protection Profile)
-
- 创建针对Terraform中WEB服务器实例的Web Protection Profile
config waf web-protection-profile inline-protection | # 进入WEB保护的配置 | |
edit "websrv-protection" | # 创建名为'websrv-protection'的WEB保护 | |
set signature-rule "Standard Protection" | # Standard Protection为FWB内置的特征库 | |
set file-upload-policy WebShell-Uploading | # 文件上传防护为FWB内置的'WebShell-Uploading' | |
set webshell-detection-policy WebShell-Uploading | # 同上,FWB已内置 | |
set custom-access-policy "Predefined - Advanced Protection" | # 同上,FWB已内置 | |
set ip-intelligence enable | ||
set bot-mitigate-policy "Predefined - Bot Mitigation" | # 同上,FWB已内置 | |
next | ||
end |
- 创建针对Terraform中DVWA靶场的Web Protection Profile
DVWA的Web Protection Profile将暂时与WEB服务器实例共用websrv这个profile。
config server-policy http-content-routing-policy | # 进入内容路由策略的配置 |
edit "croute-websrv" | # 创建名为'croute-websrv'的策略 |
set server-pool websrv | # 将服务器池websrv与本内容路由策略关联 |
config content-routing-match-list | |
edit 1 | |
set match-condition equal | |
set match-expression nlb-public-98bfxxxx3f4exxxx.elb.cn-northwest-1.amazonaws.com.cn | # 当命中该HTTP-HOST时,将触发内容路由,将请求代理到服务器池websrv |
set concatenate or | |
next | |
end | |
next | |
end |
- 创建针对DVWA靶场的内容路由
config server-policy http-content-routing-policy | # 进入内容路由策略的配置 |
edit "croute-dvwa" | # 创建名为'croute-dvwa'的策略 |
set server-pool DVWA | # 将服务器池DVWA与本内容路由策略关联 |
config content-routing-match-list | |
edit 1 | |
set match-object http-request | # 检查HTTP-REQUEST |
set match-condition match-dir | # 检查HTTP URL |
set match-expression DVWA | # 当ULR中含有DVWA的目录时,触发内容路由,将请求代理到服务器池dvwa |
set concatenate or | |
next | |
end | |
next | |
end |
config server-policy policy | # 进入服务期策略 (server-policy) |
edit "CONTENT-ROUTING" | # 创建名为'CONTENT-ROUTING"的策略 |
set deployment-mode http-content-routing | |
set ssl enable | |
set vserver vsrv | |
set service HTTP | # 前端HTTPS访问,TLS的卸载会发生在NLB,所以FWB接收的流量均是HTTP |
set replacemsg Predefined | |
set ssl-custom-cipher ECDHE-ECDSA-AES256-GCM-SHA384 ECDHE-RSA-AES256-GCM-SHA384 ECDHE-ECDSA-CHACHA20-POLY1305 ECDHE-RSA-CHACHA20-POLY1305 ECDHE-ECDSA-AES128-GCM-SHA256 ECDHE-RSA-AES128-GCM-SHA256 ECDHE-ECDSA-AES256-SHA384 ECDHE-RSA-AES256-SHA384 ECDHE-ECDSA-AES128-SHA256 ECDHE-RSA-AES128-SHA256 ECDHE-ECDSA-AES256-SHA ECDHE-RSA-AES256-SHA ECDHE-ECDSA-AES128-SHA ECDHE-RSA-AES128-SHA AES256-GCM-SHA384 AES128-GCM-SHA256 AES256-SHA256 AES128-SHA256 | |
config http-content-routing-list | |
edit 2 | # 暂时从2开始,1预留给lambda |
set content-routing-policy-name croute-dvwa | # 使用上步创建的内容路由策略“croute-dvwa" |
set web-protection-profile websrv-protection | # 暂时使用"WEB保护"创建的websrv-protection |
next | |
edit 3 | |
set content-routing-policy-name croute-websrv | # 使用上步创建的内容路由策略“croute-websrv" |
set web-protection-profile websrv-protection | # 使用"WEB保护"创建的websrv-protection |
next | |
end | |
set tlog enable | # 启用流量日志 |
next | |
end |
- 方案效果展示:
- 具体API Gateway和Lambda服务的建立取决于每个应用场景,本文参考AWS文档“Tutorial: Build a Hello World REST API with Lambda proxy integration”创建了一组用于功能演示的服务。
按文档创建完毕后,可以通过URL,如https://xzxxxxxxxx.execute-api.cn-northwest-1.amazonaws.com.cn/dev/helloworld?name=Daniel&city=Fortinet 验证服务的有效性,如下图所示。请注意下图中标注了API Gateway的Stage为’dev’,该Stage将作为FWB的HTTP目录,用于HTTP内容路由的标记。
- 创建针对API Gateway的“服务器池”
在上章“FortiWeb配置内容路由”中,已经创建有websrv和DVWA的服务器池,本节创建针对lambda的服务器池,使用上节创建API Gateway时生成的域名domain作为FWB的后端服务器,并启用SSL,指定端口为443.
config server-policy server-pool | # 进入Server Pool的配置 |
edit "lambda" | # 创建名为'lambda'的Server Pool |
config pserver-list | |
edit 0 | |
set server-type domain | |
set domain xzxxxxxxxx.execute-api.cn-northwest-1.amazonaws.com.cn | # 填入上步创建的API Gateway服务URL |
set port 443 | |
set ssl enable | # 启用SSL |
set ssl-custom-cipher ECDHE-ECDSA-AES256-GCM-SHA384 ECDHE-RSA-AES256-GCM-SHA384 ECDHE-ECDSA-CHACHA20-POLY1305 ECDHE-RSA-CHACHA20-POLY1305 ECDHE-ECDSA-AES128-GCM-SHA256 ECDHE-RSA-AES128-GCM-SHA256 ECDHE-ECDSA-AES256-SHA384 ECDHE-RSA-AES256-SHA384 ECDHE-ECDSA-AES128-SHA256 ECDHE-RSA-AES128-SHA256 ECDHE-ECDSA-AES256-SHA ECDHE-RSA-AES256-SHA ECDHE-ECDSA-AES128-SHA ECDHE-RSA-AES128-SHA AES256-GCM-SHA384 AES128-GCM-SHA256 AES256-SHA256 AES128-SHA256 | |
next | |
end | |
next | |
end |
- 创建针对API Gateway的“WEB保护”
针对lambda的WEB保护需要重写FWB发往API Gateway的HTTP host。与DVWA的防暴破类似,现定义URL重写的规则,再定义URL重写的规则组,最后关联规则组至WEB保护。
- URL重写规则
config waf url-rewrite url-rewrite-rule | # 进入WAF URL重写规则定义 |
edit "lambda-url-rewrite-rule" | # 创建名为'lambda-url-rewrite-rule' |
set host-status enable | |
set host-use-pserver enable | # 使用FWB作为host重写 |
set host FORTIWEB_PSERVER | |
config match-condition | |
edit 0 | # 当匹配来自于NLB的请求时,才进行URL重写 |
set reg-exp nlb-public-98bfxxxx3f4exxxx.elb.cn-northwest-1.amazonaws.com.cn | |
Next | |
End | |
Next | |
End |
- URL重写规则组
config waf url-rewrite url-rewrite-policy | # 进入WAF URL重写规则组定义 |
edit "lambda-url-rewrite-grp" | # 创建名为'lambda-url-rewrite-grp' |
config rule | |
edit 0 | |
set url-rewrite-rule-name lambda-url-rewrite-rule | # 该组关联重写规则 |
next | |
end | |
next | |
end |
- 创建针对lambda的WEB保护lambda-protection,并关联URL重写规则组
config waf web-protection-profile inline-protection | # 进入WEB保护的配置 |
edit "lambda-protection" | # 创建名为"lambda-protection"的规则组 |
set signature-rule "Standard Protection" | |
set url-rewrite-policy lambda-url-rewrite-grp | # WAF重写关联上步创建的规则组 |
set file-upload-policy WebShell-Uploading | |
set webshell-detection-policy WebShell-Uploading | |
set custom-access-policy "Predefined - Advanced Protection" | |
set ip-intelligence enable | |
set bot-mitigate-policy "Predefined - Bot Mitigation" | |
next | |
end |
- 创建针对API Gateway的“HTTP内容路由”
config server-policy http-content-routing-policy | # 进入内容路由策略的配置 |
edit "croute-lambda" | # 创建名为'croute-lambda'的策略 |
set server-pool lambda | # 将服务器池lambda与本内容路由策略关联 |
config content-routing-match-list | |
edit 1 | |
set match-object http-request | # 检查HTTP-REQUEST |
set match-condition match-dir | # 检查HTTP URL |
set match-expression dev | # 当ULR中含有API Gateway创建的Stage的dev目录时,触发内容路由,将请求代理到服务器池lambda |
set concatenate or | |
next | |
end | |
next | |
end |
进入server policy,修改CONTENT-ROUTING,增加一个内容路由条目1,关联lambda的内容路由croute-lambda和WEB保护lambda-protection
config server-policy policy | # 进入服务期策略 (server-policy) |
edit "CONTENT-ROUTING" | # 进入为'CONTENT-ROUTING"的策略 |
config http-content-routing-list | |
edit 1 | # 创建1 |
set content-routing-policy-name croute-lambda | |
set web-protection-profile lambda-protection | # 关联上步创建的针对API Gateway + Lambda的WEB保护lambda-protection |
next | |
end | |
next | |
end |
- 方案效果展示:
- 访问URL,如https://nlb-public-98bfxxxx3f4exxxx.elb.cn-northwest-1.amazonaws.com.cn/dev/helloworld?name=Daniel&city=Fortinet, 可获得如5.3.1一样的Lambda执行的返回页面,如下图所示:
- 在FWB上查看日志,Log Details中的HTTP Host与URL部分(下图红色圈)与我们的访问操作对应;Log Details中的Policy、HTTP Content Routing和Server Pool部分(下图蓝色圈)与5.3.4和5.3.2的配置对应。
- 在FortiGate防火墙流量日志中可以观察到南北检查状态下的该条流量,被防火墙应用控制识别为HTTPBROWSER,对应浏览器为Firefox。如果lambda应用包含有File Upload等服务,可以在防火墙层面检测到病毒文件,从而实现针对Lambda的病毒防护。
您可以在亚马逊云科技 Marketplace 中订阅并采购本方案中的 Fortinet 相关产品:
FortiGate:
BYOL(Graviton):FortiGate Next-Generation Firewall (ARM64/Graviton)
BYOL:FortiGate Next-Generation Firewall (BYOL)
FortiWeb: