W dobie zautomatyzowanych ataków typu brute-force i skanerów podatności, klasyczne rozwiązania typu Fail2Ban często przestają wystarczać. Pożerają zbyt wiele zasobów, a ich działanie opiera się wyłącznie na lokalnych logach. Odpowiedzią na te wyzwania jest CrowdSec – nowoczesne narzędzie typu Open Source, udostępniane na lekkiej licencji MIT.
Projekt bazuje na idei „cyfrowego monitoringu sąsiedzkiego”. Sercem CrowdSeca jest unikalne połączenie analizy behawioralnej z potęgą społeczności. W praktyce: gdy Twój serwer lub jakikolwiek inny użytkownik na świecie wykryje i zablokuje agresywne IP, informacja ta trafia do wspólnej bazy, błyskawicznie chroniąc całą resztę sieci. Całość napisano w języku Go, dzięki czemu rozwiązanie działa błyskawicznie i w minimalnym stopniu obciąża zasoby maszyny.
Pod FreeBSD instalacja i architektura wyglądają inaczej niż pod Linuksem – wymaga to zrozumienia podziału na Hosta i Klatki (Jails).
Złota zasada FreeBSD: CrowdSec instalujemy na Hoście
W środowisku FreeBSD z reguły zamykamy usługi w izolowanych klatkach (Jails). Jednak CrowdSec (oraz jego Bouncer) to oprogramowanie zarządzające firewallem całego serwera. Aby mógł skutecznie blokować ataki (zanim te w ogóle dotrą do środowisk webowych w klatkach), musi zostać zainstalowany bezpośrednio na systemie bazowym (Hoście). Silnik będzie czytał logi udostępnione z klatek, a złośliwe pakiety odetnie główny firewall systemowy.
Instalacja silnika (LAPI)
nstalacja pod FreeBSD jest czysta i sprowadza się do użycia systemowego menedżera pakietów:
pkg install crowdsec
Następnie aktywujemy usługę i uruchamiamy ją:
sysrc crowdsec_enable="YES"
service crowdsec start
Konfiguracja Bouncera pod firewall PF (Packet Filter)
Aby CrowdSec mógł realnie blokować ataki na poziomie sieci, potrzebujesz tzw. Bouncera. Pod FreeBSD standardem i najpotężniejszym narzędziem jest firewall pf.
Instalujemy bouncer:
pkg install crowdsec-firewall-bouncer
sysrc crowdsec_firewall_enable="YES"
Teraz musimy poinstruować nasz firewall pf, aby współpracował z CrowdSecem. Edytujemy plik /etc/pf.conf i na samej górze (w sekcji tabel) dodajemy:
table <crowdsec-blacklists> persist
table <crowdsec-blacklists6> persist
# Reguły blokujące na wejściu (wstaw przed regułami przepuszczającymi ruch)
block drop in log quick from <crowdsec-blacklists> to any
block drop in log quick from <crowdsec-blacklists6> to any
Przeładowujemy firewalla i uruchamiamy bouncera:
pfctl -f /etc/pf.conf
service crowdsec_firewall start
Scenariusze poprawiające bezpieczeństwo
W nowoczesnych wersjach CrowdSeca odchodzi się od ręcznego instalowania dziesiątek pojedynczych scenariuszy. Zamiast tego używamy gotowych, potężnych kolekcji (collections), które same dbają o dociągnięcie odpowiednich zależności, parserów logów i reguł blokujących.
Do ochrony standardowego serwera WWW instalujemy podstawowe kolekcje za pomocą narzędzia cscli:
cscli collections install crowdsecurity/sshd crowdsecurity/nginx crowdsecurity/base-http-scenarios
Co dają nam te kolekcje?
sshd – chroni przed próbami odgadnięcia hasła do konsoli serwera.
nginx (lub apache2) – uczy CrowdSeca, jak czytać logi konkretnego serwera WWW.
base-http-scenarios – to potężna paczka, która zastępuje dawne, pojedyncze reguły. Automatycznie chroni m.in. przed agresywnym skanowaniem (crawl-non_statics), próbami dostępu do ukrytych plików (sensitive-files), badaniem luk (probing), atakami typu brute-force i złośliwymi botami (bad-user-agent).
Po pomyślnej instalacji kolekcji, wystarczy przeładować silnik, aby zaczął stosować nowe reguły:
service crowdsec reload
Własna biała lista (White-list) i ochrona plików
CrowdSec pozwala na definiowanie adresów, które nigdy nie powinny zostać zablokowane (Twój adres IP, biuro, adresy zaufanych systemów). Pod FreeBSD pliki konfiguracyjne znajdują się w katalogu /usr/local/etc/.
Krok 1: Tworzenie pliku
touch /usr/local/etc/crowdsec/parsers/s02-enrich/moje-adresy.yaml
Krok 2: Zawartość pliku
name: uzytkownik/moje-adresy
description: "Moja wlasna biala lista adresow IP"
whitelist:
reason: "Zaufane IP administratora i biura"
ip:
- "1.2.3.4" # Twoje stałe IP
cidr:
- "192.168.1.0/24" # Twoja sieć lokalna
Krok 3: Ochrona pliku (Flaga immutable)
CrowdSec podczas aktualizacji (lub w wyniku błędu) mógłby nadpisać pliki parserów. We FreeBSD do sprzętowej ochrony plików przed zmianą (nawet przez użytkownika root) używamy flag systemowych:
Blokowanie pliku (tylko do odczytu)
chflags schg /usr/local/etc/crowdsec/parsers/s02-enrich/moje-adresy.yaml
Jeśli kiedyś będziesz musiał go edytować, zdejmujesz flagę poleceniem:
chflags noschg /usr/local/etc/crowdsec/parsers/s02-enrich/moje-adresy.yaml
Po edycji: service crowdsec reload.
Automatyczna aktualizacja (Cron)
System bezpieczeństwa jest na tyle dobry, na ile aktualne są jego bazy. Dodajemy aktualizację do systemowego demona cron:
crontab -e
Dopisujemy:
15 3 * * * /usr/local/bin/cscli hub update && /usr/local/bin/cscli hub upgrade && /usr/local/bin/cscli -t && /usr/sbin/service crowdsec reload 2>> /var/log/crowdsec_update_errors.log
Tworzymy plik logów z odpowiednimi restrykcjami:
touch /var/log/crowdsec_update_errors.log
chown root:wheel /var/log/crowdsec_update_errors.log
chmod 700 /var/log/crowdsec_update_errors.log
Bonus: Agresywny Honey-Pot (Dla serwerów bez WordPressa)
Jeśli na Twoim serwerze (lub w Twoich klatkach webowych) nie używasz WordPressa, każda próba dostępu do jego plików jest bezdyskusyjnym atakiem. To samo tyczy się prób odczytu plików konfiguracyjnych.
Krok 1:
touch /usr/local/etc/crowdsec/scenarios/wp-honeypot.yaml
Krok 2: Zawartość
type: leaky
name: custom/wp-honeypot
description: "Agresywne wykrywanie botów szukajacych WP/plikow wrażliwych"
filter: |
evt.Meta.log_type == 'http_access-log' &&
(
evt.Parsed.request matches (?i).*wp-login\.php.* ||
evt.Parsed.request matches (?i).*wp-admin.* ||
evt.Parsed.request matches (?i).*xmlrpc\.php.* ||
evt.Parsed.request matches (?i).*/wp-content/.* ||
evt.Parsed.request matches (?i).*wp-config\..* ||
evt.Parsed.request matches (?i).*\.env.* ||
evt.Parsed.request matches (?i).*\.git/config.* ||
evt.Parsed.request matches (?i).*\.sql.* ||
evt.Parsed.request matches (?i).*\.bak.* ||
evt.Parsed.request matches (?i).*\.php~.* ||
evt.Parsed.request matches (?i).*/phpmyadmin/.*
)
leakspeed: "0s"
capacity: 0
blackhole: 1m
Krok 3: Konfiguracja profilu (Długi ban)
Edytuj /usr/local/etc/crowdsec/profiles.yaml i dodaj na samej górze w sekcji reguł:
name: long_term_ban_wp
filters:
Alert.GetScenario() == 'custom/wp-honeypot'
decisions:
type: ban
duration: 720h # 30 dni banicji w PF
on_success: break
Konfiguracja logów z klatek (Acquisition)
Aby CrowdSec (działający na Hoście) widział, co dzieje się na serwerach WWW uruchomionych wewnątrz klatek (Jails), musi wiedzieć, gdzie szukać ich logów. Edytujemy /usr/local/etc/crowdsec/acquis.yaml:
filenames:
# Zmień ścieżkę na tę odpowiadającą Twojej strukturze Jails
/jails/*/var/log/nginx-access.log
/jails/*/var/log/nginx-error.log
labels:
type: nginx
Uruchom weryfikację:
cscli explain --type nginx --file /jails/nazwa_klatki/var/log/nginx-access.log
Jeśli CrowdSec prawidłowo parsuje linie, przeładuj usługę: service crowdsec reload. Od tej pory każdy bot skanujący strony wewnątrz odizolowanych klatek, zostanie natychmiast wycięty przez systemowy firewall PF na głównym interfejsie sieciowym.
Podsumowanie i przydatne komendy cscli
Twój serwer we FreeBSD jest teraz nie tylko chroniony przez rewelacyjny firewall pf, ale też zyskał globalną inteligencję CrowdSeca, odcinając skanery jeszcze zanim obciążą serwery WWW.
Najważniejsze polecenia administracyjne:
cscli decisions list – wyświetla listę wszystkich aktywnych blokad IP.
cscli decisions add –ip 1.2.3.4 –reason „manual ban” – ręczne odcięcie adresu na firewallu.
cscli decisions delete –ip 1.2.3.4 – zdjęcie bana.
cscli metrics – statystyki w czasie rzeczywistym.
cscli hub update / upgrade – ręczna aktualizacja reguł.
cscli bouncers list – sprawdza, czy nasz bouncer pf komunikuje się prawidłowo z silnikiem.
service crowdsec reload – ładuje nowe konfiguracje bez przerw w pracy.