Remove Fail2Ban and all configuration files from Ubuntu Server for a clean system.
sudo systemctl stop fail2ban
Clear all current bans before uninstalling:
sudo fail2ban-client unban --all
sudo systemctl disable fail2ban
Use purge to remove the package and its configuration files:
sudo apt purge fail2ban -y
Remove packages that were installed as dependencies:
sudo apt purge python3-pyinotify python3-pyasyncore -y
sudo apt autoremove -y
Delete all remaining configuration files and directories:
sudo rm -rf /etc/fail2ban
sudo rm -f /var/log/fail2ban.log
sudo rm -f /var/log/fail2ban.log.*
sudo rm -rf /var/run/fail2ban
sudo rm -rf /var/lib/fail2ban
Remove any remaining iptables rules created by fail2ban:
sudo iptables -L -n --line-numbers
Warning: This removes ALL custom iptables rules, not just fail2ban rules.
sudo iptables -F
If you only want to remove the /24 subnet bans:
# List rules with line numbers
sudo iptables -L INPUT -n --line-numbers
# Remove specific rule by line number (example: line 1)
sudo iptables -D INPUT 1
Remove all DROP rules from INPUT chain:
while sudo iptables -D INPUT -j DROP 2>/dev/null; do :; done
sudo rm -f /etc/systemd/system/fail2ban.service
sudo rm -f /etc/systemd/system/multi-user.target.wants/fail2ban.service
sudo systemctl daemon-reload
dpkg -l | grep fail2ban
Expected output: No results or status shows "rc" (removed, config files remain)
ls -la /etc/fail2ban
Expected output: ls: cannot access '/etc/fail2ban': No such file or directory
ls -la /var/log/fail2ban*
Expected output: ls: cannot access '/var/log/fail2ban*': No such file or directory
sudo systemctl status fail2ban
Expected output: Unit fail2ban.service could not be found.
sudo iptables -L INPUT -n
Expected output: No fail2ban related DROP rules
Complete uninstall in a single command sequence:
sudo systemctl stop fail2ban && \
sudo fail2ban-client unban --all 2>/dev/null; \
sudo systemctl disable fail2ban 2>/dev/null; \
sudo apt purge fail2ban python3-pyinotify python3-pyasyncore -y && \
sudo apt autoremove -y && \
sudo rm -rf /etc/fail2ban /var/run/fail2ban /var/lib/fail2ban && \
sudo rm -f /var/log/fail2ban.log* && \
sudo iptables -F && \
sudo systemctl daemon-reload
systemctl stop fail2banfail2ban-client unban --allsystemctl disable fail2banapt purge fail2banapt purge python3-pyinotify python3-pyasyncoreapt autoremoverm -rf /etc/fail2banrm -f /var/log/fail2ban.log*rm -rf /var/run/fail2ban /var/lib/fail2baniptables -Fsystemctl daemon-reloadFail2Ban is a Python daemon that tails log files (or the systemd journal), matches lines against per-service filters (regular expressions in filter.d/), and when an IP exceeds maxretry failures within findtime, runs a ban action from action.d/ for bantime. With the default iptables actions, each jail creates its own chain (for example f2b-sshd) and inserts a jump to it from INPUT; bans are individual REJECT or DROP rules inside that chain. Newer Debian and Ubuntu releases may default to the nftables actions, which create a separate inet f2b-table. Banned IPs are also persisted in a SQLite database under /var/lib/fail2ban so they can be restored after a restart.
That design explains the uninstall steps. Stopping the service normally runs each action's actionstop, which flushes and deletes the chains it created. If the daemon crashed or was killed, those chains remain and keep blocking addresses after the package is gone, which is the main thing to verify.
# 1. See what fail2ban currently manages
sudo fail2ban-client status
sudo iptables -S | grep -i f2b
sudo nft list ruleset 2>/dev/null | grep -i f2b
# 2. Stop cleanly (runs actionstop for every jail)
sudo systemctl stop fail2ban
# 3. If any f2b chains survived, remove ONLY those, not the whole ruleset
for c in $(sudo iptables -S | awk '/^-N f2b-/{print $2}'); do
sudo iptables -D INPUT -j "$c" 2>/dev/null
sudo iptables -F "$c"
sudo iptables -X "$c"
done
sudo nft delete table inet f2b-table 2>/dev/null
# 4. Then purge and clean up as in the steps above
sudo apt purge -y fail2ban && sudo apt autoremove -y
This targeted cleanup is safer than iptables -F or deleting every DROP rule in INPUT, both of which also remove rules you or other tools added on purpose. If IPv6 is in use, repeat the checks with ip6tables.
| Option | What it does | Notes |
|---|---|---|
| Keep fail2ban, tune jails | adjust bantime, findtime, ignoreip | often enough when false positives were the problem |
| Disable one jail | enabled = false in jail.local | keeps protection for other services |
| SSH keys only, no passwords | PasswordAuthentication no | removes the brute-force risk fail2ban mitigates |
| Static firewall allowlist | iptables/nftables or ufw rules | strongest for admin ports with known source IPs |
| CrowdSec | log-based detection with shared blocklists | different architecture, separate bouncer component |
Uninstalling is reasonable when moving to a different tool, when the server is behind a load balancer or cloud firewall that already filters traffic, or when debugging connectivity problems. Before removing it from an internet-facing server, make sure SSH and any login forms are protected another way.
ACCEPT or that an allow rule for your session exists.iptables-persistent or netfilter-persistent saved the f2b chains, they return on reboot; re-save the rules after cleanup.apt remove keeps /etc/fail2ban; dpkg -l then shows state rc.python3-pyinotify before purging it.