A smaller runtime to maintain
One static executable combines the daemon, administration and migration tools. No Python runtime or separate database server is required.
Static musl buildA fail2ban replacement for Linux
Predictable behavior under hostile input.
Reads your logs, detects repeated failures, and bans offending IPs. A familiar job, with a smaller runtime and explicit resource limits.
sshd · 203.0.113.7
1h ban · kernel readback confirmed Design
The same log-to-ban model, with explicit boundaries around the work your server does.
One static executable combines the daemon, administration and migration tools. No Python runtime or separate database server is required.
Static musl buildSource progress, retry state and protection ownership survive restart in SQLite. Bounded admission retains critical state when resources run short.
Memory modelBuilt-in filters compile into specialised parsers. A single pass extracts the address, with bounds checks and no allocations in the hot path.
Parser architectureTyped intent is persisted before dispatch, then confirmed by kernel readback. Choose nftables through direct netlink, or the iptables and ipset backends.
Netlink integrationMigration
Import your fail2ban configuration, review the result, then switch when you’re ready.
Choose a prebuilt Linux release or build from source.
Download a releaseInspect supported jails and project configuration into TOML. Resolve unsupported filters and actions before enabling protection.
Compare decisions in log-only mode before changing enforcement. The guide covers cutover and rollback.
Follow the migration guide# After installing fail2zig
sudo fail2zig migrate inspect --source-dir /etc/fail2ban # Review scope and blockers before planning cutover
Arbitrary regexes and shell actions need reviewed replacements. Supported schema-4 migration can carry owners, deadlines and history; in-memory partial matches do not transfer.
Check compatibilityx86_64, ARM64, ARMv7, MIPS & MIPSel. Selected live checks cover Debian 13 x86_64; other targets have cross-build, static-inspection and QEMU smoke evidence.
Verify a buildRelease qualification
0.4.0 brings native durability and verified enforcement. The release evidence separates live host checks from cross-build and emulated command checks.
Debian 13x86_64
File and journal input, all three firewall backends, service permissions and storage recovery. Other architectures have static-build and QEMU smoke evidence.
Read the qualification scopeSQLiteembedded
Durable checkpoints, retries, owners and confirmed history. Resource exhaustion pauses admission instead of silently discarding critical protection state.
Understand the resource limitsQualification boundaryLive checks preceded the version-only update to 0.4.0; rebuilt artifacts passed native/emulated checks. Ubuntu and non-x86 hardware enforcement remain untested. No comparative speed claim accompanies this release.
Comparison
Compare runtime, deployment, and firewall support. Your existing configuration is part of that decision.
Scroll horizontally to compare all columns.
| Tool | Language | Deployment | Firewall backends |
|---|---|---|---|
| fail2zig | Zig | Static musl binary | nftables / iptables / ipset |
| fail2ban | Python | Package + runtime | iptables / nftables |
| SSHGuard | C | Daemon + firewall backend | pf / iptables / nftables |
| CrowdSec | Go | Engine + remediation component | iptables / nftables |
Selected deployment characteristics. See fail2ban, SSHGuard and CrowdSec for full support details.
FAQ
No. Inspect supported configuration and action scope before switching. The schema-4 migration workflow can transfer admitted owners, deadlines and history, but not partial matches or journal cursors. Arbitrary fail2ban regexes and actions are not executed.
Read the compatibility detailsThat’s the threat model we designed to. Parsing is bounds-checked, log lines have a bounded input contract, and native processing has explicit resource limits. Storage failures pause affected ingestion while retaining protection. These controls reduce risk; the threat model documents remaining limits, including the known loopback case.
Read the threat modelZig gives us explicit allocator control, comptime code generation for built-in filters, and straightforward cross-compilation to musl targets. Rust would work. Zig fits the problem.
Static linkage avoids shared runtime libraries, but deployment still needs readable logs, writable persistent state and the selected backend’s capabilities. Journal input needs journalctl; iptables/ipset need host tools. Effects stay in the current network namespace; custom namespace selectors are unsupported in 0.4.0.
Neither. It reads logs and acts on repeated failures. It does not aggregate security events across hosts, correlate incidents, or inspect HTTP bodies.
Open source · AGPL-3.0
Read the source, try the demo, or plan your migration.