Browse documentation
On this page

Configuration reference

Native TOML settings, durations, sources, storage, enforcement and reload boundaries for fail2zig 0.4.0.

The default file is /etc/fail2zig/config.toml. Use the worked example as a starting point and validate before starting or reloading. This reference describes 0.4.0 native operation.

File format and permissions

The parser accepts a strict TOML subset: [global], [defaults] and [jails.<name>]. Unknown keys/sections, duplicate keys, mixed array types and invalid values are rejected. Use section headers, not dotted keys on the left. Comments begin with #; strings must be quoted. Jail names use ASCII letters, digits, hyphens or underscores.

Keep configuration administrator-owned and readable by the service. World-writable or non-root-group-writable configuration is refused. A non-root owner warns. The installer preserves existing operator configuration; check its permissions when changing the service group.

Duration strings

bantime, findtime, bantime_increment_max_bantime and bantime_increment_jitter accept integer seconds or quoted durations in both defaults and jail overrides.

[defaults]
bantime = "1h30m"
findtime = "10m"
bantime_increment_max_bantime = "1w"
bantime_increment_jitter = "30s"
UnitSeconds
s1
m, mm, min60
h3,600
d86,400
w604,800
mo2,629,800
y31,557,600

Months and years are fixed intervals, not calendar arithmetic. Each term is a nonnegative integer followed by a unit; terms can touch or have intervening whitespace ("1h 30m"). Fractions, signed terms, arithmetic, unknown units and overflow are rejected. Bare 24h is not valid TOML.

Finite bantime, findtime and the escalation cap must be positive. Jitter permits zero and must not exceed the cap. Only bantime accepts "permanent". CLI --duration, --timeout and migration window arguments remain numeric.

[global]

Logging and administration

KeyType / defaultMeaning
log_levelString, "info"debug, info, warn or err. Live reload supported.
log_targetString, "stderr"Stderr or an absolute log-file path. Changing the target requires restart; SIGUSR1 reopens it after rotation.
socket_pathString, "/run/fail2zig/fail2zig.sock"Local administration and monitoring socket.
pid_fileString, "/run/fail2zig/fail2zig.pid"Deprecated compatibility key; warns when explicitly set and is not written. Use systemd MainPID.

The socket is mode 0660. The configured service/monitor group has read-only access. Mutations require root or the daemon UID, verified with peer credentials. Use fail2zig --socket <path> status when overriding the default socket.

State and resource limits

KeyType / defaultMeaning
state_fileAbsolute path, "/var/lib/fail2zig/state.bin"Native SQLite store for receipts, checkpoints, policy, retries, owners, effect intent and confirmed history.
memory_ceiling_mbInteger, 64, minimum 16Configured memory budget; do not interpret it as a whole-process RSS cap.
native_memory_ceiling_mbPositive integer, 256Native reservation/admission budget in MiB. Plans that exceed the admitted bounds are refused.
native_fd_ceilingPositive integer, 2048Native descriptor admission budget.
history_retentionNonnegative integer seconds, 86400Age policy for confirmed-history cleanup; required recovery anchors stay pinned.
history_max_matchesInteger 0–1024, 10Confirmed-history match-retention policy.

The database and its parent must belong to the daemon UID. The historical .bin extension does not make it the legacy binary format. Native startup refuses corrupt, incompatible or inaccessible required state instead of starting empty. Storage failure pauses affected ingestion and reports degraded health while retaining protection. Preserve the database and WAL/SHM coherently; do not delete them to clear an error. See upgrades and the memory model.

HTTP and WebSocket

KeyType / defaultMeaning
metrics_enabledBoolean, truefalse disables both HTTP and WebSocket; IPC and protection remain available.
metrics_bindIP string, "127.0.0.1"Listen address. Loopback is not authentication.
metrics_portInteger 1–65535, 9100Port remains validated even when disabled. Zero does not disable HTTP.
websocket_max_clientsInteger 1–1024, 16Maximum simultaneous WebSocket clients.

Endpoints are /metrics, /api/status, /api/bans, /api/health and /events. Health reports readiness with HTTP 200/503. HTTP shares the privileged daemon process. Keep external access controlled or disable it if unused.

Firewall

firewall is a global string, default "auto".

ValueSelection behavior
"auto"Probe nftables, then ipset/iptables for unsupported or transient nftables failure. Permission denial stops detection.
"nftables"Probe only nftables; direct netlink.
"ipset"Probe only ipset; needs both ipset and iptables tools.
"iptables"Probe only iptables.

An explicit backend never silently switches to another. Scaffold failure also does not trigger fallback. Jail banaction selects enforcement policy, not a backend. If every enabled jail is log-only, enforcement backend detection is skipped.

on_no_backend is "fail-closed" by default: unusable required enforcement causes startup refusal. "log-only" explicitly permits degraded observe-only operation; status reports the cause. It does not install protection.

