1. 简介
您好!欢迎参加 Cloud Armor 预配置的 WAF 规则 Codelab!
Google Cloud Armor 是 Google 的企业边缘网络安全解决方案,提供 DDoS 防护、WAF 规则强制执行和大规模自适应可管理性。
Cloud Armor 扩展了预配置 WAF 规则集,旨在抵御 OWASP 十大风险 Web 应用安全漏洞。这些规则集基于 OWASP Modsecurity 核心规则集 3.0.2 版,旨在防范某些最常见的 Web 应用安全风险,包括本地文件包含 (LFI)、远程文件包含 (RFI)、远程代码执行 (RCE) 等。
在本 Codelab 中,您将学习如何使用 Google Cloud Armor WAF 规则来抵御某些常见漏洞。
学习内容
- 如何设置实例组和全球负载均衡器以支持服务
- 如何使用预配置的 WAF 规则配置 Cloud Armor 安全政策,以防范 LFI、RCE、扫描器、协议攻击和会话固定攻击
- 如何通过观察日志来验证 Cloud Armor 是否有效抵御了攻击。
所需条件
- Google Compute Engine 基础知识(实验)
- 网络组建和管理以及 TCP/IP 基础知识
- Unix/Linux 命令行基础知识
- 最好先完成 Google Cloud 中的网络导览,了解 GCP 中的网络
- (可选)完成 Cloudnet20 Cloud Armor 实验,学习如何使用 SQL 注入、基于 IP 的规则和基于地理位置的规则来保护工作负载。
Codelab 拓扑和使用情形

图 1 - Cloud Armor WAF 规则 Codelab 拓扑
OWASP Juice Shop 应用对于开展安全培训、培养安全意识非常有用,因为它的设计特意包含了“OWASP 十大风险安全漏洞”中每一个漏洞的实例。攻击者可以出于测试目的利用它。在此 Codelab 中,我们将使用它来演示一些应用攻击,随后使用 Cloud Armor WAF 规则来保护应用。该应用将以 Google Cloud 负载均衡器作为前端,Cloud Armor 安全政策和规则将应用于该负载均衡器。它将在公共互联网上提供服务,因此几乎可以从任何位置访问,并使用 Cloud Armor 和 VPC 防火墙规则进行保护。
2. 设置和要求
自定进度的环境设置



请记住项目 ID,它在所有 Google Cloud 项目中都是唯一的名称(上述名称已被占用,您无法使用,抱歉!)。它稍后将在此 Codelab 中被称为 PROJECT_ID。
- 接下来,您需要在 Cloud 控制台中启用结算功能,才能使用 Google Cloud 资源。
运行此 Codelab 应该不会产生太多的费用(如果有费用的话)。请务必按照“清理”部分中的所有说明操作,该部分介绍了如何关停资源,以免产生超出本教程范围的结算费用。Google Cloud 的新用户符合参与 $300 USD 免费试用计划的条件。
启动 Cloud Shell
虽然可以通过笔记本电脑对 Google Cloud 进行远程操作,但在此 Codelab 中,您将使用 Google Cloud Shell,这是一个在云端运行的命令行环境。
在 GCP 控制台中,点击右上角工具栏上的 Cloud Shell 图标:

预配和连接到环境应该只需要片刻时间。完成后,您应该会看到如下内容:

