Le problème : CrowdSec qui bannit… mon propre accès
Sur mon OPNsense, j’utilise CrowdSec (via le plugin os-crowdsec) pour bloquer automatiquement les IP malveillantes qui scannent ou attaquent les services exposés sur mon réseau.
Problème : de temps en temps, c’est ma propre IP publique qui se fait bannir. Mon installation est la suivante :
- Box Opérateur en frontal, qui fait de la redirection de ports vers mon OPNsense,
- OPNsense derrière, qui reçoit donc le trafic avec mon IP publique dynamique comme source,
- CrowdSec qui analyse ce trafic et, en cas d’erreurs d’authentification ou de comportement suspect depuis mon propre poste (typo de mot de passe, scan de sécurité personnel, accès depuis un réseau mobile, etc.), finit par bannir cette IP.
Résultat : je me retrouve bloqué par mon propre pare-feu depuis l’extérieur. Mon IP change régulièrement (IP dynamique) — impossible donc de la whitelister une bonne fois pour toutes dans la configuration.
La solution : un petit script qui tourne sur OPNsense, détecte mon IP publique actuelle, et maintient automatiquement une whitelist CrowdSec à jour.
Le principe
Depuis la version 1.6, CrowdSec propose un mécanisme natif d’allowlists (cscli allowlists), bien plus propre qu’un fichier de whitelist parser à éditer à la main. On va donc :
- Créer une allowlist dédiée (
home-dynip), - Écrire un script qui récupère l’IP publique actuelle et compare avec la dernière connue,
- Si l’IP a changé : retirer l’ancienne de l’allowlist, ajouter la nouvelle, et lever un éventuel bannissement en cours,
- Planifier ce script via cron, toutes les 5 minutes.
Vérifiez d’abord votre version de cscli en SSH sur OPNsense :
cscli versionIl faut une version 1.6.2 ou supérieure pour disposer de la commande cscli allowlists. Testé ici avec CrowdSec 1.8.1.
Le script
Petite précision importante : si votre OPNsense est, comme le mien, derrière une box qui fait le NAT (double NAT), l’IP de l’interface WAN d’OPNsense n’est pas votre IP publique réelle. Il faut donc la demander à un service externe (ifconfig.me, api.ipify.org…), avec plusieurs services en secours au cas où l’un serait indisponible.
Créez le fichier /usr/local/bin/crowdsec-whitelist-myip.sh :
#!/bin/sh
# Auto-whitelist this OPNsense's current dynamic public IP
# in CrowdSec, so CrowdSec never bans your own home IP again.
ALLOWLIST="home-dynip"
STATE_FILE="/var/db/crowdsec-whitelist-myip.state"
LOG_TAG="crowdsec-whitelist-myip"
CSCLI="/usr/local/bin/cscli"
JQ="/usr/local/bin/jq"
log() {
logger -t "$LOG_TAG" "$1"
}
get_public_ip() {
for url in https://api.ipify.org https://ifconfig.me https://ipv4.icanhazip.com; do
ip=$(curl -s -4 --max-time 5 "$url" 2>/dev/null | tr -d '[:space:]')
case "$ip" in
[0-9]*.[0-9]*.[0-9]*.[0-9]*)
echo "$ip"
return 0
;;
esac
done
return 1
}
CURRENT_IP=$(get_public_ip)
if [ -z "$CURRENT_IP" ]; then
log "ERROR: unable to determine current public IP, aborting"
exit 1
fi
# Crée l'allowlist si elle n'existe pas encore (appel peu coûteux, à chaque run)
if ! "$CSCLI" allowlists list -o json 2>/dev/null | "$JQ" -e --arg n "$ALLOWLIST" 'any(.[]; .name == $n)' >/dev/null 2>&1; then
"$CSCLI" allowlists create "$ALLOWLIST" -d "Dynamic public IP - auto-managed, do not edit by hand" >/dev/null 2>&1
log "Created allowlist '$ALLOWLIST'"
fi
OLD_IP=""
[ -f "$STATE_FILE" ] && OLD_IP=$(cat "$STATE_FILE" 2>/dev/null)
if [ "$CURRENT_IP" = "$OLD_IP" ]; then
# Rien n'a changé, mais on vérifie que l'entrée est toujours bien présente
# (au cas où quelqu'un aurait vidé l'allowlist à la main).
if ! "$CSCLI" allowlists inspect "$ALLOWLIST" -o json 2>/dev/null | "$JQ" -e --arg ip "$CURRENT_IP" 'any(.items[]?; .value == $ip)' >/dev/null 2>&1; then
"$CSCLI" allowlists add "$ALLOWLIST" "$CURRENT_IP" -d "auto re-added $(date '+%Y-%m-%d %H:%M:%S')" >/dev/null 2>&1
log "Re-added missing IP $CURRENT_IP to '$ALLOWLIST'"
fi
exit 0
fi
if [ -n "$OLD_IP" ]; then
"$CSCLI" allowlists remove "$ALLOWLIST" "$OLD_IP" >/dev/null 2>&1
log "Removed stale IP $OLD_IP from '$ALLOWLIST'"
fi
"$CSCLI" allowlists add "$ALLOWLIST" "$CURRENT_IP" -d "auto-updated $(date '+%Y-%m-%d %H:%M:%S')" >/dev/null 2>&1
# Lève un éventuel ban déjà en place sur la nouvelle IP
"$CSCLI" decisions delete -i "$CURRENT_IP" >/dev/null 2>&1
echo "$CURRENT_IP" >"$STATE_FILE"
log "Whitelisted new public IP $CURRENT_IP (previous: ${OLD_IP:-none})"
Rendez-le exécutable :
chmod +x /usr/local/bin/crowdsec-whitelist-myip.shPlanification via cron
Sur OPNsense, plutôt que d’utiliser crontab -e (qui peut être écrasé par la synchronisation de configuration de l’interface web), on dépose un fichier dédié dans /usr/local/etc/cron.d/. C’est l’emplacement officiellement supporté pour des tâches cron « faites main », qui ne sera pas touché par OPNsense.
Créez /usr/local/etc/cron.d/whitelist-myip.cron :
SHELL=/bin/sh
PATH=/etc:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin
#minute hour mday month wday who command
*/5 * * * * root /usr/local/bin/crowdsec-whitelist-myip.sh
Puis relancez le service cron pour qu’il prenne en compte le nouveau fichier :
service cron restartTest
Lancez le script une première fois à la main pour vérifier que tout fonctionne :
/usr/local/bin/crowdsec-whitelist-myip.sh
cat /var/db/crowdsec-whitelist-myip.state
cscli allowlists inspect home-dynipVous devriez voir votre IP publique actuelle listée dans l’allowlist home-dynip, avec un commentaire horodaté. Relancez le script une seconde fois : comme l’IP n’a pas changé, il ne doit rien modifier (pas de doublon, pas de log superflu) — c’est le comportement attendu, le script est idempotent.
Pour aller plus loin
- Fréquence : 5 minutes est un bon compromis. Si votre IP change très rarement, vous pouvez espacer davantage (par exemple toutes les 15 minutes).
- Logs : le script écrit dans le syslog via
logger -t crowdsec-whitelist-myip, consultable depuis l’interface OPNsense (Journal système > Général) ou en ligne de commande. - Double NAT : si votre OPNsense est directement exposé sur l’IP publique (pas de box devant), vous pouvez simplifier le script en lisant directement l’IP de l’interface WAN plutôt que d’interroger un service externe.
- Sécurité : cette allowlist ne désactive pas CrowdSec pour votre IP vis-à-vis des autres scénarios de détection critiques si vous configurez l’allowlist avec une portée plus fine ; ici on part du principe que l’on fait confiance à son propre réseau domestique.
