# Opsæt Fail2ban til webservere

> Fail2ban til Nginx og Apache: aktivér passende jails, test egne filtre med fail2ban-regex, spær gengangere, og undgå at låse jer selv ude.

Kilde: https://phpsos.de/da/blog/fail2ban-fuer-webserver/  
Status: 25.10.2026  
Udbyder: PHP SOS, PHP-nødhjælp og serversikkerhed. Akut hjælp på WhatsApp: https://wa.me/491736494914?text=Hej%20PHP%20SOS%2C%20vi%20har%20brug%20for%20hj%C3%A6lp%20med%20vores%20PHP-server.%20Firma%3A%20%E2%80%A6%20Website%3A%20%E2%80%A6

**Kort sagt:** Fail2ban læser logfiler og spærrer i firewallen adresser, der inden for et tidsvindue falder for ofte i øjnene. Til Nginx og Apache medfølger færdige jails som `nginx-botsearch` eller `apache-noscript`; egne filtre tester I med `fail2ban-regex`. Indstillinger hører hjemme i `jail.local`, jeres egne adresser i `ignoreip`, gengangere opfanger `recidive`-jail'et. Mod enkelte målrettede angreb hjælper Fail2ban ikke, mod massescanninger gør det.

## Når logs er fulde af scannere

Den, der i disse dage ser på sine webserveres adgangsprotokoller, finder dem ofte fulde af forespørgsler til stier, der slet ikke findes: gamle admin-flader, testfiler, kendte svagheder i andre produkter. I en situation som PHP2Shell kommer der målrettet søgning efter sårbare servere til: Cloudflare og Patchstack rapporterede om angrebsforsøg, Unit 42 talte mere end 22,6 millioner eksponerede, potentielt sårbare instanser.

Fail2ban er et gennemprøvet værktøj mod denne masse. Det læser logfiler, genkender med filtre påfaldende poster og spærrer afsenderadressen i en fastlagt tid i firewallen. Det aflaster serveren, mindsker logstøjen og gør systematisk gennemprøvning fra én kilde besværlig.

