Browse documentation
On this page

Example jail configuration

A 0.4.0 configuration for Debian SSH journal input, confirmed-ban recidive and an optional file jail.

Start with the shipped 0.4.0 example. This version makes the source and duration choices explicit. Adjust paths and policy for your host, then validate before starting the service.

Configuration

[global]
log_level = "info"
socket_path = "/run/fail2zig/fail2zig.sock"
state_file = "/var/lib/fail2zig/state.bin"
memory_ceiling_mb = 64
metrics_enabled = true
metrics_bind = "127.0.0.1"
metrics_port = 9100
firewall = "auto"
on_no_backend = "fail-closed"
 
[defaults]
bantime = "10m"
findtime = "10m"
maxretry = 5
banaction = "nftables"
ignoreip = ["127.0.0.1/8", "::1"]
 
[jails.sshd]
enabled = true
filter = "sshd"
source = "journald"
journal_executables = ["/usr/sbin/sshd", "/usr/lib/openssh/sshd-session"]
maxretry = 3
bantime = "1h"
bantime_increment_enabled = true
bantime_increment_multiplier = 1
bantime_increment_factor = 2
bantime_increment_formula = "exponential"
bantime_increment_max_bantime = "1w"
bantime_increment_jitter = "0s"
 
[jails.recidive]
enabled = true
filter = "recidive"
source = "internal"
maxretry = 2
findtime = "1d"
bantime = "1w"
 
[jails.nginx-http-auth]
enabled = false
filter = "nginx-http-auth"
source = "file"
timestamp = "undated"
logpath = ["/var/log/nginx/error.log"]

Why these settings

SSH journal origins include both Debian 13 listener/session executable paths. Check paths on your own installation; do not substitute a journal tag for origin validation. Recidive consumes confirmed bans from other jails, so it needs no log file.

The optional nginx jail stays disabled until you verify its source and matcher. undated explicitly uses the undated input contract; choose a supported dated contract when your format supplies usable event timestamps. Test representative records with fail2zig rule-test before enabling enforcement.

The SSH example doubles durations with multiplier 1 and factor 2, up to one week, with jitter disabled. Other jails inherit the defaults. Quoted durations are configuration syntax; command-line time arguments still use integers.

Keep loopback ignores, including when replacing ignoreip in an individual jail. 0.4.0 has a known matching-loopback-SSH cleanup limitation. Add management addresses only when your trust policy requires it; do not blindly ignore broad networks.

Validate and inspect

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

Validation does not start the service. Status/jails require a running daemon and show the actual storage, source and protection state. The SQLite parent and store must belong to the service UID, and systemd must permit writes there. See upgrading before reusing an older state path.

firewall chooses the global backend; banaction enables enforcement. To observe only, set banaction = "log-only" and check all jail overrides. To disable HTTP and WebSocket while retaining IPC monitoring, set metrics_enabled = false.

See the configuration reference for other settings and administration for reload/restart boundaries.

Edit on GitHub →