De la cybersécurité: les bots qui vous spamment au 404-flood

Il y a peu de temps je vous parlais du renforcement de la sécurité de ce serveur.

Cependant, mes rapports Crowdsec croulaient sous les alertes, difficile de se repérer là dedans, d’autant plus que ça impliquait : ralentissement des serveurs, spam des logs etc etc etc … ça m’a quelque peu irritée.

Ne serait-ce qu’aujourd’hui. 42 requêtes en 404 depuis la même IP en quelques heures. En creusant un peu, j’ai réalisé que mon serveur était en train de se faire scanner méthodiquement par des bots automatisés qui cherchaient des failles connues. Pas une attaque ciblée contre moi — juste des robots qui balayent internet en masse à la recherche de portes mal fermées.

Dans cet article, je vous explique comment j’ai identifié le problème, et surtout comment j’ai blindé mon serveur Apache étape par étape.

C’est quoi exactement ces bots ?

Avant de se défendre, il faut comprendre à quoi on a affaire. Ces bots font ce qu’on appelle du HTTP probing (ou fingerprinting) : ils envoient des requêtes HTTP à des chemins connus pour détecter quels logiciels tournent sur votre serveur.

Par exemple, si votre serveur répond 200 OK à une requête sur /+CSCOE+/logon.html, le bot sait que vous avez Cisco AnyConnect installé. Il peut alors exploiter les failles connues de ce logiciel.

Voici quelques exemples de chemins que les bots testent systématiquement :

/.env # Variables d'environnement (mots de passe !)
/.git/config # Configuration Git exposée
/.vscode/sftp.json # Identifiants FTP de votre éditeur
/wp-admin/ # Interface admin WordPress
/phpinfo.php # Infos système PHP
/boaform/admin/formLogin # Routeurs ADSL
/Orion/Login.aspx # SolarWinds Orion
/global-protect/login.esp # Palo Alto GlobalProtect

La bonne nouvelle : si vous n’avez pas ces logiciels, les bots repartent bredouilles. La mauvaise : chaque requête consomme des ressources et pollue vos logs.

Étape 1 — Identifier ce qui se passe

Commencez par regarder qui génère le plus de 404 sur votre serveur :

grep " 404 " /var/log/apache2/access.log | awk '{print $1}' | sort | uniq -c | sort -rn | head -20

Et quels chemins sont ciblés :

grep " 404 " /var/log/apache2/access.log | awk '{print $7}' | sort | uniq -c | sort -rn | head -20

Pour identifier un pays depuis une IP suspecte :

whois 72.14.186.247 | grep -i "^country:" | head -1

Étape 2 — Bloquer les chemins sensibles dans Apache

La première ligne de défense, c’est de faire répondre Apache 403 Forbidden directement sur les chemins suspects, sans même solliciter PHP ou votre application.

Créez le fichier /etc/apache2/conf-available/block-scanners.conf :

<LocationMatch "(?i)(.env|.git|.ftpconfig|.vscode|.idea|phpinfo.php|boaform|solr|RASHTML5|AnyConnect|GlobalProtect|Orion|dana-na|sftp.json|ftp-sync.json|WebServers.xml|deployment-config.json|remote-sync.json|/backend|phpmyadmin|pma|adminer|webmin|cpanel|plesk)">
Require all denied
</LocationMatch>

Activez-la :

a2enconf block-scanners
apache2ctl configtest && systemctl reload apache2

Vérifiez que ça fonctionne :

curl -s -o /dev/null -w "%{http_code}" http://localhost/.env
# Doit retourner 403

Étape 3 — Bloquer les User-Agents de scanners connus

Certains outils de scan s’identifient clairement dans leur User-Agent. Autant en profiter pour les bloquer directement.

Créez /etc/apache2/conf-available/block-useragents.conf :

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{HTTP_USER_AGENT} (zgrab|python-httpx|Go-http-client|Odin|ForestEngine|visionheight|crawler|scanner) [NC]
    RewriteRule .* - [F,L]
</IfModule>
a2enconf block-useragents
apache2ctl configtest && systemctl reload apache2

Note : Certains bots imitent de vrais navigateurs (Chrome, Firefox avec des versions très anciennes). On ne peut pas tous les attraper comme ça, mais ça élimine déjà les moins sophistiqués.


Étape 4 — Configurer Fail2ban pour bannir les récidivistes

Fail2ban surveille vos logs et bannit automatiquement les IPs qui dépassent un certain seuil d’erreurs. C’est votre filet de sécurité pour tout ce qui passe à travers les règles Apache.

Si vous ne l’avez pas encore :

apt install fail2ban ipset -y

Créez le filtre /etc/fail2ban/filter.d/apache-404flood.conf :

[Definition]
failregex = ^<HOST> .* "(GET|POST|HEAD) .* HTTP/.*" 404
ignoreregex =

Créez la jail dans /etc/fail2ban/jail.d/apache-bots.conf :

