Add variable to not block if redis is unreachable (#214)

*  Add variable to not block if redis is unreachable

* 🚨 fix lint

* 📝 Update README.md
This commit is contained in:
maxlerebourg
2025-02-10 20:10:29 +01:00
committed by GitHub
parent c34d7f4617
commit 4708d76854
4 changed files with 22 additions and 2 deletions
+5
View File
@@ -411,6 +411,10 @@ Only one instance of the plugin is *possible*.
- string - string
- default: "" - default: ""
- Database selection for the Redis service - Database selection for the Redis service
- RedisUnreachableBlock
- bool
- default: true
- Block request when Redis is unreachable (if Redis is unreachable, 1-second delay is added to each request)
- HTTPTimeoutSeconds - HTTPTimeoutSeconds
- int64 - int64
- default: 10 - default: 10
@@ -535,6 +539,7 @@ http:
redisCacheHost: "redis:6379" redisCacheHost: "redis:6379"
redisCachePassword: password redisCachePassword: password
redisCacheDatabase: "5" redisCacheDatabase: "5"
redisCacheUnreachableBlock: true
crowdsecLapiTLSCertificateAuthority: |- crowdsecLapiTLSCertificateAuthority: |-
-----BEGIN CERTIFICATE----- -----BEGIN CERTIFICATE-----
MIIEBzCCAu+gAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwgZQxCzAJBgNVBAYTAlVT MIIEBzCCAu+gAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwgZQxCzAJBgNVBAYTAlVT
+8 -1
View File
@@ -81,6 +81,7 @@ type Bouncer struct {
forwardedCustomHeader string forwardedCustomHeader string
crowdsecStreamRoute string crowdsecStreamRoute string
crowdsecHeader string crowdsecHeader string
redisUnreachableBlock bool
banTemplateString string banTemplateString string
clientPoolStrategy *ip.PoolStrategy clientPoolStrategy *ip.PoolStrategy
serverPoolStrategy *ip.PoolStrategy serverPoolStrategy *ip.PoolStrategy
@@ -168,6 +169,7 @@ func New(_ context.Context, next http.Handler, config *configuration.Config, nam
remediationCustomHeader: config.RemediationHeadersCustomName, remediationCustomHeader: config.RemediationHeadersCustomName,
forwardedCustomHeader: config.ForwardedHeadersCustomName, forwardedCustomHeader: config.ForwardedHeadersCustomName,
defaultDecisionTimeout: config.DefaultDecisionSeconds, defaultDecisionTimeout: config.DefaultDecisionSeconds,
redisUnreachableBlock: config.RedisCacheUnreachableBlock,
banTemplateString: banTemplateString, banTemplateString: banTemplateString,
crowdsecStreamRoute: crowdsecStreamRoute, crowdsecStreamRoute: crowdsecStreamRoute,
crowdsecHeader: crowdsecHeader, crowdsecHeader: crowdsecHeader,
@@ -240,7 +242,7 @@ func New(_ context.Context, next http.Handler, config *configuration.Config, nam
// ServeHTTP principal function of plugin. // ServeHTTP principal function of plugin.
// //
//nolint:nestif //nolint:nestif,gocyclo
func (bouncer *Bouncer) ServeHTTP(rw http.ResponseWriter, req *http.Request) { func (bouncer *Bouncer) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
if !bouncer.enabled { if !bouncer.enabled {
bouncer.next.ServeHTTP(rw, req) bouncer.next.ServeHTTP(rw, req)
@@ -278,6 +280,11 @@ func (bouncer *Bouncer) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
if cacheErr != nil { if cacheErr != nil {
cacheErrString := cacheErr.Error() cacheErrString := cacheErr.Error()
bouncer.log.Debug(fmt.Sprintf("ServeHTTP:Get ip:%s isBanned:false %s", remoteIP, cacheErrString)) bouncer.log.Debug(fmt.Sprintf("ServeHTTP:Get ip:%s isBanned:false %s", remoteIP, cacheErrString))
if !bouncer.redisUnreachableBlock && cacheErrString == cache.CacheUnreachable {
bouncer.log.Error(fmt.Sprintf("ServeHTTP:Get ip:%s redisUnreachable=true", remoteIP))
handleNextServeHTTP(bouncer, remoteIP, rw, req)
return
}
if cacheErrString != cache.CacheMiss { if cacheErrString != cache.CacheMiss {
bouncer.log.Error(fmt.Sprintf("ServeHTTP:Get ip:%s %s", remoteIP, cacheErrString)) bouncer.log.Error(fmt.Sprintf("ServeHTTP:Get ip:%s %s", remoteIP, cacheErrString))
handleBanServeHTTP(bouncer, rw) handleBanServeHTTP(bouncer, rw)
+7 -1
View File
@@ -23,6 +23,8 @@ const (
CaptchaDoneValue = "d" CaptchaDoneValue = "d"
// CacheMiss error string when cache is miss. // CacheMiss error string when cache is miss.
CacheMiss = "cache:miss" CacheMiss = "cache:miss"
// CacheUnreachable error string when cache is unreachable.
CacheUnreachable = "cache:unreachable"
) )
//nolint:gochecknoglobals //nolint:gochecknoglobals
@@ -60,9 +62,13 @@ func (redisCache) get(key string) (string, error) {
if err == nil && len(valueString) > 0 { if err == nil && len(valueString) > 0 {
return valueString, nil return valueString, nil
} }
if err.Error() == simpleredis.RedisMiss { errRedisMessage := err.Error()
if errRedisMessage == simpleredis.RedisMiss {
return "", errors.New(CacheMiss) return "", errors.New(CacheMiss)
} }
if errRedisMessage == simpleredis.RedisUnreachable {
return "", errors.New(CacheUnreachable)
}
return "", err return "", err
} }
+2
View File
@@ -74,6 +74,7 @@ type Config struct {
RedisCachePassword string `json:"redisCachePassword,omitempty"` RedisCachePassword string `json:"redisCachePassword,omitempty"`
RedisCachePasswordFile string `json:"redisCachePasswordFile,omitempty"` RedisCachePasswordFile string `json:"redisCachePasswordFile,omitempty"`
RedisCacheDatabase string `json:"redisCacheDatabase,omitempty"` RedisCacheDatabase string `json:"redisCacheDatabase,omitempty"`
RedisCacheUnreachableBlock bool `json:"redisCacheUnreachableBlock,omitempty"`
BanHTMLFilePath string `json:"banHtmlFilePath,omitempty"` BanHTMLFilePath string `json:"banHtmlFilePath,omitempty"`
CaptchaHTMLFilePath string `json:"captchaHtmlFilePath,omitempty"` CaptchaHTMLFilePath string `json:"captchaHtmlFilePath,omitempty"`
CaptchaProvider string `json:"captchaProvider,omitempty"` CaptchaProvider string `json:"captchaProvider,omitempty"`
@@ -128,6 +129,7 @@ func New() *Config {
RedisCacheHost: "redis:6379", RedisCacheHost: "redis:6379",
RedisCachePassword: "", RedisCachePassword: "",
RedisCacheDatabase: "", RedisCacheDatabase: "",
RedisCacheUnreachableBlock: true,
} }
} }