Blokering af onde robotter med fail2ban

På min lille virtuelle private server kører bl.a. en række WordPress-sider (som fx denne blog). En ret stor del af indholdet på nettet leveres af WordPress, og derfor er det måske ikke så mærkeligt, at der også er en del aktivitet på nettet, der handler om at udnytte huller i og gætte brugernavne og kodeord til WordPress-sider.

I min log kunne jeg se en masse forespørgsler til WordPress’ loginside, fx:

xxx.xxx.xxx.xxx - - [25/Feb/2024:08:41:54 +0100] "POST https://[helmstedt].dk/wp-login.php HTTP/1.1" 200 240 "-" "Mozilla/5.0 (X11; Fedora; Linux x86_64; rv:94.0) Gecko/20100101 Firefox/95.0"

Den slags forespørgsler er ret uskadelige, hvis man bruger et kodeord, der er svært at gætte, men jeg bryder mig ikke om tanken om, at en masse robotter forsøger at overtage mine sider.

Derfor installerede jeg fail2ban på min server. Fail2ban kan monitorere en logfil og blokere for IP-adresser, der gør noget, man ikke vil have. Det fungerer ved, at man opsætter en regel for, hvad fail2ban skal kigge efter, og når programmet så støder på et mønster i log-filen, der opfylder reglen, sættes IP-adresser “i fængsel” (blokeres i en periode).

Jeg startede med at flytte adressen på mine login-formularer fra /wp-login.php til en anden adresse (jeg brugte en plugin til WordPress til formålet), sådan at fremtidige besøg til denne URL ville give en 404-fejl.

Så definerede jeg mit “fængsel”. Ét enkelt besøg, der opfylder filterreglen “wordpress” betyder 96 timers blokering i min servers firewall. Jeg sørgede for at undtage min egen IP-adresse fra reglen, så jeg ikke ved en fejl kommer til at lukke mig selv ude:

[DEFAULT]
bantime = 1h
ignoreip = 127.0.0.1/8 ::1 xxx.xxx.xxx.xxx [min hjemme-ip]

[sshd]
enabled = false

[wordpress]
iptables-multiport[name=wordpress, port="http,https", protocol=tcp]
enabled = true
filter = wordpress
port = http,https
logpath = /var/log/nginx/access.log
maxretry = 1
bantime = 96h

Så skrev jeg (med hjælp fra en søgning på internettet) filter-reglen. En GET- eller POST-forespørgsel til på “wp-login.php” med HTTP-kode 404 eller 403 eller en forespørgsel til “xmlrpc.php”, sætter den IP-adresse (“<HOST>”), der har forespurgt i fængsel:

[Definition]
failregex = ^<HOST> .*"(GET|POST).*\/wp-login.php.*(404|403).*$
			^<HOST> .*"(GET|POST).*\/xmlrpc.php.*$

fail2ban har nu kørt i et par døgn, og der er allerede 1418 forskellige IP-adresser, der er havnet i mit nye fængsel.

Det må være en ret omfattende industri at bryde ind i folks WordPress-installationer.

Serveradministration (for begynder)

Jeg kører mine Django-baserede hjemmesider fra en lillebitte Virtuel Privat Server (VPS) hos DigitalOcean. Det koster $6,25 om måneden. Hvis du er interesseret i at prøve det, kan du bruge dette link: [link fjernet]. Når du bruger linket får du lov at bruge for $100 inden for 60 dage. Hvis du senere bruger 25 rigtige $, får jeg også $25 til min konto.

Nå: I nat fejlede et script, jeg bruger til at tage backups af mine databaser, og jeg forstod ikke rigtig hvorfor. Det var noget med, jeg ikke fik lov at logge på med SSH. Så kiggede jeg på min servers ressourceforbrug:

I løbet af natten var CPU-belastningen gået fra ca. 3% til omkring 15%. Av.

Jeg undersøgte først de kørende processer med Linux-kommandoen top, men jeg kunne ikke rigtig se noget problem:

Efter lidt googling fandt jeg ud af at kigge på mine systemlogs med kommandoen journalctl:

Av. En masse forskellige IP-adresser var åbenbart i gang med at forsøge at logge ind med SSH på min server.

Jeg gjorde min firewall mere restriktiv ved at åbne for de par IP-blokke (fx min hjemmeinternetforbindelse), som jeg ved skal have adgang. Alt andet indgående traffik til port 22 (som SSH bruger), lukkede jeg for.

Resultatet:

Min lille server har det godt igen – og jeg lærte lidt om fejlsøgning på og overvågning af Linux-servere.