Hvad Fail2ban ikke kan, er lige så vigtigt: En enkelt forespørgsel, der udnytter en sårbarhed, forhindres ikke. Mod PHP2Shell hjælper kun PHP-opdateringen. Hvordan automatiserede angreb forløber, beskriver [Massescanninger efter upatchet PHP](https://phpsos.de/da/blog/automatisierte-massenscans/).

## Fail2ban til Nginx og Apache: de medfølgende jails

Et jail forbinder et filter med en logfil og en spærringshandling. Den medfølgende `jail.conf` indeholder allerede jails til webservere. De er som standard slået fra og aktiveres enkeltvis.

| Jail | Webserver | Genkender |
|---|---|---|
| `nginx-http-auth` | Nginx | mislykkede HTTP-Basic-logins |
| `nginx-limit-req` | Nginx | forespørgsler, der overskrider Nginx's rate limit |
| `nginx-botsearch` | Nginx | søgning efter typiske, ikke-eksisterende stier |
| `nginx-bad-request` | Nginx | fejlbehæftede forespørgsler |
| `apache-auth` | Apache | mislykkede logins |
| `apache-badbots` | Apache | kendte skadelige bot-kendetegn |
| `apache-noscript` | Apache | kald til ikke-eksisterende scripts |
| `apache-overflows` | Apache | overlange forespørgsler |
| `apache-botsearch` | Apache | søgning efter typiske, ikke-eksisterende stier |
| `php-url-fopen` | begge | bestemte mønstre af forsøg på URL-indbinding |
| `recidive` | begge | adresser, som Fail2ban gentagne gange har spærret |

Standardværdierne i den medfølgende konfiguration er snarere milde: spærring i 10 minutter efter 5 hits på 10 minutter. Til webservere med megen scannertrafik er en længere spærring og en stigende faktor for gentagelser umagen værd.

## Grundkonfigurationen i jail.local

`jail.conf` siger selv, at den ikke skal ændres, fordi opdateringer erstatter den. Egne værdier hører hjemme i `/etc/fail2ban/jail.local`. Det følgende eksempel for Nginx sætter fornuftige standarder og aktiverer passende jails:

```ini
# /etc/fail2ban/jail.local
[DEFAULT]
# Indtast egne faste adresser (erstat eksempeladressen)
ignoreip = 127.0.0.1/8 ::1 203.0.113.10
bantime  = 1h
findtime = 10m
maxretry = 5
bantime.increment = true

[nginx-http-auth]
enabled = true

[nginx-botsearch]
enabled = true

[recidive]
enabled  = true
bantime  = 1w
findtime = 1d
```

Til Apache aktiverer I i stedet f.eks. `apache-auth`, `apache-noscript` og `apache-botsearch`. Logstierne medbringer Fail2ban pr. distribution; afviger jeres stier, sætter I `logpath` i det pågældende jail. Læser jeres system kun logs via journalen, hjælper `backend = systemd`.

## Et eget filter til masseforespørgsler på PHP-filer

Et typisk mønster i den aktuelle situation er mange forespørgsler på kort tid til PHP-filer, der ikke findes. Et eget filter genkender det på statuskoden 404. Det beskriver kun, hvad der står i jeres eget log:

```ini
# /etc/fail2ban/filter.d/nginx-php-404.conf
[Definition]
failregex = ^<HOST> -.*"(GET|POST|HEAD) [^"]*\.php[^"]*" 404
ignoreregex =
```

```ini
# Tilføjelse i /etc/fail2ban/jail.local
[nginx-php-404]
enabled  = true
port     = http,https
filter   = nginx-php-404
logpath  = /var/log/nginx/access.log
maxretry = 20
findtime = 1m
bantime  = 1h
```

Før I aktiverer filteret, kontrollerer I det mod det rigtige log. Så ser I, hvor mange linjer det rammer, og om legitime adgange er med:

```bash
fail2ban-regex /var/log/nginx/access.log /etc/fail2ban/filter.d/nginx-php-404.conf
sudo systemctl restart fail2ban
sudo fail2ban-client status
sudo fail2ban-client status nginx-php-404
# Frigiv en ved en fejl spærret adresse
sudo fail2ban-client set nginx-php-404 unbanip 203.0.113.25
```

Vælg grænsen rundhåndet. En crawler, der gennemarbejder forældede links, eller en overvågningstjeneste må ikke havne i spærringen.

## De hyppigste faldgruber

Fail2ban er hurtigt installeret, men let at bruge forkert. Disse punkter bør I kontrollere før produktiv brug:

1. **Selvudelukkelse:** Kontor-, VPN- og overvågningsadresser hører hjemme i `ignoreip`, før jails bliver aktive.
2. **Forudgående tjenester:** Bag CDN eller load balancer ser Fail2ban uden tilpasning kun deres adresser. Mere herom i vejledningen [Beskyt admin-logins mod brute force](https://phpsos.de/da/ratgeber/brute-force-login-schutz/).
3. **Logrotation:** Efter skiftet af logfilen skal Fail2ban læse den nye fil. Kontrollér efter første rotation, om jails fortsat tæller hits.
4. **Samspil med firewall:** Fail2ban indfører spærringer i firewallen. Den, der administrerer sin firewall med en fuldstændig genindlæsning af regelsættet, kan dermed slette disse poster. Hvordan I opbygger firewallen selv, står under [Firewall til webservere: Åbn kun nødvendige porte](https://phpsos.de/da/blog/firewall-fuer-webserver/).
5. **IPv6:** Angreb kommer også via IPv6. Kontrollér, om jeres spærringshandling dækker begge protokoller.

> **Tip:**
> Analysér spærrelisterne regelmæssigt. Hober spærringer sig op fra bestemte net eller til bestemte stier, er det et tegn på målrettet søgning og en anledning til at se nærmere på den berørte applikation.

## Konklusion: Et værktøj mod masse, ikke mod alt

Fail2ban er hurtigt opsat og tager en del af det vedvarende beskydning fra webservere. De medfølgende jails dækker typiske mønstre, egne filtre kan med `fail2ban-regex` uden fare testes mod ægte logs, og `recidive`-jail'et sørger for, at hårdnakkede kilder holdes ude længere.

Overvurdér det dog ikke. Fail2ban reagerer på gentagelse, ikke på det første hit, og det ser kun, hvad der står i logs. Mod en sårbarhed som PHP2Shell hjælper alene opdateringen, mod distribuerede angreb fra mange adresser hjælper Fail2ban knap. Dets værdi udfolder sig som ét lag blandt flere: ved siden af en slank firewall, en hærdet webserverkonfiguration, tofaktorlogin og en overvågning, der ikke blot spærrer påfaldende forhold, men også melder dem.

## Hvordan hjælper PHP SOS konkret?

- **Analysér logs:** Vi ser på, hvilke mønstre der optræder i jeres adgangsprotokoller, og udvælger passende jails.
- **Opsæt og test:** Vi opsætter Fail2ban med egne filtre, tester hvert filter mod ægte logs og indfører jeres faste adresser som undtagelse.
- **Afklar samspillet:** CDN, load balancer, firewall og logrotation afstemmer vi, så spærringer rammer de rigtige adresser.
- **Observér:** Inden for rammerne af [sikkerhedsovervågningen](https://phpsos.de/da/leistungen/security-monitoring/) analyserer vi spærringer og påfaldende forhold løbende.


## Ofte stillede spørgsmål

**Beskytter Fail2ban mod PHP2Shell?**  
Nej. Fail2ban reagerer først, efter at en adresse gentagne gange er faldet i øjnene i logs. Et enkelt vellykket angreb forhindres ikke dermed. Men Fail2ban sænker belastningen fra scannere og gør gentagne forsøg fra samme kilde dyrere.

**Hvorfor skal jeg ikke ændre jail.conf direkte?**  
Filen erstattes ved pakkeopdateringer, og det siger den selv. Egne indstillinger hører hjemme i en jail.local eller i filer under jail.d. Dér overskriver de standardværdierne målrettet.

**Hvad er recidive-jail'et?**  
Et jail, der analyserer Fail2bans egen protokol. Den, der gang på gang bliver spærret, får en tydeligt længere spærring. I den medfølgende konfiguration er den en uge.

**Fungerer Fail2ban bag Cloudflare eller en load balancer?**  
Kun med ekstra konfiguration. Uden den står den forudgående tjenestes adresse i logs, og en spærring ville ramme alle besøgende. Webserveren skal så overtage den rigtige besøgsadresse, og spærringer sættes bedre hos den forudgående tjeneste.

## Kilder

- [Fail2ban: medfølgende jail.conf](https://github.com/fail2ban/fail2ban/blob/master/config/jail.conf)
- [BSI IT-Grundschutz (tysk metodik til informationssikkerhed)](https://www.bsi.bund.de/DE/Themen/Unternehmen-und-Organisationen/Standards-und-Zertifizierung/IT-Grundschutz/it-grundschutz_node.html)
- [OWASP Cheat Sheets](https://cheatsheetseries.owasp.org/)
