# fail2ban banaction: choosing how IPs are blocked

> What fail2ban banaction does, banaction vs action, which ban action to use (nftables, iptables, ufw, firewalld), DROP vs REJECT, chains and verifying bans.
>
> Source: https://fail2ban.dev/config/banaction/ · Updated 2026-10-25 · Checked against fail2ban 1.1.1
> fail2ban.dev is an independent guide, not the official fail2ban project.

`banaction` is the firewall action fail2ban uses to block an IP: `nftables`, `iptables-multiport`, `ufw`, `firewallcmd-rich-rules` and so on (files in `/etc/fail2ban/action.d/`). Set it once in `[DEFAULT]` of `/etc/fail2ban/jail.local` and every jail uses it. **Pick the firewall your system actually runs**: nftables on current Debian, Ubuntu and Arch; firewalld on RHEL, Rocky, Alma and Fedora; ufw if you manage your firewall with ufw.

```ini
[DEFAULT]
banaction          = nftables
banaction_allports = nftables[type=allports]
```
sudo fail2ban-client reload
```
$ sudo fail2ban-client get sshd actions
The jail sshd has the following actions:
nftables
```

Three options, three jobs:

| Option | What it is | Default |
|---|---|---|
| `banaction` | The firewall action for **per-port** bans | `nftables` (1.1.1 Debian paths), `iptables-multiport` before 1.1.1 |
| `banaction_allports` | The firewall action for **all-port** bans (used by `recidive`, `pam-generic`) | `nftables[type=allports]`, `iptables-allports` before 1.1.1 |
| `action` | **Everything** that happens on a ban: the firewall plus optional email, reporting… | `%(action_)s` |

`action` is built from `banaction`. The default chain in `jail.conf` is:

```ini
action  = %(action_)s
```

Always change `banaction` and `banaction_allports` together. Otherwise `recidive` keeps using the old firewall.

## Which banaction should I use?

