Cloud Armor 预配置 WAF 规则 Codelab

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 基础知识 ( Codelab)
  • 网络组建和管理以及 TCP/IP 基础知识
  • Unix/Linux 命令行基础知识
  • 通过 Google Cloud 中的网络完成 GCP 中的网络导览,很有帮助
  • (可选)完成 Cloudnet20 Cloud Armor 实验,了解如何通过 SQL 注入、基于 IP 和基于地理位置的规则保护工作负载。

Codelab 拓扑和应用场景

119e13312f3cec25.jpeg

图 1 - Cloud Armor WAF 规则 Codelab 拓扑

OWASP Juice Shop 应用对于安全培训和安全意识很有用,因为它包含 OWASP 10 大安全漏洞的每个设计实例。攻击者可利用该漏洞进行测试。在此 Codelab 中,我们将使用它演示一些应用攻击,然后使用 Cloud Armor WAF 规则保护应用。该应用的前端是一个 Google Cloud 负载平衡器,Cloud Armor 安全政策和规则将应用于该负载平衡器。它将在公共互联网上提供,因此几乎可以随时随地访问,并使用 Cloud Armor 和 VPC 防火墙规则进行保护。

2. 设置和要求

自定进度的环境设置

  1. 登录 Cloud 控制台,然后创建一个新项目或重复使用现有项目。 如果您还没有 Gmail 或 Google Workspace 账号,则必须创建一个

96a9c957bc475304

b9a10ebdf5b5a448.png

a1e3c01a38fa61c2.png

请记住项目 ID,它在所有 Google Cloud 项目中都是唯一的名称(上述名称已被占用,您无法使用,抱歉!)。它稍后将在此 Codelab 中被称为 PROJECT_ID

  1. 接下来,您需要在 Cloud 控制台中启用结算功能,才能使用 Google Cloud 资源。

运行此 Codelab 应该不会产生太多的费用(如果有费用的话)。请务必按照“清理”部分部分,其中会指导您如何关停资源,以免产生超出本教程范围的结算费用。Google Cloud 的新用户符合参与 300 美元的免费试用计划的条件。

启动 Cloud Shell

虽然可以通过笔记本电脑对 Google Cloud 进行远程操作,但在此 Codelab 中,您将使用 Google Cloud Shell,这是一个在云端运行的命令行环境。

在 GCP 控制台中,点击右上角工具栏上的 Cloud Shell 图标:

bce75f34b2c53987.png

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

f6ef2b5f13479f3a.png

这个虚拟机已加载了您需要的所有开发工具。它提供了一个持久的 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 通过端口 3000 访问测试应用网站的外部 IP。第二条防火墙规则将用于允许来自负载平衡器的来源 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

创建 FW 规则以允许 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 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 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].

验证果汁店服务是否处于在线状态

通过 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
<...>

你还可以通过浏览器查看果汁店!

428c18eee6708c28

我们现在可以探索 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 标志以查看完整输出。

观察知名扫描器的访问权限

商业和开源软件都会出于各种目的扫描应用,包括扫描漏洞。这些工具使用众所周知的用户代理和其他标头。观察 curl 是否适用于众所周知的用户代理标头:

通过 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 核心规则集,应用查找规则的规则(包括命令注入)。系统会检测并阻止典型的操作系统命令。

在 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 核心规则集 ver.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 安全规则

至此我们已经创建了安全政策,让我们来具体看看已配置了哪些规则。

d00e4102fc89e44f.png

规则是按优先级评估的:优先级数值较小的规则会先进行评估,规则触发后,系统不会继续处理优先级值较高的规则。

  • 优先级 9000 - 禁止 LFI(包含本地文件)
  • 优先级 9001 - 阻止 RCE(远程代码执行/命令注入)
  • 优先级 9002 - 检测到阻止扫描器
  • 优先级 9003 - HTTP 拆分和 HTTP 走私等块协议攻击
  • 优先级 9004 - 阻止会话修复攻击
  • 优先级 10000 - 允许您的 IP 访问网站
  • 默认优先级 - 拒绝。

*注意“允许您的 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 日志

983a6cab0cff940d

RCE 日志

988a3a571f9d9d45

扫描器检测日志

7ed661863ba27555

协议攻击日志

17ee3cbe0bd98939

会话固定日志

80d1ddfd0fe982e1

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 十大攻击

后续步骤