Naar de inhoud
Actuele kortingscode:10% kortingGebruiken bij je bestelling

Fail2ban: aanvallen op SSH automatisch blokkeren

Fail2ban houdt mislukte inlogpogingen in de gaten en blokkeert aanvallers automatisch. Installatie op Ubuntu 24.04 en Debian 13, jail.local regel voor regel uitgelegd, recidive, een IP deblokkeren en fouten oplossen.

  • gevorderd
  • ~20 min
  • Bijgewerkt op 2-10-2026

Fail2ban volgt de logregels over inlogpogingen en blokkeert een IP-adres dat herhaaldelijk een verkeerd wachtwoord invoert een tijd lang in de firewall. Je installeert het, stelt verstandige regels in, inclusief een strengere straf voor terugkerende aanvallers, en leert hoe je een adres deblokkeert als het jou zelf overkomt.

Wat je nodig hebt

  • Een VPS bij StormHost met Ubuntu 24.04 of Debian 13
  • Een SSH-verbinding als root (handleiding)
  • De console in de browser geopend, voor het geval je jezelf blokkeert
  • Ongeveer 20 minuten

Wat fail2ban doet#

Fail2ban werkt met zogeheten jails (letterlijk “gevangenissen”). Elke jail bewaakt één service en bestaat uit drie delen:

DeelWat het doetVoorbeeld voor SSH
FilterHerkent in de logregels een mislukte poging en haalt het IP-adres eruit.Regels als Failed password for root from 198.51.100.25.
Logbron (backend)Waar de logregels vandaan komen: uit het systeemjournal of uit een bestand.Het journal van de SSH-service.
Actie (banaction)Wat er gebeurt met een adres dat de limiet overschrijdt.Voegt het toe aan de geblokkeerde adressen in de firewall (nftables).

Maakt een adres binnen findtime maxretry fouten, dan blokkeert fail2ban het voor de duur van bantime. Als die tijd om is, deblokkeert fail2ban het adres zelf.

Fail2ban vervangt geen SSH-sleutel

Fail2ban vertraagt aanvallers en houdt de logs schoon, maar beschermt niet volledig tegen het raden van een zwak wachtwoord. De beste combinatie is een SSH-sleutel met uitgeschakeld wachtwoord en daarbij fail2ban.

Installatie#

Geldt voor zowel Ubuntu 24.04 als Debian 13.

  1. Werk de pakketlijst bij en installeer fail2ban:

    bash
    apt update
    apt install fail2ban
    • fail2ban – het programma zelf. Als afhankelijkheid wordt ook python3-systemd geïnstalleerd, waardoor fail2ban het systeemjournal kan lezen.
  2. Controleer of de tool nft beschikbaar is, waarmee fail2ban blokkeert:

    bash
    command -v nft || apt install nftables
    • command -v nft – toont het pad naar het programma nft, als het bestaat.
    • || – het volgende commando wordt alleen uitgevoerd als het vorige is mislukt, dus als nft ontbreekt.
    • apt install nftables – installeert de tool. De installatie zelf schakelt geen regels in en verandert niets aan UFW.
  3. Controleer of de service draait:

    bash
    systemctl status fail2ban

    Zoek de regel Active: active (running). Sluit de uitvoer af met de toets q.

Na de installatie beschermt fail2ban SSH al met de standaardinstellingen van de distributie: de jail sshd staat aan, leest de logregels uit het systeemjournal en blokkeert via nftables. De standaardstraf is echter maar 10 minuten, pas de instellingen daarom aan.

Waarom jail.local en niet jail.conf#

