mirror of
https://github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin.git
synced 2026-07-21 11:38:59 +02:00
✨ Add a logger instance to bouncer instance (#134)
* ✨ Add a logger instance to bouncer instance * 🍱 fix test * 🍱 fix lint * 🍱 fix lint * 🍱 fix lint * 🍱 fix lint * 🍱 fix lint * 🍱 fix test * 🍱 fix test * 🍱 fix lint + test * 🍱 fix test * 🍱 fix test * 🍱 fix test * 🍱 fix lint * 🍱 fix lint
This commit is contained in:
Vendored
+23
-19
@@ -44,7 +44,9 @@ func (localCache) deleteDecision(clientIP string) {
|
||||
cache.Del(clientIP)
|
||||
}
|
||||
|
||||
type redisCache struct{}
|
||||
type redisCache struct {
|
||||
log *logger.Log
|
||||
}
|
||||
|
||||
func (redisCache) getDecision(clientIP string) (bool, error) {
|
||||
banned, err := redis.Get(clientIP)
|
||||
@@ -58,15 +60,15 @@ func (redisCache) getDecision(clientIP string) (bool, error) {
|
||||
return false, err
|
||||
}
|
||||
|
||||
func (redisCache) setDecision(clientIP string, value string, duration int64) {
|
||||
func (rc redisCache) setDecision(clientIP string, value string, duration int64) {
|
||||
if err := redis.Set(clientIP, []byte(value), duration); err != nil {
|
||||
logger.Error(fmt.Sprintf("cache:setDecisionRedisCache %s", err.Error()))
|
||||
rc.log.Error(fmt.Sprintf("cache:setDecisionRedisCache %s", err.Error()))
|
||||
}
|
||||
}
|
||||
|
||||
func (redisCache) deleteDecision(clientIP string) {
|
||||
func (rc redisCache) deleteDecision(clientIP string) {
|
||||
if err := redis.Del(clientIP); err != nil {
|
||||
logger.Error(fmt.Sprintf("cache:deleteDecisionRedisCache %s", err.Error()))
|
||||
rc.log.Error(fmt.Sprintf("cache:deleteDecisionRedisCache %s", err.Error()))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,40 +81,42 @@ type cacheInterface interface {
|
||||
// Client Cache client.
|
||||
type Client struct {
|
||||
cache cacheInterface
|
||||
log *logger.Log
|
||||
}
|
||||
|
||||
// New Initialize cache client.
|
||||
func (client *Client) New(isRedis bool, host, pass, database string) {
|
||||
// Init Initialize cache client.
|
||||
func (c *Client) Init(log *logger.Log, isRedis bool, host, pass, database string) {
|
||||
c.log = log
|
||||
if isRedis {
|
||||
redis.Init(host, pass, database)
|
||||
client.cache = &redisCache{}
|
||||
c.cache = &redisCache{log: log}
|
||||
} else {
|
||||
client.cache = &localCache{}
|
||||
c.cache = &localCache{}
|
||||
}
|
||||
logger.Debug(fmt.Sprintf("cache:New initialized isRedis:%v", isRedis))
|
||||
c.log.Debug(fmt.Sprintf("cache:New initialized isRedis:%v", isRedis))
|
||||
}
|
||||
|
||||
// DeleteDecision delete decision in cache.
|
||||
func (client *Client) DeleteDecision(clientIP string) {
|
||||
logger.Debug(fmt.Sprintf("cache:DeleteDecision ip:%v", clientIP))
|
||||
client.cache.deleteDecision(clientIP)
|
||||
func (c *Client) DeleteDecision(clientIP string) {
|
||||
c.log.Debug(fmt.Sprintf("cache:DeleteDecision ip:%v", clientIP))
|
||||
c.cache.deleteDecision(clientIP)
|
||||
}
|
||||
|
||||
// GetDecision check in the cache if the IP has the banned / not banned value.
|
||||
// Otherwise return with an error to add the IP in cache if we are on.
|
||||
func (client *Client) GetDecision(clientIP string) (bool, error) {
|
||||
logger.Debug(fmt.Sprintf("cache:GetDecision ip:%v", clientIP))
|
||||
return client.cache.getDecision(clientIP)
|
||||
func (c *Client) GetDecision(clientIP string) (bool, error) {
|
||||
c.log.Debug(fmt.Sprintf("cache:GetDecision ip:%v", clientIP))
|
||||
return c.cache.getDecision(clientIP)
|
||||
}
|
||||
|
||||
// SetDecision update the cache with the IP as key and the value banned / not banned.
|
||||
func (client *Client) SetDecision(clientIP string, isBanned bool, duration int64) {
|
||||
logger.Debug(fmt.Sprintf("cache:SetDecision ip:%v isBanned:%v duration:%vs", clientIP, isBanned, duration))
|
||||
func (c *Client) SetDecision(clientIP string, isBanned bool, duration int64) {
|
||||
c.log.Debug(fmt.Sprintf("cache:SetDecision ip:%v isBanned:%v duration:%vs", clientIP, isBanned, duration))
|
||||
var value string
|
||||
if isBanned {
|
||||
value = cacheBannedValue
|
||||
} else {
|
||||
value = cacheNoBannedValue
|
||||
}
|
||||
client.cache.setDecision(clientIP, value, duration)
|
||||
c.cache.setDecision(clientIP, value, duration)
|
||||
}
|
||||
|
||||
Vendored
+5
-3
@@ -4,12 +4,14 @@ package cache
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
logger "github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin/pkg/logger"
|
||||
)
|
||||
|
||||
func Test_GetDecision(t *testing.T) {
|
||||
IPInCache := "10.0.0.10"
|
||||
IPNotInCache := "10.0.0.20"
|
||||
client := &Client{cache: &localCache{}}
|
||||
client := &Client{cache: &localCache{}, log: logger.New("INFO")}
|
||||
client.SetDecision(IPInCache, true, 10)
|
||||
type args struct {
|
||||
clientIP string
|
||||
@@ -45,7 +47,7 @@ func Test_GetDecision(t *testing.T) {
|
||||
}
|
||||
|
||||
func Test_SetDecision(t *testing.T) {
|
||||
client := &Client{cache: &localCache{}}
|
||||
client := &Client{cache: &localCache{}, log: logger.New("INFO")}
|
||||
IPInCache := "10.0.0.11"
|
||||
type args struct {
|
||||
clientIP string
|
||||
@@ -76,7 +78,7 @@ func Test_SetDecision(t *testing.T) {
|
||||
func Test_DeleteDecision(t *testing.T) {
|
||||
IPInCache := "10.0.0.12"
|
||||
IPNotInCache := "10.0.0.22"
|
||||
client := &Client{cache: &localCache{}}
|
||||
client := &Client{cache: &localCache{}, log: logger.New("INFO")}
|
||||
client.SetDecision(IPInCache, true, 10)
|
||||
type args struct {
|
||||
clientIP string
|
||||
|
||||
@@ -235,11 +235,9 @@ func validateParamsTLS(config *Config) error {
|
||||
|
||||
func validateParamsIPs(listIP []string, key string) error {
|
||||
if len(listIP) > 0 {
|
||||
if _, err := ip.NewChecker(listIP); err != nil {
|
||||
if _, err := ip.NewChecker(logger.New("INFO"), listIP); err != nil {
|
||||
return fmt.Errorf("%s must be a list of IP/CIDR :%w", key, err)
|
||||
}
|
||||
} else {
|
||||
logger.Debug(fmt.Sprintf("No IP provided for %s", key))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -275,16 +273,18 @@ func validateParamsRequired(config *Config) error {
|
||||
}
|
||||
|
||||
// GetTLSConfigCrowdsec get TLS config from Config.
|
||||
func GetTLSConfigCrowdsec(config *Config) (*tls.Config, error) {
|
||||
//
|
||||
//nolint:nestif
|
||||
func GetTLSConfigCrowdsec(config *Config, log *logger.Log) (*tls.Config, error) {
|
||||
tlsConfig := new(tls.Config)
|
||||
tlsConfig.RootCAs = x509.NewCertPool()
|
||||
//nolint:gocritic
|
||||
if config.CrowdsecLapiScheme != HTTPS {
|
||||
logger.Debug("getTLSConfigCrowdsec:CrowdsecLapiScheme https:no")
|
||||
log.Debug("getTLSConfigCrowdsec:CrowdsecLapiScheme https:no")
|
||||
return tlsConfig, nil
|
||||
} else if config.CrowdsecLapiTLSInsecureVerify {
|
||||
logger.Debug("getTLSConfigCrowdsec:CrowdsecLapiTLSInsecureVerify tlsInsecure:true")
|
||||
tlsConfig.InsecureSkipVerify = true
|
||||
log.Debug("getTLSConfigCrowdsec:CrowdsecLapiTLSInsecureVerify tlsInsecure:true")
|
||||
// If we return here and still want to use client auth this won't work
|
||||
// return tlsConfig, nil
|
||||
} else {
|
||||
@@ -292,12 +292,13 @@ func GetTLSConfigCrowdsec(config *Config) (*tls.Config, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cert := []byte(certAuthority)
|
||||
if !tlsConfig.RootCAs.AppendCertsFromPEM(cert) {
|
||||
logger.Debug("getTLSConfigCrowdsec:CrowdsecLapiTLSCertificateAuthority read cert failed")
|
||||
// here we return because if CrowdsecLapiTLSInsecureVerify is false
|
||||
// and CA not load, we can't communicate with https
|
||||
return nil, fmt.Errorf("getTLSConfigCrowdsec:cannot load CA and verify cert is enabled")
|
||||
if len(certAuthority) > 0 {
|
||||
if !tlsConfig.RootCAs.AppendCertsFromPEM([]byte(certAuthority)) {
|
||||
// here we return because if CrowdsecLapiTLSInsecureVerify is false
|
||||
// and CA not load, we can't communicate with https
|
||||
return nil, fmt.Errorf("getTLSConfigCrowdsec:cannot load CA and verify cert is enabled")
|
||||
}
|
||||
log.Debug("getTLSConfigCrowdsec:CrowdsecLapiTLSCertificateAuthority CA added successfully")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@ import (
|
||||
"crypto/tls"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
logger "github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin/pkg/logger"
|
||||
)
|
||||
|
||||
func getMinimalConfig() *Config {
|
||||
@@ -147,7 +149,7 @@ func Test_validateParamsIPs(t *testing.T) {
|
||||
{name: "Not validate localhost", args: args{listIP: []string{0: "localhost"}}, wantErr: true},
|
||||
{name: "Not validate a weird ip", args: args{listIP: []string{0: "0.0.0.0/89"}}, wantErr: true},
|
||||
{name: "Not validate a weird ip 2", args: args{listIP: []string{0: "0.0.0.256/12"}}, wantErr: true},
|
||||
{name: "Validate an ip not trimed", args: args{listIP: []string{0: " 0.0.0.0/0"}}, wantErr: false},
|
||||
{name: "Validate an ip not trimmed", args: args{listIP: []string{0: " 0.0.0.0/0"}}, wantErr: false},
|
||||
{name: "Validate an ip", args: args{listIP: []string{0: "0.0.0.0/12"}}, wantErr: false},
|
||||
{name: "Validate an ip list", args: args{listIP: []string{0: "0.0.0.0/0", 1: "1.1.1.1/1"}}, wantErr: false},
|
||||
}
|
||||
@@ -231,7 +233,7 @@ func Test_GetTLSConfigCrowdsec(t *testing.T) {
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got, err := GetTLSConfigCrowdsec(tt.args.config)
|
||||
got, err := GetTLSConfigCrowdsec(tt.args.config, logger.New("INFO"))
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("getTLSConfigCrowdsec() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
|
||||
+4
-4
@@ -8,7 +8,7 @@ import (
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin/pkg/logger"
|
||||
logger "github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin/pkg/logger"
|
||||
)
|
||||
|
||||
// CHECKER
|
||||
@@ -20,14 +20,14 @@ type Checker struct {
|
||||
}
|
||||
|
||||
// NewChecker builds a new Checker given a list of CIDR-Strings to trusted IPs.
|
||||
func NewChecker(trustedIPs []string) (*Checker, error) {
|
||||
func NewChecker(log *logger.Log, trustedIPs []string) (*Checker, error) {
|
||||
checker := &Checker{}
|
||||
|
||||
for _, ipMaskRaw := range trustedIPs {
|
||||
ipMask := strings.TrimSpace(ipMaskRaw)
|
||||
if ipAddr := net.ParseIP(ipMask); ipAddr != nil {
|
||||
checker.authorizedIPs = append(checker.authorizedIPs, &ipAddr)
|
||||
logger.Debug(fmt.Sprintf("IP %v is trusted", ipAddr))
|
||||
log.Debug(fmt.Sprintf("IP %v is trusted", ipAddr))
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ func NewChecker(trustedIPs []string) (*Checker, error) {
|
||||
return nil, fmt.Errorf("parsing CIDR trusted IPs %s: %w", ipAddr, err)
|
||||
}
|
||||
checker.authorizedIPsNet = append(checker.authorizedIPsNet, ipAddr)
|
||||
logger.Debug(fmt.Sprintf("IP network %v is trusted", ipAddr))
|
||||
log.Debug(fmt.Sprintf("IP network %v is trusted", ipAddr))
|
||||
}
|
||||
|
||||
return checker, nil
|
||||
|
||||
+25
-16
@@ -8,32 +8,41 @@ import (
|
||||
"os"
|
||||
)
|
||||
|
||||
var (
|
||||
loggerInfo = log.New(io.Discard, "INFO: CrowdsecBouncerTraefikPlugin: ", log.Ldate|log.Ltime) //nolint:gochecknoglobals
|
||||
loggerDebug = log.New(io.Discard, "DEBUG: CrowdsecBouncerTraefikPlugin: ", log.Ldate|log.Ltime) //nolint:gochecknoglobals
|
||||
loggerError = log.New(io.Discard, "ERROR: CrowdsecBouncerTraefikPlugin: ", log.Ldate|log.Ltime) //nolint:gochecknoglobals
|
||||
)
|
||||
// Log Logger struct.
|
||||
type Log struct {
|
||||
logError *log.Logger
|
||||
logInfo *log.Logger
|
||||
logDebug *log.Logger
|
||||
}
|
||||
|
||||
// Init Set Default log level to info in case log level to defined.
|
||||
func Init(logLevel string) {
|
||||
loggerError.SetOutput(os.Stderr)
|
||||
loggerInfo.SetOutput(os.Stdout)
|
||||
// New Set Default log level to info in case log level to defined.
|
||||
func New(logLevel string) *Log {
|
||||
logError := log.New(io.Discard, "ERROR: CrowdsecBouncerTraefikPlugin: ", log.Ldate|log.Ltime)
|
||||
logInfo := log.New(io.Discard, "INFO: CrowdsecBouncerTraefikPlugin: ", log.Ldate|log.Ltime)
|
||||
logDebug := log.New(io.Discard, "DEBUG: CrowdsecBouncerTraefikPlugin: ", log.Ldate|log.Ltime)
|
||||
logError.SetOutput(os.Stderr)
|
||||
logInfo.SetOutput(os.Stdout)
|
||||
if logLevel == "DEBUG" {
|
||||
loggerDebug.SetOutput(os.Stdout)
|
||||
logDebug.SetOutput(os.Stdout)
|
||||
}
|
||||
return &Log{
|
||||
logError: logError,
|
||||
logInfo: logInfo,
|
||||
logDebug: logDebug,
|
||||
}
|
||||
}
|
||||
|
||||
// Info log to Stdout.
|
||||
func Info(str string) {
|
||||
loggerInfo.Printf(str)
|
||||
func (l *Log) Info(str string) {
|
||||
l.logInfo.Printf(str)
|
||||
}
|
||||
|
||||
// Debug log to Stdout.
|
||||
func Debug(str string) {
|
||||
loggerDebug.Printf(str)
|
||||
func (l *Log) Debug(str string) {
|
||||
l.logDebug.Printf(str)
|
||||
}
|
||||
|
||||
// Error log to Stderr.
|
||||
func Error(str string) {
|
||||
loggerError.Printf(str)
|
||||
func (l *Log) Error(str string) {
|
||||
l.logError.Printf(str)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user