Commands
How to ban an IP manually in fail2ban
fail2ban normally bans by itself, but you can add any address to a jail by hand — for a few minutes, for a subnet, or forever. Here is how each works and what to watch out for.
To ban an IP manually in fail2ban, run sudo fail2ban-client set <jail> banip <IP> — for example sudo fail2ban-client set sshd banip 203.0.113.42. The ban takes effect immediately, uses the jail's ban action and lasts for the jail's bantime. To ban permanently, add the IP to a dedicated jail with bantime = -1. Subnets in CIDR form such as 198.51.100.0/24 are accepted too.
$ sudo fail2ban-client set sshd banip 192.0.2.15 192.0.2.16
2The number is how many addresses were newly banned. 0 means the address was already banned in that jail.
Ban an IP in an existing jail#
sudo fail2ban-client set <jail> banip <IP> [<IP> ...]The jail must exist and be running (sudo fail2ban-client status lists them). The address is blocked the way that jail blocks everything else: with the sshd jail and the nftables action, only the SSH port is closed to it; with a jail using banaction_allports, every port is.
Check the result and the expiry time:
$ sudo fail2ban-client get sshd banip --with-time
203.0.113.42 2026-10-25 18:36:10 + 3600 = 2026-10-25 19:36:10
192.0.2.15 2026-10-25 18:36:14 + 3600 = 2026-10-25 19:36:14
192.0.2.16 2026-10-25 18:36:14 + 3600 = 2026-10-25 19:36:14The log records manual bans exactly like automatic ones:
2026-10-25 18:36:11,027 fail2ban.actions [1997]: NOTICE [sshd] Ban 203.0.113.42Ban an IP permanently#
A manual ban in the sshd jail expires after that jail's bantime (10 minutes in stock jail.conf). Changing the whole jail to bantime = -1 would make every automatic ban permanent too, which is rarely what you want. The clean way to block an IP permanently is a separate jail that only holds manual bans:
[manual]
enabled = true
# no filter: this jail never bans on its own, only via banip
filter =
bantime = -1
# block all ports and protocols (TCP, UDP, ICMP), not just one service
banaction = %(banaction_allports)s
protocol = allReload and ban into it:
sudo fail2ban-client reload
sudo fail2ban-client set manual banip 203.0.113.42An empty filter = is valid: fail2ban logs WARNING No filter set for jail manual at startup and the jail simply never matches log lines. The jail needs no logpath. Bans with bantime = -1 never expire:
$ sudo fail2ban-client get manual banip --with-time
203.0.113.42 2026-10-25 18:42:27 + -1 = 9999-12-31 23:59:59Permanent bans survive restarts. fail2ban stores every ban in /var/lib/fail2ban/fail2ban.sqlite3, never purges ones with bantime = -1, and re-applies them when the jail starts. The log then shows Restore Ban lines:
2026-10-25 18:42:38,639 fail2ban.actions [3190]: NOTICE [manual] Restore Ban 198.51.100.0/24
2026-10-25 18:42:38,650 fail2ban.actions [3190]: NOTICE [manual] Restore Ban 203.0.113.42If you'd rather have fail2ban escalate automatically — short bans first, permanent for repeat offenders — use the recidive jail or incremental bans instead of banning by hand.
Ban a subnet or IP range (CIDR)#
banip accepts networks in CIDR notation, IPv4 and IPv6:
$ sudo fail2ban-client set manual banip 198.51.100.0/24
1
$ sudo fail2ban-client set manual banip 2001:db8::/64
1Whether the firewall accepts it depends on the ban action:
| Ban action | CIDR bans |
|---|---|
nftables (1.1.1+) |
Yes — the set is created with flags interval |
nftables (1.1.0 and older) |
No — the set holds single addresses only |
iptables, iptables-multiport, iptables-allports |
Yes (-s 198.51.100.0/24) |
iptables-ipset, firewallcmd-ipset |
Set ipsettype = hash:net for networks |
ufw |
Yes |
Express a range like 198.51.100.0–198.51.100.255 as CIDR (198.51.100.0/24). fail2ban has no "from–to" syntax.
fail2ban-client banned <IP> compares exact strings: if you banned 198.51.100.0/24, asking about 198.51.100.7 returns [[]] even though the firewall blocks it. Ask about the network you banned instead.
Ban a list of IPs from a blocklist file#
banip takes many addresses in one call, so you can feed it a file with one IP or CIDR per line:
# skip comments and blank lines, ban in batches of 500
grep -Ev '^\s*(#|$)' /etc/fail2ban/blocklist.txt \
| xargs -n 500 sudo fail2ban-client set manual banipBecause the manual jail uses bantime = -1 and the database restores its bans, you only need to run this when the list changes. To replace the whole list, clear the jail first with sudo fail2ban-client restart --unban manual, then re-run the command.
For large public blocklists (tens of thousands of entries), a native firewall set loaded directly with nft or ipset is lighter than routing each entry through fail2ban.
Ban an IP in every jail?#
There is no "ban everywhere" command. Pick one jail that blocks all ports — the manual jail above, or recidive, which uses banaction_allports — and ban the address there. A ban on all ports covers every service.
Report a failure instead of banning#
set <jail> attempt <IP> records a failure for an address as if the filter had found it in the log. The IP is banned only when it reaches maxretry within findtime. Use it to test a jail end to end, or from a script that detects abuse fail2ban can't see in a log:
sudo fail2ban-client set sshd attempt 192.0.2.50Check that the ban reached the firewall#
# nftables (default on Debian 13, Ubuntu 24.04+, Fedora)
sudo nft list set inet f2b-table addr-set-manual
# iptables
sudo iptables -L f2b-manual -n
# ufw
sudo ufw status | grep 203.0.113.42If fail2ban lists the IP but the firewall doesn't block it, read banned but still connecting. To lift a manual ban, see unban an IP.
FAQ#
How do I manually ban an IP with fail2ban?#
Run sudo fail2ban-client set <jail> banip <IP>, for example sudo fail2ban-client set sshd banip 203.0.113.42. The ban is applied at once with the jail's action and lasts for the jail's bantime. The command prints 1 when the IP was banned and 0 if it already was.
How do I permanently ban an IP in fail2ban?#
Create a jail with filter = (empty), bantime = -1, banaction = %(banaction_allports)s and protocol = all, reload, then run sudo fail2ban-client set manual banip <IP>. Bans in that jail never expire and are restored from the database after restarts, while your other jails keep their normal ban times.
Can fail2ban ban a whole subnet?#
Yes. sudo fail2ban-client set manual banip 198.51.100.0/24 bans a network in CIDR notation, IPv4 or IPv6. The firewall action must support it: iptables and ufw do, nftables does from fail2ban 1.1.1, and ipset-based actions need ipsettype = hash:net.
Does a manual ban survive a fail2ban restart?#
Yes, as long as it hasn't expired. fail2ban stores bans in its SQLite database and restores active ones when the jail starts, logging Restore Ban. Use fail2ban-client restart --unban <jail> or fail2ban-client unban <IP> to remove them for good.
How do I blacklist IPs from a file?#
Run grep -Ev '^\s*(#|$)' blocklist.txt | xargs -n 500 sudo fail2ban-client set manual banip, where manual is a jail with bantime = -1. Each line can be an IP or a CIDR network. fail2ban stores the bans, so you only re-run it when the file changes.
Spotted something wrong or out of date? Tell us — every page is checked against the current fail2ban release.