zecm-via/crowdsec-bouncer-traefik-plugin
GitHub: zecm-via/crowdsec-bouncer-traefik-plugin
该插件将 CrowdSec 的 IP 声誉判断与 AppSec WAF 能力集成到 Traefik 反向代理中,实现对恶意请求的实时封禁或验证码挑战。
Stars: 0 | Forks: 0



[](https://github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin/actions)
[](https://goreportcard.com/badge/github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin)
# Crowdsec Bouncer Traefik 插件
此插件旨在以 Traefik 插件的形式实现一个 Crowdsec Bouncer。
其目的是使 Traefik 能够根据 IP 的声誉和行为,对来自这些 IP 的请求进行授权或拦截。
Crowdsec 实用程序将提供社区黑名单,其中包含在 Crowdsec 网络中被大量举报并经验证被封禁的 IP。
当与 Crowdsec 结合使用时,它将利用本地 API 分析 Traefik 的日志,并对用户/机器人发出的请求做出决策。恶意行为者将根据其针对您网站使用的模式而被封禁。
从插件版本 1.2.0 和 Crowdsec 1.6.0 开始支持 Appsec 功能。
AppSec 组件提供:
- 低成本的虚拟补丁功能。
- 支持您原有的 ModSecurity 规则。
- 将传统 WAF 的优势与高级 CrowdSec 功能相结合,以实现其他方式难以完成的高级行为检测。
有关 Appsec 的更多信息,请参阅 [Crowdsec 文档](https://doc.crowdsec.net/docs/next/appsec/intro/)。
由 [Crowdsec](https://docs.crowdsec.net/u/bouncers/intro) 提供且受该插件支持的风险控制措施可以是 `ban` 或 `captcha`。
对于 `ban` 风险控制,用户将在 Traefik 中被拦截(HTTP 403)。
对于 `captcha` 风险控制,用户将被重定向到一个页面以完成验证码挑战。
成功完成后,如果 Crowdsec 仍有决策需要验证用户行为,该用户将在一段指定时间内被清除记录,之后可能需要再次进行验证。有关更多信息和配置说明,请参阅验证码示例。
目前支持以下验证码提供商:
- [hcaptcha](https://www.hcaptcha.com/)
- [recaptcha](https://www.google.com/recaptcha/about/)
- [turnstile](https://www.cloudflare.com/products/turnstile/)
- [custom/wicketkeeper](https://github.com/a-ve/wicketkeeper)
此插件有 5 种运行模式:
| 模式 | 描述 |
| ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| none | 如果客户端 IP 在封禁列表中,它将收到 HTTP 403 响应。否则,请求将照常继续。所有请求都会调用 Crowdsec LAPI |
| live | 如果客户端 IP 在封禁列表中,它将收到 HTTP 403 响应。否则,请求将照常继续。bouncer 可以利用本地缓存来减少向 Crowdsec LAPI 发出的请求数量。它将缓存每个发起查询的 IP 的状态。 |
| stream | 流式模式允许您在本地缓存中仅保留被封禁的 IP,每个未命中缓存的请求都会被授权。每隔一分钟,缓存会根据 Crowdsec LAPI 的最新信息进行更新。 |
| alone | 独立模式,类似于流式模式,但黑名单 IP 是从 CAPI 获取的。每隔两小时,缓存会根据 Crowdsec CAPI 的最新信息进行更新。它不包含任何本地封禁的 IP,但可以在没有 crowdsec 服务的情况下工作。 |
| appsec | 禁用 Crowdsec IP 检查,但应用 Crowdsec Appsec 检查。此模式适用于在防火墙级别应用 Crowdsec IP 检查的情况。 |
为了提高性能,建议使用 `流式模式`,默认情况下决策每 60 秒更新一次,这是 Traefik 和 Crowdsec 之间唯一的通信。发生的每个请求都会命中缓存以便快速做出决策。
缓存可以是 Traefik 本地的内存缓存,也可以使用单独的 Redis 实例。
以下是详细说明每种模式工作原理的 Mermaid 图表:
## 用法
要开始使用,请使用 `docker-compose.yml` 文件。
您可以通过以下方式运行它:
```
make run
```
### 注意
### 变量
- Enabled
- bool
- 默认值:false
- 启用插件
- LogLevel
- string
- 默认值:`INFO`,期望值为:`DEBUG`、`INFO`、`WARN`、`ERROR`
- 日志将写入 `stdout` / `stderr`,如果提供了 LogFilePath,则写入文件
- LogFormat
- string
- 默认值:`common`,期望值为:`common`、`json`
- 日志格式:`common` 用于传统文本日志,`json` 用于结构化 JSON 日志
- LogFilePath
- string
- 默认值:""
- 写入日志的文件路径,必须可被 Traefik 写入,日志轮转可能需要重启 Traefik
- MetricsUpdateIntervalSeconds
- int64
- 默认值:600
- 向 Crowdsec 更新指标的时间间隔(秒)
- 如果设置为 0 或更小,则禁用指标收集
- CrowdsecMode
- string
- 默认值:`live`,期望值为:`none`、`live`、`stream`、`alone`、`appsec`
- CrowdsecAppsecEnabled
- bool
- 默认值:false
- 启用 Crowdsec Appsec Server (WAF)。
- CrowdsecAppsecHost
- string
- 默认值:"crowdsec:7422"
- 可用的 Crowdsec Appsec Server 主机和端口。
- CrowdsecAppsecTlsInsecureVerify
- bool
- 默认值:false
- 禁用对 Appsec 提供的证书的验证
- CrowdsecAppsecTlsCertificateAuthority
- string
- 默认值:""
- Appsec 的 PEM 编码证书授权机构 (CA)
- CrowdsecAppsecScheme
- string
- 默认值:`CrowdsecLapiScheme` 的值,期望值为:`http`、`https`
- CrowdsecAppsecPath
- string
- 默认值:"/"
- 可用的 Crowdsec Appsec Server 路径。将附加到 CrowdsecAppsecHost 后面。必须以 "/" 结尾。
- CrowdsecAppsecFailureBlock
- bool
- 默认值:true
- 当 Crowdsec Appsec Server 返回 [状态码 500](https://docs.crowdsec.net/docs/next/appsec/protocol#response-code) 时阻止请求。
- CrowdsecAppsecUnreachableBlock
- bool
- 默认值:true
- 当 Crowdsec Appsec Server 无法访问时阻止请求。
- CrowdsecAppsecBodyLimit
- int64
- 默认值:10485760 (= 10MB)
- 仅将前指定数量的字节传输给 Crowdsec Appsec Server。
- CrowdsecAppsecKey
- string
- 默认值:`CrowdsecLapiKey` 的值
- bouncer 的 Crowdsec AppSec 密钥。
- CrowdsecLapiScheme
- string
- 默认值:`http`,期望值为:`http`、`https`
- CrowdsecLapiHost
- string
- 默认值:"crowdsec:8080"
- 可用的 Crowdsec LAPI 主机和端口。
- CrowdsecLapiPath
- string
- 默认值:"/"
- 可用的 Crowdsec LAPI Server 路径。将附加到 CrowdsecLapiHost 后面。必须以 "/" 结尾。
- CrowdsecLapiKey
- string
- 默认值:""
- bouncer 的 Crowdsec LAPI 密钥。
- CrowdsecLapiTlsInsecureVerify
- bool
- 默认值:false
- 禁用对 Crowdsec LAPI 提供的证书的验证
- CrowdsecLapiTlsCertificateAuthority
- string
- 默认值:""
- Crowdsec LAPI 的 PEM 编码证书授权机构 (CA)
- CrowdsecLapiTlsCertificateBouncer
- string
- 默认值:""
- bouncer 的 PEM 编码客户端证书
- CrowdsecLapiTlsCertificateBouncerKey
- string
- 默认值:""
- bouncer 的 PEM 编码客户端私钥
- ClientTrustedIPs
- string
- 默认值:[]
- 受信任的客户端 IP 列表,它们将绕过 bouncer 或缓存的任何检查(适用于 LAN 或 VPN IP)
- RemediationHeadersCustomName
- string
- 默认值:""
- 当请求由插件处理时,您希望在响应中使用的标头名称(标头的可能值为 `ban`、`captcha` 或 `solved-captcha`)
- ForwardedHeadersCustomName
- string
- 默认值:"X-Forwarded-For"
- 用于获取客户端真实 IP 的标头名称
- ForwardedHeadersTrustedIPs
- []string
- 默认值:[]
- 位于 Traefik 前面的受信任代理的 IP 列表(例如:Cloudflare)
- RedisCacheEnabled
- bool
- 默认值:false
- 启用 Redis 缓存代替内存缓存
- RedisCacheHost
- string
- 默认值:"redis:6379"
- Redis 服务的主机名和端口
- RedisCachePassword
- string
- 默认值:""
- Redis 服务的密码
- RedisCacheDatabase
- string
- 默认值:""
- 为 Redis 服务选择数据库
- RedisCacheUnreachableBlock
- bool
- 默认值:true
- 当 Redis 无法访问时阻止请求(如果 Redis 无法访问,每个请求都会增加 1 秒的延迟)
- HTTPTimeoutSeconds
- int64
- 默认值:10
- 连接 Crowdsec LAPI 的默认超时时间(秒)
- UpdateIntervalSeconds
- int64
- 默认值:60
- 仅在 `stream` 模式下使用,从 LAPI 获取黑名单 IP 的请求间隔时间
- UpdateMaxFailure
- int64
- 默认值:0
- 仅在 `stream` 和 `alone` 模式下使用,在阻止流量之前无法连接到 Crowdsec 的最大次数(设置为 -1 表示永不阻止)
- DefaultDecisionSeconds
- int64
- 默认值:60
- 仅在 `live` 模式下使用,最大决策持续时间
- RemediationStatusCode
- int
- 默认值:403
- 针对被封禁用户(非验证码)的 HTTP 状态码
- CrowdsecCapiMachineId
- string
- 仅在 `alone` 模式下使用,Crowdsec CAPI 的登录名
- CrowdsecCapiPassword
- string
- 仅在 `alone` 模式下使用,Crowdsec CAPI 的密码
- CrowdsecCapiScenarios
- []string
- 仅在 `alone` 模式下使用,Crowdsec CAPI 的场景
- CaptchaProvider
- string
- 用于验证验证码的提供商,期望值为:`hcaptcha`、`recaptcha`、`turnstile` 或 `custom`
- CaptchaCustomJsURL
- string
- 如果 CaptchaProvider 为 `custom`,则用于在 HTML 中加载挑战的 URL(例如 hcaptcha:`https://hcaptcha.com/1/api.js`)
- CaptchaCustomValidateURL
- string
- 如果 CaptchaProvider 为 `custom`,则用于验证挑战的 URL(例如 hcaptcha:`https://api.hcaptcha.com/siteverify`)
- CaptchaCustomKey
- string
- 如果 CaptchaProvider 为 `custom`,用于设置验证码提供商使用的 div 的类名(例如 hcaptcha:`h-captcha`)
- CaptchaCustomResponse
- string
- 如果 CaptchaProvider 为 `custom`,用于设置从 captcha.html 到 Traefik 的 POST body 中的字段(例如 hcaptcha:`h-captcha-response`)
- CaptchaSiteKey
- string
- 验证码提供商的站点密钥
- CaptchaSecretKey
- string
- 验证码提供商的站点密钥
- CaptchaGracePeriodSeconds
- int64
- 默认值:1800(= 30 分钟)
- 验证码验证通过后,如果 Crowdsec 决仍然有效,需要再次进行验证之前的宽限期
- CaptchaHTMLFilePath
- string
- 默认值:/captcha.html
- 存储验证码模板的路径
- BanHTMLFilePath
- string
- 默认值:""
- 存储 ban html 文件的路径(默认为空 ""=禁用)
- TraceHeadersCustomName
- string
- 默认值:""
- 要注入到 ban HTML 响应中的请求标头名称(默认为空 ""=禁用)
### 配置
对于每个插件,Traefik 静态配置必须定义模块名称(就像 Go 包通常做的那样)。
以下声明(此处以 YAML 给出)定义了一个插件:
```
# 静态配置
experimental:
plugins:
bouncer:
moduleName: github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin
version: vX.Y.Z # To update
```
```
# 简化的动态配置
http:
routers:
my-router:
rule: host(`whoami.localhost`)
service: service-foo
entryPoints:
- web
middlewares:
- crowdsec
services:
service-foo:
loadBalancer:
servers:
- url: http://127.0.0.1:5000
middlewares:
crowdsec:
plugin:
bouncer:
enabled: true
logLevel: DEBUG
crowdsecMode: live
crowdsecLapiKey: privateKey-foo
crowdsecLapiHost: crowdsec:8080
```
```
# 完全动态配置
http:
routers:
my-router:
rule: host(`whoami.localhost`)
service: service-foo
entryPoints:
- web
middlewares:
- crowdsec
services:
service-foo:
loadBalancer:
servers:
- url: http://127.0.0.1:5000
middlewares:
crowdsec:
plugin:
bouncer:
enabled: false
logLevel: DEBUG
logFormat: common
LogFilePath: ""
updateIntervalSeconds: 60
updateMaxFailure: 0
defaultDecisionSeconds: 60
remediationStatusCode: 403
httpTimeoutSeconds: 10
crowdsecMode: live
crowdsecAppsecEnabled: false
crowdsecAppsecScheme: ""
crowdsecAppsecHost: crowdsec:7422
crowdsecAppsecPath: "/"
crowdsecAppsecFailureBlock: true
crowdsecAppsecUnreachableBlock: true
crowdsecAppsecBodyLimit: 10485760
crowdsecLapiKey: privateKey-foo
crowdsecLapiScheme: http
crowdsecLapiHost: crowdsec:8080
crowdsecLapiPath: "/"
crowdsecLapiTLSInsecureVerify: false
crowdsecCapiMachineId: login
crowdsecCapiPassword: password
crowdsecCapiScenarios:
- crowdsecurity/http-path-traversal-probing
- crowdsecurity/http-xss-probing
- crowdsecurity/http-generic-bf
forwardedHeadersTrustedIPs:
- 10.0.10.23/32
- 10.0.20.0/24
clientTrustedIPs:
- 192.168.1.0/24
forwardedHeadersCustomName: X-Custom-Header
remediationHeadersCustomName: cs-remediation
redisCacheEnabled: false
redisCacheHost: "redis:6379"
redisCachePassword: password
redisCacheDatabase: "5"
redisCacheUnreachableBlock: true
crowdsecLapiTLSCertificateAuthority: |-
-----BEGIN CERTIFICATE-----
MIIEBzCCAu+gAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwgZQxCzAJBgNVBAYTAlVT
...
Q0veeNzBQXg1f/JxfeA39IDIX1kiCf71tGlT
-----END CERTIFICATE-----
crowdsecLapiTLSCertificateBouncer: |-
-----BEGIN CERTIFICATE-----
MIIEHjCCAwagAwIBAgIUOBTs1eqkaAUcPplztUr2xRapvNAwDQYJKoZIhvcNAQEL
...
RaXAnYYUVRblS1jmePemh388hFxbmrpG2pITx8B5FMULqHoj11o2Rl0gSV6tHIHz
N2U=
-----END CERTIFICATE-----
crowdsecLapiTLSCertificateBouncerKey: |-
-----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEAtYQnbJqifH+ZymePylDxGGLIuxzcAUU4/ajNj+qRAdI/Ux3d
...
ic5cDRo6/VD3CS3MYzyBcibaGaV34nr0G/pI+KEqkYChzk/PZRA=
-----END RSA PRIVATE KEY-----
captchaProvider: hcaptcha
captchaSiteKey: FIXME
captchaSecretKey: FIXME
captchaGracePeriodSeconds: 1800
captchaHTMLFilePath: /captcha.html
banHTMLFilePath: /ban.html
traceHeadersCustomName: X-Request-ID
metricsUpdateIntervalSeconds: 600
```
#### 使用文件内容填充变量
`CrowdsecLapiTlsCertificateBouncerKey`、`CrowdsecLapiTlsCertificateBouncer`、`CrowdsecLapiTlsCertificateAuthority`、`CrowdsecAppsecTlsCertificateAuthority`、`CrowdsecCapiMachineId`、`CrowdsecCapiPassword`、`CrowdsecLapiKey`、`CrowdsecAppsecKey`、`CaptchaSiteKey`、`CaptchaSecretKey` 和 `RedisCachePassword` 可以直接提供原始内容,或者通过 Traefik 可读取的文件路径提供。
如果为同一个变量同时提供了内容和文件,将优先使用文件变量。
格式为:
- 内容:VariableName: XXX
- 文件:VariableNameFile: /path
#### 与 LAPI 进行认证
您可以使用 LAPIKEY 或使用客户端证书与 LAPI 进行身份验证。
有关每个选项的更多详细信息,请参见下文。
#### 生成 LAPI 密钥
您可以为 LAPI 生成一个 crowdsec API 密钥。
您可以在此处遵循文档说明:[docs.crowdsec.net/docs/user_guides/lapi_mgmt](https://docs.crowdsec.net/docs/user_guides/lapi_mgmt)
```
docker compose -f docker-compose-local.yml up -d crowdsec
docker exec crowdsec cscli bouncers add crowdsecBouncer
```
必须将此 LAPI 密钥设置到 docker-compose.yml 中标记为 FIXME-LAPI-KEY 的位置
```
..
whoami:
labels:
- "traefik.http.middlewares.crowdsec.plugin.bouncer.crowdseclapikey=FIXME-LAPI-KEY"
- "traefik.http.middlewares.crowdsec.plugin.bouncer.crowdseclapischeme=http"
- "traefik.http.middlewares.crowdsec.plugin.bouncer.crowdseclapihost=crowdsec:8080"
..
crowdsec:
environment:
BOUNCER_KEY_TRAEFIK: FIXME-LAPI-KEY
```
注意:
然后您可以运行所有容器:
```
docker compose up -d
```
#### 使用证书与 CrowdSec 进行认证
您可以查看 `examples/tls-auth` 中的示例,了解如何使用客户端证书与 LAPI 进行身份验证。
在这种情况下,与 LAPI 的通信必须通过 HTTPS 进行。
在 `examples/tls-auth/gencerts.sh` 中提供了一个用于生成证书的脚本,并且该脚本必须与创建 PKI 所需的输入文件位于同一目录中。
#### 使用 HTTPS 与 LAPI 进行通信
要通过 HTTPS 与 LAPI 进行通信,您需要通过将 `crowdsecLapiTLSInsecureVerify` 设置为 true 来接受任何证书,或者使用 `crowdsecLapiTLSCertificateAuthority` 或 `crowdsecLapiTLSCertificateAuthorityFile` 添加 Crowdsec 服务器证书所使用的 CA。
将 `crowdsecLapiScheme` 设置为 https。
为此,Crowdsec 必须在 HTTPS 下进行监听。
请参阅 [tls-auth 示例](https://github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin/blob/main/examples/tls-auth/README.md) 或官方文档:[docs.crowdsec.net/docs/local_api/tls_auth/](https://docs.crowdsec.net/docs/local_api/tls_auth/)
#### 使用 HTTPS 与 Appsec 进行通信
要通过 HTTPS 与 Appsec 进行通信,您需要通过将 `crowdsecAppsecTLSInsecureVerify` 设置为 true 来接受任何证书,或者使用 `crowdsecAppsecTLSCertificateAuthority` 或 `crowdsecAppsecTLSCertificateAuthorityFile` 添加 Crowdsec 服务器证书所使用的 CA。
将 `crowdsecAppsecScheme` 设置为 https。
目前,AppSec 组件不支持 mTLS 身份验证。
#### 手动将 IP 添加到黑名单(用于测试目的)
```
docker compose up -d crowdsec
docker exec crowdsec cscli decisions add --ip 10.0.0.10 -d 10m # this will be effective 10min
docker exec crowdsec cscli decisions remove --ip 10.0.0.10
docker exec crowdsec cscli decisions add --ip 10.0.0.10 -d 10m -t captcha # this will return a captcha challenge
docker exec crowdsec cscli decisions remove --ip 10.0.0.10 -t captcha
```
### 示例
#### 1. 位于另一个代理服务(例如:cloudflare)后面 [examples/behind-proxy/README.md](https://github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin/blob/main/examples/behind-proxy/README.md)
#### 2. 使用 Redis 作为外部共享缓存 [examples/redis-cache/README.md](https://github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin/blob/main/examples/redis-cache/README.md)
#### 3. 使用不会被 crowdsec 过滤的受信任 IP(例如:LAN 或 VPN) [examples/trusted-ips/README.md](https://github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin/blob/main/examples/trusted-ips/README.md)
#### 4. 在单个虚拟机中使用作为二进制文件安装的 Crowdsec 和 Traefik [examples/binary-vm/README.md](https://github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin/blob/main/examples/binary-vm/README.md)
#### 5. 使用与 Crowdsec 的 HTTPS 通信和 TLS 身份验证 [examples/tls-auth/README.md](https://github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin/blob/main/examples/tls-auth/README.md)
#### 6. 在 Kubernetes 中使用 Crowdsec 和 Traefik [examples/kubernetes/README.md](https://github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin/blob/main/examples/kubernetes/README.md)
#### 7. 在没有 Crowdsec 的独立模式下使用 Traefik [examples/standalone-mode/README.md](https://github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin/blob/main/examples/standalone-mode/README.md)
#### 8. 启用 AppSec 功能的 Traefik [examples/appsec-enabled/README.md](https://github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin/blob/main/examples/appsec-enabled/README.md)
#### 9. 启用 Captcha 风险控制功能的 Traefik [examples/captcha/README.md](https://github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin/blob/main/examples/captcha/README.md)
#### 10. 使用自定义 Ban HTML 页面的 Traefik [examples/custom-ban-page/README.md](https://github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin/blob/main/examples/custom-ban-page/README.md)
#### 11. 使用自定义 Captcha Whicketkeeper 的 Traefik [examples/custom-captcha/README.md](https://github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin/blob/main/examples/custom-captcha/README.md)
### 本地模式
Traefik 还提供了一种开发者模式,可用于对非托管在 GitHub 上的插件进行临时测试。
要在本地模式下使用插件,Traefik 静态配置必须定义模块名称(就像 Go 包通常做的那样),以及指向 [Go 工作区](https://golang.org/doc/gopath_code.html#Workspaces) 的路径,该路径可以是本地 GOPATH 或任何目录。
插件必须放置在 `./plugins-local` 目录中,
该目录应位于运行 Traefik 二进制文件的进程的工作目录中。
插件的源代码组织结构应如下所示:
```
./plugins-local/
└── src
└── github.com
└── maxlerebourg
└── crowdsec-bouncer-traefik-plugin
├── bouncer.go
├── bouncer_test.go
├── go.mod
├── LICENSE
├── Makefile
├── readme.md
└── vendor/*
```
对于本地开发,提供了一个 `docker-compose.local.yml`,它重现了 Traefik 所需的目录布局。
一旦您生成并填充了您的 _LAPI-KEY_ (crowdsecLapiKey),此操作即可生效;如果未填充,请阅读上方的相关信息。
```
docker compose -f docker-compose.local.yml up -d
```
等效于
```
make run_local
```
### 关于
[mathieuHa](https://github.com/mathieuHa) 和 [我](https://github.com/maxlerebourg) 自 2020 年起就在 [Primadviz](https://primadviz.com) 使用 Traefik。
我们拥有 Web 开发和安全工程师背景,并希望将一项非常有前途的技术(Crowdsec)的强大功能添加到我们喜爱的边缘路由器中。
我们最初接触到了这个项目:[github.com/fbonalair/traefik-crowdsec-bouncer](https://github.com/fbonalair/traefik-crowdsec-bouncer)
该项目使用 traefik 和 forward auth 中间件来验证每个请求。
他们必须通过一个 Web 服务器,然后该服务器联系另一个 Web 服务(即 crowdsec LAPI),以便根据源 IP 做出决策。
我们最初通过实现流式模式和本地缓存提出了一些改进建议。
在 Traefik 黑客马拉松期间,我们决定将我们的解决方案直接实现为 Traefik 插件,这样大家就可以在 [plugins.traefik.io](https://plugins.traefik.io) 上找到它,并且性能更好。
none 模式工作流
``` sequenceDiagram participant User participant TraefikPlugin User->>TraefikPlugin: Can I access that webpage create participant CrowdsecLAPI TraefikPlugin-->>CrowdsecLAPI: Does the User IP has a Crowdsec Decision ? Destroy CrowdsecLAPI CrowdsecLAPI-->>TraefikPlugin: Yes a ban Decision TraefikPlugin->>User: No, HTTP 403 ``` ``` sequenceDiagram participant User participant TraefikPlugin User->>TraefikPlugin: Can I access that webpage create participant CrowdsecLAPI TraefikPlugin-->>CrowdsecLAPI: Does the User IP has a crowdsec decision ? Destroy CrowdsecLAPI CrowdsecLAPI-->>TraefikPlugin: Nothing, all good! Destroy TraefikPlugin TraefikPlugin->>Webserver: Forwarding this HTTP Request from User Webserver->>User: HTTP Response ```live 模式工作流
``` sequenceDiagram participant User participant TraefikPlugin User->>TraefikPlugin: Can I access that webpage create participant PluginCache TraefikPlugin-->>PluginCache: Does the User IP has a crowdsec decision ? PluginCache-->>TraefikPlugin: Nothing, all good! create participant CrowdsecLAPI TraefikPlugin-->>CrowdsecLAPI: Does the User IP has a crowdsec decision ? Destroy CrowdsecLAPI CrowdsecLAPI-->>TraefikPlugin: Yes a ban Decision TraefikPlugin-->>PluginCache: Store the information for this IP for DefaultDecisionSeconds Destroy PluginCache PluginCache-->>TraefikPlugin: Done TraefikPlugin->>User: No, HTTP 403 ``` ``` sequenceDiagram participant User participant TraefikPlugin User->>TraefikPlugin: Can I access that webpage create participant PluginCache TraefikPlugin-->>PluginCache: Does the User IP has a crowdsec decision ? PluginCache-->>TraefikPlugin: Nothing, all good! create participant CrowdsecLAPI TraefikPlugin-->>CrowdsecLAPI: Does the User IP has a crowdsec decision ? Destroy CrowdsecLAPI CrowdsecLAPI-->>TraefikPlugin: Nothing, all good! TraefikPlugin-->>PluginCache: Store the information for this IP for DefaultDecisionSeconds Destroy PluginCache PluginCache-->>TraefikPlugin: Done TraefikPlugin->>Webserver: Forwarding this HTTP Request from User Webserver->>User: HTTP Response ```stream 模式工作流
``` sequenceDiagram participant TraefikPlugin participant CrowdsecLAPI TraefikPlugin->>CrowdsecLAPI: What are the current decisions Destroy CrowdsecLAPI CrowdsecLAPI->>TraefikPlugin: Here is the list create participant PluginCache TraefikPlugin-->>PluginCache: Store this list Destroy PluginCache PluginCache-->>TraefikPlugin: Done ``` ``` sequenceDiagram participant User participant TraefikPlugin User->>TraefikPlugin: Can I access that webpage create participant PluginCache TraefikPlugin-->>PluginCache: Does the User IP has a crowdsec decision ? Destroy PluginCache PluginCache-->>TraefikPlugin: Yes a ban decision Destroy TraefikPlugin TraefikPlugin->>User: No, HTTP 403 ``` ``` sequenceDiagram participant User participant TraefikPlugin User->>TraefikPlugin: Can I access that webpage create participant PluginCache TraefikPlugin-->>PluginCache: Does the User IP has a crowdsec decision ? Destroy PluginCache PluginCache-->>TraefikPlugin: Nothing, all good! Destroy TraefikPlugin TraefikPlugin->>Webserver: Forwarding this HTTP Request from User Webserver->>User: HTTP Response ```alone 模式工作流
``` sequenceDiagram participant TraefikPlugin participant CrowdsecCAPI TraefikPlugin->>CrowdsecCAPI: What are the current decisions from CAPI Destroy CrowdsecCAPI CrowdsecCAPI->>TraefikPlugin: Here is the list create participant PluginCache TraefikPlugin-->>PluginCache: Store this list Destroy PluginCache PluginCache-->>TraefikPlugin: Done ``` ``` sequenceDiagram participant User participant TraefikPlugin User->>TraefikPlugin: Can I access that webpage create participant PluginCache TraefikPlugin-->>PluginCache: Does the User IP has a crowdsec decision ? Destroy PluginCache PluginCache-->>TraefikPlugin: Yes a ban decision Destroy TraefikPlugin TraefikPlugin->>User: No, HTTP 403 ``` ``` sequenceDiagram participant User participant TraefikPlugin User->>TraefikPlugin: Can I access that webpage create participant PluginCache TraefikPlugin-->>PluginCache: Does the User IP has a crowdsec decision ? Destroy PluginCache PluginCache-->>TraefikPlugin: Nothing, all good! Destroy TraefikPlugin TraefikPlugin->>Webserver: Forwarding this HTTP Request from User Webserver->>User: HTTP Response ```appsec 模式工作流
``` sequenceDiagram participant User participant TraefikPlugin User->>TraefikPlugin: Can I access that webpage create participant CrowdsecAppSec TraefikPlugin-->>CrowdsecAppSec: Is this request malicious ? Destroy CrowdsecAppSec CrowdsecAppSec-->>TraefikPlugin: Yes I think so Destroy TraefikPlugin TraefikPlugin->>User: No, HTTP 403 ``` ``` sequenceDiagram participant User participant TraefikPlugin User->>TraefikPlugin: Can I access that webpage create participant CrowdsecAppSec TraefikPlugin-->>CrowdsecAppSec: Is this request malicious ? Destroy CrowdsecAppSec CrowdsecAppSec-->>TraefikPlugin: No I don't think so Destroy TraefikPlugin TraefikPlugin->>Webserver: Forwarding this HTTP Request from User Webserver->>User: HTTP Response ```验证码决策工作流
``` sequenceDiagram participant User participant TraefikPlugin User->>TraefikPlugin: Can I access that webpage create participant PluginCache TraefikPlugin-->>PluginCache: Does the User IP has a Crowdsec Decision ? PluginCache-->>TraefikPlugin: Yes a Catpcha Decision TraefikPlugin->>User: Please complete this captcha User->>TraefikPlugin: Fine, done! create participant ProviderCaptcha TraefikPlugin-->>ProviderCaptcha: Is the validation OK ? Destroy ProviderCaptcha ProviderCaptcha-->>TraefikPlugin: Yes TraefikPlugin-->>PluginCache: Set the User IP Clean for captchaGracePeriodSeconds Destroy PluginCache PluginCache-->>TraefikPlugin: Done Destroy TraefikPlugin TraefikPlugin->>Webserver: Forwarding this HTTP Request from User Webserver->>User: HTTP Response ```标签:CrowdSec, EVTX分析, Go语言, Streamlit, Traefik插件, WAF, 反爬虫, 搜索引擎查询, 日志审计, 程序破解, 访问控制, 请求拦截