ADR 0179: the intrusion seat serves its verbs, a container may log to the journal, and every door declares its jail; designs 31 and 33
This commit is contained in:
@@ -1,10 +1,14 @@
|
||||
---
|
||||
layer: to-be
|
||||
status: proposed
|
||||
code: []
|
||||
updated: 2026-09-27
|
||||
status: in-progress
|
||||
code:
|
||||
- mesh-controller: internal/catalogue/jails_into.go, internal/catalogue/manifest.go (Jail, Jailing)
|
||||
- mesh-catalog: modules/fail2ban (jailing, the base and the seat's verbs), modules/mailu, modules/route-proxy, modules/gitea (jails)
|
||||
- mesh-host: internal/declaration/declaration.go (a container's logging)
|
||||
updated: 2026-10-02
|
||||
decisions:
|
||||
- 02-DECISIONS/0112-a-module-definition-names-no-node-mesh-or-path.md
|
||||
- 02-DECISIONS/0179-the-intrusion-seat-serves-its-verbs-and-every-door-declares-its-jail.md
|
||||
---
|
||||
|
||||
# 31 — A module declares its fail2ban jail, and the mesh composes them per node
|
||||
@@ -63,3 +67,28 @@ jail, composed from the postgres module's manifest, without anyone editing a nod
|
||||
beside)
|
||||
- mesh-catalog `modules/fail2ban` (the base: sshd, recidive, ignoreip); the service modules
|
||||
(`postgres`, `mssql`, `mailu`) that will declare jails
|
||||
|
||||
## Decided and built, 2026-10-02
|
||||
|
||||
[ADR 0179](../../02-DECISIONS/0179-the-intrusion-seat-serves-its-verbs-and-every-door-declares-its-jail.md)
|
||||
made this the rule and built it. A module declares `jails` — each a name, the `failregex` of a
|
||||
failed attempt in its log, and the stanza's own keys — and the fail2ban module declares `jailing`:
|
||||
the one file the stanzas compose into and the directory each filter lands in. The controller gathers
|
||||
every assigned module's jails per node into those; the holder's daemon restarts on the composed file.
|
||||
|
||||
What made it workable was the log. A container's output went to a file of the runtime's own, under
|
||||
a path that changes when the container is recreated, so no jail could read a container's service
|
||||
however it logged. A container now declares `logging: journald`, the host runs it with the journal as
|
||||
its driver, and a jail reads it with `backend = systemd` and a `journalmatch` on the container's
|
||||
name — the same way the base's ssh jail has always read the ssh daemon. The first three doors: the
|
||||
mail front end (every login failure on its proxying ports), the forge (a failed authentication
|
||||
attempt) and the public proxy (a certificate or request for a name the mesh does not serve, which
|
||||
the proxy now says in its log). The base is strict — three in a day for a day; twice banned in two
|
||||
weeks for four — and the mesh's own range stays never banned.
|
||||
|
||||
The seat the module holds serves `status`, `banned`, `ban` and `unban`, from a runtime that carries
|
||||
only the fail2ban client with the daemon's socket shared in; the jails are composed, the ban list is
|
||||
the daemon's, and both are read through the console.
|
||||
|
||||
*How it is checked:* ADR 0179's table.
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ code: [mesh-controller, mesh-tools]
|
||||
updated: 2026-10-02
|
||||
decisions:
|
||||
- 02-DECISIONS/0170-the-firewall-seat-serves-its-verbs.md
|
||||
- 02-DECISIONS/0179-the-intrusion-seat-serves-its-verbs-and-every-door-declares-its-jail.md
|
||||
- 02-DECISIONS/0160-the-mesh-issues-an-assignments-subjects-and-a-runtime-serves-what-it-is-issued.md
|
||||
- 02-DECISIONS/0159-a-tool-call-names-the-machine-and-a-holder-serves-its-seats-verbs.md
|
||||
- 02-DECISIONS/0154-the-meshs-own-verbs-are-the-controller-seats-tools.md
|
||||
@@ -182,6 +183,16 @@ container to declare a capability. Removing a predecessor's rule set is an opera
|
||||
through the seat, recorded on the bus, instead of a shell on the machine. *How it is checked:* ADR
|
||||
0169's table.
|
||||
|
||||
## The intrusion seat's verbs, 2026-10-02
|
||||
|
||||
[ADR 0179](../../02-DECISIONS/0179-the-intrusion-seat-serves-its-verbs-and-every-door-declares-its-jail.md).
|
||||
The second node-scoped seat to carry verbs: `node-intrusion-prevention` serves `status` (every jail
|
||||
with what it watches and holds), `banned` (every address held now, with its jail and when the ban
|
||||
ends), `ban` and `unban` (an operator's act on the live ban list). The fail2ban module serves them
|
||||
from a runtime that carries only the daemon's client, the socket shared in from the machine — no
|
||||
capability, no machine network, since the daemon on the machine does the banning. The module's own
|
||||
tool beside them reads one jail's effective settings. *How it is checked:* ADR 0179's table.
|
||||
|
||||
## What this does not settle
|
||||
|
||||
- Which verbs each seat should serve. That is a decision per seat, and the reason to do it slowly: a
|
||||
|
||||
Reference in New Issue
Block a user