diff --git a/bouncer.go b/bouncer.go index 2c5df3e..8dd985d 100644 --- a/bouncer.go +++ b/bouncer.go @@ -15,6 +15,7 @@ import ( cache "github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin/pkg/cache" ip "github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin/pkg/ip" logger "github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin/pkg/logger" + simpleredis "github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin/pkg/redis" ) const ( @@ -187,10 +188,16 @@ func (bouncer *Bouncer) ServeHTTP(rw http.ResponseWriter, req *http.Request) { } logger.Debug(fmt.Sprintf("ServeHTTP ip:%v", remoteHost)) + healthy := crowdsecStreamHealthy if bouncer.crowdsecMode != noneMode { isBanned, err := cache.GetDecision(remoteHost) - if err == nil { - logger.Debug(fmt.Sprintf("ServeHTTP cacheHit isBanned:%v", isBanned)) + if err != nil { + logger.Debug(err.Error()) + if err.Error() == simpleredis.RedisUnreachable { + healthy = false + } + } else { + logger.Debug(fmt.Sprintf("ServeHTTP cache:hit isBanned:%v", isBanned)) if isBanned { rw.WriteHeader(http.StatusForbidden) } else { @@ -202,7 +209,7 @@ func (bouncer *Bouncer) ServeHTTP(rw http.ResponseWriter, req *http.Request) { // Right here if we cannot join the stream we forbid the request to go on. if bouncer.crowdsecMode == streamMode { - if crowdsecStreamHealthy { + if healthy { bouncer.next.ServeHTTP(rw, req) } else { rw.WriteHeader(http.StatusForbidden) @@ -269,7 +276,7 @@ func handleNoStreamCache(bouncer *Bouncer, rw http.ResponseWriter, req *http.Req } body, err := crowdsecQuery(bouncer, routeURL.String()) if err != nil { - logger.Info(fmt.Sprintf("%w", err)) + logger.Info(err.Error()) rw.WriteHeader(http.StatusForbidden) return } @@ -326,7 +333,7 @@ func handleStreamCache(bouncer *Bouncer) { } body, err := crowdsecQuery(bouncer, streamRouteURL.String()) if err != nil { - logger.Info(fmt.Sprintf("%w", err)) + logger.Info(err.Error()) crowdsecStreamHealthy = false return } diff --git a/exemples/redis-cache/docker-compose.redis.yml b/exemples/redis-cache/docker-compose.redis.yml index 9eb70c6..de84146 100644 --- a/exemples/redis-cache/docker-compose.redis.yml +++ b/exemples/redis-cache/docker-compose.redis.yml @@ -43,6 +43,7 @@ services: # crowdseclapikey must be uniq to the middleware attached to the service - "traefik.http.middlewares.crowdsec1.plugin.bouncer.crowdseclapikey=40796d93c2958f9e58345514e67740e5" - "traefik.http.middlewares.crowdsec1.plugin.bouncer.rediscacheenabled=true" + - "traefik.http.middlewares.crowdsec1.plugin.bouncer.loglevel=DEBUG" whoami2: image: 4206969/spiderfoot diff --git a/go.mod b/go.mod index c3ff139..729f8f0 100644 --- a/go.mod +++ b/go.mod @@ -1,7 +1,5 @@ module github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin -go 1.17 +go 1.18 require github.com/leprosus/golang-ttl-map v1.1.7 - -require github.com/tehnerd/goUtils v0.0.0-20150515130609-5a2d8fb2ded8 // indirect diff --git a/go.sum b/go.sum index 9a2f881..ea5d6cc 100644 --- a/go.sum +++ b/go.sum @@ -1,4 +1,2 @@ github.com/leprosus/golang-ttl-map v1.1.7 h1:cF4AAFDDnJTFSV+/42sKLhmMluvLdRlCGS2UaifH6UM= github.com/leprosus/golang-ttl-map v1.1.7/go.mod h1:4QWHJPeVBbrkhOhXdhCv9IEiyj/YzkO04/iexy4vSe0= -github.com/tehnerd/goUtils v0.0.0-20150515130609-5a2d8fb2ded8 h1:/b777evAfRRdUJHasZLgQ/w8D/s1HtbaeDXsCVsV0B0= -github.com/tehnerd/goUtils v0.0.0-20150515130609-5a2d8fb2ded8/go.mod h1:UuuqaOb+pZOxJZtjF1mBWTo8HYa7HQCbNkwUEaG9uU0= diff --git a/pkg/cache/cache.go b/pkg/cache/cache.go index f971a42..7cd3f79 100644 --- a/pkg/cache/cache.go +++ b/pkg/cache/cache.go @@ -27,7 +27,7 @@ func getDecisionLocalCache(clientIP string) (bool, error) { if isCached && isValid && len(bannedString) > 0 { return bannedString == cacheBannedValue, nil } - return false, fmt.Errorf("no cache data") + return false, fmt.Errorf("cache:miss") } func setDecisionLocalCache(clientIP string, value string, duration int64) { @@ -46,7 +46,7 @@ func getDecisionRedisCache(clientIP string) (bool, error) { if err == nil && len(bannedString) > 0 { return bannedString == cacheBannedValue, nil } - return false, fmt.Errorf("no cache data") + return false, err } func setDecisionRedisCache(clientIP string, value string, duration int64) { diff --git a/pkg/redis/redis.go b/pkg/redis/redis.go index 88af052..64ba15c 100644 --- a/pkg/redis/redis.go +++ b/pkg/redis/redis.go @@ -11,6 +11,12 @@ import ( logger "github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin/pkg/logger" ) +const ( + RedisUnreachable = "redis:unreachable" + RedisMiss = "redis:miss" + RedisTimeout = "redis:timeout" +) + type RedisCmd struct { Command string Name string @@ -34,8 +40,10 @@ func genRedisArray(params ...[]byte) []byte { } func askRedis(hostnamePort string, cmd RedisCmd, channel chan RedisCmd) { - conn, err := net.Dial("tcp", hostnamePort) + dialer := net.Dialer{Timeout: 2 * time.Second} + conn, err := dialer.Dial("tcp", hostnamePort) if err != nil { + channel <- RedisCmd{Error: fmt.Errorf(RedisUnreachable)} return } defer conn.Close() @@ -47,24 +55,24 @@ func askRedis(hostnamePort string, cmd RedisCmd, channel chan RedisCmd) { case "SET": data := genRedisArray([]byte("SET"), []byte(cmd.Name), []byte(cmd.Data), []byte("EX"), []byte(fmt.Sprintf("%v", cmd.Duration))) writer.PrintfLine(string(data)) - logger.Debug("Redis set") + logger.Debug("redis:set") case "DEL": data := genRedisArray([]byte("DEL"), []byte(cmd.Name)) writer.PrintfLine(string(data)) - logger.Debug("Redis del") + logger.Debug("redis:del") case "GET": data := genRedisArray([]byte("GET"), []byte(cmd.Name)) writer.PrintfLine(string(data)) - logger.Debug("Redis get") + logger.Debug("redis:get") for { select { case <-time.After(time.Second * 1): - channel <- RedisCmd{Error: fmt.Errorf("timeout")} + channel <- RedisCmd{Error: fmt.Errorf(RedisTimeout)} return default: read, _ := reader.ReadLineBytes() if string(read) != "$1" { - channel <- RedisCmd{Error: fmt.Errorf("miss")} + channel <- RedisCmd{Error: fmt.Errorf(RedisMiss)} return } read, _ = reader.ReadLineBytes() diff --git a/vendor/modules.txt b/vendor/modules.txt index c40726e..5e64cb5 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1,5 +1,3 @@ # github.com/leprosus/golang-ttl-map v1.1.7 ## explicit; go 1.15 github.com/leprosus/golang-ttl-map -# github.com/tehnerd/goUtils v0.0.0-20150515130609-5a2d8fb2ded8 -## explicit