De standaardinstellingen staan in /etc/fail2ban/jail.conf en in /etc/fail2ban/jail.d/defaults-debian.conf. Pas deze bestanden niet aan, een update van het pakket zou ze kunnen overschrijven. Je eigen instellingen horen in /etc/fail2ban/jail.local. Fail2ban leest de bestanden in de volgorde jail.conf › jail.d/*.conf › jail.local › jail.d/*.local en een latere waarde overschrijft altijd een eerdere.

Configuratie regel voor regel#

  1. Maak het bestand aan:

    bash
    nano /etc/fail2ban/jail.local
  2. Plak er het volgende in:

    /etc/fail2ban/jail.localini
    [DEFAULT]
    # Adressen die nooit worden geblokkeerd (gescheiden door een spatie)
    ignoreip = 127.0.0.1/8 ::1
    # Duur van de eerste blokkade
    bantime = 1h
    # Venster waarin mislukte pogingen worden geteld
    findtime = 10m
    # Aantal mislukte pogingen waarna de blokkade volgt
    maxretry = 5
    # Terugkerende aanvallers steeds langer blokkeren
    bantime.increment = true
    bantime.factor = 1
    bantime.maxtime = 1w
    
    [sshd]
    enabled = true
    port = ssh
    backend = systemd
    
    [recidive]
    enabled = true
    backend = auto
    logpath = /var/log/fail2ban.log
    banaction = %(banaction_allports)s
    bantime = 1w
    findtime = 1d
    maxretry = 5
  3. Sla op (Ctrl+O, Enter) en sluit de editor (Ctrl+X).

De secties tussen vierkante haken: [DEFAULT] geldt voor alle jails, [sshd] en [recidive] alleen voor die ene jail, en ze hebben voorrang op [DEFAULT].

InstellingWat het doetAanbevolen waardeWanneer aanpassen
ignoreipAdressen en bereiken die fail2ban nooit blokkeert. Gescheiden door een spatie. 127.0.0.1/8 ::1 is de VPS zelf.127.0.0.1/8 ::1Voeg je eigen IP-adres toe, alleen als het vast is (kantoor, eigen server). Voeg het dynamische adres van een thuisverbinding niet toe, na een tijd kan iemand anders het krijgen.
bantimeHoe lang een adres geblokkeerd blijft. Eenheden: m minuten, h uren, d dagen, w weken. De standaard is 10m.1hKorter (30m) als je vaak een typefout maakt en de console niet bij de hand hebt.
findtimeHet tijdvenster waarin fouten worden opgeteld.10mLanger (1h) tegen trage aanvallen die eens in de paar minuten een wachtwoord proberen.
maxretryHoeveel fouten binnen findtime tot een blokkade leiden. Bij 3 kun je jezelf met een typefout blokkeren, bij 10 krijgt een aanvaller meer pogingen.53 voor SSH met uitgeschakeld wachtwoord (een legitieme gebruiker met een sleutel maakt geen fouten).
bantime.incrementBij elke volgende blokkade van hetzelfde adres wordt de duur langer. Fail2ban onthoudt de geschiedenis in een database.truefalse als je altijd dezelfde duur wilt.
bantime.factorDe vermenigvuldiger van de groei. Met de waarde 1 groeit de duur 1, 2, 4, 8… × bantime.1Hoger (2) voor snellere groei.
bantime.maxtimeHet plafond waar de duur van de blokkade niet boven komt.1wLanger (4w) voor zeer hardnekkige aanvallers.
enabledSchakelt de jail in. Jails staan standaard uit.truefalse schakelt de jail tijdelijk uit.
portWelke poorten voor het adres worden geblokkeerd. ssh betekent poort 22.sshDraait SSH op een andere poort, schrijf die dan als getal, bijvoorbeeld 2222 (zie hieronder).
backendWaar de logregels vandaan komen. systemd = het systeemjournal, auto = het bestand uit logpath.systemd voor sshd, auto voor recidiveNooit, tenzij je weet waarom. Debian 13 heeft geen bestand /var/log/auth.log, SSH moet daarom het journal lezen.
logpathHet bestand met de logregels (alleen bij backend = auto)./var/log/fail2ban.logBlijft ongewijzigd.
banactionHoe er wordt geblokkeerd. %(banaction_allports)s = alle poorten blokkeren, niet alleen SSH.%(banaction_allports)sBlijft ongewijzigd.

Recidive: een strengere straf voor terugkerende aanvallers#

De jail recidive leest de logregels van fail2ban zelf (/var/log/fail2ban.log). Krijgt hetzelfde adres binnen findtime (1 dag) minstens maxretry (5) blokkades in welke jail dan ook, dan blokkeert recidive het voor bantime (1 week) en op alle poorten. Een aanvaller die blijft terugkomen, verliest zo de toegang tot de VPS helemaal.

Daarom leest recidive een bestand (backend = auto) en niet het journal: fail2ban schrijft zijn logregels naar het bestand /var/log/fail2ban.log, niet naar het journal.

Om fail2ban de geschiedenis van blokkades lang genoeg te laten onthouden (voor bantime.increment en voor het herstellen van blokkades van een week na een herstart), verleng je de bewaartermijn in de database:

bash
nano /etc/fail2ban/fail2ban.local
/etc/fail2ban/fail2ban.localini
[Definition]
dbpurgeage = 8d
InstellingWat het doetAanbevolen waardeWanneer aanpassen
dbpurgeageNa hoeveel tijd oude gegevens over blokkades uit de database /var/lib/fail2ban/fail2ban.sqlite3 worden verwijderd. De standaard is 1d.8dAltijd iets langer dan de langste bantime en bantime.maxtime.

Starten en controleren#

  1. Controleer de configuratie:

    bash
    fail2ban-client -t
    • -t – test van de configuratie. Als het goed gaat, verschijnt OK: configuration test is successful. Bij een fout worden het bestand en het probleem genoemd.
  2. Herstart fail2ban, zodat het de nieuwe instellingen laadt:

    bash
    systemctl restart fail2ban
  3. Toon de ingeschakelde jails:

    bash
    fail2ban-client status
    Uitvoertext
    Status
    |- Number of jail:	2
    `- Jail list:	recidive, sshd
  4. Bekijk de status van de jail sshd:

    bash
    fail2ban-client status sshd
    Uitvoertext
    Status for the jail: sshd
    |- Filter
    |  |- Currently failed:	2
    |  |- Total failed:	57
    |  `- Journal matches:	_SYSTEMD_UNIT=ssh.service + _COMM=sshd
    `- Actions
       |- Currently banned:	3
       |- Total banned:	12
       `- Banned IP list:	198.51.100.25 198.51.100.40 198.51.100.77
RegelBetekenis
Currently failedHoeveel adressen nu binnen het venster findtime minstens één fout hebben, maar nog niet geblokkeerd zijn.
Total failedHet aantal geregistreerde fouten sinds de start van fail2ban.
Journal matchesWelke logregels uit het journal de jail leest. Op Ubuntu kan dit afwijken (sshd.service), op de werking heeft dat geen invloed.
Currently bannedHoeveel adressen nu geblokkeerd zijn.
Total bannedHoeveel blokkades er sinds de start zijn geweest.
Banned IP listDe lijst met adressen die op dit moment geblokkeerd zijn.

Een IP-adres deblokkeren#

Heb je jezelf geblokkeerd, log dan in via de console in de browser (of vanaf een ander netwerk, bijvoorbeeld via mobiele data) en gebruik een van deze commando's:

CommandoWat het doet
fail2ban-client set sshd unbanip 198.51.100.25Deblokkeert het adres in de jail sshd.
fail2ban-client unban 198.51.100.25Deblokkeert het adres in alle jails (ook in recidive) en verwijdert het uit de database.
fail2ban-client unban --allDeblokkeert alle adressen in alle jails. Aanvallers worden bij volgende pogingen opnieuw geblokkeerd.
fail2ban-client banned 198.51.100.25Toont in welke jails het adres geblokkeerd is.

Vul in plaats van 198.51.100.25 je eigen openbare IP-adres in. Ken je het niet, dan vind je het in de lijst Banned IP list aan de hand van het tijdstip (logregels over blokkades: grep "Ban " /var/log/fail2ban.log | tail), of je ziet het op een willekeurige pagina “wat is mijn IP-adres” die je opent op de computer waarmee je verbinding maakt.

Je eigen adres vind je ook op het moment dat je via SSH bent ingelogd: echo $SSH_CLIENT toont als eerste gegeven het adres waarvandaan je verbinding maakt.

Hoe je merkt dat je zelf geblokkeerd bent#

  • SSH meldt ineens Connection refused of Connection timed out, terwijl het even daarvoor nog werkte.
  • Vanaf een ander netwerk (mobiele data) maak je zonder problemen verbinding.
  • Heeft recidive je geblokkeerd, dan werken voor jou ook de andere services op de VPS niet (website, gameserver), voor andere mensen wel.
  • In de console zie je je adres in de uitvoer van fail2ban-client status sshd.

Je klantaccount en een nieuw wachtwoord

De tabbladen Bestanden en Databases loggen met een wachtwoord via SSH in op de VPS. Als je het rootwachtwoord wijzigt en de tabbladen een paar keer proberen in te loggen met het oude, kan fail2ban ook het adres blokkeren waarvandaan je klantaccount verbinding maakt. Voer het nieuwe wachtwoord na een wijziging daarom meteen in bij Bestanden › Inloggegevens wijzigen. Werkt het tabblad al niet meer, voer dan fail2ban-client unban --all uit en vul de gegevens opnieuw in.

SSH op een andere poort#

Heb je SSH verplaatst (bijvoorbeeld naar 2222), pas dan in jail.local de regel in de sectie [sshd] aan:

/etc/fail2ban/jail.localini
[sshd]
enabled = true
port = 2222
backend = systemd
  • port = 2222 – fail2ban blokkeert deze poort voor de aanvaller. Bij een onjuiste poort zou de blokkade geen enkel effect hebben. Scheid meerdere poorten met een komma: port = 22,2222.

Voer daarna fail2ban-client -t en systemctl restart fail2ban uit.

Meer jails: Nginx#

Draai je op de VPS een website met Nginx, dan kun je die ook bewaken. Voeg aan jail.local toe:

/etc/fail2ban/jail.localini
[nginx-http-auth]
enabled = true
backend = auto

[nginx-botsearch]
enabled = true
backend = auto
JailWat die bewaakt
nginx-http-authVerkeerde wachtwoorden bij pagina's die met een wachtwoord zijn beveiligd (HTTP Basic Auth).
nginx-botsearchBots die naar bekende kwetsbare adressen zoeken (/wp-login.php, /phpmyadmin en dergelijke).
  • backend = auto – Nginx schrijft naar het bestand /var/log/nginx/error.log, niet naar het journal. Zonder deze regel zou de jail op Ubuntu het journal lezen en niets vinden.

Fail2ban en de firewall#

Fail2ban blokkeert via nftables in een eigen tabel, f2b-table. Daardoor werkt het naast UFW en ook naast de firewall in je klantaccount, en overschrijft het daar niets van. De geblokkeerde adressen zie je met het commando:

bash
nft list table inet f2b-table
  • nft list table inet f2b-table – toont de tabel van fail2ban, inclusief de sets (addr-set-sshd …) met de geblokkeerde adressen.

Wil je de geblokkeerde adressen rechtstreeks in ufw status zien, zet dan in [DEFAULT] de regel banaction = ufw (UFW moet ingeschakeld zijn). Stel voor de jail recidive dan ook banaction = ufw in. Het standaard gebruikte nftables is echter sneller en dat raden we aan.

Fail2ban beschermt alleen wat in de VPS draait. De firewall in je klantaccount wordt niet door fail2ban aangestuurd.

Controle#

  1. Probeer handmatig een testadres te blokkeren:

    bash
    fail2ban-client set sshd banip 198.51.100.25
  2. Controleer of het in de firewall staat: nft list table inet f2b-table moet het adres 198.51.100.25 bevatten.

  3. Deblokkeer het: fail2ban-client set sshd unbanip 198.51.100.25.

  4. Controleer na een uur of twee fail2ban-client status sshd. Op een openbare VPS zijn Total failed en Total banned meestal al snel niet meer nul.

Als iets niet werkt#

fail2ban-client -t meldt een fout#

De uitvoer noemt het bestand en de sectie. Meestal gaat het om een typefout in de naam van een instelling, een ontbrekende = of een waarde zonder eenheid. Herstel het bestand en herhaal de test.

Have not found any log file for sshd jail#

De jail sshd probeert het bestand /var/log/auth.log te lezen, dat op Debian 13 niet bestaat. In de sectie [sshd] moet backend = systemd staan.

No module named 'asynchat' (Ubuntu 24.04)#

De oorspronkelijke versie van fail2ban in Ubuntu 24.04 werkte niet met Python 3.12. De oplossing zit in de updates van de distributie: voer apt update && apt full-upgrade uit en daarna systemctl restart fail2ban.

Fail2ban meldt adressen als geblokkeerd, maar de aanvaller blijft wachtwoorden proberen#

  • Zoek in /var/log/fail2ban.log naar fouten bij de actie (bijvoorbeeld nft: not found). Installeer in dat geval het pakket nftables.
  • Controleer of port in de jail overeenkomt met de werkelijke poort van SSH.

Waar je details vindt#

bash
tail -n 50 /var/log/fail2ban.log
journalctl -u fail2ban -n 50
  • tail -n 50 /var/log/fail2ban.log – de laatste 50 regels van het log van fail2ban (blokkades Ban, deblokkades Unban, fouten).
  • journalctl -u fail2ban -n 50 – de laatste 50 logregels van de service, handig als fail2ban helemaal niet start.

Samenvatting

  • Fail2ban blokkeert IP-adressen na herhaalde mislukte inlogpogingen; je installeert het met het commando apt install fail2ban.
  • Je eigen instellingen horen in /etc/fail2ban/jail.local, nooit in jail.conf.
  • SSH leest het journal (backend = systemd), recidive leest een bestand (backend = auto).
  • Deblokkeren: fail2ban-client set sshd unbanip <IP> of fail2ban-client unban <IP>, en als je jezelf buitensluit, gebruik je de console.
  • Pas na het verplaatsen van SSH port in de jail sshd aan.

Zoeken in de handleidingen