Lab 10: fail2ban — Intrusion Prevention

Time: 40 minutes | Level: Advanced | Docker: docker run -it --rm --privileged ubuntu:22.04 bash

fail2ban is an intrusion prevention framework that monitors log files for patterns indicating brute-force or other attacks, then automatically bans offending IPs using firewall rules (iptables/nftables). This lab covers installation, jail configuration, custom filters, testing, and operational management of fail2ban.


Step 1: Install fail2ban

apt-get update -qq && apt-get install -y fail2ban 2>/dev/null

Verify installation:

fail2ban-client --version
dpkg -l fail2ban

📸 Verified Output:

$ docker run --rm ubuntu:22.04 bash -c "apt-get update -qq 2>/dev/null && apt-get install -y -qq fail2ban 2>/dev/null && fail2ban-client --version"
Fail2Ban v0.11.2

Check installed components:

# Key files and directories
ls /etc/fail2ban/
ls /etc/fail2ban/filter.d/ | head -10
ls /etc/fail2ban/action.d/ | head -10

📸 Verified Output:

$ docker run --rm ubuntu:22.04 bash -c "apt-get install -y -qq fail2ban 2>/dev/null && ls /etc/fail2ban/"
action.d
fail2ban.conf
fail2ban.d
filter.d
jail.conf
jail.d
paths-common.conf
paths-debian.conf

💡 The directory structure separates concerns: filter.d/ contains log pattern rules (what to detect), action.d/ contains ban actions (what to do), and jail.d/ or jail.local combines them into active "jails".


Step 2: jail.conf vs jail.local

Critical rule: Never edit jail.conf directly. It gets overwritten on package updates.

📸 Verified Output:

Create jail.local to override defaults:

📸 Verified Output:

💡 The [sshd] jail uses maxretry = 3 — lower than the default 5 — because SSH brute forces are extremely common and 3 failures is enough to identify an attacker. After 3 failures within 10 minutes, the IP is banned for 24 hours.


Step 3: Understanding the [sshd] Filter

📸 Verified Output:

Key elements of a filter:

Element
Purpose

failregex

Regex patterns that match log lines indicating failure

ignoreregex

Patterns to ignore (false positive prevention)

<HOST>

Placeholder that matches and captures the attacker's IP

<F-USER>

Placeholder capturing the attempted username

datepattern

How to parse timestamps from log lines


Step 4: Backends — systemd vs polling

fail2ban supports multiple backends for reading logs:

Backend
Description
Use When

auto

Auto-detects best available

Default — use this

systemd

Reads from journald

systemd-based systems without log files

polling

Polls log files with inotify

Traditional syslog, log files

pyinotify

inotify-based (Linux only)

High-performance file watching

gamin

FAM-based file monitoring

Older systems

Configure backend per-jail:

💡 On modern Ubuntu with systemd, SSH logs go to journald AND /var/log/auth.log. Use backend = auto — fail2ban will pick pyinotify or polling automatically and it works reliably.


Step 5: Creating a Custom Filter

Build a custom filter for a web application login endpoint:

Add the jail for this filter:


Step 6: Testing Filters with fail2ban-regex

Before deploying, test your filter against real or sample log data:

Test the custom webapp filter:

📸 Verified Output:

💡 fail2ban-regex is your best friend for filter development. Always test before deploying — a broken regex that never matches means attackers never get banned; one that over-matches could ban legitimate users.


Step 7: Operational Management — fail2ban-client

Managing fail2ban in production:

📸 Verified Output (real host sample):


Step 8: Capstone — Harden a Production SSH Server with fail2ban

Scenario: Your SSH server is experiencing heavy brute-force attacks. Implement an aggressive, multi-tier fail2ban configuration that bans short-term on few failures, and escalates to permanent bans for persistent attackers.

📸 Verified Output:


Summary

Task
Command / File
Notes

Install

apt-get install fail2ban

Installs daemon + client

Version check

fail2ban-client --version

Verify installation

Config file

/etc/fail2ban/jail.conf

Default config — do not edit

Local overrides

/etc/fail2ban/jail.local

Your customizations here

Jail directory

/etc/fail2ban/jail.d/

Drop-in jail configs

Filters directory

/etc/fail2ban/filter.d/

Log pattern definitions

Actions directory

/etc/fail2ban/action.d/

Ban action scripts

Start service

systemctl start fail2ban

Activate the daemon

Check status

fail2ban-client status

List all active jails

Jail status

fail2ban-client status sshd

Show ban counts and IPs

Ban an IP

fail2ban-client set sshd banip <IP>

Manual ban

Unban an IP

fail2ban-client set sshd unbanip <IP>

Remove a ban

Test filter

fail2ban-regex <logfile> <filter>

Debug filter patterns

Reload config

fail2ban-client reload

Apply configuration changes

Key settings

bantime, findtime, maxretry

Core tuning parameters

Incremental bans

bantime.increment = true

Escalating bans for repeat offenders

Last updated