zecm-via/crowdsec-bouncer-traefik-plugin

GitHub: zecm-via/crowdsec-bouncer-traefik-plugin

该插件将 CrowdSec 的 IP 声誉判断与 AppSec WAF 能力集成到 Traefik 反向代理中,实现对恶意请求的实时封禁或验证码挑战。

Stars: 0 | Forks: 0

![GitHub](https://img.shields.io/github/license/maxlerebourg/crowdsec-bouncer-traefik-plugin) ![GitHub go.mod Go version](https://img.shields.io/github/go-mod/go-version/maxlerebourg/crowdsec-bouncer-traefik-plugin) ![GitHub tag (latest SemVer)](https://img.shields.io/github/v/tag/maxlerebourg/crowdsec-bouncer-traefik-plugin) [![构建状态](https://github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin/actions/workflows/go-cross.yml/badge.svg)](https://github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin/actions) [![Go 报告卡](https://goreportcard.com/badge/github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin)](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 图表:
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 ```
## 用法 要开始使用,请使用 `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) 上找到它,并且性能更好。
标签:CrowdSec, EVTX分析, Go语言, Streamlit, Traefik插件, WAF, 反爬虫, 搜索引擎查询, 日志审计, 程序破解, 访问控制, 请求拦截