====== Crowdsec ======
===== Documentation =====
* [[https://docs.crowdsec.net/docs/configuration/crowdsec_configuration|crowdsec_configuration]]
* [[https://docs.crowdsec.net/docs/scenarios|scenarios]]
* [[https://docs.crowdsec.net/docs/user_guides/decisions_mgmt/|Decisions management]]
"Average Malevolent Duration (In Days) of Most Reported AS" page 11 sur [[https://majorityreport.crowdsec.net/hubfs/CrowdSec_Majority_Report.pdf|CrowdSec Majority Report]]
===== Installer crowdsec =====
* https://docs.crowdsec.net/docs/getting_started/install_crowdsec
# Ajouter le dépôt
curl -s https://packagecloud.io/install/repositories/crowdsec/crowdsec/script.deb.sh | sudo bash
sudo apt install crowdsec
Pour relancer la configuration : /usr/share/crowdsec/wizard.sh -c
pour la configuration utiliser le fichier ''/etc/crowdsec/config.yaml.local''. Par exemple désactiver l'agent [[/informatique/system_admin/Prometheus|Prometheus]].
#
# doc:
# https://docs.crowdsec.net/docs/configuration/crowdsec_configuration
#
common:
log_level: info
prometheus:
enabled: false
db_config:
use_wal: true
CrowdSec alone will not block any IP address. If you want to block them, you must use a bouncer. You can find them on https://hub.crowdsec.net/browse/#bouncers
sudo apt install crowdsec-firewall-bouncer-iptables
Appliquer les changements
sudo systemctl restart crowdsec
Tester le blocage
Exécuter plusieurs fois cette requête, **depuis une machine qui peut être bloquée** :
curl -I https://www.site.fr -H "User-Agent: OpenVAS"
Puis vérifier sur la machine www.site.fr que l'IP est bien bannie
sudo cscli decisions list
==== Alternatives ====
Aukfood vous guide pour [[https://www.aukfood.fr/automatiser-linstallation-et-la-configuration-de-crowdsec-avec-ansible/|automatiser l'installation de Crowdsec]] avec [[/informatique/ansible|Ansible]].
===== Quelques commandes =====
Pour voir les IP bannies (ou autres décisions):
sudo cscli decisions list
Bloquer/débloquer une IP à la mano
sudo cscli decisions add --ip "2a01:4f9:c010:ee9f::1"
sudo cscli decisions delete --ip "2a01:4f9:c010:ee9f::1"
# supprimer toutes les décisions
sudo cscli decisions delete --all
Voir dans le Firewall les IP bannies
$ sudo iptables -L -n -v
Chain INPUT (policy DROP 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
13800 933K DROP all -- * * 0.0.0.0/0 0.0.0.0/0 match-set crowdsec-blacklists src
$ sudo ipset list crowdsec-blacklists
68.178.149.158 timeout 598324
114.242.150.197 timeout 598322
$ sudo ipset list crowdsec6-blacklists
2001:470:1:c84::15 timeout 490300
2a01:7e01::f03c:92ff:fe7a:e887 timeout 281500
Lister les collections
sudo cscli collections list
Mise à jour des scénarios
sudo cscli hub update
sudo cscli hub upgrade
===== Scenario =====
Il ne semble pas possible de surcharger la configuration des scenarios. En fait c'est une mauvaise idée de modifier les scénarios officiels car les alertes doivent être "standard". Du coup s'ils sont modifiés ils doivent être traités comme "tainted". Donc il vaut mieux en créer des spécifiques.
- https://github.com/crowdsecurity/crowdsec/issues/2534
- https://github.com/crowdsecurity/crowdsec/issues/3533
[[https://docs.crowdsec.net/docs/scenarios/format/|Scenario format]]:
* **capacity**: the number of events in the bucket before it overflows.
* **leakspeed**: A duration that represent how often an event will be leaking from the bucket.
* **blackhole**: A duration for which a bucket will be "silenced" after overflowing. This is intended to limit / avoid spam of buckets that might be very rapidly triggered. The blackhole only applies to the individual bucket.
==== Wordpress ====
* https://www.it-connect.fr/comment-proteger-son-site-wordpress-avec-crowdsec/
* https://docs.crowdsec.net/docs/bouncers/wordpress
3 scenarios Wordpress sont fournis avec Crowdsec:
# cat /etc/crowdsec/scenarios/http-bf-wordpress_bf.yaml
type: leaky
name: crowdsecurity/http-bf-wordpress_bf
description: "detect wordpress bruteforce"
debug: false
# failed auth on wp-login.php returns 200
filter: "evt.Meta.log_type == 'http_access-log' && evt.Parsed.file_name == 'wp-login.php' && evt.Parsed.verb == 'POST' && evt.Meta.http_status == '200'"
groupby: evt.Meta.source_ip
capacity: 5
leakspeed: 10s
blackhole: 5m
labels:
service: http
type: bruteforce
remediation: true
# cat /etc/crowdsec/scenarios/http-wordpress_user-enum.yaml
type: leaky
name: crowdsecurity/http-wordpress_user-enum
description: "detect wordpress probing : authors enumeration"
debug: false
filter: "evt.Meta.log_type == 'http_access-log' && Upper(evt.Parsed.http_args) contains 'AUTHOR='"
groupby: evt.Meta.source_ip
distinct: evt.Parsed.http_args
capacity: 5
leakspeed: "10s"
blackhole: 5m
labels:
service: http
type: bruteforce
remediation: true
# cat /etc/crowdsec/scenarios/http-wordpress_wpconfig.yaml
type: leaky
name: crowdsecurity/http-wordpress_wpconfig
description: "detect wordpress probing : variations around wp-config.php by wpscan"
debug: false
filter: "evt.Meta.log_type == 'http_access-log' && evt.Parsed.file_name contains 'wp-config.php'"
groupby: evt.Meta.source_ip
distinct: evt.Parsed.file_name
capacity: 5
leakspeed: "10s"
blackhole: 5m
labels:
service: http
type: bruteforce
remediation: true
==== No Wordpress Here ====
J'en ai pondu un pour les serveurs sans Wordpress.
''/etc/crowdsec/scenarios/cyrille37-http-no-wordpress-here.yml''
type: leaky
format: 2.0
name: cyrille37/http-no-wordpress-here
description: "Detect attempt to access Wordpress files on machine without Wordpress running"
filter: 'evt.Meta.log_type in ["http_access-log", "http_error-log"] and (evt.Meta.http_path contains "wp-login" or evt.Meta.http_path contains "wp-content")'
groupby: "evt.Meta.source_ip"
capacity: 2
leakspeed: 5s
blackhole: 5m
labels:
service: http
type: discovery
remediation: true
===== Technique =====
==== Local API ====
Ajouter une ''decision'' via l'API n'est pas si simple
Documentation:
* https://crowdsecurity.github.io/api_doc/lapi/#/watchers/pushAlerts
* [[https://www.crowdsec.net/blog/introduction-to-the-local-api|Introduction to the local API]]
* implémentation partielle https://github.com/crowdsecurity/php-lapi-client
Questions:
* https://discourse.crowdsec.net/t/php-lapi-client-missing-api-verbs/1846
* https://discourse.crowdsec.net/t/ban-ips-via-api/1679/5
===== Test env =====
Un p'tit docker dans lequel créé l'environnement de test pour crowdsec
docker run -ti ubuntu bash
apt update && apt upgrade
apt install nano git wget gettext
Puis suivre
- [[https://doc.crowdsec.net/docs/contributing/contributing_test_env/|Creating a test environment]]
Pour résoudre l'erreur "exec crowdsec, command not found" :
# ajouter au PATH l'emplacement de `cscli` et `crowdsec`.
# ajouter dans /root/.bashrc
PATH=$PATH:/home/ubuntu/crowdsec-v1.7.2/tests
Créer une image à partir du container:
docker commit f6df6306f9e4 crowdsec_test_environnement
Exemple d'usage de l'image pour travailler sur les logs container :
# tous les fichiers sont dans le dossier `sympa_logs`,
# le monter dans le container au bon endroit dans `.../crowdsec-v1.7.2/tests/hub/.tests/`
DEST_HUB=/home/ubuntu/crowdsec-v1.7.2/tests/hub
docker run --rm -ti \
-v ./tests-sympa_ww-logs:$DEST_HUB/.tests/sympa_ww-logs \
-v ./tests-sympa_ww-http-scan:$DEST_HUB/.tests/sympa_ww-http-scan \
-v ./hub-cyrille37/cyrille37-sympa_ww-logs.yaml:$DEST_HUB/parsers/s01-parse/cyrille37/sympa_ww-logs.yaml \
-v ./hub-cyrille37/cyrille37-sympa_ww-logs.md:$DEST_HUB/parsers/s01-parse/cyrille37/sympa_ww-logs.md \
-v ./hub-cyrille37/cyrille37-sympa_ww-http-scan.yaml:$DEST_HUB/scenarios/cyrille37/sympa_ww-http-scan.yaml \
-v ./hub-cyrille37/cyrille37-sympa_ww-http-scan.md:$DEST_HUB/scenarios/cyrille37/sympa_ww-http-scan.md \
crowdsec_test_environnement bash
# se placer dans l'environnement de test
cd /home/ubuntu/crowdsec-v1.7.2/tests/hub
Ensuite :
* [[https://docs.crowdsec.net/docs/next/log_processor/parsers/create|Creating parser]]
* [[https://docs.crowdsec.net/docs/next/log_processor/scenarios/create|Creating scenario]]
# in crowdsec-v1.7.2/tests/hub
cscli -c ../dev.yaml hubtest run sympa_ww-logs --clean
cscli -c ../dev.yaml hubtest run sympa_ww-http-scan --clean
En cas d'erreur de syntaxe, le run suivant lève une erreur du genre ''cscli hubtest run: unable to copy 'patterns' ...''. il faut supprimer les dossiers ''results'' et ''runtime'' dans le dossier du test.
# in crowdsec-v1.7.2/tests/hub
rm -rf .tests/sympa-logs/results .tests/sympa_ww-logs/runtime
rm -rf .tests/sympa-http-scan/results .tests/sympa_ww-http-scan/runtime
J'ai fait un ''parser'' et ''scenario'' pour "sympa" (service "wwsympa) : https://github.com/crowdsecurity/hub/pull/1580