Browse documentation
On this page

Upgrading to 0.4.0

Plan the state transition, service ownership and rollback when upgrading an existing fail2zig installation.

0.4.0 combines daemon and administration in one executable, stores native state in SQLite and runs the shipped service under a dedicated account. Preserve the old installation before making this transition.

Identify the existing state

The filename state.bin does not identify the format.

Existing stateUpgrade path
Released fail2zig 0.3.0 binary state, including format v4No automatic converter. Keep it for rollback and plan an explicit protection transition.
Compatible native fail2zig SQLiteOffline ownership transition to the service UID; retain the database and any WAL/SHM siblings coherently.
fail2ban schema-4 SQLiteUse fail2ban migration. Never use a foreign database as the native daemon store.

Preserve rollback first

Stop fail2zig and every other state writer. Record the running version, configuration, executable, unit overrides and installed protection. Preserve a coherent offline copy of the state and any WAL/SHM siblings. Keep all writers stopped throughout installation.

Use the 0.4.0 release assets. The installer verifies downloaded content against SHA256SUMS, creates the non-login fail2zig account and preserves operator configuration. It never enables, starts or restarts the service.

Released 0.3.0 binary state

The installer refuses to reinterpret legacy state as SQLite. A deliberately fresh native database loses the saved bans, counters/history and source positions. Existing legacy firewall rules are not automatically adopted as native owners.

Plan the protection gap, record old protection and remove only verified old-owned effects during cutover. Verify the new daemon’s protection independently. Do not run both versions against one state path or infer source continuity from matching filenames. If the reset or gap is unacceptable, retain the old installation until you have an acceptable transition. The fail2ban converter cannot convert this format.

Existing native SQLite

For the default /var/lib/fail2zig/state.bin path, the installer checks the parent, database and existing state.bin-wal / state.bin-shm files, the daemon lock and active writers before changing ownership. Only those verified objects receive the transition; there is no recursive chown or silent reset.

Custom state paths need explicit offline handling. Verify a dedicated real parent, regular single-link files and expected owners; reject symlinks. The native parent and database must belong to the daemon UID, with a non-group/world-writable parent and private files. Grant the custom parent through a matching systemd ReadWritePaths override. Follow the tagged state-upgrade contract for the exact checks. Never recursively change ownership of shared directories.

Review configuration and service identity

  • Administration becomes fail2zig <command>; the installer removes the retired fail2zig-client after installing its replacement.
  • The unit runs as fail2zig:fail2zig. FAIL2ZIG_GROUP selects a custom service/monitor group during installation. Group membership grants monitoring, not mutation.
  • The service retains CAP_NET_ADMIN, CAP_NET_RAW and CAP_DAC_READ_SEARCH. HTTP shares those privileges; disable it with metrics_enabled = false if unused.
  • File sources need an explicit timestamp contract. Debian 13 SSH journal sources need both /usr/sbin/sshd and /usr/lib/openssh/sshd-session in journal_executables.
  • Integer durations still work. The four supported fields also accept quoted values such as "1h30m"; see the configuration reference.

Start and verify explicitly

After the state transition and configuration review:

sudo fail2zig --validate-config --config /etc/fail2zig/config.toml
sudo systemctl daemon-reload
sudo systemctl start fail2zig
sudo fail2zig version
sudo fail2zig status
sudo fail2zig jails
sudo fail2zig list
sudo fail2zig history

Inspect expected owners, deadlines, source health and storage readiness. When HTTP is enabled, /api/health returns 200 only when ready. Check the actual firewall and a controlled external test path before retiring rollback backups.

If storage cannot open, inspect the configured path, ownership, mount and systemd write restrictions. Restore access to the original state; do not delete it, reset checkpoints or make it world-writable to silence an error.

Known limits

Keep default loopback ignores. In 0.4.0, a matching loopback SSH failure with those ignores removed can lead to native-storage intervention. Firewall effects stay in the daemon’s current network namespace; custom namespace selectors and service overrides that move it between namespaces are unsupported.

Selected live qualification used Debian 13 x86_64 before the version-only change from the unpublished 0.3.1 candidate. Rebuilt 0.4.0 artifacts passed native/emulated command checks. ARM64, ARM and MIPS targets have cross-build/static/QEMU evidence, not hardware-enforcement qualification; Ubuntu remains untested.

Edit on GitHub →