Browse documentation
On this page

Log watching and continuity

File identity, durable checkpoints, journal origins and the confirmed-ban recidive source.

Sources feed durable records

File, journal and internal events enter native ingestion. A complete record gets a durable receipt; detection, retries, source progress and effect intent are committed consistently. Source acknowledgement follows commit. A restart must not turn a retry into a new event with a new deadline.

flowchart LR
  F[Files and rotation] --> R[Durable receipts]
  J[Validated journal origins] --> R
  I[Confirmed-ban events] --> R
  R --> D[Detection and policy]
  D --> P[Owned protection]

File input

Set source = "file", absolute logpath entries and an explicit timestamp contract for the actual log format. Available contracts are iso8601, syslog, epoch_seconds, common_log and undated; use timezone settings when required. Undated input is an explicit choice, not permission to treat arbitrary malformed dates as current events.

Checkpoints retain identity and exact saved position across restart and rotation. Lost continuity, unsafe replay and incompatible source generations require visible recovery/intervention; the daemon does not invent a position to appear healthy. Missing paths can pass configuration validation, but runtime source readiness is a separate admission check. Validate actual read/search permissions under the service identity.

Journal input

Journal input uses journald and the journalctl executable. The source validates local machine identity, root UID, transport and the configured root-owned executable paths before admitting a detection. A client-controlled journal tag is not an authorization signal.

[jails.sshd]
filter = "sshd"
source = "journald"
journal_executables = ["/usr/sbin/sshd", "/usr/lib/openssh/sshd-session"]

Both paths are required for the qualified Debian 13 SSH listener/session split. Check the executable locations and origin policy for your host. Native journal progress is durable. This differs from importing fail2ban state: fail2ban has no saved journal cursor to transfer, so that migration requires a disclosed reset/replay boundary.

Internal recidive

[jails.recidive]
filter = "recidive"
source = "internal"
maxretry = 2
findtime = "1d"
bantime = "1w"

Recidive consumes confirmed bans from other jails through the internal source. It needs no log file, journal selector or custom rule file. A policy decision or log-only would-ban is not confirmation of installed protection.

Source selection and health

source = "auto" resolves the configured input at startup. Prefer an explicit source for a reviewed deployment. The deprecated fail2ban backend alias names a source; global.firewall separately chooses enforcement.

fail2zig jails
fail2zig status

Inspect source health, storage and readiness, not just whether the process exists. Storage failure pauses affected ingestion while retaining protection. Recovery must restore the store and verify source continuity before healthy admission. See migration continuity.

Edit on GitHub →