[apache-404flood]
enabled   = true
port      = http,https
filter    = apache-404flood
logpath   = /var/log/apache2/access.log
maxretry  = 10
findtime  = 600
bantime   = 604800
action    = iptables-ipset-proto6-allports

Quelques explications sur les paramètres :

  • findtime = 600 : fenêtre de 10 minutes (pas 30 secondes !) — les bots sophistiqués espacent volontairement leurs requêtes pour passer sous les radars
  • bantime = 604800 : 7 jours de ban — suffisamment dissuasif
  • iptables-ipset-proto6-allports : utilise ipset (tables de hachage kernel) plutôt qu’iptables classique, bien plus performant avec des milliers d’IPs bannies
systemctl restart fail2ban
fail2ban-client status apache-404flood

Étape 5 — Géoblocage via Apache

Si vous constatez que la majorité des attaques viennent de certains pays, vous pouvez les bloquer en amont. Mon kernel OVH ne supporte pas les modules iptables géographiques, donc j’utilise Apache directement avec des listes CIDR.

Créez le script /usr/local/bin/block-countries-apache.sh :

#!/bin/bash
COUNTRIES="ru cn kp jp"
OUTFILE="/etc/apache2/conf-available/block-countries.conf"
TMPDIR=$(mktemp -d)
 
echo "# Géoblocage — généré le $(date)" > "$OUTFILE"
echo "<Location />" >> "$OUTFILE"
echo "    <RequireAll>" >> "$OUTFILE"
echo "        Require all granted" >> "$OUTFILE"
 
for CC in $COUNTRIES; do
    curl -sL "https://www.ipdeny.com/ipblocks/data/aggregated/${CC}-aggregated.zone" -o "$TMPDIR/$CC.zone"
    while IFS= read -r CIDR; do
        [[ -z "$CIDR" || "$CIDR" == "#"* ]] && continue
        echo "        Require not ip $CIDR" >> "$OUTFILE"
    done < "$TMPDIR/$CC.zone"
done
 
echo "    </RequireAll>" >> "$OUTFILE"
echo "</Location>" >> "$OUTFILE"
rm -rf "$TMPDIR"
chmod +x /usr/local/bin/block-countries-apache.sh
/usr/local/bin/block-countries-apache.sh
a2enconf block-countries
apache2ctl configtest && systemctl reload apache2

Automatisez la mise à jour hebdomadaire (les plages IP changent) :

# Dans crontab -e :
0 3 * * 0 /usr/local/bin/block-countries-apache.sh &amp;&amp; systemctl reload apache2

Étape 6 — Bloquer les hébergeurs abusifs

Une surprise de mes investigations : les attaques viennent de moins en moins de pays asiatiques, et de plus en plus de clouds commerciaux (AWS, DigitalOcean). Les attaquants louent des VPS à quelques euros par mois pour lancer leurs scans.

AWS publie officiellement ses plages d’IPs. On peut les bloquer de la même façon :

#!/bin/bash
OUTFILE="/etc/apache2/conf-available/block-hosters.conf"
TMPDIR=$(mktemp -d)
 
echo "<Location />" > "$OUTFILE"
echo "    <RequireAll>" >> "$OUTFILE"
echo "        Require all granted" >> "$OUTFILE"
 
# AWS EC2
curl -s https://ip-ranges.amazonaws.com/ip-ranges.json | python3 -c "
import json,sys
data=json.load(sys.stdin)
prefixes=[p['ip_prefix'] for p in data['prefixes'] if p['service']=='EC2']
print('\n'.join(prefixes))
" > "$TMPDIR/aws.txt"
 
while IFS= read -r CIDR; do
    [[ -z "$CIDR" ]] && continue
    echo "        Require not ip $CIDR" >> "$OUTFILE"
done < "$TMPDIR/aws.txt"
 
echo "    </RequireAll>" >> "$OUTFILE"
echo "</Location>" >> "$OUTFILE"
rm -rf "$TMPDIR"

Attention : Ne bloquez pas Google Cloud si vous voulez que Googlebot indexe vos sites.


Bilan

Après cette soirée de travail, voici l’état de mon serveur :

ProtectionRôle
block-scanners.confPaths suspects → 403 immédiat
block-useragents.confScanners connus → 403 immédiat
block-countries.confRU/CN/KP/JP → 403
block-hosters.confAWS EC2 + DigitalOcean → 403
Fail2banBan automatique 7 jours des récidivistes
CrowdSecBlacklists communautaires temps réel
NetdataSurveillance réseau en amont

Le tout sans toucher au kernel, sans CDN tiers, et en gardant le contrôle complet sur mon infrastructure.


Ce qu’il faut retenir

Les bots qui scannent internet ne vous ciblent pas personnellement — ils balayent des millions d’adresses IP en continu. L’objectif n’est pas de les arrêter (c’est impossible), c’est de rendre votre serveur inintéressant : pas de chemins sensibles exposés, pas de réponse utile, ban rapide en cas d’insistance.

Avec ces quelques configurations, la majorité des scans opportunistes se heurtent à un mur avant même d’avoir pu glaner la moindre information.