Add CrowdsecAppsecUnreachableBlock (#175)

*  Add CrowdsecAppsecUnreachableBlock

* 🍱 update readme

* 🍱 fix lint

* 🍱 fix lint
This commit is contained in:
maxlerebourg
2024-06-09 10:59:45 +02:00
committed by GitHub
parent f89c5e25a9
commit 123cf15434
3 changed files with 44 additions and 31 deletions
+5
View File
@@ -333,6 +333,10 @@ Only one instance of the plugin is *possible*.
- bool - bool
- default: true - default: true
- Block request when Crowdsec Appsec Server have a [status 500](https://docs.crowdsec.net/docs/next/appsec/protocol#response-code). - Block request when Crowdsec Appsec Server have a [status 500](https://docs.crowdsec.net/docs/next/appsec/protocol#response-code).
- CrowdsecAppsecUnreachableBlock
- bool
- default: true
- Block request when Crowdsec Appsec Server is unreachable.
- CrowdsecLapiScheme - CrowdsecLapiScheme
- string - string
- default: `http`, expected values are: `http`, `https` - default: `http`, expected values are: `http`, `https`
@@ -486,6 +490,7 @@ http:
crowdsecAppsecEnabled: false crowdsecAppsecEnabled: false
crowdsecAppsecHost: crowdsec:7422 crowdsecAppsecHost: crowdsec:7422
crowdsecAppsecFailureBlock: true crowdsecAppsecFailureBlock: true
crowdsecAppsecUnreachableBlock: true
crowdsecLapiKey: privateKey-foo crowdsecLapiKey: privateKey-foo
crowdsecLapiKeyFile: /etc/traefik/cs-privateKey-foo crowdsecLapiKeyFile: /etc/traefik/cs-privateKey-foo
crowdsecLapiHost: crowdsec:8080 crowdsecLapiHost: crowdsec:8080
+10 -4
View File
@@ -63,6 +63,7 @@ type Bouncer struct {
appsecEnabled bool appsecEnabled bool
appsecHost string appsecHost string
appsecFailureBlock bool appsecFailureBlock bool
appsecUnreachableBlock bool
crowdsecScheme string crowdsecScheme string
crowdsecHost string crowdsecHost string
crowdsecKey string crowdsecKey string
@@ -146,6 +147,7 @@ func New(_ context.Context, next http.Handler, config *configuration.Config, nam
appsecEnabled: config.CrowdsecAppsecEnabled, appsecEnabled: config.CrowdsecAppsecEnabled,
appsecHost: config.CrowdsecAppsecHost, appsecHost: config.CrowdsecAppsecHost,
appsecFailureBlock: config.CrowdsecAppsecFailureBlock, appsecFailureBlock: config.CrowdsecAppsecFailureBlock,
appsecUnreachableBlock: config.CrowdsecAppsecUnreachableBlock,
crowdsecScheme: config.CrowdsecLapiScheme, crowdsecScheme: config.CrowdsecLapiScheme,
crowdsecHost: config.CrowdsecLapiHost, crowdsecHost: config.CrowdsecLapiHost,
crowdsecKey: config.CrowdsecLapiKey, crowdsecKey: config.CrowdsecLapiKey,
@@ -546,7 +548,7 @@ func crowdsecQuery(bouncer *Bouncer, stringURL string, isPost bool) ([]byte, err
req.Header.Add(bouncer.crowdsecHeader, bouncer.crowdsecKey) req.Header.Add(bouncer.crowdsecHeader, bouncer.crowdsecKey)
res, err := bouncer.httpClient.Do(req) res, err := bouncer.httpClient.Do(req)
if err != nil { if err != nil {
return nil, fmt.Errorf("crowdsecQuery url:%s %w", stringURL, err) return nil, fmt.Errorf("crowdsecQuery:unreachable url:%s %w", stringURL, err)
} }
defer func() { defer func() {
if err = res.Body.Close(); err != nil { if err = res.Body.Close(); err != nil {
@@ -602,7 +604,11 @@ func appsecQuery(bouncer *Bouncer, ip string, httpReq *http.Request) error {
res, err := bouncer.httpClient.Do(req) res, err := bouncer.httpClient.Do(req)
if err != nil { if err != nil {
return fmt.Errorf("appsecQuery %w", err) bouncer.log.Error("appsecQuery:unreachable")
if bouncer.appsecUnreachableBlock {
return fmt.Errorf("appsecQuery:unreachable %w", err)
}
return nil
} }
defer func() { defer func() {
if err = res.Body.Close(); err != nil { if err = res.Body.Close(); err != nil {
@@ -610,9 +616,9 @@ func appsecQuery(bouncer *Bouncer, ip string, httpReq *http.Request) error {
} }
}() }()
if res.StatusCode == http.StatusInternalServerError { if res.StatusCode == http.StatusInternalServerError {
bouncer.log.Debug("crowdsecQuery statusCode:500") bouncer.log.Info("appsecQuery:failure")
if bouncer.appsecFailureBlock { if bouncer.appsecFailureBlock {
return fmt.Errorf("appsecQuery statusCode:%d", res.StatusCode) return errors.New("appsecQuery statusCode:500")
} }
return nil return nil
} }
+29 -27
View File
@@ -41,6 +41,7 @@ type Config struct {
CrowdsecAppsecEnabled bool `json:"crowdsecAppsecEnabled,omitempty"` CrowdsecAppsecEnabled bool `json:"crowdsecAppsecEnabled,omitempty"`
CrowdsecAppsecHost string `json:"crowdsecAppsecHost,omitempty"` CrowdsecAppsecHost string `json:"crowdsecAppsecHost,omitempty"`
CrowdsecAppsecFailureBlock bool `json:"crowdsecAppsecFailureBlock,omitempty"` CrowdsecAppsecFailureBlock bool `json:"crowdsecAppsecFailureBlock,omitempty"`
CrowdsecAppsecUnreachableBlock bool `json:"crowdsecAppsecUnreachableBlock,omitempty"`
CrowdsecLapiScheme string `json:"crowdsecLapiScheme,omitempty"` CrowdsecLapiScheme string `json:"crowdsecLapiScheme,omitempty"`
CrowdsecLapiHost string `json:"crowdsecLapiHost,omitempty"` CrowdsecLapiHost string `json:"crowdsecLapiHost,omitempty"`
CrowdsecLapiKey string `json:"crowdsecLapiKey,omitempty"` CrowdsecLapiKey string `json:"crowdsecLapiKey,omitempty"`
@@ -91,33 +92,34 @@ func contains(source []string, target string) bool {
// New creates the default plugin configuration. // New creates the default plugin configuration.
func New() *Config { func New() *Config {
return &Config{ return &Config{
Enabled: false, Enabled: false,
LogLevel: "INFO", LogLevel: "INFO",
CrowdsecMode: LiveMode, CrowdsecMode: LiveMode,
CrowdsecAppsecEnabled: false, CrowdsecAppsecEnabled: false,
CrowdsecAppsecHost: "crowdsec:7422", CrowdsecAppsecHost: "crowdsec:7422",
CrowdsecAppsecFailureBlock: true, CrowdsecAppsecFailureBlock: true,
CrowdsecLapiScheme: HTTP, CrowdsecAppsecUnreachableBlock: true,
CrowdsecLapiHost: "crowdsec:8080", CrowdsecLapiScheme: HTTP,
CrowdsecLapiKey: "", CrowdsecLapiHost: "crowdsec:8080",
CrowdsecLapiTLSInsecureVerify: false, CrowdsecLapiKey: "",
UpdateIntervalSeconds: 60, CrowdsecLapiTLSInsecureVerify: false,
UpdateMaxFailure: 0, UpdateIntervalSeconds: 60,
DefaultDecisionSeconds: 60, UpdateMaxFailure: 0,
HTTPTimeoutSeconds: 10, DefaultDecisionSeconds: 60,
CaptchaProvider: "", HTTPTimeoutSeconds: 10,
CaptchaSiteKey: "", CaptchaProvider: "",
CaptchaSecretKey: "", CaptchaSiteKey: "",
CaptchaGracePeriodSeconds: 1800, CaptchaSecretKey: "",
CaptchaHTMLFilePath: "/captcha.html", CaptchaGracePeriodSeconds: 1800,
BanHTMLFilePath: "", CaptchaHTMLFilePath: "/captcha.html",
ForwardedHeadersCustomName: "X-Forwarded-For", BanHTMLFilePath: "",
ForwardedHeadersTrustedIPs: []string{}, ForwardedHeadersCustomName: "X-Forwarded-For",
ClientTrustedIPs: []string{}, ForwardedHeadersTrustedIPs: []string{},
RedisCacheEnabled: false, ClientTrustedIPs: []string{},
RedisCacheHost: "redis:6379", RedisCacheEnabled: false,
RedisCachePassword: "", RedisCacheHost: "redis:6379",
RedisCacheDatabase: "", RedisCachePassword: "",
RedisCacheDatabase: "",
} }
} }