firewall_namespace is an ownership anchor, not a request to enter another namespace. Effects remain in the daemon’s current network namespace. Custom selectors and unit overrides that move the daemon between namespaces are unsupported in 0.4.0; leave this setting at its built-in default.

DNS and timezone data

dns_server is an optional resolver IP; dns_port defaults to 53 and accepts 1–65535. Native hostname rules use bounded resolution and retain retry state; a hostname is not an arbitrary command. timezone_root defaults to "/usr/share/zoneinfo" for named timezone data. Leave these defaults unless the chosen input contract requires an explicit deployment setting.

[defaults]

KeyType / defaultMeaning
bantimeSeconds/duration, 600, or "permanent"Initial ban duration.
findtimePositive seconds/duration, 600Window for repeated failures.
maxretryInteger 1–128, 5Failures required within findtime.
sourceString, "auto"auto, file, journald or internal.
banactionString, "nftables"nftables, iptables, ipset all mean enforce through the selected global backend; log-only means observe.
ignoreipString array, []Exact IPs/CIDRs excluded from ban policy. The shipped example includes loopback ignores.

enforce = true/false is also accepted as a policy spelling. Do not combine it with banaction in the same section. Prefer banaction for consistency with the shipped configuration. No value here enables arbitrary shell actions.

Escalation

KeyDefaultMeaning
bantime_increment_enabledfalseEnable escalating durations.
bantime_increment_multiplier1.0Positive base multiplier.
bantime_increment_factor1.0Nonnegative growth factor; integer or decimal.
bantime_increment_formula"linear"linear or exponential, not an arbitrary expression.
bantime_increment_scope"per-jail"per-jail or overall recurrence scope.
bantime_increment_max_bantime604800Positive seconds/duration cap.
bantime_increment_jitter0Seconds/duration jitter bound, at most the cap.

Linear uses bantime × multiplier × (1 + factor × n); exponential uses bantime × multiplier × factor^n, where n is the prior ban count used by the policy. For doubling with no jitter, set multiplier 1, factor 2 and formula "exponential". A multiplier of 2 alone does not select doubling growth.

0.4.0 inherits escalation settings field by field. A jail overrides only the keys it explicitly sets; omitted keys retain [defaults] values. This differs from the old grouped-inheritance documentation.

[jails.<name>]

A jail declares a source, matcher and policy. Enabled jails must have admitted protection; unknown built-in filters without native rule files fail validation.

KeyDefault / contract
enabledtrue; disabled jails are not started.
filterBuilt-in service name, or the service name for a custom rule-file jail. Built-ins accept hyphen/underscore forms.
logpathArray of absolute file paths, default empty. Use file-source paths that the service can read.
sourceInherits defaults. Prefer explicit source selection for reviewed configurations.
maxretry, findtime, bantime, banactionOverride the corresponding default.
ignoreipReplaces, rather than appends to, the defaults list. Repeat loopback entries when overriding.
bantime_increment_*Field-by-field overrides as described above.

Source and time contracts

KeyContract
timestampFile inputs require an explicit format: iso8601, syslog, epoch_seconds, common_log or undated. Choose for the actual log format.
timezone_offset_minutesFixed offset from UTC, -1439–1439, for the selected timestamp contract.
timezoneNamed timezone; cannot be combined with the fixed offset.
timezone_ambiguityreject, earlier or later; requires a named timezone.
journal_executablesRoot-owned executable paths admitting journal origins. For Debian 13 SSH, include both paths below.
rule_filesUp to eight distinct absolute paths to bounded native JSON rules.
ignore_fileOptional ignore-policy file for custom rule jails; its contents can be reloaded.
[jails.sshd]
filter = "sshd"
source = "journald"
journal_executables = ["/usr/sbin/sshd", "/usr/lib/openssh/sshd-session"]

auto resolves the configured source at startup. file reads declared paths; journald requires journalctl and admitted origins; internal is the confirmed-ban feed for recidive. Internal recidive does not use log paths or custom rule files. A source is healthy only after its runtime checks pass; configuration validation alone is not that check. See log watching.

Deprecated and migration-managed settings

backend is a deprecated source alias accepted in defaults/jails: systemd maps to journald; auto, polling, pyinotify and gamin map to auto. Using both source and backend in one section is an error. It never chooses the firewall backend.

native_ingestion defaults to true; disabling native operation is not a supported 0.4.0 deployment route. compatibility_manifest and compatibility_pending are migration-managed admission metadata. Do not clear blockers by hand to force an unsupported imported jail into service.

Validation and reload

sudo fail2zig --validate-config --config /etc/fail2zig/config.toml

Diagnostics identify file, line, column, section and key when available. Unreadable files and permission failures can be positionless. Validation summarizes configured sources; an auto source is resolved when the daemon starts. Inspect the actual source and readiness through fail2zig jails and fail2zig status.

Some settings apply through fail2zig reload; others return restart_required. See the reload table. Neither successful syntax validation nor a reload request establishes installed firewall protection.

The tagged parser and shipped example define the release’s accepted configuration.

Edit on GitHub →