Ingenting i fail2ban släpper ett paket av sig självt: det anropar en åtgärd, och det är åtgärden som namnger ett protokoll och en port. När jailen rapporterar en ban medan daemonen fortsätter att acceptera inloggningar, är banen oftast verklig och smalare än loggen antyder. En klient som återansluter över den andra transporten möter aldrig regeln som installerades. Jämför vad åtgärden installerade med vad daemonen lyssnar på innan du ändrar något, eftersom beviset ligger i brandväggskedjan som åtgärden skrev, inte i jailens lista.

Läs kedjan, inte jailens sammanfattning

fail2ban sätter in sin egen kedja före tjänstens kedja, så en räknarlista visar exakt vad som finns. En kedja uppkallad efter jailen, som håller en enda regel vars protokollkolumn läser udp, är en fullständig förklaring till TCP-inloggningar som fortsätter att komma in. Endast UDP-paket från den blockerade källan avvisas. Tjänsten har en TCP-lyssnare, och ingenting i den kedjan rör den.

Se också upp för granne-jail-effekten. En värd kan se perfekt konfigurerad ut bara för att en annan jail levererar den halva som saknas, och samma bygge gör ingenting där den jailen inte är installerad.

Åtgärden namnger ett protokoll, och det är där det brister

Varje banaction är en mall för ett brandväggskommando, och protokollet sitter i en av dess platshållare. Trångheten är avsiktlig, eftersom en webb-jail och en DNS-jail inte har något att göra med att blockera identiska portar. Det blir en fälla när tjänsten lyssnar på mer än en transport, vilket VPN-daemoner rutinmässigt gör. Filtret kan övervaka misslyckade inloggningar från båda transporterna medan åtgärden täcker en.

SoftEther- och OpenVPN-utrullningar lyssnar vanligtvis på UDP och TCP samtidigt, och eftersom loggraden ser likadan ut i båda fallen övervakar filtret båda. Asymmetrin syns aldrig i jailens egen rapport. fail2ban räknade felen korrekt och installerade sedan en regel som gäller för hälften av trafiken som felen kom in på.

Låt banen täcka båda transporterna

Rätta det i jaildefinitionen i stället; handskrivna regler blandas om vid nästa omladdning. Skriv ut två åtgärder, en för varje protokoll:

action = %(banaction)s[name=%(__name__)s-tcp, actionname=%(__name__)s-tcp, protocol="tcp", port="%(port)s", chain="%(chain)s"]
         %(banaction)s[name=%(__name__)s-udp, actionname=%(__name__)s-udp, protocol="udp", port="%(port)s", chain="%(chain)s"]

Försök inte förkorta det med protocol = all. Standard-banaction är en multiport-åtgärd, och den expanderar till -p <protocol> -m multiport --dports <port>; utan L4-protokoll finns det inget för portmatchningen att testa, så iptables avvisar regeln medan jailen fortfarande rapporterar en lyckad ban. En åtgärd för alla portar som iptables-allports eller nftables-allports accepterar en enda post, men blockerar varje port på den källan, vilket är ett annat beslut och kräver sin egen motivering. Låt protocol stå på tcp eller udp och acceptera de två posterna.

Bevisa att regeln finns i stället för att lita på inställningen, eftersom en inställning beskriver en avsikt tills en kedja håller den:

iptables -S f2b-vpn-tcp
iptables -S f2b-vpn-udp

Varje kedja bör lista en regel, med -p tcp i den första och -p udp i den andra, och båda namnger den blockerade adressen. Bekräfta sedan att samma adress nekas på båda transporterna. En ban du inte har sett i kedjan är ett hopp, och nästa rapport om samma symtom kommer att kosta samma timme igen.

Vad en ban fortfarande missar, och nästa fall

Det åtgärden gör är att avvisa en enda källa, och bara på de portar som anges i den. Den gör ingenting mot en angripare som roterar adresser, och den kan inte skilja en fientlig maskin från en carrier-grade NAT-utgång som delas av hundratals användare, där en enda ban stänger ute människor som inte gjort något. Se till att filtret läser adressen som klienten faktiskt har, inte en vidarebefordrad header eller en proxyadress. Håll fönstret kort nog att ett misstag löper ut av sig självt.

Inget av detta talar för att hoppa över protokollrättningen; det talar för att hålla två idéer samtidigt. Banen är smalare än jailens sammanfattning antyder, och även en fullständig ban är smalare än hotet. Ställ brandväggskedjan bredvid daemonens lyssnarlista och jämför protokoll för protokoll, eftersom de två listorna avgör om en ban överhuvudtaget kan nå tjänsten.

Håll omladdningskommandot och kedjelistan i runbooken bredvid jailen. Nästa person behöver båda, och jailens sammanfattning kommer inte att berätta något av dem för hen.

Relaterade artiklar