Crowdsec : Installation et sécurisation du serveur Local API

Crowdsec Cybersécurité Open source

Dans ce premier article, nous allons monter le serveur Crowdsec Local API et sécuriser l'accès à l'API.

C'est sur ce serveur que seront centralisées :

  • Les alertes et les décisions remontées par les clients dits machines faisant tourner Crowdsec agent.
  • Les alertes récupérées depuis le serveur Central API.
  • Les décisions consommées par les bouncers.

La communication avec la Local API est par défaut non chiffrée. Afin de sécuriser celle-ci, nous mettrons en place le chiffrement en se basant sur un certificat auto-signé.

Concernant la base de données, nous utiliserons celle configurée automatiquement lors de l'installation, à savoir Sqlite. Pour notre démo, elle fera l'affaire.

En cas de traffic important attendu, il vaut mieux utiliser une base de données du type MySQL ou PostgreSQL.

Serveur Crowdsec Local API :

  • OS : Debian 10
  • RAM : 2048
  • IP : 192.168.1.202/255.255.255.0
  • Nom d'hôte : srv-cs-lapi
  • Domaine de portée locale : lab.lan
  • FQDN : srv-cs-lapi.lab.lan

maquette01

Afin d'assurer une communication sécurisée entre les agents Crowdsec et le serveur Local API, nous chiffrerons les communications en se basant sur un certificat auto-signé.

Pour créer le certificat et la clé, exécutez le script suivant sur le serveur en passant le fqdn "srv-cs-lapi.lab.lan" :

#!/bin/bash

read -p "Saisir le nom du domaine : " fqdn

keycertifname=${fqdn%.*.*}
dirPKI="/root/pki/CA"
dirCerts="/root/pki/certs/${fqdn}"

if [ ! -d ${dirPKI} ]
then
 mkdir -p ${dirPKI}
fi

if [ ! -d ${dirCerts} ]
then
 mkdir -p ${dirCerts}
fi

if [ ! -f ${dirPKI}/ca.key ]
then
 echo "Creation AC "
 openssl genrsa -aes256 4096 > ${dirPKI}/ca.key
 chmod 600 ${dirPKI}/ca.key
 openssl req -new -x509 -days 365 -subj "/C=FR/ST=France/L=Quelque-part/O=Maison, Inc./CN=CA-Racine" \
 -key ${dirPKI}/ca.key > ${dirPKI}/ca.crt
 openssl x509 -in ${dirPKI}/ca.crt -outform DER -out ${dirPKI}/ca.der
fi

if [ ! -f ${dirCerts}/${keycertifname}.crt ]
then
 echo "************************ Creation certif serveur ******************************"

 openssl genrsa 4096 > ${dirCerts}/${certif}.key
 chmod 600 ${dirCerts}/${certif}.key

 echo "*********************** Generation du CSR *************************************"
 openssl req -newkey rsa:2048 -nodes -keyout ${dirCerts}/${keycertifname}.key\
 -subj "/C=FR/ST=France/L=Quelque-part/O=Maison, Inc./CN=${fqdn}" \
 -out ${dirCerts}/${keycertifname}.csr

 echo "*********************** Signature du CSR **************************************"
 openssl x509 -req -extfile <(printf "subjectAltName=DNS:${fqdn}") -days 365 \
 -in ${dirCerts}/${keycertifname}.csr \
 -CA ${dirPKI}/ca.crt -CAkey ${dirPKI}/ca.key -CAcreateserial \
 -out ${dirCerts}/${keycertifname}.crt -sha256
 rm ${dirCerts}/${keycertifname}.csr
else
 echo "le certificat serveur et la cle pour le FDQN ${fqdn} existent déjà"
 exit 1
fi

Ce qui donne :

root@srv-cs-lapi:~# ./pki.sh 
Saisir le nom du domaine : srv-cs-lapi.lab.lan
Creation AC 
Generating RSA private key, 4096 bit long modulus (2 primes)
...................................................................++++
..........................................................++++
e is 65537 (0x010001)
Enter pass phrase: SAISIR UN MOT DE PASSE
Verifying - Enter pass phrase: SAISIR DE NOUVEAU LE MOT DE PASSE
Enter pass phrase for /root/pki/CA/ca.key: SAISIR LE MOT DE PASSE PRECEDENT
************************ Creation certif serveur ******************************
Generating RSA private key, 4096 bit long modulus (2 primes)
.......................++++
..........................................................................................++++
e is 65537 (0x010001)
*********************** Generation du CSR *************************************
Generating a RSA private key
.........................+++++
..............................................+++++
writing new private key to '/root/pki/certs/srv-cs-lapi.lab.lan/srv-cs-lapi.key'
-----
*********************** Signature du CSR **************************************
Signature ok
subject=C = FR, ST = France, L = Quelque-part, O = "Maison, Inc.", CN = srv-cs-lapi.lab.lan
Getting CA Private Key
Enter pass phrase for /root/pki/CA/ca.key:SAISIR LE MOT DE PASSE PRECEDENT

