Fail2ban reads failure events from logs and applies ban actions. It complements protection for services such as SSH, but needs the correct log source, filter, and firewall action. Installing the service alone does not protect every entry point.
Scope and installation
These examples cover SSH with distribution packages on systemd-based Debian/Ubuntu. Check the distribution, actual SSH port, and installed Fail2ban version first. Fedora, RHEL, and other distributions have different repositories and logging defaults.
| |
Prefer maintained distribution packages. If source installation is required, consult upstream guidance to select a release and confirm dependencies, service integration, and future updates.
Identify the SSH log source
Ubuntu/Debian commonly use the ssh service unit; other environments may use sshd. Inspect the actual unit and logs:
| |
For file-based logging, confirm that a file such as /var/log/auth.log exists and receives SSH authentication events. A path in a tutorial is not evidence that the machine writes to it.
Configure a small SSH jail override
Keep the distribution’s jail.conf and place only the overrides in /etc/fail2ban/jail.d/sshd.local. Copying the entire default file makes later upstream changes harder to inherit.
Before enabling protection, retain a second management session or console and add a verified fixed administration address to ignoreip. The example below contains loopback addresses only, not your remote management address.
| |
- Set
portto the actual value if SSH uses a custom port. - The
systemdbackend reads the journal; do not combine it with a copied file-basedlogpath. - For file logs, choose a suitable backend and a verified path, for example
backend = pollingwithlogpath = /var/log/auth.log. maxretryandfindtimedefine the trigger;bantimesets the ban duration. Adjust them for the service and recovery options.
Validate before enabling
| |
After configuration validation succeeds, enable or reload the service:
| |
Confirm that sshd is enabled, the log source is correct, and the ban action works. Test from a controlled source while retaining a recovery path rather than repeatedly failing authentication on your only management connection.
Bans, unbans, and persistence
192.0.2.10 is a documentation example address. Replace it with a verified target before running these commands:
| |
Upstream defaults enable SQLite persistence, with dbfile set to /var/lib/fail2ban/fail2ban.sqlite3. It is therefore inaccurate to say that all bans disappear on restart. Restoration also depends on the database, remaining ban duration, purge policy, and distribution configuration. Check effective configuration and actual status after a restart.
Before protecting other services
Do not enable a nginx-404 jail without its matching filter. Confirm the filter file, actual log format, and false-positive scope, then verify controlled samples with fail2ban-regex. A JavaScript regex tool does not replace Fail2ban’s filter tests.
If no ban occurs, inspect the sequence: log production, backend ingestion, filter matching, and firewall action. Run fail2ban-client -t after configuration changes instead of guessing through repeated restarts.