A module declares its fail2ban jail; the mesh composes them per node (to-be 31)
The mechanism, mirroring Filtering: a module declares Jails (name, failregex, jail stanza) naming no node/path (ADR 0112); the intrusion-prevention holder declares Jailing (where composed jails go); the mesh gathers every assigned module's jails into one jail.d file (a fixed id the fail2ban service restarts on) plus a filter.d file per jail. A node not running a module has none of its jails. Tested. Behaviour-neutral until a service module declares a jail — the per-service content (postgres/mssql/mailu failregex+logpath) is authored next, against how each container actually logs.
This commit is contained in:
@@ -366,6 +366,14 @@ type Manifest struct {
|
||||
// that could only see its own ports would write a rule set that closed everything else.
|
||||
Filtering *Filtering `json:"filtering,omitempty"`
|
||||
|
||||
// Jails are the fail2ban jails this module declares for its own service (novox/hq to-be 31).
|
||||
// Written into whichever node runs the module, the same way `listens` become that node's rules.
|
||||
Jails []Jail `json:"jails,omitempty"`
|
||||
|
||||
// Jailing marks the module that composes the node's fail2ban jails — the intrusion-prevention
|
||||
// holder. Like Filtering: one module per node gathers what every module declared and writes it.
|
||||
Jailing *Jailing `json:"jailing,omitempty"`
|
||||
|
||||
// Guards are ports of this module's the mesh refuses on an adopted node except from the
|
||||
// private network and from the machine itself (novox/hq ADR 0100) — the store's port and the
|
||||
// broker's management port. The ports the software uses; the mesh guards where the machine
|
||||
@@ -615,6 +623,36 @@ func (l Listening) At() string {
|
||||
return l.Protocol
|
||||
}
|
||||
|
||||
// Jail is a fail2ban jail a module declares for its own service (novox/hq to-be 31).
|
||||
//
|
||||
// **The module names no node and no path** (ADR 0112): it says what a break-in on its service looks
|
||||
// like — the failregex — and the jail's own keys (the port it watches, where it logs, how many
|
||||
// tries, how long to ban). The mesh writes it into whichever node's fail2ban runs the module, the
|
||||
// same way a module's `listens` become that node's firewall rules. A node not running the module
|
||||
// has no such jail.
|
||||
type Jail struct {
|
||||
// Name is the jail and its filter, e.g. "postgres-auth". One holder of the name per node.
|
||||
Name string `json:"name"`
|
||||
// Failregex is what a failed authentication looks like in the service's log — the filter.
|
||||
Failregex string `json:"failregex"`
|
||||
// Jail is the body of the jail's stanza: the keys under [<name>] the module knows and the mesh
|
||||
// does not — the port it watches, its logpath and backend, maxretry, bantime.
|
||||
Jail string `json:"jail"`
|
||||
}
|
||||
|
||||
// Jailing says a module composes the node's fail2ban jails — the intrusion-prevention holder. Like
|
||||
// Filtering for the firewall: one module gathers what every other module declared and writes it
|
||||
// where it owns. Into is the one jail file the stanzas are composed into (so the fail2ban service
|
||||
// can restart on a single resource); FilterInto is the directory each jail's filter file goes in.
|
||||
type Jailing struct {
|
||||
Into string `json:"into"`
|
||||
FilterInto string `json:"filter-into"`
|
||||
}
|
||||
|
||||
// ComposedJailsID is the single jail file the mesh composes every declared jail into, so the
|
||||
// fail2ban service names one resource in its restart-on and a jail added or removed reaches it.
|
||||
func ComposedJailsID() string { return "composed-jails" }
|
||||
|
||||
// Filtering says where a module wants the computed rule set.
|
||||
type Filtering struct {
|
||||
// Into is the path to write it to. Whatever loads it is this module's own business — an
|
||||
|
||||
Reference in New Issue
Block a user