root@srv-cs-lapi:~# tree pki
pki
├── CA
│   ├── ca.crt
│   ├── ca.der
│   ├── ca.key
│   └── ca.srl
└── certs
    └── srv-cs-lapi.lab.lan
        ├── srv-cs-lapi.crt
        └── srv-cs-lapi.key

3 directories, 6 files

Attention : certains sites proposent l'installation par un dépôt chez s3-eu-west-1.amazonaws.com. Ce n'est plus le dépôt officiel et vous n'obtiendrez pas les derniers paquets.

# apt install -y gnupg lsb-release apt-transport-https curl 
# curl -L https://packagecloud.io/crowdsec/crowdsec/gpgkey | apt-key add -
# echo "deb https://packagecloud.io/crowdsec/crowdsec/debian/ $(lsb_release -cs) main" | tee /etc/apt/sources.list.d/crowdsec.list > /dev/null
# apt update
# apt-get install crowdsec
# systemctl reload crowdsec
# systemctl enable crowdsec

ou bien se rendre sur https://packagecloud.io/crowdsec/crowdsec/install et utiliser le script proposé.

On vérifie que le service tourne bien :

# systemctl status crowdsec
 crowdsec.service - Crowdsec agent
   Loaded: loaded (/lib/systemd/system/crowdsec.service; enabled; vendor preset: enabled)
   Active: active (running) since Thu 2021-07-08 14:39:19 CEST; 5min ago
 Main PID: 3168 (crowdsec)
    Tasks: 13 (limit: 2358)
   Memory: 37.8M
   CGroup: /system.slice/crowdsec.service
           └─3168 /usr/bin/crowdsec -c /etc/crowdsec/config.yaml

Afin que les agents et les bouncers puissent se connecter au serveur Local API, nous allons faire écouter Crowdsec sur le réseau.

On stoppe le service crowdsec : # systemctl stop crowdsec

Ensuite on édite deux fichiers :

vim /etc/crowdsec/config.yaml :
# Au niveau du bloc "api:", remplacer 127.0.0.1 par l'IP 0.0.0.0, ce qui donne :
(...)
  server:
    log_level: info
    listen_uri: 0.0.0.0:8080
(...)

vim /etc/crowdsec/local_api_credentials.yaml
# Remplacer 127.0.0.1 par le fqdn du serveur renseigné dans lors de la génération du certificat, ce qui donne :
url: http://srv-cs-lapi.lab.lan:8080
(...)

Le FQDN doit évidemment pointer vers au moins le 127.0.0.1.

On relance le service : systemctl start crowdsec && systemctl status crowdsec

Si souci, consulter les logs dans /var/log/crowdsec.log

cp /root/pki/CA/ca.crt /usr/local/share/ca-certificates/
update-ca-certificates

mkdir /etc/crowdsec/ssl
cp pki/certs/srv-cs-lapi.lab.lan/srv-cs-lapi.{crt,key} /etc/crowdsec/ssl

Fichier config.yaml :

vim /etc/crowdsec/config.yaml :
# Décommentez les lignes suivantes et indiquez le chemin vers le certif serveur et la clé
(...)
tls:
      cert_file: /etc/crowdsec/ssl/srv-cs-lapi.crt
      key_file: /etc/crowdsec/ssl/srv-cs-lapi.key
(...)

Fichier local_api_credentials.yaml: remplacez http://srv-cs-lapi.lab.lan:8080 par https://srv-cs-lapi.lab.lan:8080

Relancez le service Crowdsec : systemctl restart crowdsec

Vérification du port d'écoute :

ss -laputen | grep 8080 | grep -i listen
tcp   LISTEN 0      128    *:8080   *:*      users:(("crowdsec",pid=5364,fd=10)) ino:25435 sk:5 v6only:0 <->

Vérification des logs :

cat /var/log/crowdsec.log 
ou 
tail -f /var/log/crowdsec.log 
ou 
journalctl -f -u crowdsec

Vérification avec la commande cscli que nous retrouverons dans le prochain article : Capture%20d%E2%80%99%C3%A9cran%20du%202021-07-08%2015-26-00

Maintenant que nous avons préparé et sécurisé le terrain, nous allons pouvoir nous amuser avec Crowdsec. Dans le prochain article, nous allons installer un serveur Nginx qui se connectera au serveur Crowdsec Local API ce qui nous permettra d'aborder l'ajout d'une machine à l'aide de la commande cscli.

Article précédent Article suivant