# Block brute-force attacks with Fail2ban or CrowdSec

> Stop repeated login attempts on your Linux server: set up Fail2ban with a systemd backend or CrowdSec with its firewall bouncer, test bans and unban yourself.

Difficulty: Intermediate\
Tested on: Ubuntu 24.04 LTS, Ubuntu 26.04 LTS, Debian 12, Debian 13

Every server on the internet sees a steady stream of login attempts. Fail2ban and CrowdSec read your logs, recognise repeated failures and block the offending addresses in the firewall for a while. This guide sets up either tool on Ubuntu 24.04/26.04 or Debian 12/13 and shows you how to test and undo bans.

## Before you start

- SSH and your firewall are already set up: see [secure a new Linux server](/guides/secure-a-new-linux-server).
- Know your own public IP address, so you can exclude it from bans.
- Pick **one** of the two tools for SSH. You can combine them for different log sources, but not on the same one.

## Option A: Fail2ban

### Install

```bash
sudo apt update
sudo apt install fail2ban python3-systemd
```

### Configure

Never edit `jail.conf`; put your settings in `jail.local`, which overrides it:

```bash
sudo nano /etc/fail2ban/jail.local
```

```ini
[DEFAULT]
bantime = 1h
findtime = 10m
maxretry = 5
ignoreip = 127.0.0.1/8 ::1 198.51.100.7

[sshd]
enabled = true
backend = systemd
```

- `backend = systemd` reads SSH events from the journal. Debian 12 and later no longer write `/var/log/auth.log` by default, so this setting is needed there and works on Ubuntu too.
- `ignoreip`: replace `198.51.100.7` with your own IP address.
- If you moved SSH to another port, add `port = 2222` to the `[sshd]` section.

Restart and enable:

```bash
sudo systemctl enable fail2ban
sudo systemctl restart fail2ban
```

### Verify

```bash
sudo fail2ban-client status
sudo fail2ban-client status sshd
```

The second command lists the jail's filter results: `Currently failed`, `Total failed` and the `Banned IP list`. From another network (not your ignored address), try a few wrong logins; the `Total failed` counter rises, and after `maxretry` failures the address appears in the banned list.

### Unban an address

```bash
sudo fail2ban-client set sshd unbanip 203.0.113.50
```

## Option B: CrowdSec

CrowdSec has two parts: the **security engine** reads logs and makes decisions, and a **bouncer** enforces them, here in the firewall.

### Install

The CrowdSec documentation describes how to add its official package repository for Debian and Ubuntu; follow it, then install the engine:

```bash
sudo apt update
sudo apt install crowdsec
```

The installer detects common services, such as SSH and web servers, and installs matching collections. Add the firewall bouncer that matches your firewall framework:

**nftables**

```bash
sudo apt install crowdsec-firewall-bouncer-nftables
```
**iptables**

```bash
sudo apt install crowdsec-firewall-bouncer-iptables
```

### Verify

```bash
sudo cscli collections list
sudo cscli bouncers list
sudo cscli metrics
```

`collections list` should include `crowdsecurity/sshd` (and `crowdsecurity/linux`), `bouncers list` should show your firewall bouncer as valid, and `metrics` shows which log files are read and how many lines were parsed.

### See and remove decisions

```bash
sudo cscli decisions list
sudo cscli decisions delete --ip 203.0.113.50
```

To make sure you are never blocked, add your address to an allow list as described in the CrowdSec documentation.

## Protect more than SSH

- **Fail2ban** ships filters for many services, such as nginx authentication, Postfix and Dovecot. Enable a jail by adding its section to `jail.local` with `enabled = true` and the right log path or backend.
- **CrowdSec** installs collections with `sudo cscli collections install` and the collection name, for example for nginx or WordPress, and reloads with `sudo systemctl reload crowdsec`.

## Troubleshooting

**Fail2ban does not start: "Have not found any log file for sshd jail".** It looks for `/var/log/auth.log`, which Debian 12 and later do not create. Set `backend = systemd` in the `[sshd]` section and install `python3-systemd`.

**The counters stay at zero.** The jail reads the wrong source or the SSH log format changed. Check `sudo fail2ban-client status sshd` and test the filter against the journal: `sudo fail2ban-regex systemd-journal sshd`.

**CrowdSec decisions exist but nothing is blocked.** The bouncer is missing or not registered. Check `sudo cscli bouncers list` and `sudo systemctl status crowdsec-firewall-bouncer`.

**You banned yourself.** Use the console and the unban commands above, then add your address to `ignoreip` or the CrowdSec allow list. See [locked out after a firewall change](/guides/locked-out-after-firewall-change).

## Next steps

- Make SSH itself harder to attack: [SSH hardening](/guides/ssh-hardening).
- Floods are a different problem: [DDoS protection basics](/guides/ddos-protection-basics).

## Frequently asked questions

### Do I need Fail2ban if SSH accepts keys only?

Key-only SSH cannot be brute-forced, so Fail2ban mainly reduces log noise there. It is most useful for services that still accept passwords, such as mail, FTP or web login pages.

### Fail2ban or CrowdSec: which should I choose?

Fail2ban is small, local and easy to reason about. CrowdSec parses more log types out of the box and can use community blocklists. Choose one per log source; running both on the same logs only duplicates work.

### I banned myself. How do I get back in?

Connect from another network or through the web console, then remove the ban with fail2ban-client set sshd unbanip or cscli decisions delete --ip and your address. Add your own IP to the ignore or allow list.

### Do these tools protect against DDoS attacks?

No. They react to log entries from individual addresses, which helps against password guessing and abusive clients, not against large floods. See our DDoS basics guide for those.

### Will they work with Docker containers?

Bans are applied to the host firewall, and Docker publishes ports through its own rules, so traffic to containers may bypass them. Configure the ban action for Docker or let a reverse proxy on the host handle the traffic.

---

Source: <https://hyperdc.com/guides/security/fail2ban-crowdsec>\
Updated: 2026-10-09
