Ban lists: where Guard and fail2ban ban addresses
A program bans an address (every port, or a protocol's ports) for a time; the ban list says what it is kept from: the firewall, some hosts behind it, or everything. Bans drop ahead of every rule, close the address's connections, group IPv6 by /64, are kept in the database across restarts and audited. Never banned: the inside, the firewall's own addresses, the caller, the list's never. bans grant (bans:write:LIST), hc banlist/bans/ban/unban, Traffic -> Bans, a fail2ban action in contrib/, and failed logins and refused tokens logged for Guard and fail2ban. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
6f56eefae2
commit
500bfc7bdd
44 files changed
+2541
-39
No files matched your search
@@ -0,0 +1,53 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"net/netip"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Ban is an address a ban list keeps out (docs/bans.md): of every port,
|
||||
// or of one protocol and port. Bans are kept apart from the
|
||||
// configuration, like a dynamic set's entries: not in the history, and
|
||||
// not on probation.
|
||||
type Ban struct {
|
||||
ID int64 `json:"id"`
|
||||
ListID int64 `json:"list_id"`
|
||||
List string `json:"list"`
|
||||
// Address is what is banned: an address, or an IPv6 prefix of the
|
||||
// list's grouping ("2001:db8:1:2::/64").
|
||||
Address string `json:"address"`
|
||||
Protocol string `json:"protocol,omitempty"` // tcp or udp; "" every port
|
||||
Port int `json:"port,omitempty"`
|
||||
// Expires is when the ban ends (nil: it doesn't); Timeout the
|
||||
// seconds it has left then.
|
||||
Expires *time.Time `json:"expires,omitempty"`
|
||||
Timeout int `json:"timeout,omitempty"`
|
||||
Created time.Time `json:"created"`
|
||||
// Who banned it (the user or token's name), Source the program's own
|
||||
// name for why ("guard/ssh", "fail2ban/sshd"), Reason free text (a
|
||||
// log line).
|
||||
Who string `json:"who"`
|
||||
Source string `json:"source,omitempty"`
|
||||
Reason string `json:"reason,omitempty"`
|
||||
}
|
||||
|
||||
// Prefix is the banned address as a prefix.
|
||||
func (b *Ban) Prefix() (netip.Prefix, error) {
|
||||
if p, err := netip.ParsePrefix(b.Address); err == nil {
|
||||
return p, nil
|
||||
}
|
||||
a, err := netip.ParseAddr(b.Address)
|
||||
if err != nil {
|
||||
return netip.Prefix{}, err
|
||||
}
|
||||
return netip.PrefixFrom(a, a.BitLen()), nil
|
||||
}
|
||||
|
||||
// BanAddress writes a banned prefix: an address alone when it is one
|
||||
// address, else the prefix.
|
||||
func BanAddress(p netip.Prefix) string {
|
||||
if p.IsSingleIP() {
|
||||
return p.Addr().String()
|
||||
}
|
||||
return p.String()
|
||||
}
|
||||
Reference in new issue
Block a user