Aller au contenu principal
~/GiwiSoft
Qtr50fqtr50fqtr5

Sécuriser un serveur auto-hébergé avec Tailscale et CrowdSec

Giwi 4 min de lecture DevOps, Infrastructure

Héberger ses propres services expose nécessairement des ports sur Internet. Chaque port ouvert est une surface d’attaque potentielle. Les logs de mon serveur montraient des tentatives de connexion SSH, des scans de ports, des bots qui cherchaient des failles WordPress, alors que je n’ai jamais eu WordPress.

J’ai mis en place deux lignes de défense complémentaires : Tailscale pour le réseau privé et CrowdSec pour la détection d’intrusion.

Tailscale : un VPN maillé simplissime

Tailscale crée un réseau privé maillé (WireGuard) entre vos appareils. Plus besoin d’ouvrir des ports : vos services ne sont accessibles que depuis votre réseau Tailscale.

Installation

curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up

Un lien s’affiche, on l’ouvre dans le navigateur, on s’authentifie avec son compte (Google, GitHub, Microsoft). C’est tout. Plus de configuration de clés, plus de ports à ouvrir.

Architecture avec Tailscale

6v5j396v5j396v5j.png

J’expose uniquement mon blog au public. Tous les autres services (monitoring, analytics, Ollama, bases de données) ne sont accessibles que via l’IP Tailscale.

Tags et ACLs

Tailscale permet de contrôler finement les accès :

{
"acls": [
// Mon poste principal accède à tout
{ "action": "accept", "src": ["tag:admin"], "dst": ["*:*"] },
// Le serveur ne peut pas initier de connexion
{ "action": "accept", "src": ["tag:server"], "dst": ["tag:admin:*"] },
// Mon téléphone : seulement le monitoring
{ "action": "accept", "src": ["tag:phone"], "dst": ["tag:server:8090"] }
],
"tagOwners": {
"tag:admin": ["xavier@exemple.com"],
"tag:server": ["xavier@exemple.com"],
"tag:phone": ["xavier@exemple.com"]
}
}

Résultat : même si un attaquant trouve un moyen d’accéder au serveur, il ne pourra pas pivoter vers les autres machines du Tailnet.

CrowdSec : la détection d’intrusion communautaire

CrowdSec analyse les logs de votre serveur pour détecter les comportements malveillants et bannir automatiquement les IPs suspectes. La force du projet, c’est sa communauté : quand mon serveur détecte une attaque, l’IP est partagée et tous les autres membres CrowdSec sont protégés.

Installation avec Docker

crowdsec:
image: crowdsecurity/crowdsec:latest
volumes:
- ./crowdsec/config:/etc/crowdsec
- ./crowdsec/data:/var/lib/crowdsec/data
- /var/log/auth.log:/var/log/auth.log:ro
- /var/log/nginx:/var/log/nginx:ro
environment:
- COLLECTIONS=crowdsecurity/linux crowdsecurity/nginx crowdsecurity/sshd
restart: unless-stopped

Bouncer Nginx

Le bouncer est le composant qui applique les décisions (bannir une IP). Pour Nginx :

crowdsec-bouncer:
image: crowdsecurity/crowdsec:latest
command: "crowdsec-bouncer"
volumes:
- ./crowdsec/bouncer.yaml:/etc/crowdsec/bouncer.yaml
# bouncer.yaml
type: nginx
mode: live
update_frequency: 10s
# nginx.conf
location / {
# Transmission de l'IP réelle
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

# CrowdSec Bouncer (via Lua ou API)
# Bloque automatiquement les IPs malveillantes
access_by_lua_file /etc/nginx/crowdsec.lua;
}

Avec Traefik

Si vous utilisez Traefik, le bouncer est aussi disponible :

labels:
- "traefik.http.middlewares.crowdsec.plugin.crowdsec.enabled=true"

Scénarios activés

CrowdSec utilise des scénarios prédéfinis pour détecter différents types d’attaques :

# /etc/crowdsec/config.yaml
collections:
- crowdsecurity/linux
- crowdsecurity/nginx
- crowdsecurity/sshd
- crowdsecurity/http-cve
- crowdsecurity/http-probing

scenarios:
- crowdsecurity/http-brute-force
- crowdsecurity/ssh-brute-force
- crowdsecurity/http-scan-uniques

Visualisation avec Metabase

CrowdSec peut envoyer ses métriques vers une base de données, consultable via Metabase :

crowdsec:
environment:
- DSN=postgres://user:password@postgres/crowdsec

Je peux ainsi voir les IPs bloquées, le nombre d’attaques détectées par pays, les scénarios les plus actifs. Bref, des statistiques fascinantes (et un peu flippantes).

La combinaison gagnante

Tailscale et CrowdSec sont complémentaires :

Protection Tailscale CrowdSec
Réseau privé Oui (VPN maillé) Non
Détection d’intrusion Non Oui (analyse de logs)
Blocage IP Non Oui (bouncer)
Communauté Non Oui (base de donnée partagée)
Exposition de ports Minimale Inutile si Tailscale
Protection SSH Oui (pas de port exposé) Oui (détection brute-force)

Architecture finale

Mon serveur expose uniquement le port 443 (HTTPS) via Traefik :

pba6i7pba6i7pba6.png

Tous les services internes ne sont accessibles que depuis l’IP Tailscale. CrowdSec protège l’entrée publique (le blog) contre les attaques. Même en cas de faille sur le blog, les services internes restent inaccessibles sans être connecté au Tailnet.

Conclusion

Tailscale a transformé ma façon de gérer mon serveur : plus de ports à ouvrir dans le firewall, plus de certificats VPN à gérer, une configuration réseau qui tient en une commande. CrowdSec ajoute une couche de sécurité active qui manquait à ma stack.

Depuis leur installation, mon serveur est passé de “visible par tout le monde” à “visible uniquement par moi”. Les tentatives d’intrusion dans les logs ont chuté de 100%, et je dors mieux.

Et vous, comment sécurisez-vous votre serveur auto-hébergé ?