这个虚拟机已加载了您需要的所有开发工具。它提供了一个持久的 5GB 主目录,并且在 Google Cloud 中运行,大大增强了网络性能和身份验证功能。只需一个浏览器,即可完成本实验中的所有工作。
准备工作
在 Cloud Shell 中,确保项目 ID 已设置
gcloud config list project gcloud config set project [YOUR-PROJECT-NAME] PROJECT_ID=[YOUR-PROJECT-NAME] echo $PROJECT_ID
启用 API
启用所有必要的服务
gcloud services enable compute.googleapis.com gcloud services enable logging.googleapis.com gcloud services enable monitoring.googleapis.com
3. 创建 VPC 网络
创建 VPC 网络
在 Cloud Shell 中
gcloud compute networks create ca-lab-vpc --subnet-mode custom
输出
Created NAME SUBNET_MODE BGP_ROUTING_MODE IPV4_RANGE GATEWAY_IPV4 ca-lab-vpc CUSTOM REGIONAL
创建子网
在 Cloud Shell 中
gcloud compute networks subnets create ca-lab-subnet \
--network ca-lab-vpc --range 10.0.0.0/24 --region us-central1
输出
Created NAME REGION NETWORK RANGE ca-lab-subnet us-central1 ca-lab-vpc 10.0.0.0/24
创建 VPC 防火墙规则
创建 VPC 和子网之后,您现在需要设置一些防火墙规则。第一条防火墙规则将用于允许所有 IP 访问测试应用网站外部 IP 的 3000 端口。第二条防火墙规则将用于允许来自负载均衡器源 IP 的健康检查。
在 Cloud Shell 中
gcloud compute firewall-rules create allow-js-site --allow tcp:3000 --network ca-lab-vpc
输出
Creating firewall...done. NAME NETWORK DIRECTION PRIORITY ALLOW DENY DISABLED allow-js-site ca-lab-vpc INGRESS 1000 tcp:3000 False
创建防火墙规则,以允许来自 Google 健康检查范围的健康检查。
在 Cloud Shell 中
gcloud compute firewall-rules create allow-health-check \
--network=ca-lab-vpc \
--action=allow \
--direction=ingress \
--source-ranges=130.211.0.0/22,35.191.0.0/16 \
--target-tags=allow-healthcheck \
--rules=tcp
输出
Creating firewall...done. NAME NETWORK DIRECTION PRIORITY ALLOW DENY DISABLED allow-health-check ca-lab-vpc INGRESS 1000 tcp False
4. 设置测试应用
下一步是创建测试应用,在本例中是 OWASP Juice Shop Web 服务器。
创建计算实例时,我们使用容器映像来确保服务器具备适当的服务。此服务器将部署在 us-central1-c 中,并具有允许健康检查的网络标记。
创建 OWASP Juice Shop 应用
使用知名的开源 OWASP Juice Shop 应用作为存在漏洞的应用。您还可以通过 网站使用此应用,以进行 OWASP 安全挑战。
在 Cloud Shell 中
gcloud compute instances create-with-container owasp-juice-shop-app --container-image bkimminich/juice-shop \
--network ca-lab-vpc \
--subnet ca-lab-subnet \
--private-network-ip=10.0.0.3 \
--machine-type n1-standard-2 \
--zone us-central1-c \
--tags allow-healthcheck
输出
NAME ZONE MACHINE_TYPE PREEMPTIBLE owasp-juice-shop-app us-central1-c n1-standard-2 INTERNAL_IP EXTERNAL_IP STATUS 10.0.0.3 <public IP> RUNNING
设置 Cloud 负载均衡器组件:实例组
创建非托管式实例组。
在 Cloud Shell 中
gcloud compute instance-groups unmanaged create juice-shop-group \
--zone=us-central1-c
输出
NAME LOCATION SCOPE NETWORK MANAGED INSTANCES juice-shop-group us-central1-c zone 0
将 Juice Shop GCE 实例添加到非托管式实例组。
在 Cloud Shell 中
gcloud compute instance-groups unmanaged add-instances juice-shop-group \
--zone=us-central1-c \
--instances=owasp-juice-shop-app
输出
Updated [https://www.googleapis.com/compute/v1/projects/<project name>/zones/us-central1-c/instanceGroups/juice-shop-group].
将命名端口设置为 Juice Shop 应用的端口。
在 Cloud Shell 中
gcloud compute instance-groups unmanaged set-named-ports \ juice-shop-group \ --named-ports=http:3000 \ --zone=us-central1-c
输出
Updated [https://www.googleapis.com/compute/v1/projects/<project name>/zones/us-central1-c/instanceGroups/juice-shop-group].
现在您已经创建了非托管式实例组,接下来需要创建健康检查、后端服务、网址映射、目标代理和转发规则。
设置 Cloud 负载均衡器组件:健康检查
为 Juice Shop 服务端口创建健康检查。
在 Cloud Shell 中
gcloud compute health-checks create tcp tcp-port-3000 \
--port 3000
输出
Created NAME PROTOCOL tcp-port-3000 TCP
设置 Cloud 负载均衡器组件:后端服务
创建后端服务参数。
在 Cloud Shell 中
gcloud compute backend-services create juice-shop-backend \
--protocol HTTP \
--port-name http \
--health-checks tcp-port-3000 \
--enable-logging \
--global
输出
NAME BACKENDS PROTOCOL juice-shop-backend HTTP
将 Juice Shop 实例组添加到后端服务。
在 Cloud Shell 中
gcloud compute backend-services add-backend juice-shop-backend \
--instance-group=juice-shop-group \
--instance-group-zone=us-central1-c \
--global
输出
Updated [https://www.googleapis.com/compute/v1/projects/cythom-host1/global/backendServices/juice-shop-backend].
设置 Cloud 负载均衡器组件:网址映射
创建要发送到后端的网址映射。
在 Cloud Shell 中
gcloud compute url-maps create juice-shop-loadbalancer \
--default-service juice-shop-backend
输出
NAME DEFAULT_SERVICE juice-shop-loadbalancer backendServices/juice-shop-backend
设置 Cloud 负载均衡器组件:目标代理
创建目标代理以充当网址映射的前端。
在 Cloud Shell 中
gcloud compute target-http-proxies create juice-shop-proxy \
--url-map juice-shop-loadbalancer
输出
NAME URL_MAP juice-shop-proxy juice-shop-loadbalancer
设置 Cloud 负载均衡器组件:转发规则
为负载均衡器创建转发规则。
在 Cloud Shell 中
gcloud compute forwarding-rules create juice-shop-rule \
--global \
--target-http-proxy=juice-shop-proxy \
--ports=80
输出
Created [https://www.googleapis.com/compute/v1/projects/cythom-host1/global/forwardingRules/juice-shop-rule].
验证 Juice Shop 服务是否在线
在 Cloud Shell 中
PUBLIC_SVC_IP="$(gcloud compute forwarding-rules describe juice-shop-rule --global --format="value(IPAddress)")"
在 Cloud Shell 中
echo $PUBLIC_SVC_IP
输出
<public VIP of service>
请等待几分钟后再继续,否则您可能会收到 HTTP/1.1 404 Not Found 响应。
在 Cloud Shell 中
curl -Ii http://$PUBLIC_SVC_IP
输出
HTTP/1.1 200 OK <...>
您也可以在浏览器中查看 Juice Shop!

现在,我们已准备好探索 Juice Shop 漏洞,以及如何使用 Cloud Armor WAF 规则集来防范这些漏洞。
5. 演示已知漏洞
为了节省时间,我们将通过简化的步骤演示 Cloud Armor WAF 规则传播前后的状态。
观察 LFI 漏洞:路径遍历
“本地文件包含”是指利用请求中缺乏输入验证的漏洞,来查看服务器上存在的文件,从而可能泄露敏感数据的过程。下面只是展示了路径遍历的可行性。使用浏览器或 curl,观察应用提供的现有路径。
在 Cloud Shell 中
curl -Ii http://$PUBLIC_SVC_IP/ftp
输出
HTTP/1.1 200 OK <...>
另请注意,路径遍历也同样可以正常工作:
在 Cloud Shell 中
curl -Ii http://$PUBLIC_SVC_IP/ftp/../
输出
HTTP/1.1 200 OK <...>
观察 RCE 漏洞
远程代码执行包括各种 UNIX 和 Windows 命令注入场景,允许攻击者执行通常仅限特权用户使用的操作系统命令。下面展示了一个传入的简单 ls 命令执行示例。
在 Cloud Shell 中
curl -Ii http://$PUBLIC_SVC_IP/ftp?doc=/bin/ls
输出
HTTP/1.1 200 OK <...>
您可以移除 curl 标志来观察完整的输出。
观察已知扫描器的访问情况
商业扫描应用和开源扫描应用都会出于各种目的(包括扫描漏洞)执行扫描。这些工具使用常见的 User-Agent 和其他标头。观察 curl 使用常见的 User-Agent 标头:
在 Cloud Shell 中
curl -Ii http://$PUBLIC_SVC_IP -H "User-Agent: blackwidow"
输出
HTTP/1.1 200 OK <...>
观察协议攻击:HTTP 拆分
某些 Web 应用会使用用户的输入来生成响应中的标头。如果应用未能正确过滤输入,攻击者可能会使用 %0d%0a 序列(用于分隔不同行的 CRLF 序列)来污染输入参数。这样一来,响应结果可能会被任何执行解析的实体(例如中间代理服务器)解读为两个响应,从而可能在随后的请求中提供虚假内容。在输入参数中插入 %0d%0a 序列,这可能会导致系统显示具有误导性的页面。
在 Cloud Shell 中
curl -Ii "http://$PUBLIC_SVC_IP/index.html?foo=advanced%0d%0aContent-Length:%200%0d%0a%0d%0aHTTP/1.1%20200%20OK%0d%0aContent-Type:%20text/html%0d%0aContent-Length:%2035%0d%0a%0d%0a<html>Sorry,%20System%20Down</html>"
输出
HTTP/1.1 200 OK <...>
观察会话固定
在 Cloud Shell 中
curl -Ii http://$PUBLIC_SVC_IP -H session_id=X
输出
HTTP/1.1 200 OK <...>
6. 定义 Cloud Armor WAF 规则
列出预配置的 WAF 规则:
在 Cloud Shell 中
gcloud compute security-policies list-preconfigured-expression-sets
输出
EXPRESSION_SET
Sqli-canary
RULE_ID
owasp-crs-v030001-id942110-sqli
owasp-crs-v030001-id942120-sqli
<...>
创建 Cloud Armor 安全政策
在 Cloud Shell 中执行以下命令:
gcloud compute security-policies create block-with-modsec-crs \
--description "Block with OWASP ModSecurity CRS"
更新安全政策默认规则
请注意,默认规则的优先级数值为 2147483647
在 Cloud Shell 中执行以下命令:
gcloud compute security-policies rules update 2147483647 \
--security-policy block-with-modsec-crs \
--action "deny-403"
由于默认规则配置为拒绝操作,我们必须允许来自您自己的 IP 的访问。请找到您的公共 IP(可以通过 curl、ipmonkey、whatismyip 等方式查找)。
在 Cloud Shell 中执行以下命令:
MY_IP=$(curl ifconfig.me)
添加第一条规则,以允许从您自己的 IP(在下方代码中插入您的 IP)进行访问
在 Cloud Shell 中执行以下命令:
gcloud compute security-policies rules create 10000 \
--security-policy block-with-modsec-crs \
--description "allow traffic from my IP" \
--src-ip-ranges "$MY_IP/32" \
--action "allow"
更新安全政策以阻止 LFI 攻击
应用 OWASP ModSecurity 核心规则集,防止“本地文件包含”所需的路径遍历。
在 Cloud Shell 中执行以下命令:
gcloud compute security-policies rules create 9000 \
--security-policy block-with-modsec-crs \
--description "block local file inclusion" \
--expression "evaluatePreconfiguredExpr('lfi-stable')" \
--action deny-403
更新安全政策,以阻止远程代码执行 (RCE)
根据 OWASP ModSecurity 核心规则集,应用查找 RCE(包括命令注入)的规则。检测并阻止典型的操作系统命令。
在 Cloud Shell 中执行以下命令:
gcloud compute security-policies rules create 9001 \
--security-policy block-with-modsec-crs \
--description "block rce attacks" \
--expression "evaluatePreconfiguredExpr('rce-stable')" \
--action deny-403
更新安全政策以阻止安全扫描器
应用 OWASP ModSecurity 核心规则集,阻止已知的安全扫描器、脚本化 HTTP 客户端和网络爬虫。
在 Cloud Shell 中执行以下命令:
gcloud compute security-policies rules create 9002 \
--security-policy block-with-modsec-crs \
--description "block scanners" \
--expression "evaluatePreconfiguredExpr('scannerdetection-stable')" \
--action deny-403
更新安全政策以阻止协议攻击
根据 OWASP ModSecurity 核心规则集,应用用于查找回车符 (CR) %0d、换行符 (LF) %0a 以及其他类型的协议攻击(例如 HTTP 请求走私)的规则。
在 Cloud Shell 中执行以下命令:
gcloud compute security-policies rules create 9003 \
--security-policy block-with-modsec-crs \
--description "block protocol attacks" \
--expression "evaluatePreconfiguredExpr('protocolattack-stable')" \
--action deny-403
更新安全政策以阻止会话固定
根据 OWASP ModSecurity 核心规则集,应用以下规则:
在 Cloud Shell 中执行以下命令:
gcloud compute security-policies rules create 9004 \
--security-policy block-with-modsec-crs \
--description "block session fixation attacks" \
--expression "evaluatePreconfiguredExpr('sessionfixation-stable')" \
--action deny-403
将安全政策附加到后端服务
在 Cloud Shell 中执行以下命令:
gcloud compute backend-services update juice-shop-backend \
--security-policy block-with-modsec-crs \
--global
规则可能需要一段时间才能生效(但不会超过 10 分钟)。在确信经过足够的时间后,测试之前演示的漏洞,以在下一步中确认 Cloud Armor WAF 规则的强制执行情况。
7. 观察采用了 OWASP ModSecurity 核心规则集的 Cloud Armor 保护机制
确认 LFI 漏洞已得到缓解
在 Cloud Shell 中
curl -Ii http://$PUBLIC_SVC_IP/?a=../
输出
HTTP/1.1 403 Forbidden <...>
确认 RCE 攻击已得到缓解
在 Cloud Shell 中
curl -Ii http://$PUBLIC_SVC_IP/ftp?doc=/bin/ls
输出
HTTP/1.1 403 Forbidden <..>
确认已知扫描器检测有效
在 Cloud Shell 中
curl -Ii http://$PUBLIC_SVC_IP -H "User-Agent: blackwidow"
输出
HTTP/1.1 403 Forbidden <..>
确认协议攻击已得到缓解
根据 OWASP ModSecurity 核心规则集 3.0.2 版,通过以下方式确认协议攻击已得到缓解:
在 Cloud Shell 中
curl -Ii "http://$PUBLIC_SVC_IP/index.html?foo=advanced%0d%0aContent-Length:%200%0d%0a%0d%0aHTTP/1.1%20200%20OK%0d%0aContent-Type:%20text/html%0d%0aContent-Length:%2035%0d%0a%0d%0a<html>Sorry,%20System%20Down</html>"
输出
HTTP/1.1 403 Forbidden <..>
确认会话固定攻击尝试已被阻止
在 Cloud Shell 中
curl -Ii http://$PUBLIC_SVC_IP/?session_id=a
输出
HTTP/1.1 403 Forbidden <..>
8. 查看 Cloud Armor 安全规则
现在我们已经创建了安全政策,下面我们来看看具体配置了哪些规则。

规则按照优先级评估:优先级值较小的规则最先评估,一旦触发,系统就不会继续处理优先级值更高的规则。
- 优先级 9000 - 阻止 LFI(本地文件包含)
- 优先级 9001 - 阻止 RCE(远程代码执行/命令注入)
- 优先级 9002 - 阻止检测到的扫描器
- 优先级 9003 - 阻止 HTTP 拆分和 HTTP 走私等协议攻击
- 优先级 9004 - 阻止会话固定攻击
- 优先级 10000 - 允许您的 IP 地址访问网站
- 优先级 Default - 拒绝。
*请注意,为“允许您的 IP”规则配置的优先级数值最大(即最后评估),以允许访问网站,但依然能阻止任何攻击。
9. 观察 Cloud Armor 安全政策日志
在 Cloud Armor 控制台页面中,您可以查看安全政策的详细信息,然后依次点击 Logs 标签页和 View policy logs 链接,前往 Cloud Logging 页面。它会自动基于关注的安全政策执行过滤,例如 resource.type:(http_load_balancer) AND jsonPayload.enforcedSecurityPolicy.name:(block-with-modsec-crs)。观察 403 错误响应代码,并展开日志详情,观察强制执行的安全政策的名称、匹配的字段值,以及下方预配置的表达式 ID(或签名 ID)。以下屏幕截图中的日志示例对应的是本 Codelab 所配置的强制执行安全政策。
LFI 日志

RCE 日志

扫描器检测日志

协议攻击日志

会话固定日志

10. 实验清理
您已完成本实验,现在请清理资源。
运行以下命令可删除 Cloud Armor 安全政策、负载均衡器、实例、防火墙规则和 VPC 网络。
从后端服务中移除 Cloud Armor 安全政策
gcloud -q compute backend-services update juice-shop-backend --security-policy "" --global
删除 Cloud Armor 安全政策
删除安全政策会自动删除关联的规则。
gcloud -q compute security-policies delete block-with-modsec-crs
删除负载均衡器资源
要删除的这些负载均衡器资源包括转发规则、目标 HTTP 代理、网址映射、后端、健康检查和实例组。
gcloud -q compute forwarding-rules delete juice-shop-rule --global
gcloud -q compute target-http-proxies delete juice-shop-proxy
gcloud -q compute url-maps delete juice-shop-loadbalancer
gcloud -q compute backend-services delete juice-shop-backend \
--global
gcloud -q compute health-checks delete tcp-port-3000
gcloud -q compute instance-groups unmanaged delete juice-shop-group --zone=us-central1-c
删除实例
gcloud -q compute instances delete owasp-juice-shop-app --zone us-central1-c
删除防火墙规则、子网和 VPC
gcloud -q compute firewall-rules delete allow-health-check gcloud -q compute firewall-rules delete allow-js-site gcloud -q compute networks subnets delete ca-lab-subnet --region us-central1 gcloud -q compute networks delete ca-lab-vpc
11. 恭喜!
恭喜您完成了 Cloud Armor 预配置的 WAF 规则 Codelab!
所学内容
- 如何设置实例组和全球 Cloud 负载均衡器
- 如何使用预配置的 WAF 规则配置 Cloud Armor 安全政策,以防范 LFI、RCE、扫描器、协议攻击和会话固定攻击
- 如何通过日志验证 Cloud Armor 是否有效抵御了部分 OWASP 十大攻击
后续步骤
- 使用 Cloud Armor 预配置的 WAF 规则保护您的应用免受 OWASP 十大漏洞的侵害
- 根据敏感度级别微调规则
- 使用自定义规则语言参考文档可实现更具体的安全强制执行。