| Banaction | Firewall | Use it when | Per-port / all ports |
|---|---|---|---|
| [`nftables`](/actions/#action-nftables) | nftables (own table `inet f2b-table`) | Debian 11+, Ubuntu 22.04+, Arch, any system without firewalld or ufw | `nftables` / `nftables[type=allports]` |
| [`iptables-multiport`](/actions/#action-iptables-multiport) | iptables (legacy or iptables-nft) | Older systems, or rules that must sit in a specific iptables chain (Docker) | `iptables[type=multiport]` / `iptables-allports` |
| [`iptables-ipset`](/actions/#action-iptables-ipset) | iptables + ipset | Large numbers of bans on iptables systems | `iptables-ipset[type=multiport]` / `[type=allports]` |
| [`ufw`](/actions/#action-ufw) | ufw | You manage the firewall with ufw (Ubuntu desktops, many VPS guides) | Blocks all ports of the IP |
| [`firewallcmd-rich-rules`](/actions/#action-firewallcmd-rich-rules) | firewalld | RHEL, Rocky, Alma, Fedora with firewalld running | per port |
| [`firewallcmd-ipset`](/actions/#action-firewallcmd-ipset) | firewalld + ipset | firewalld with many bans | `firewallcmd-ipset[actiontype=<allports>]` |
| [`route`](/actions/#action-route) | routing table | No firewall at all; blackholes the IP with `ip route add unreachable` | all traffic |
| [`hostsdeny`](/actions/#action-hostsdeny) | `/etc/hosts.deny` | Only programs built with TCP Wrappers; rarely useful today | per daemon |
| [`cloudflare-token`](/actions/#action-cloudflare-token) | Cloudflare API | Sites behind Cloudflare: block at the edge, use in addition to a local action | edge |
| [`pf`](/actions/#action-pf) | pf | FreeBSD, OpenBSD, macOS | `pf[actiontype=<allports>]` |

The [action library](/actions/) lists every ban action with its parameters.

### iptables or nftables?

Use **nftables** unless something forces iptables. Since fail2ban 1.1.1 the upstream defaults are nftables (Debian paths), and Debian 13, Ubuntu 24.04 and Ubuntu 26.04 packages set it too. On systems where `iptables` is really `iptables-nft`, both end up in nftables anyway; the nftables action is just more efficient because it keeps bans in a set instead of one rule per IP.

Choose iptables when other tooling expects iptables chains: Docker's `DOCKER-USER` chain, Shorewall, or scripts that parse `iptables -S`. Don't mix: if a host runs firewalld, use the firewalld actions; with ufw, use ufw. A ban added behind the firewall manager's back can be flushed when the manager reloads.

### ufw

```ini
[DEFAULT]
banaction          = ufw
banaction_allports = ufw
```

### firewalld

On Fedora, RHEL, Rocky and Alma the `fail2ban-firewalld` package installs `/etc/fail2ban/jail.d/00-firewalld.conf`, which already sets firewalld actions. Don't override `banaction` in `jail.local` unless you've disabled firewalld. Verify with:

```bash
sudo firewall-cmd --list-rich-rules
```

## Default banaction per distribution

| System | fail2ban | Default banaction | Set by |
|---|---|---|---|
| Upstream 1.1.1 tarball | 1.1.1 | `nftables` / `nftables[type=allports]` | `paths-debian.conf` (included by stock `jail.conf`) |
| Upstream 1.1.0 and older | ≤ 1.1.0 | `iptables-multiport` / `iptables-allports` | `jail.conf` |
| Debian 13, Ubuntu 26.04 | 1.1.0 | `nftables` | `jail.d/defaults-debian.conf` |
| Ubuntu 24.04 | 1.0.2 | `nftables` | `jail.d/defaults-debian.conf` |
| Debian 12, Ubuntu 22.04 | 1.0.2 / 0.11.2 | `iptables-multiport` | `jail.conf` |
| Fedora, RHEL/Rocky/Alma (EPEL) | 1.1.0 | firewalld rich rules | `jail.d/00-firewalld.conf` from `fail2ban-firewalld` |
| FreeBSD, macOS (current development) | 1.1.2-dev | `pf` | `paths-freebsd.conf`, `paths-osx.conf` |

In the 1.1.2 development branch, `paths-arch.conf`, `paths-fedora.conf` and `paths-opensuse.conf` also default to nftables. Always confirm on your machine:

```bash
```

Most firewall actions take a `blocktype` parameter:

| Action | Default blocktype | Drop instead |
|---|---|---|
| `nftables` | `reject` | `nftables[blocktype=drop]` |
| `iptables-*` | `REJECT --reject-with icmp-port-unreachable` | `iptables-multiport[blocktype=DROP]` |
| `ufw` | `reject` | `ufw[blocktype=deny]` |
| `route` | `unreachable` | `route[blocktype=blackhole]` |

- **REJECT** answers immediately ("port unreachable"). Clients fail fast, including your own users if they're banned by mistake, which makes problems easy to diagnose.
- **DROP** silently discards packets. The client waits for a timeout, which slows down some scanners, and your server reveals slightly less.

For brute-force protection the difference is small; the attacker is blocked either way. Set it inside the brackets of `banaction`:

```ini
[DEFAULT]
banaction          = nftables[blocktype=drop]
banaction_allports = nftables[type=allports, blocktype=drop]
```

## Chains: INPUT, FORWARD and DOCKER-USER

The `chain` option tells iptables-based actions where to hook in. The stock value `chain = <known/chain>` means "the action's own default": `INPUT` for the iptables actions. The nftables action creates its own chain `f2b-chain` in table `inet f2b-table`, hooked on `input`.

Traffic to Docker containers with published ports goes through `FORWARD`, not `INPUT`, so an INPUT ban doesn't stop it. With iptables, put the jail's rules in `DOCKER-USER`:

```ini
[vaultwarden]
enabled   = true
banaction = iptables-multiport
chain     = DOCKER-USER
```

## Check that bans reach the firewall

After a ban, look for the IP in the firewall itself:

```bash
sudo nft list table inet f2b-table

# iptables / ipset: chain f2b-<jail>, set f2b-<jail>
sudo iptables -S f2b-sshd
sudo ipset list f2b-sshd

# ufw
sudo ufw status numbered | grep 203.0.113.42

# firewalld
sudo firewall-cmd --list-rich-rules
```

```text
$ sudo fail2ban-client set sshd banip 192.0.2.15 192.0.2.16
2
```
sudo nft list table inet f2b-table | grep 192.0.2.15
sudo fail2ban-client set sshd unbanip 192.0.2.15 192.0.2.16
```

## FAQ

### What is banaction in fail2ban?

`banaction` names the firewall action, a file in `/etc/fail2ban/action.d/`, that fail2ban uses to block IPs, for example `nftables`, `iptables-multiport`, `ufw` or `firewallcmd-rich-rules`. The default `action = %(action_)s` calls it with each jail's port and protocol, so one `banaction` line in `[DEFAULT]` sets the firewall for all jails.

### What is the difference between action and banaction?

`banaction` is only the firewall part. `action` is the complete list of things done on a ban, and by default it's built from `banaction` (`action_`, `action_mw`, `action_mwl`). Change `banaction` to switch firewalls; change `action` to add email alerts, reporting or several actions at once.

### Should fail2ban use iptables or nftables?

nftables on any current Linux distribution: it's the default since fail2ban 1.1.1 and on Debian 13 and Ubuntu 24.04+, and it stores bans in efficient sets. Use iptables actions only when you need specific iptables chains such as `DOCKER-USER`, and the firewalld or ufw actions if those manage your firewall.

### Should fail2ban DROP or REJECT?

Either works. REJECT (the default for nftables and iptables) tells the client immediately that the port is closed; DROP silently discards packets so the client waits for a timeout. To drop, use `banaction = nftables[blocktype=drop]` or `iptables-multiport[blocktype=DROP]`.

### What is banaction_allports?

The action used by jails that should block every port of an attacker, such as `recidive` and `pam-generic`. It defaults to `nftables[type=allports]` in 1.1.1 (`iptables-allports` before). Change it whenever you change `banaction`, so all jails use the same firewall.
