Fail2Ban installeren en configureren op een Linux VPS
Stel Fail2Ban in om brute-force-aanvallen op SSH en Nginx te blokkeren. Behandelt UFW- en nftables-banacties, aangepaste jails, recidive-escalatie en filtertests op Ubuntu 24.04 en Debian 12.
Fail2Ban bewaakt je logbestanden op herhaalde authenticatiefouten en blokkeert de betreffende IP-adressen via je firewall. Het stopt brute-force-aanvallen voordat ze slagen. Een pas geïnstalleerde VPS ontvangt doorgaans binnen enkele minuten SSH-inlogpogingen. Fail2Ban is de standaardverdediging.
Deze handleiding behandelt de installatie op Ubuntu 24.04 en Debian 12, de configuratie van SSH- en Nginx-jails, beide backends voor banacties (UFW en nftables), de recidive-jail voor herhaaldelijke overtreders, en het testen van filters met fail2ban-regex. Elke configuratiewijziging bevat een verificatiestap.
Vereisten: Een VPS met Ubuntu 24.04 of Debian 12 met root- of sudo-toegang. Je firewall moet al actief zijn en SSH moet al beveiligd zijn. Deze handleiding maakt deel uit van de serie Linux VPS-beveiliging.
Hoe installeer ik Fail2Ban op Ubuntu 24.04 en Debian 12?
Installeer Fail2Ban met apt. Het pakket zit in de standaard repositories van beide distributies. Ubuntu 24.04 levert versie 1.0.2, Debian 12 eveneens. Op Debian 12 heb je ook python3-systemd nodig zodat Fail2Ban het systemd-journal kan lezen.
sudo apt update && sudo apt install -y fail2ban
Op Debian 12, installeer de systemd Python-bindings:
sudo apt install -y python3-systemd
Activeer en start de service:
sudo systemctl enable --now fail2ban
De enable-vlag zorgt ervoor dat Fail2Ban start bij het opstarten. De --now-vlag start het direct. Controleer of het draait:
sudo systemctl status fail2ban
De output toont Active: active (running) in de uitvoer moeten zien. Als de status failed toont, bekijk dan het journal:
journalctl -u fail2ban -n 20 --no-pager
Wat is het verschil tussen jail.conf, jail.local en jail.d/?
jail.conf is het standaard configuratiebestand dat met het pakket wordt meegeleverd. Pakketupdates overschrijven dit bestand. Bewerk jail.conf nooit rechtstreeks. Je wijzigingen verdwijnen bij de volgende apt upgrade.
jail.local is het traditionele override-bestand. Fail2Ban leest eerst jail.conf en past vervolgens de instellingen uit jail.local daaroverheen toe. Dit werkt, maar het bestand groeit uit tot een monoliet die moeilijk te onderhouden is.
De jail.d/-directory is de betere aanpak. Plaats één .conf-bestand per jail. Fail2Ban laadt ze alfabetisch na jail.conf en jail.local. Elke service blijft geïsoleerd en het is eenvoudig om jails toe te voegen of te verwijderen zonder andere configuraties aan te raken.
Deze handleiding gebruikt drop-in-bestanden in jail.d/. Controleer of de directory bestaat:
ls /etc/fail2ban/jail.d/
Deze zou al moeten bestaan. Als je bestanden ziet zoals defaults-debian.conf, is dat normaal. Op Ubuntu 24.04 activeert dit bestand de sshd-jail en stelt het banaction = nftables in als standaard banactie. Op Debian 12 activeert het de sshd-jail. Omdat Fail2Ban de bestanden in jail.d/ alfabetisch laadt, moet elk aangepast standaardbestand alfabetisch na defaults-debian.conf gesorteerd zijn om de instellingen te overschrijven. Deze handleiding gebruikt daarom zz-defaults.conf.
Hoe configureer ik de SSH-jail in Fail2Ban?
De SSH-jail bewaakt authenticatielogs en blokkeert IP's die te vaak falen bij het inloggen. Op Ubuntu 24.04 en Debian 12 is de sshd-jail standaard geactiveerd via /etc/fail2ban/jail.d/defaults-debian.conf. Maar de standaardwaarden zijn te ruim (5 pogingen, 10 minuten ban). Verscherp ze.
Maak een drop-in-configuratie:
sudo tee /etc/fail2ban/jail.d/sshd.conf > /dev/null << 'EOF'
[sshd]
enabled = true
mode = aggressive
port = ssh
backend = systemd
maxretry = 3
findtime = 600
bantime = 3600
EOF
Wat elke instelling betekent:
| Parameter | Waarde | Betekenis |
|---|---|---|
enabled |
true |
Activeert deze jail |
mode |
aggressive |
Detecteert meer SSH-foutpatronen, inclusief key-authenticatiefouten |
port |
ssh |
Bewaakt de SSH-poort (wordt opgelost naar 22, of je aangepaste poort) |
backend |
systemd |
Leest uit het systemd-journal in plaats van logbestanden |
maxretry |
3 |
Blokkeert na 3 mislukte pogingen |
findtime |
600 |
Telt fouten binnen een venster van 10 minuten |
bantime |
3600 |
Blokkeert voor 1 uur (3600 seconden) |
Als je je SSH-poort hebt gewijzigd (dat zou je moeten doen), vervang dan ssh door je poortnummer:
port = 2222
Herstart Fail2Ban om toe te passen:
sudo systemctl restart fail2ban
Controleer of de jail actief is:
sudo fail2ban-client status sshd
Verwachte uitvoer:
Status for the jail: sshd
|- Filter
| |- Currently failed: 0
| |- Total failed: 0
| `- Journal matches: _SYSTEMD_UNIT=sshd.service + _COMM=sshd
`- Actions
|- Currently banned: 0
|- Total banned: 0
`- Banned IP list:
Let goed op: de regel Journal matches bevestigt dat Fail2Ban uit het systemd-journal leest, niet uit een logbestand. Dit is correct voor Ubuntu 24.04 en Debian 12.
Hoe stel ik Fail2Ban in met UFW als banactie?
Als je UFW als firewall gebruikt, configureer Fail2Ban dan om banregels via UFW in te voegen. Dit is het eenvoudigste pad, geschikt voor de meeste configuraties.
Maak een standaardbestand dat UFW als banactie instelt. De bestandsnaam zz-defaults.conf is bewust gekozen: op Ubuntu 24.04 levert het pakket defaults-debian.conf die banaction = nftables instelt. Jouw bestand moet alfabetisch daarna gesorteerd zijn om die standaard te overschrijven.
sudo tee /etc/fail2ban/jail.d/zz-defaults.conf > /dev/null << 'EOF'
[DEFAULT]
banaction = ufw
banaction_allports = ufw
backend = systemd
EOF
Herstart en controleer:
sudo systemctl restart fail2ban
sudo fail2ban-client status sshd
Wanneer Fail2Ban een IP blokkeert, voert het ufw insert 1 deny from <IP> to any uit. Controleer de UFW-regels na een ban:
sudo ufw status numbered
Je ziet de deny-regels van Fail2Ban bovenaan de lijst.
Hoe configureer ik Fail2Ban om nftables te gebruiken in plaats van iptables?
Voor productieservers die nftables rechtstreeks gebruiken (zonder UFW), gebruik de nftables-multiport banactie. Fail2Ban maakt zijn eigen nftables-tabel aan en beheert de banregels daar zonder je bestaande regelset te verstoren.
Maak het standaardbestand. Op Ubuntu 24.04 stelt defaults-debian.conf al banaction = nftables in, dus deze stap is technisch optioneel. Maar het is goed gebruik om expliciet te zijn. Op Debian 12 is dit bestand vereist.
sudo tee /etc/fail2ban/jail.d/zz-defaults.conf > /dev/null << 'EOF'
[DEFAULT]
banaction = nftables-multiport
banaction_allports = nftables[type=allports]
chain = input
backend = systemd
EOF
Herstart en controleer:
sudo systemctl restart fail2ban
sudo fail2ban-client status sshd
Om de nftables-integratie te bevestigen, toon de Fail2Ban-tabel:
sudo nft list tables
De output toont een tabel moeten zien met de naam inet f2b-table. Na een ban kun je de inhoud inspecteren:
sudo nft list table inet f2b-table
Vergelijking van UFW- en nftables-banacties
| Aspect | UFW (banaction = ufw) |
nftables (banaction = nftables-multiport) |
|---|---|---|
| Bancommando | ufw insert 1 deny from <IP> |
Voegt IP toe aan nftables-set |
| Waar regels verschijnen | ufw status numbered |
nft list table inet f2b-table |
| IPv6-ondersteuning | Ja (UFW regelt het) | Ja (inet-familie) |
| Persistentie | UFW-regels overleven herstarts | Fail2Ban past ze opnieuw toe bij opstarten |
| Prestaties | Lineaire regelmatching | Set-gebaseerde lookup (sneller bij grote aantallen) |
| Geschikt voor | Eenvoudige opstellingen, enkele service | Productie, veel jails, hoge banaantallen |
Kies één aanpak. Meng geen UFW- en nftables-banacties op dezelfde server.
Hoe zet ik mijn IP-adres op de whitelist in Fail2Ban?
Voeg je IP toe aan ignoreip om te voorkomen dat je jezelf buitensluit. Dit is belangrijk. Als je drie keer je wachtwoord verkeerd intypt, blokkeert Fail2Ban je eigen IP. Je verliest SSH-toegang.
Voeg je IP toe aan de standaardinstellingen:
sudo tee /etc/fail2ban/jail.d/01-whitelist.conf > /dev/null << 'EOF'
[DEFAULT]
ignoreip = 127.0.0.1/8 ::1 YOUR_IP_HERE
EOF
Vervang YOUR_IP_HERE door je werkelijke publieke IP. Je kunt het vinden door curl -4 ifconfig.me uit te voeren op je lokale machine. Voeg meerdere IP's toe gescheiden door spaties.
Herstart en controleer of de whitelist geladen is:
sudo systemctl restart fail2ban
sudo fail2ban-client get sshd ignoreip
De uitvoer toont alle IP's en reeksen op de whitelist. Bevestig dat je IP in de lijst staat.
Waarschuwing: Als je verbinding maakt vanaf een dynamisch IP, biedt het whitelisten beperkte bescherming. Houd een secundaire toegangsmethode achter de hand (consoletoegang via het paneel van je hostingprovider) als backup voor het geval je geblokkeerd wordt.
Hoe bescherm ik Nginx met aangepaste Fail2Ban-jails?
Fail2Ban wordt geleverd met verschillende Nginx-filters. De meest bruikbare zijn nginx-http-auth voor brute-force op HTTP Basic Authentication en nginx-botsearch voor scanners die niet-bestaande paden afvragen. Je kunt ook aangepaste filters schrijven voor applicatiespecifieke patronen.
nginx-http-auth-jail
Deze jail blokkeert IP's die herhaaldelijk falen bij HTTP Basic Authentication. Het leest uit het Nginx-foutenlog.
sudo tee /etc/fail2ban/jail.d/nginx-http-auth.conf > /dev/null << 'EOF'
[nginx-http-auth]
enabled = true
port = http,https
logpath = /var/log/nginx/error.log
maxretry = 3
findtime = 600
bantime = 3600
EOF
nginx-botsearch-jail
Deze jail vangt bots die scannen naar kwetsbare paden (/wp-admin, /phpmyadmin, /.env). Het leest het Nginx-toegangslog op 404-responses.
sudo tee /etc/fail2ban/jail.d/nginx-botsearch.conf > /dev/null << 'EOF'
[nginx-botsearch]
enabled = true
port = http,https
logpath = /var/log/nginx/access.log
maxretry = 5
findtime = 600
bantime = 7200
EOF
Aangepast filter: buitensporige 4xx-fouten blokkeren
Voor applicaties achter Nginx wil je mogelijk IP's blokkeren die te veel 4xx-fouten genereren. Dit vangt credential stuffing, API-misbruik en padenumeratie. De ingebouwde filters dekken dit niet, dus maak een aangepast filter.
Maak het filterbestand:
sudo tee /etc/fail2ban/filter.d/nginx-4xx.conf > /dev/null << 'EOF'
[Definition]
failregex = ^<HOST> - \S+ \[.*\] "[A-Z]+ .+" (400|401|403|404|405) \d+
ignoreregex = ^<HOST> - \S+ \[.*\] "[A-Z]+ /favicon\.ico
^<HOST> - \S+ \[.*\] "[A-Z]+ /robots\.txt
EOF
De failregex matcht regels in het Nginx-toegangslog waar de respons een 4xx-statuscode is. De ignoreregex sluit veelvoorkomende false positives uit zoals favicon.ico- en robots.txt-verzoeken.
Maak de jail:
sudo tee /etc/fail2ban/jail.d/nginx-4xx.conf > /dev/null << 'EOF'
[nginx-4xx]
enabled = true
port = http,https
filter = nginx-4xx
logpath = /var/log/nginx/access.log
maxretry = 20
findtime = 600
bantime = 3600
EOF
De hogere maxretry van 20 voorkomt het blokkeren van legitieme gebruikers die een paar 404's tegenkomen tijdens normaal surfen.
Herstart Fail2Ban en controleer of alle jails geladen zijn:
sudo systemctl restart fail2ban
sudo fail2ban-client status
Verwachte uitvoer met alle actieve jails:
Status
|- Number of jail: 4
`- Jail list: nginx-4xx, nginx-botsearch, nginx-http-auth, sshd
Meer over de bescherming van Nginx op applicatieniveau vind je in de handleiding over Nginx rate limiting.
Hoe test ik Fail2Ban-filters met fail2ban-regex?
Test het filter tegen echte logs voordat je een jail activeert. De tool fail2ban-regex voert een filter uit tegen een logbestand en rapporteert matches. Dit voorkomt het uitrollen van een filter dat niets matcht (nutteloos) of alles matcht (blokkeert legitieme gebruikers).
Test het aangepaste nginx-4xx-filter:
sudo fail2ban-regex /var/log/nginx/access.log /etc/fail2ban/filter.d/nginx-4xx.conf
Voorbeelduitvoer:
Running tests
=============
Use failregex filter file : nginx-4xx, basedir: /etc/fail2ban
Use log file : /var/log/nginx/access.log
Use encoding : utf-8
Results
=======
Failregex: 42 total
|- #) [# of hits] regular expression
| 1) [42] ^<HOST> - \S+ \[.*\] "[A-Z]+ .+" (400|401|403|404|405) \d+
`-
Ignoreregex: 3 total
Date template hits:
...
Lines: 1842 lines, 0 ignored, 42 matched, 1800 missed
Let goed op: de uitvoer toont 42 gematchte regels van 1842. Dat is een redelijke verhouding. Als het filter 90% van de regels zou matchen, is de regex te breed. Als het 0 regels matcht, is ofwel de regex onjuist, of het log bevat nog geen 4xx-fouten.
Om te zien welke regels gematcht zijn:
sudo fail2ban-regex --print-all-matched /var/log/nginx/access.log /etc/fail2ban/filter.d/nginx-4xx.conf
Om te zien welke regels niet gematcht zijn (handig voor fijnafstelling):
sudo fail2ban-regex --print-all-missed /var/log/nginx/access.log /etc/fail2ban/filter.d/nginx-4xx.conf
Test het ingebouwde sshd-filter tegen het systemd-journal:
sudo fail2ban-regex systemd-journal /etc/fail2ban/filter.d/sshd.conf
Hoe stel ik de recidive-jail in voor herhaaldelijke overtreders?
De recidive-jail bewaakt het eigen log van Fail2Ban. Wanneer een IP meerdere keren wordt geblokkeerd in welke jail dan ook, past de recidive-jail een langere ban toe. Het is een escalatie: eerste overtreding = 1 uur, recidivisten = 1 week.
Op een drukke productieserver is de recidive-jail wat hardnekkige aanvallers daadwerkelijk buiten de deur houdt.
sudo tee /etc/fail2ban/jail.d/recidive.conf > /dev/null << 'EOF'
[recidive]
enabled = true
logpath = /var/log/fail2ban.log
banaction = %(banaction_allports)s
maxretry = 3
findtime = 86400
bantime = 604800
EOF
| Parameter | Waarde | Betekenis |
|---|---|---|
logpath |
/var/log/fail2ban.log |
Fallback-logpad. Met backend = systemd leest Fail2Ban in plaats daarvan zijn eigen journal-entries (het recidive-filter heeft een ingebouwde journalmatch-directive) |
maxretry |
3 |
Slaat aan na 3 bans van andere jails |
findtime |
86400 |
Kijkt 24 uur terug (86400 seconden) |
bantime |
604800 |
Blokkeert voor 1 week (604800 seconden) |
banaction |
%(banaction_allports)s |
Blokkeert alle poorten, niet alleen de poort die de ban veroorzaakte |
Het recidive-filter wordt meegeleverd met Fail2Ban in /etc/fail2ban/filter.d/recidive.conf. Je hoeft het niet zelf te maken.
Herstart en controleer:
sudo systemctl restart fail2ban
sudo fail2ban-client status recidive
Hoe monitor ik bans en deblokkeer ik een IP-adres?
Fail2Ban biedt fail2ban-client voor alle monitoring- en beheertaken. Deze commando's werken ongeacht je banactie-backend.
Algehele status controleren
sudo fail2ban-client status
Toont alle actieve jails en hun bantellers.
Een specifieke jail controleren
sudo fail2ban-client status sshd
Toont momenteel geblokkeerde IP's, totaal aantal bans en huidige fouten.
Een IP handmatig blokkeren
sudo fail2ban-client set sshd banip 203.0.113.50
Een IP deblokkeren
sudo fail2ban-client set sshd unbanip 203.0.113.50
Als het IP door de recidive-jail was geblokkeerd, deblokkeer het daar ook:
sudo fail2ban-client set recidive unbanip 203.0.113.50
Controleren welke banactie een jail gebruikt
sudo fail2ban-client get sshd actions
Configuratie herladen zonder herstart
sudo fail2ban-client reload
Het Fail2Ban-log lezen
journalctl -u fail2ban -f
Dit volgt het Fail2Ban-servicelog in realtime. Je ziet ban- en deblokkeergebeurtenissen terwijl ze plaatsvinden.
Het Fail2Ban-applicatielog met bandetails:
sudo tail -f /var/log/fail2ban.log
Commandoreferentie fail2ban-client
| Commando | Doel |
|---|---|
fail2ban-client status |
Alle jails tonen |
fail2ban-client status <jail> |
Jaildetails en geblokkeerde IP's tonen |
fail2ban-client set <jail> banip <IP> |
Een IP handmatig blokkeren |
fail2ban-client set <jail> unbanip <IP> |
Een IP deblokkeren |
fail2ban-client reload |
Volledige configuratie herladen |
fail2ban-client reload <jail> |
Enkele jail herladen |
fail2ban-client get <jail> bantime |
Banduur tonen |
fail2ban-client get <jail> findtime |
Foutenvenster tonen |
fail2ban-client get <jail> maxretry |
Pogingsdrempel tonen |
fail2ban-client get <jail> ignoreip |
Whitelisted IP's tonen |
fail2ban-client get <jail> actions |
Gebruikte banactie tonen |
End-to-end verificatie: een ban uitlokken en bevestigen dat het werkt
Ga er niet van uit dat je configuratie werkt. Test het. Lok een echte ban uit en verifieer de hele keten: logdetectie, banactie, firewallregel en deblokkering.
Stap 1: Probeer vanaf een andere machine (niet je whitelisted IP) SSH-logins met een verkeerd wachtwoord. Na 3 mislukkingen (overeenkomend met maxretry) zou de verbinding geweigerd moeten worden.
Als je geen tweede machine hebt, gebruik fail2ban-client om een ban te simuleren:
sudo fail2ban-client set sshd banip 198.51.100.25
Stap 2: Controleer of de ban geregistreerd is:
sudo fail2ban-client status sshd
Het geblokkeerde IP zou in Banned IP list moeten verschijnen.
Stap 3: Controleer of de firewallregel bestaat.
Voor UFW:
sudo ufw status numbered | grep 198.51.100.25
Voor nftables:
sudo nft list table inet f2b-table
Het IP zou in een set binnen de tabel moeten verschijnen.
Stap 4: Deblokkeer en verifieer de verwijdering:
sudo fail2ban-client set sshd unbanip 198.51.100.25
sudo fail2ban-client status sshd
Het IP zou niet meer in de banlijst moeten verschijnen. Controleer de firewall opnieuw om te bevestigen dat de regel verwijderd is.
Referentie configuratieparameters Fail2Ban
| Parameter | Standaard | Aanbevolen | Beschrijving |
|---|---|---|---|
bantime |
10m |
1h of 3600 |
Duur van de ban |
findtime |
10m |
10m of 600 |
Venster voor het tellen van fouten |
maxretry |
5 |
3 voor SSH, 5-20 voor web |
Fouten voor blokkering |
ignoreip |
127.0.0.1/8 ::1 |
Voeg je IP toe | IP's die nooit geblokkeerd worden |
banaction |
nftables (Ubuntu 24.04), iptables-multiport (upstream) |
ufw of nftables-multiport |
Uit te voeren firewallcommando |
backend |
auto |
systemd |
Logbron (systemd-journal op moderne distributies) |
destemail |
root@localhost |
Je e-mail | Ontvanger van meldingen |
action |
%(action_)s |
%(action_mwl)s voor e-mailmeldingen |
Actie bij blokkering |
Gaat er iets mis?
Fail2Ban start niet: Controleer op syntaxfouten in je jail-bestanden. Een ontbrekende haak of ongeldige waarde verhindert het opstarten.
sudo fail2ban-client -t
Dit test de configuratie zonder de service te starten. Los alle gemelde fouten op.
Jail toont 0 matches maar er zijn aanvallen gaande: De backend is waarschijnlijk verkeerd. Op Ubuntu 24.04 en Debian 12, gebruik backend = systemd. Als je backend = auto gebruikt en het systeem geen /var/log/auth.log heeft, leest Fail2Ban niets.
Geblokkeerd IP kan nog steeds verbinden: De banactie komt niet overeen met je firewall. Als je UFW gebruikt, stel banaction = ufw in. Als je nftables rechtstreeks gebruikt, stel banaction = nftables-multiport in. Controleer of de firewallregel na een ban daadwerkelijk bestaat.
Je hebt jezelf geblokkeerd: Krijg toegang tot je server via de webconsole van je hostingprovider (VNC/KVM). Vanaf daar:
sudo fail2ban-client set sshd unbanip YOUR_IP
Of stop Fail2Ban volledig:
sudo systemctl stop fail2ban
Herstel vervolgens je ignoreip-configuratie en herstart.
Fail2Ban gebruikt te veel geheugen: Op servers met grote logbestanden kan Fail2Ban geheugen verbruiken. Stel dbpurgeage in om de databasegrootte te beperken:
sudo tee /etc/fail2ban/jail.d/99-performance.conf > /dev/null << 'EOF'
[DEFAULT]
dbpurgeage = 7d
EOF
Copyright 2026 Virtua.Cloud. Alle rechten voorbehouden. Deze inhoud is een origineel werk van het Virtua.Cloud-team. Reproductie, herpublicatie of herdistributie zonder schriftelijke toestemming is verboden.