From c21b434c4e926172df7f7f8f20f0697ad5a3ad98 Mon Sep 17 00:00:00 2001 From: Anthrazz <25553648+Anthrazz@users.noreply.github.com> Date: Wed, 10 Jan 2024 20:12:57 +0100 Subject: [PATCH 1/2] defender: implement logging of events and bans (#1495) defender: implement logging of events and bans Signed-off-by: Anthrazz <25553648+Anthrazz@users.noreply.github.com> --- internal/common/defender.go | 41 +++++++++++++++++++++++++++++----- internal/common/defenderdb.go | 2 ++ internal/common/defendermem.go | 3 +++ 3 files changed, 41 insertions(+), 5 deletions(-) diff --git a/internal/common/defender.go b/internal/common/defender.go index bac934f8..0086523b 100644 --- a/internal/common/defender.go +++ b/internal/common/defender.go @@ -19,17 +19,18 @@ import ( "time" "github.com/drakkan/sftpgo/v2/internal/dataprovider" + "github.com/drakkan/sftpgo/v2/internal/logger" ) // HostEvent is the enumerable for the supported host events -type HostEvent int +type HostEvent string // Supported host events const ( - HostEventLoginFailed HostEvent = iota - HostEventUserNotFound - HostEventNoLoginTried - HostEventLimitExceeded + HostEventLoginFailed HostEvent = "LoginFailed" + HostEventUserNotFound = "UserNotFound" + HostEventNoLoginTried = "NoLoginTried" + HostEventLimitExceeded = "LimitExceeded" ) // Supported defender drivers @@ -132,6 +133,36 @@ func (d *baseDefender) getScore(event HostEvent) int { return score } +// logEvent do log an defender event which modifies the score of an host +func (d *baseDefender) logEvent(ip, protocol string, event HostEvent, totalScore int) { + // ignore events which do not change the host score + eventScore := d.getScore(event) + if eventScore == 0 { + return + } + + logger.GetLogger().Debug(). + Timestamp(). + Str("sender", "defender"). + Str("client_ip", ip). + Str("protocol", protocol). + Str("event", string(event)). + Int("increase_score_by", eventScore). + Int("score", totalScore). + Send() +} + +// logBan do log a ban of an host due to a too high host score +func (d *baseDefender) logBan(ip, protocol string) { + logger.GetLogger().Info(). + Timestamp(). + Str("sender", "defender"). + Str("client_ip", ip). + Str("protocol", protocol). + Str("event", "banned"). + Send() +} + type hostEvent struct { dateTime time.Time score int diff --git a/internal/common/defenderdb.go b/internal/common/defenderdb.go index 0c5fd770..a3ccd8c9 100644 --- a/internal/common/defenderdb.go +++ b/internal/common/defenderdb.go @@ -100,7 +100,9 @@ func (d *dbDefender) AddEvent(ip, protocol string, event HostEvent) { if err != nil { return } + d.baseDefender.logEvent(ip, protocol, event, host.Score) if host.Score > d.config.Threshold { + d.baseDefender.logBan(ip, protocol) banTime := time.Now().Add(time.Duration(d.config.BanTime) * time.Minute) err = dataprovider.SetDefenderBanTime(ip, util.GetTimeAsMsSinceEpoch(banTime)) if err == nil { diff --git a/internal/common/defendermem.go b/internal/common/defendermem.go index 3375cfda..31e48be8 100644 --- a/internal/common/defendermem.go +++ b/internal/common/defendermem.go @@ -206,9 +206,11 @@ func (d *memoryDefender) AddEvent(ip, protocol string, event HostEvent) { idx++ } } + d.baseDefender.logEvent(ip, protocol, event, hs.TotalScore) hs.Events = hs.Events[:idx] if hs.TotalScore >= d.config.Threshold { + d.baseDefender.logBan(ip, protocol) d.banned[ip] = time.Now().Add(time.Duration(d.config.BanTime) * time.Minute) delete(d.hosts, ip) d.cleanupBanned() @@ -222,6 +224,7 @@ func (d *memoryDefender) AddEvent(ip, protocol string, event HostEvent) { d.hosts[ip] = hs } } else { + d.baseDefender.logEvent(ip, protocol, event, ev.score) d.hosts[ip] = hostScore{ TotalScore: ev.score, Events: []hostEvent{ev}, From 03ebd5b8415deee0bab11b33c15ad8e6c3ed58ba Mon Sep 17 00:00:00 2001 From: Nicola Murino Date: Wed, 10 Jan 2024 20:15:51 +0100 Subject: [PATCH 2/2] fix a lint warning from the previous PR Signed-off-by: Nicola Murino --- internal/common/defender.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/internal/common/defender.go b/internal/common/defender.go index 0086523b..903ca141 100644 --- a/internal/common/defender.go +++ b/internal/common/defender.go @@ -28,9 +28,9 @@ type HostEvent string // Supported host events const ( HostEventLoginFailed HostEvent = "LoginFailed" - HostEventUserNotFound = "UserNotFound" - HostEventNoLoginTried = "NoLoginTried" - HostEventLimitExceeded = "LimitExceeded" + HostEventUserNotFound HostEvent = "UserNotFound" + HostEventNoLoginTried HostEvent = "NoLoginTried" + HostEventLimitExceeded HostEvent = "LimitExceeded" ) // Supported defender drivers @@ -133,7 +133,7 @@ func (d *baseDefender) getScore(event HostEvent) int { return score } -// logEvent do log an defender event which modifies the score of an host +// logEvent logs a defender event that changes a host's score func (d *baseDefender) logEvent(ip, protocol string, event HostEvent, totalScore int) { // ignore events which do not change the host score eventScore := d.getScore(event) @@ -152,7 +152,7 @@ func (d *baseDefender) logEvent(ip, protocol string, event HostEvent, totalScore Send() } -// logBan do log a ban of an host due to a too high host score +// logBan logs a host's ban due to a too high host score func (d *baseDefender) logBan(ip, protocol string) { logger.GetLogger().Info(). Timestamp().