Det här sätter du upp
Alla servrar på internet sonderas dygnet runt: lösenordsgissningar över SSH, och skannrar som frågar din webbserver efter /.env, /wp-login.php och administrationssidor för program du inte kör. CrowdSec läser dina loggar, känner igen mönstren och ser till att angriparens adress blockeras i brandväggen i fyra timmar. Idén är densamma som i Fail2ban, med färdiga regler för att upptäcka angrepp från en gemensam samling, Hub.
CrowdSec består av två delar. Motorn, crowdsec, läser loggar och fattar beslut. En bouncer verkställer besluten; här brandväggsbouncern, som med nftables stoppar all trafik från en blockerad adress, på alla portar, över IPv4 och IPv6.
CrowdSec utvecklas av CrowdSec SAS, ett franskt företag i Montrouge, registrerat i Nanterre under nummer 880 140 496. Motorn, brandväggsbouncern och reglerna på Hub är öppen källkod under MIT-licensen. Webbkonsolen på app.crowdsec.net och de större blocklistorna är CrowdSecs kommersiella tjänster, med en kostnadsfri nivå för konsolen. Även om CrowdSec SAS är franskt bygger dess onlinetjänster på amerikanska företag. Dess integritetspolicy anger AWS, GCP, Firebase, Slack och ClickUp, alla amerikanska, som mottagare av data, och anger att överföringar utanför EU sker med Europeiska kommissionens standardavtalsklausuler. När vi kontrollerade körde det centrala API:et på api.crowdsec.net hos Amazon Web Services på Irland, konsolen hos Vercel, och nedladdningarna från Hub kom via Amazon CloudFront och Cloudflare. CrowdSecs rättsliga information anger Webflow, Inc. i San Francisco som värd för webbplatsen; när vi kontrollerade svarade webbplatsen från Vercel.
Guiden har två upplägg. Välj ett, så anpassas stegen nedan:
- Bara lokalt: CrowdSec registrerar sig aldrig hos CrowdSecs centrala API, Central API. Det upptäcker och blockerar angrepp mot den här servern utifrån serverns egna loggar, och skickar ingenting om dem någonstans.
- Gemensam blocklista: servern registrerar sig hos Central API. Den rapporterar adresserna som angrep den och får i gengäld en blocklista med omkring 15 000 adresser som har angripit andra CrowdSec-användare, så att de blockeras innan de når dig.
Varje steg nedan har körts på en nyinstallerad VC-P Alloy (2 vCPU, 8 GB) hos Melonslab med Debian 13:
- Riktiga angripare blockerades inom tre minuter efter installationen: en lösenordsgissare från internet, via SSH-reglerna, och en skanner som letade efter känsliga filer i Caddy.
- En skur av förfrågningar efter sidor som inte finns, skickade till serverns egen IPv4- och IPv6-adress, fick adressen blockerad av regeln för sondering, och följande förfrågningar fick inget svar.
- Från testplatser på andra håll på internet fick en blockerad adress inget svar på port 443 över IPv4 och IPv6 medan andra fick kontakt, och fick kontakt igen när blockeringen togs bort.
- ufw höll en port som den inte hade öppnat stängd medan CrowdSec blockerade adresser på portarna den hade öppnat, och
ufw reloadlät CrowdSecs regler vara kvar. - En adress på listan över tillåtna adresser blockerades aldrig, varken av en regel eller för hand.
- I upplägget Bara lokalt visade en paketfångst ingen anslutning till CrowdSecs tjänster efter installationen, inte heller efter en omstart.
- I upplägget Gemensam blocklista loggade en proxy varje förfrågan till Central API; steg 8 visar vad de innehöll.
- Allt startade igen av sig självt efter en omstart av servern, med blockeringarna kvar.
CrowdSec använde omkring 160 MB minne och 0,15 % av en processorkärna i vila, och brandväggsbouncern omkring 26 MB. Med den gemensamma blocklistan inläst växte det till omkring 205 MB och 37 MB. Med Caddy använde hela servern 530 till 610 MB.
Innan du börjar
Du behöver:
- en server hos Melonslab med Debian 13;
- SSH-nycklar, automatiska säkerhetsuppdateringar och ufw, uppsatta enligt steg 1 till 4 i säkerhetsguiden, med port 22, 80 och 443 öppna;
- för webbserverdelen, ett namn som
example.commed en A- och en AAAA-post som pekar på servern; - adresserna du ansluter från, för listan över tillåtna adresser i steg 5. Byter din internetleverantör adress åt dig behöver du också konsolen, se Om du blockerar dig själv.
Exemplen använder 203.0.113.10 och 2001:db8::10 för serverns adresser och 198.51.100.7 för din egen. Byt genomgående ut dem mot dina egna.
CrowdSec blockerar adresser, och en angripare med många adresser får fortfarande några försök från var och en. Det ersätter inte inloggning med bara nycklar eller uppdateringar: det minskar bruset och stoppar en skanner innan den hittar den enda svaga sidan.
1. Lägg till CrowdSecs paketförråd
Debian 13 har ett eget crowdsec-paket, men det är version 1.4.6 från 2022, och brandväggsbouncern är 0.0.25. Reglerna på Hub skrivs för aktuella versioner, så den här guiden använder CrowdSecs paketförråd, med version 1.8.1. Paketförrådet ligger hos packagecloud.io; på vår testserver kom nedladdningarna från Amazon Web Services i Kalifornien och Amazon CloudFront.
CrowdSecs dokumentation lägger till paketförrådet med ett skript som körs direkt i skalet. Det här är samma steg för hand. Som root:
apt update
apt install -y curl gpg
curl -fsSL https://packagecloud.io/crowdsec/crowdsec/gpgkey | gpg --dearmor -o /etc/apt/keyrings/crowdsec.gpg
Skapa /etc/apt/sources.list.d/crowdsec.sources:
Types: deb
URIs: https://packagecloud.io/crowdsec/crowdsec/any/
Suites: any
Components: main
Signed-By: /etc/apt/keyrings/crowdsec.gpg
Sedan:
apt update
apt-cache policy crowdsec
Kandidaten är 1.8.1 eller senare, från packagecloud.io.
2. Installera CrowdSec
Med Bara lokalt
Vid installationen frågar paketet om det ska registrera sig hos Central API, och registrerar sig om ingen svarar. Svara nej i förväg:
echo "crowdsec crowdsec/capi boolean false" | debconf-set-selections
apt install -y crowdsec
Loggen bekräftar att Central API är avstängt:
grep "Central API" /var/log/crowdsec.log
level=info msg="push and pull to Central API disabled"
cscli capi status svarar the Central API (CAPI) must be configured with 'cscli capi register'.
Paketet hämtar Hubs index och regler, tittar på vad som körs på servern och installerar matchande samlingar: på vår testserver crowdsecurity/linux, crowdsecurity/sshd och, eftersom Caddy redan var installerad, crowdsecurity/caddy med de allmänna webbreglerna. För att se dem:
cscli collections list
Installerar du Caddy efter CrowdSec lägger du till samlingen själv med cscli collections install crowdsecurity/caddy.
3. Läs SSH-loggen från journalen
CrowdSecs installation pekar SSH-reglerna mot /var/log/auth.log. Debian 13 skriver SSH:s logg bara till systemd-journalen: filen finns, men förblir tom, så CrowdSec skulle aldrig se en lösenordsgissning. Låt det läsa journalen i stället. Skapa /etc/crowdsec/acquis.d/sshd-journal.yaml:
# Debian 13 logs SSH to the journal only, so /var/log/auth.log stays empty
source: journalctl
journalctl_filter:
- "_SYSTEMD_UNIT=ssh.service"
labels:
type: syslog
Läs sedan in CrowdSecs inställningar på nytt:
systemctl reload crowdsec
grep journalctl /var/log/crowdsec.log | tail -1
level=info msg="Spawning process" command="journalctl --follow -n 0 _SYSTEMD_UNIT=ssh.service" ...
Installationens egna filer i /etc/crowdsec/acquis.d/ får vara kvar. De loggar varningar som No matching files for pattern /var/log/syslog, vilket inte gör någon skada.
Med en egen fil i den katalogen kör paketuppdateringar inte längre den automatiska installationen igen; de säger det med The automatic setup will not proceed to avoid any conflict. Lägger du senare till en tjänst på servern installerar du dess samling själv, som för Caddy i steg 2.
4. Låt CrowdSec läsa Caddys logg
Caddy skriver ingen åtkomstlogg förrän du ber om det. Lägg till ett log-block för din webbplats i /etc/caddy/Caddyfile:
example.com {
root * /usr/share/caddy
file_server
log {
output file /var/log/caddy/access.log
}
}
Caddy skriver en rad JSON per förfrågan, vilket är formatet CrowdSecs Caddy-regler förväntar sig. Verkställ och gör en förfrågan:
systemctl reload caddy
curl -sI https://example.com
tail -1 /var/log/caddy/access.log
På Debian 13 behövs ett steg till. Dess Caddy är version 2.6.2, och Caddy-reglerna från Hub läser besökarens adress från fältet client_ip, som Caddy lade till först i version 2.7. Version 2.6 skriver den som remote_ip. Utan rättningen nedan läser CrowdSec Caddys logg och känner igen skannrar, men kan inte blockera dem: loggen visar scope is Ip but Meta[source_ip] doesn't exist varje gång en regel slår till.
Skapa /etc/crowdsec/parsers/s02-enrich/00-caddy-remote-ip.yaml:
# Debian 13 has Caddy 2.6, whose logs have remote_ip but not client_ip,
# which the caddy-logs parser reads. Without this, nothing gets banned.
name: local/caddy-remote-ip
description: "Take the client address from remote_ip in Caddy 2.6 logs"
filter: "evt.Meta.log_type == 'http_access-log' && evt.Meta.source_ip == '' && evt.Unmarshaled.caddy.request.remote_ip != nil"
statics:
- parsed: remote_ip
expression: evt.Unmarshaled.caddy.request.remote_ip
- meta: source_ip
expression: evt.Unmarshaled.caddy.request.remote_ip
Den fyller bara i adressen när den saknas, så den gör ingenting när Debian väl levererar en nyare Caddy. Testa den på loggens sista rad och läs sedan in inställningarna på nytt:
tail -1 /var/log/caddy/access.log > /tmp/line.json
cscli explain --file /tmp/line.json --type caddy
systemctl reload crowdsec
Under s02-enrich är local/caddy-remote-ip markerad med grönt, och tolkningen slutar med parser success.
5. Lägg dina egna adresser på listan över tillåtna
Gör det innan du installerar bouncern. Skriver du fel lösenord några gånger, eller testar CrowdSec från din egen dator, blockerar det dig som vem som helst. En lista över tillåtna adresser, en allowlist, gör att adresser aldrig blockeras:
cscli allowlists create mine -d "My own addresses"
cscli allowlists add mine 198.51.100.7 -d "home"
Lägg till alla adresser du ansluter från, även IPv6; ett adressintervall fungerar också, till exempel 2001:db8:1234::/48. För att kontrollera:
cscli allowlists inspect mine
cscli decisions add --ip 198.51.100.7 -d 1m -R test
Det andra kommandot nekas:
Error: cscli decisions add: 198.51.100.7 is allowlisted by item 198.51.100.7 from mine (home), use --bypass-allowlist to add the decision anyway
När en tillåten adress utlöser en regel visar CrowdSecs logg alert source 198.51.100.7 is allowlisted ... skipping, och ingenting blockeras. Lägger du till en adress som redan är blockerad tas blockeringen bort. cscli allowlists remove mine 198.51.100.7 tar bort en adress från listan igen.
6. Installera brandväggsbouncern
apt install -y crowdsec-firewall-bouncer-nftables
Paketet registrerar bouncern hos CrowdSec av sig självt (API Key successfully created) och startar den. För att kontrollera:
cscli bouncers list
nft list tables
Bouncern finns i listan med en färsk tid under Last API pull, och två tabeller har dykt upp bredvid ufw:s: ip crowdsec och ip6 crowdsec6. Var tionde sekund hämtar bouncern nya beslut och lägger adresserna i en mängd i tabellerna. Dess regel stoppar all trafik från de adresserna, innan ufw:s regler ens prövas.
7. Se det blockera
Inom några minuter på vår testserver hade riktiga angripare utlöst reglerna: en lösenordsgissare över SSH och en skanner som letade efter känsliga filer. För att se vad CrowdSec har upptäckt:
cscli alerts list
cscli decisions list
| ID | Source | Scope:Value | Reason | Action | Country | AS | Events | expiration | Alert ID |
| 4 | crowdsec | Ip:192.0.2.38 | crowdsecurity/ssh-slow-bf | ban | GB | 209854 Cyberzone S.A.| 11 | 3h59m53s | 4 |
En alert är vad en regel upptäckte; ett beslut, decision, är blockeringen som följer. cscli alerts inspect 4 visar mer, till exempel vilka användarnamn en SSH-gissare provade.
För att kontrollera att en blockering verkligen stänger servern blockerar du en adress för hand. Ta en adress du kan testa från, till exempel en andra internetanslutning eller en telefon på mobildata, och inte en som finns på din lista över tillåtna:
cscli decisions add --ip 192.0.2.50 -d 30m -R "test ban"
Inom 10 sekunder finns adressen i brandväggen:
nft list set ip crowdsec crowdsec-blacklists-cscli
Från den enheten får webbplatsen och SSH nu inget svar. I vårt test fick den blockerade testplatsen inget svar på port 443 över IPv4, och en blockerad IPv6-adress inget svar över IPv6, medan alla andra platser fick kontakt. Ta bort blockeringen:
cscli decisions delete --ip 192.0.2.50
Enheten får kontakt igen inom 10 sekunder.
8. Kontrollera vad servern skickar till CrowdSec
Med Bara lokalt
För att se varje namn servern slår upp kör du det här och låter det vara igång medan du startar om CrowdSec och bouncern från en andra session:
tcpdump -l -n -i eth0 -Q out udp port 53
systemctl restart crowdsec crowdsec-firewall-bouncer
Inget crowdsec.net-namn dyker upp. I vårt test slog servern bara upp namn på CrowdSecs tjänster under installationen: packagecloud.io för paketen, och cdn-hub.crowdsec.net, hub-data.crowdsec.net och version.crowdsec.net för Hub. Därefter visade en paketfångst ingen anslutning till CrowdSec alls, inte heller efter en omstart. Bouncern pratar bara med motorn på 127.0.0.1:8080.
Två saker kontaktar fortfarande CrowdSec, och skickar ingenting om serverns angripare:
crowdsec-hubupdate.timerkörcscli hub updateochcscli hub upgradeen gång om dagen, för att hämta nya versioner av reglerna från Hub. Det gör även paketet när det uppdateras. CrowdSec ser serverns adress och dess CrowdSec-version. För att stoppa timern kör dusystemctl disable --now crowdsec-hubupdate.timer, och uppdaterar reglerna för hand som i steg 12.apthämtar uppdateringar från packagecloud.io.
CrowdSec slår också upp det omvända DNS-namnet för varje adress det blockerar, via serverns vanliga resolver. Det är en del av reglerna som känner igen snälla robotar, inte en tjänst hos CrowdSec.
Om du installerade CrowdSec med Central API innan du läste det här, stäng av det. Sätt ett # framför raden online_client: och raden credentials_path: under den i /etc/crowdsec/config.yaml, och starta om:
systemctl restart crowdsec
grep "Central API" /var/log/crowdsec.log | tail -1
Sista raden lyder push and pull to Central API disabled. Blockeringar från den gemensamma blocklistan finns kvar tills de går ut, efter upp till en vecka. För att ta bort dem nu:
cscli decisions delete --origin CAPI
systemctl restart crowdsec-firewall-bouncer
Bouncern släpper dem först efter omstarten.
9. ufw och CrowdSec tillsammans
ufw och bouncern har var sina tabeller i nftables och rör inte varandras regler. CrowdSecs kedjor körs med prioritet filter - 10, så en blockerad adress stoppas först, även på en port som ufw tillåter. All annan trafik går sedan genom ufw som förut. För att se båda:
nft list tables
ufw status
table ip filter
table ip6 filter
table ip crowdsec
table ip6 crowdsec6
ip filter och ip6 filter är ufw:s. I vårt test, med en blockering på plats, lämnade ufw reload, ufw disable och ufw enable alla CrowdSecs tabeller och den blockerade adressen kvar. Ett testprogram på port 8081, som ufw inte hade öppnat, förblev stängt från internet, medan adresser som inte var blockerade nådde port 22 och 443.
Två vanor håller det så. Låt bouncerns deny_action: DROP vara som den är, och töm inte hela regeluppsättningen med nft flush ruleset: det tar bort både ufw:s och CrowdSecs regler, tills båda startas om.
10. Kommandon för vardagen
cscli decisions list # who is blocked now, and why
cscli decisions list --origin crowdsec # only blocks from your own logs
cscli decisions delete --ip 192.0.2.38 # lift one block
cscli alerts list # what was detected
cscli alerts inspect 4 # details of one alert
cscli metrics # lines read, rules hit, packets dropped
cscli metrics börjar med Acquisition Metrics: hur många rader CrowdSec läste från varje logg och hur många som matchade dess regler. Saknas en logg där, eller står Lines read kvar på noll medan tjänsten används, ser CrowdSec inte den loggen. Lyckade SSH-inloggningar räknas som Lines unparsed, vilket är normalt. Längre ner visar Bouncer Metrics hur mycket trafik bouncern har stoppat, uppdelat på var blockeringen kom ifrån.
Blockeringar varar i fyra timmar, inställt i /etc/crowdsec/profiles.yaml. Varje alert, och dess blockering, finns kvar i CrowdSecs databas i /var/lib/crowdsec/data/ efter att blockeringen har gått ut, och cscli alerts list fortsätter att visa dem.
11. Om du blockerar dig själv
Når du inte servern längre, och din adress inte fanns på listan över tillåtna, använder du konsolen. Öppna din server i kundportalen, gå till fliken Server och välj Open console. Den visar serverns skärm och fungerar utan nätverk. Logga in som root med root-lösenordet, och kör:
cscli decisions list
cscli decisions delete --ip 198.51.100.7
cscli allowlists add mine 198.51.100.7 -d "home"
Bouncern öppnar brandväggen åt dig inom 10 sekunder. Vet du inte vilken adress du har visar cscli decisions list de senast blockerade, med orsaken.
12. Uppdateringar
CrowdSec kommer från ett eget paketförråd, som de automatiska uppdateringarna från säkerhetsguiden inte täcker. För att låta dem installera CrowdSecs uppdateringar också skapar du /etc/apt/apt.conf.d/52unattended-upgrades-crowdsec:
Unattended-Upgrade::Origins-Pattern {
"origin=packagecloud.io/crowdsec/crowdsec,label=crowdsec";
};
För att kontrollera:
unattended-upgrade --dry-run --debug 2>&1 | grep 'Allowed origins'
Raden slutar med origin=packagecloud.io/crowdsec/crowdsec,label=crowdsec. I vårt test uppdaterade en körning av unattended-upgrade CrowdSec från 1.8.0 till 1.8.1. Journalkällan, rättningen för Caddy, listan över tillåtna adresser och blockeringarna fanns kvar, och likaså inställningen från steg 2.
Reglerna kommer från Hub och uppdateras separat, en gång om dagen, via crowdsec-hubupdate.timer. För att uppdatera dem för hand:
cscli hub update
cscli hub upgrade
systemctl reload crowdsec
hub update hämtar listan över vad som är nytt, och hub upgrade installerar det. Filer du har skapat själv, som rättningen för Caddy i steg 4, lämnas orörda: hub upgrade rapporterar local/caddy-remote-ip - not downloading local item.
Felsökning
SSH-gissningar fyller journalen, men CrowdSec blockerar ingen. CrowdSec läser den tomma /var/log/auth.log. Lägg till journalkällan från steg 3. cscli metrics listar då journalctl:journalctl-_SYSTEMD_UNIT=ssh.service under Acquisition Metrics, med en siffra under Lines read efter nästa SSH-inloggning.
Skannrar syns i Caddys logg, och cscli metrics visar att regler slår till, men ingenting blockeras. CrowdSecs logg visar scope is Ip but Meta[source_ip] doesn't exist. Caddy 2.6 skriver adressen i ett fält som Caddy-reglerna inte läser; lägg till tolkaren från steg 4.
Caddys logg syns inte i cscli metrics. Webbplatsen saknar log-block, eller skriver någon annanstans än i /var/log/caddy/, där /etc/crowdsec/acquis.d/setup.caddy.yaml letar.
cscli decisions add säger att adressen är tillåten. Den finns på din lista från steg 5, vilket är meningen. --bypass-allowlist lägger till blockeringen ändå.
Du har blockerat dig själv. Se steg 11.