网络应用防火墙(WAF)可以保护网络应用,免受各种攻击。这些攻击包括但不限于跨站脚本攻击、SQL注入攻击、Cookie污染等等。对于访问量特别大的应用,最要防的是机器人流量。这些流量哪怕并不直接攻击,但是会占用服务器资源,导致不能正常响应真实人类用户的请求。比如,电商的爆品,在某一时刻开启购买,就得防止技术黄牛的流量。

这具体怎么做呢?一般都是购买了 WAF 来完成这件事。各大云厂商(阿里云盾、AWS CloudFront)、CDN 服务商(Cloudflare、Akamai)等都提供这种 WAF 服务。由于流量在到达真正的服务之前,会被 CDN 和 WAF 连接器进行过滤,就可以有效防止机器人刷流量。以下是用登录场景做为例子的一个序列图:

image.png

其中授权服务,比如之前介绍过的 Keycloak、Duende IdentityServer 等,是多个应用依赖的服务,如果不被保护,裸奔在网络上,很容易被机器人流量挤爆,影响所有系统的登录。

可以看到 WAF 会在原始的 html 请求里添加一些脚本,来收集浏览器指纹信息,并对流量做过滤。对于识别出的机器人流量,会在打到授权服务前被拦截阻止,达到保护认证服务的目的。

最后,附上这个序列图的源码(使用 mermaid js 画的):

sequenceDiagram autonumber

participant UA as 用户 participant C as CDN participant AS as 连接器 participant RS as 授权服务

activate UA UA ->> RS: GET id6.azurewebsite.net/login note left of UA: 用户请求授权 RS -->> UA: html

UA ->> C: GET /obfuscated C ->> AS: GET /v6/challenge/APIKEYID note left of UA: 页面上包含了一段脚本,
对用户进行进行验证 AS -->> C: JavaScript challenge 代码 C -->> UA: JavaScript challenge 代码

UA ->> C: POST /obfuscated C ->> AS: POST /v6/challenge/APIKEYID note left of UA: 浏览器上传自己的指纹
并请求令牌 AS -->> C: 令牌 C -->> UA: 令牌 note left of UA: 存储令牌到 Cookie 中 deactivate UA

alt 生物人 activate UA UA ->> C: POST /api/v1/account/login C ->> AS: POST /v6/challenge/APIKEYID AS -->> C: 允许访问,放行 C ->> RS: POST /api/v1/account/login RS -->> UA: 200 OK deactivate UA else 机器人 activate UA UA ->> C: POST /api/v1/account/login C ->> AS: POST /v6/challenge/APIKEYID AS -->> C: 拒绝访问,阻止 C -->> UA: 403 Forbidden 禁止访问 deactivate UA end