mirror of
https://github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin.git
synced 2026-07-21 11:38:59 +02:00
Merge remote-tracking branch 'origin' into 28-bypassing-crowdsec-for-local-ips
This commit is contained in:
+12
-5
@@ -15,6 +15,7 @@ import (
|
|||||||
cache "github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin/pkg/cache"
|
cache "github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin/pkg/cache"
|
||||||
ip "github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin/pkg/ip"
|
ip "github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin/pkg/ip"
|
||||||
logger "github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin/pkg/logger"
|
logger "github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin/pkg/logger"
|
||||||
|
simpleredis "github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin/pkg/redis"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -187,10 +188,16 @@ func (bouncer *Bouncer) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
|
|||||||
}
|
}
|
||||||
logger.Debug(fmt.Sprintf("ServeHTTP ip:%v", remoteHost))
|
logger.Debug(fmt.Sprintf("ServeHTTP ip:%v", remoteHost))
|
||||||
|
|
||||||
|
healthy := crowdsecStreamHealthy
|
||||||
if bouncer.crowdsecMode != noneMode {
|
if bouncer.crowdsecMode != noneMode {
|
||||||
isBanned, err := cache.GetDecision(remoteHost)
|
isBanned, err := cache.GetDecision(remoteHost)
|
||||||
if err == nil {
|
if err != nil {
|
||||||
logger.Debug(fmt.Sprintf("ServeHTTP cacheHit isBanned:%v", isBanned))
|
logger.Debug(err.Error())
|
||||||
|
if err.Error() == simpleredis.RedisUnreachable {
|
||||||
|
healthy = false
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
logger.Debug(fmt.Sprintf("ServeHTTP cache:hit isBanned:%v", isBanned))
|
||||||
if isBanned {
|
if isBanned {
|
||||||
rw.WriteHeader(http.StatusForbidden)
|
rw.WriteHeader(http.StatusForbidden)
|
||||||
} else {
|
} 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.
|
// Right here if we cannot join the stream we forbid the request to go on.
|
||||||
if bouncer.crowdsecMode == streamMode {
|
if bouncer.crowdsecMode == streamMode {
|
||||||
if crowdsecStreamHealthy {
|
if healthy {
|
||||||
bouncer.next.ServeHTTP(rw, req)
|
bouncer.next.ServeHTTP(rw, req)
|
||||||
} else {
|
} else {
|
||||||
rw.WriteHeader(http.StatusForbidden)
|
rw.WriteHeader(http.StatusForbidden)
|
||||||
@@ -269,7 +276,7 @@ func handleNoStreamCache(bouncer *Bouncer, rw http.ResponseWriter, req *http.Req
|
|||||||
}
|
}
|
||||||
body, err := crowdsecQuery(bouncer, routeURL.String())
|
body, err := crowdsecQuery(bouncer, routeURL.String())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Info(fmt.Sprintf("%w", err))
|
logger.Info(err.Error())
|
||||||
rw.WriteHeader(http.StatusForbidden)
|
rw.WriteHeader(http.StatusForbidden)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -326,7 +333,7 @@ func handleStreamCache(bouncer *Bouncer) {
|
|||||||
}
|
}
|
||||||
body, err := crowdsecQuery(bouncer, streamRouteURL.String())
|
body, err := crowdsecQuery(bouncer, streamRouteURL.String())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Info(fmt.Sprintf("%w", err))
|
logger.Info(err.Error())
|
||||||
crowdsecStreamHealthy = false
|
crowdsecStreamHealthy = false
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ services:
|
|||||||
# crowdseclapikey must be uniq to the middleware attached to the service
|
# 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.crowdseclapikey=40796d93c2958f9e58345514e67740e5"
|
||||||
- "traefik.http.middlewares.crowdsec1.plugin.bouncer.rediscacheenabled=true"
|
- "traefik.http.middlewares.crowdsec1.plugin.bouncer.rediscacheenabled=true"
|
||||||
|
- "traefik.http.middlewares.crowdsec1.plugin.bouncer.loglevel=DEBUG"
|
||||||
|
|
||||||
whoami2:
|
whoami2:
|
||||||
image: 4206969/spiderfoot
|
image: 4206969/spiderfoot
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
module github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin
|
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/leprosus/golang-ttl-map v1.1.7
|
||||||
|
|
||||||
require github.com/tehnerd/goUtils v0.0.0-20150515130609-5a2d8fb2ded8 // indirect
|
|
||||||
|
|||||||
@@ -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 h1:cF4AAFDDnJTFSV+/42sKLhmMluvLdRlCGS2UaifH6UM=
|
||||||
github.com/leprosus/golang-ttl-map v1.1.7/go.mod h1:4QWHJPeVBbrkhOhXdhCv9IEiyj/YzkO04/iexy4vSe0=
|
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=
|
|
||||||
|
|||||||
Vendored
+2
-2
@@ -27,7 +27,7 @@ func getDecisionLocalCache(clientIP string) (bool, error) {
|
|||||||
if isCached && isValid && len(bannedString) > 0 {
|
if isCached && isValid && len(bannedString) > 0 {
|
||||||
return bannedString == cacheBannedValue, nil
|
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) {
|
func setDecisionLocalCache(clientIP string, value string, duration int64) {
|
||||||
@@ -46,7 +46,7 @@ func getDecisionRedisCache(clientIP string) (bool, error) {
|
|||||||
if err == nil && len(bannedString) > 0 {
|
if err == nil && len(bannedString) > 0 {
|
||||||
return bannedString == cacheBannedValue, nil
|
return bannedString == cacheBannedValue, nil
|
||||||
}
|
}
|
||||||
return false, fmt.Errorf("no cache data")
|
return false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func setDecisionRedisCache(clientIP string, value string, duration int64) {
|
func setDecisionRedisCache(clientIP string, value string, duration int64) {
|
||||||
|
|||||||
+14
-6
@@ -11,6 +11,12 @@ import (
|
|||||||
logger "github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin/pkg/logger"
|
logger "github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin/pkg/logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
RedisUnreachable = "redis:unreachable"
|
||||||
|
RedisMiss = "redis:miss"
|
||||||
|
RedisTimeout = "redis:timeout"
|
||||||
|
)
|
||||||
|
|
||||||
type RedisCmd struct {
|
type RedisCmd struct {
|
||||||
Command string
|
Command string
|
||||||
Name string
|
Name string
|
||||||
@@ -34,8 +40,10 @@ func genRedisArray(params ...[]byte) []byte {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func askRedis(hostnamePort string, cmd RedisCmd, channel chan RedisCmd) {
|
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 {
|
if err != nil {
|
||||||
|
channel <- RedisCmd{Error: fmt.Errorf(RedisUnreachable)}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer conn.Close()
|
defer conn.Close()
|
||||||
@@ -47,24 +55,24 @@ func askRedis(hostnamePort string, cmd RedisCmd, channel chan RedisCmd) {
|
|||||||
case "SET":
|
case "SET":
|
||||||
data := genRedisArray([]byte("SET"), []byte(cmd.Name), []byte(cmd.Data), []byte("EX"), []byte(fmt.Sprintf("%v", cmd.Duration)))
|
data := genRedisArray([]byte("SET"), []byte(cmd.Name), []byte(cmd.Data), []byte("EX"), []byte(fmt.Sprintf("%v", cmd.Duration)))
|
||||||
writer.PrintfLine(string(data))
|
writer.PrintfLine(string(data))
|
||||||
logger.Debug("Redis set")
|
logger.Debug("redis:set")
|
||||||
case "DEL":
|
case "DEL":
|
||||||
data := genRedisArray([]byte("DEL"), []byte(cmd.Name))
|
data := genRedisArray([]byte("DEL"), []byte(cmd.Name))
|
||||||
writer.PrintfLine(string(data))
|
writer.PrintfLine(string(data))
|
||||||
logger.Debug("Redis del")
|
logger.Debug("redis:del")
|
||||||
case "GET":
|
case "GET":
|
||||||
data := genRedisArray([]byte("GET"), []byte(cmd.Name))
|
data := genRedisArray([]byte("GET"), []byte(cmd.Name))
|
||||||
writer.PrintfLine(string(data))
|
writer.PrintfLine(string(data))
|
||||||
logger.Debug("Redis get")
|
logger.Debug("redis:get")
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-time.After(time.Second * 1):
|
case <-time.After(time.Second * 1):
|
||||||
channel <- RedisCmd{Error: fmt.Errorf("timeout")}
|
channel <- RedisCmd{Error: fmt.Errorf(RedisTimeout)}
|
||||||
return
|
return
|
||||||
default:
|
default:
|
||||||
read, _ := reader.ReadLineBytes()
|
read, _ := reader.ReadLineBytes()
|
||||||
if string(read) != "$1" {
|
if string(read) != "$1" {
|
||||||
channel <- RedisCmd{Error: fmt.Errorf("miss")}
|
channel <- RedisCmd{Error: fmt.Errorf(RedisMiss)}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
read, _ = reader.ReadLineBytes()
|
read, _ = reader.ReadLineBytes()
|
||||||
|
|||||||
Vendored
-2
@@ -1,5 +1,3 @@
|
|||||||
# github.com/leprosus/golang-ttl-map v1.1.7
|
# github.com/leprosus/golang-ttl-map v1.1.7
|
||||||
## explicit; go 1.15
|
## explicit; go 1.15
|
||||||
github.com/leprosus/golang-ttl-map
|
github.com/leprosus/golang-ttl-map
|
||||||
# github.com/tehnerd/goUtils v0.0.0-20150515130609-5a2d8fb2ded8
|
|
||||||
## explicit
|
|
||||||
|
|||||||
Reference in New Issue
Block a user