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.

Updated 6 min readChecked against fail2ban 1.1.1

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.

output
$ sudo fail2ban-client set sshd banip 192.0.2.15 192.0.2.16
2

The 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#

bash
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:

output
$ 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:14

The log records manual bans exactly like automatic ones:

log
2026-10-25 18:36:11,027 fail2ban.actions        [1997]: NOTICE  [sshd] Ban 203.0.113.42

Ban 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:

/etc/fail2ban/jail.d/manual.local
[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 = all

Reload and ban into it:

bash
sudo fail2ban-client reload
sudo fail2ban-client set manual banip 203.0.113.42

An 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:

text
$ sudo fail2ban-client get manual banip --with-time
203.0.113.42 	2026-10-25 18:42:27 + -1 = 9999-12-31 23:59:59

Permanent 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:

log
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.42

If 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:

output
$ sudo fail2ban-client set manual banip 198.51.100.0/24
1
$ sudo fail2ban-client set manual banip 2001:db8::/64
1

Whether 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:

bash
# 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 banip

Because 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:

bash
sudo fail2ban-client set sshd attempt 192.0.2.50

Check that the ban reached the firewall#

bash
# 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.42

If 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.