From b15ef2ac0ecedcf380d3376e18da009ebc77cfaa Mon Sep 17 00:00:00 2001 From: yuriy0803 <68668177+yuriy0803@users.noreply.github.com> Date: Sat, 9 Dec 2023 18:40:41 +0100 Subject: [PATCH] addToFail2Ban sudo apt-get install fail2ban --- api.json | 3 ++- policy/policy.go | 56 ++++++++++++++++++++++++++++++------------------ 2 files changed, 37 insertions(+), 22 deletions(-) diff --git a/api.json b/api.json index 66ed7fa..2769131 100644 --- a/api.json +++ b/api.json @@ -39,7 +39,8 @@ "timeout": 1800, "invalidPercent": 30, "checkThreshold": 30, - "malformedLimit": 5 + "malformedLimit": 5, + "fail2banCommand": "fail2ban-client" }, "limits": { "enabled": false, diff --git a/policy/policy.go b/policy/policy.go index 6154d8d..1e5dfcb 100644 --- a/policy/policy.go +++ b/policy/policy.go @@ -33,12 +33,13 @@ type Limits struct { } type Banning struct { - Enabled bool `json:"enabled"` - IPSet string `json:"ipset"` - Timeout int64 `json:"timeout"` - InvalidPercent float32 `json:"invalidPercent"` - CheckThreshold int32 `json:"checkThreshold"` - MalformedLimit int32 `json:"malformedLimit"` + Enabled bool `json:"enabled"` + IPSet string `json:"ipset"` + Timeout int64 `json:"timeout"` + InvalidPercent float32 `json:"invalidPercent"` + CheckThreshold int32 `json:"checkThreshold"` + MalformedLimit int32 `json:"malformedLimit"` + Fail2BanCommand string `json:"fail2banCommand"` } type Stats struct { @@ -69,6 +70,34 @@ type PolicyServer struct { walletblacklist []string } +// addToFail2Ban adds the given IP address to Fail2Ban's blacklist. +func addToFail2Ban(ip string) error { + cmd := exec.Command("fail2ban-client", "set", "blacklist", "add", ip) + output, err := cmd.CombinedOutput() + if err != nil { + return fmt.Errorf("Error adding to Fail2Ban: %v, Output: %s", err, output) + } + return nil +} + +// doBan bans the specified IP address using the configured IPSet and timeout. +func (s *PolicyServer) doBan(ip string) { + set, timeout := s.config.Banning.IPSet, s.config.Banning.Timeout + cmd := fmt.Sprintf("sudo ipset add %s %s timeout %v -!", set, ip, timeout) + args := strings.Fields(cmd) + head := args[0] + args = args[1:] + + log.Printf("Banned %v with timeout %v on ipset %s", ip, timeout, set) + + _, err := exec.Command(head, args...).Output() + if err != nil { + log.Printf("CMD Error: %s", err) + // Add a call here to add the IP address to Fail2Ban + addToFail2Ban(ip) + } +} + func Start(cfg *Config, storage *storage.RedisClient) *PolicyServer { s := &PolicyServer{config: cfg, startedAt: util.MakeTimestamp()} grace := util.MustParseDuration(cfg.Limits.Grace) @@ -338,21 +367,6 @@ func (s *PolicyServer) InWhiteList(ip string) bool { return util.StringInSlice(ip, s.whitelist) } -func (s *PolicyServer) doBan(ip string) { - set, timeout := s.config.Banning.IPSet, s.config.Banning.Timeout - cmd := fmt.Sprintf("sudo ipset add %s %s timeout %v -!", set, ip, timeout) - args := strings.Fields(cmd) - head := args[0] - args = args[1:] - - log.Printf("Banned %v with timeout %v on ipset %s", ip, timeout, set) - - _, err := exec.Command(head, args...).Output() - if err != nil { - log.Printf("CMD Error: %s", err) - } -} - func (x *Stats) heartbeat() { now := util.MakeTimestamp() atomic.StoreInt64(&x.LastBeat, now)