Comment arrêter un serveur qui envoie du spam
Dernière mise à jour:
Le premier signe est rarement le spam lui-même. C'est un e-mail d'abus de l'hébergeur, un client dont les factures arrivent dans les indésirables, des rebonds que vous n'avez jamais envoyés, ou une file d'attente de dix mille messages. À ce stade, l'adresse du serveur est en général déjà sur une liste noire, et tous les e-mails légitimes qui en partent en pâtissent aussi.
Le spam sort d'un serveur de trois façons : une boîte mail dont le mot de passe a été deviné ou volé, un script PHP (une extension piratée ou un formulaire de contact détourné) qui appelle mail(), ou un programme qui parle SMTP directement aux autres serveurs. Les étapes ci-dessous trouvent laquelle, l'arrêtent, nettoient, ferment la brèche et sortent l'adresse des listes. Les commandes sont pour Postfix et Exim sur Debian, Ubuntu et la famille RHEL ; spammer@example.com, QUEUE_ID et 203.0.113.10 désignent ce que vous trouvez.
Vérifier si le serveur envoie du spam
Commencez par la file d'attente du courrier. Un serveur sain a une poignée de messages en attente, souvent aucun. Des milliers de messages, ou un expéditeur qui en possède la plupart, signifient du spam. La deuxième commande liste les expéditeurs qui ont le plus de messages en file.
sudo postqueue -p | tail -n 1
sudo postqueue -p | awk '/^[0-9A-Za-z]/ {print $7}' | sort | uniq -c | sort -rn | headExim, comme sur cPanel et avec le exim4 de Debian (la commande exim existe aussi), compte la file avec exim -bpc. Les lignes suivantes listent les principaux expéditeurs et les principaux domaines de destination :
sudo exim -bpc
sudo exim -bp | awk '/^ *[0-9]+[mhd] / {print $4}' | sort | uniq -c | sort -rn | head
sudo exim -bp | exiqsumm | sort -rn | headUn expéditeur <> ou MAILER-DAEMON est un rebond. Une file pleine de rebonds signifie que le serveur a accepté ou envoyé du courrier vers des adresses qui n'existent pas : typique d'un spam parti d'ici, ou du backscatter d'un formulaire qui envoie une copie à n'importe quelle adresse saisie.
Quel compte envoie
Le spam envoyé par une boîte mail apparaît comme un utilisateur authentifié avec bien plus de messages que les autres. Postfix l'enregistre sous sasl_username, dans les fichiers de log ou, sans rsyslog, dans le journal :
sudo sh -c "zgrep -h -o 'sasl_username=[^ ,]*' /var/log/mail.log* /var/log/maillog* 2>/dev/null" \
| sort | uniq -c | sort -rn | head
sudo journalctl --since "24 hours ago" -t postfix/smtpd | grep -o 'sasl_username=[^ ,]*' \
| sort | uniq -c | sort -rn | headExim enregistre la connexion sous A= pour chaque message accepté, et le dossier du script sous cwd= pour le courrier soumis localement (cPanel l'enregistre par défaut). Un cwd= à l'intérieur d'un site, comme /home/user/public_html/wp-content/…, désigne le script :
sudo grep -h ' <= ' /var/log/exim_mainlog /var/log/exim4/mainlog 2>/dev/null \
| grep -o ' A=[^ ]*' | sort | uniq -c | sort -rn | head
sudo grep -h -o 'cwd=[^ ]*' /var/log/exim_mainlog /var/log/exim4/mainlog 2>/dev/null \
| sort | uniq -c | sort -rn | headQuel script PHP envoie
Le courrier envoyé par la fonction mail() de PHP passe par le sendmail local et ne s'authentifie pas : il n'a donc pas d'utilisateur. Lisez les en-têtes d'un message en file : avec mail.add_x_header activé, PHP ajoute X-PHP-Originating-Script, l'identifiant utilisateur et le nom de fichier du script.
sudo postcat -hq QUEUE_ID | grep -iE '^(From|To|Subject|X-PHP-Originating-Script):'
sudo exim -Mvh QUEUE_ID | grep -iE '(From|To|Subject|X-PHP-Originating-Script):'Si l'en-tête n'y est pas, activez-le, et faites journaliser par PHP chaque appel à mail() avec le chemin complet et la ligne du script. Trouvez le php.ini qu'utilise votre serveur web (PHP-FPM a le sien sur Debian et Ubuntu) :
php --ini | grep 'Loaded Configuration'
ls /etc/php/*/fpm/php.ini /etc/php.ini 2>/dev/nullmail.add_x_header = On
mail.log = syslogRedémarrez PHP-FPM ou le serveur web (sudo systemctl restart php8.3-fpm, php-fpm ou httpd, selon le système), attendez quelques minutes et lisez le journal :
sudo journalctl --since "1 hour ago" | grep 'mail() on' | tail -n 20
sudo grep -h 'mail() on' /var/log/syslog /var/log/messages 2>/dev/null | tail -n 20Les programmes qui parlent SMTP directement
Certains outils de spam contournent le serveur de messagerie et se connectent eux-mêmes au port 25 des serveurs des destinataires : ils ne laissent donc rien dans la file. Regardez les connexions SMTP sortantes et les programmes auxquels elles appartiennent. Votre serveur de messagerie (master/smtp pour Postfix, exim) est normal ; php, perl, python ou un nom aléatoire ne l'est pas.
sudo ss -tnp state established '( dport = :25 or dport = :465 or dport = :587 )'
sudo ss -tnp state established '( dport = :25 )' | grep -o 'users:(("[^"]*"' | sort | uniq -c | sort -rnArrêter le spam tout de suite
Arrêtez d'abord la source, puis la file. Pour une boîte mail, changez son mot de passe dans votre panel ou votre système de messagerie et fermez ses sessions. Pour un script, gardez-en une copie comme preuve et rendez-le illisible, pour que le serveur web ne puisse plus l'exécuter :
sudo mkdir -p /root/evidence
sudo cp -p /path/to/script.php /root/evidence/
sudo chmod 000 /path/to/script.phpPour un processus qui parle SMTP directement, trouvez son PID dans la sortie de ss ci-dessus, vérifiez d'où il vient et arrêtez-le comme dans le guide sur les crypto-mineurs : c'est un malware, et il a sa propre persistance.
Pendant le nettoyage, empêchez la file de partir. Avec Postfix, defer_transports retient tout ce qui doit être livré à distance et continue d'accepter le nouveau courrier : rien n'est perdu.
sudo postconf -e 'defer_transports = smtp'
sudo postfix reloadQuand la file est propre (étape suivante), relâchez-la :
sudo postconf -e 'defer_transports ='
sudo postfix reload
sudo postqueue -fAvec Exim, gelez les messages de l'expéditeur trouvé. Les messages gelés restent dans la file et ne sont pas livrés :
sudo exiqgrep -i -f 'spammer@example\.com' | xargs -r sudo exim -MfAttention: Tant que la livraison à distance est suspendue, le courrier légitime attend aussi. Ne la laissez pas suspendue plus de quelques heures : passé la durée de vie de la file (5 jours par défaut dans Postfix), les messages en attente reviennent en rebond.
Nettoyer la file d'attente
Supprimez le spam par expéditeur, et les rebonds avec, pour que les messages légitimes de la file restent. Relancez d'abord l'étape 1 pour être sûr de l'adresse de l'expéditeur.
sudo postqueue -p | awk '/^[0-9A-Za-z]/ && $7 == "spammer@example.com" {sub(/[*!]$/, "", $1); print $1}' \
| sudo postsuper -d -
sudo postqueue -p | awk '/^[0-9A-Za-z]/ && $7 == "MAILER-DAEMON" {sub(/[*!]$/, "", $1); print $1}' \
| sudo postsuper -d -Avec Exim, la première ligne supprime les messages de l'expéditeur, la seconde les messages gelés, qui après un spam sont surtout des rebonds :
sudo exiqgrep -i -f 'spammer@example\.com' | xargs -r sudo exim -Mrm
sudo exiqgrep -z -i | xargs -r sudo exim -MrmAttention: postsuper -d ALL et la suppression de toute la file Exim effacent aussi les messages légitimes, et un message supprimé ne se récupère pas. Supprimez par expéditeur, sauf si la file ne contient rien d'autre.
Comptez à nouveau la file. Si elle se remplit encore, la source est toujours active : revenez à l'étape 1.
Trouver par où le spam est sorti
Changer un mot de passe ou supprimer un script arrête cette vague. La suivante commence si vous ne savez pas comment tout a démarré.
Une boîte mail compromise
Une boîte mail utilisée par un spammeur se connecte depuis de nombreuses adresses, souvent dans de nombreux pays, parfois des milliers en une journée. Comptez les adresses qui l'ont utilisée :
sudo sh -c "zgrep -h 'user@example.com' /var/log/mail.log* /var/log/maillog* /var/log/exim_mainlog* /var/log/exim4/mainlog* 2>/dev/null" \
| grep -oE '\[[0-9]{1,3}(\.[0-9]{1,3}){3}\]' | sort | uniq -c | sort -rn | head -20Le mot de passe a été deviné (cherchez de nombreux échecs de connexion sur cette boîte avant la première réussite) ou volé sur l'ordinateur de l'utilisateur ou sur un autre site. Choisissez un nouveau mot de passe long, et vérifiez toutes les autres boîtes dont le mot de passe est faible.
Un script PHP
Un script qui envoie tout ce qu'une requête lui demande est soit un malware déposé par une faille, soit un formulaire légitime sans protection. Cherchez les scripts d'envoi et les fichiers PHP modifiés récemment dans les sites :
sudo grep -rlE 'mail\s*\(\s*\$_(POST|GET|REQUEST)|LeafMailer|eval\s*\(\s*base64_decode' \
--include='*.php' /var/www /home 2>/dev/null | head -50
sudo find /var/www /home -name '*.php' -type f -mtime -7 2>/dev/null | head -50Puis regardez qui a appelé le script, et à quelle fréquence. Un formulaire de contact envoyé des milliers de fois par quelques adresses est détourné ; un fichier que personne ne devrait connaître, appelé par de nombreuses adresses, est une porte dérobée.
sudo sh -c "grep -hI 'POST /path/to/script.php' /var/log/nginx/*access*.log /var/log/apache2/*access*.log /var/log/httpd/*access_log 2>/dev/null" \
| awk '{print $1}' | sort | uniq -c | sort -rn | head- Un script malveillant : supprimez-le, puis trouvez comment il a été déposé (une extension ou un thème obsolète, un mot de passe administrateur faible, un formulaire d'upload) et fermez cette porte. Le guide sur les crypto-mineurs montre comment chercher le reste de ce que laisse un attaquant.
- Un formulaire détourné : ajoutez un CAPTCHA ou un champ caché que les robots remplissent, ne laissez jamais le visiteur choisir le destinataire, et n'envoyez pas de copie à l'adresse saisie dans le formulaire.
Un relais ouvert
Plus rare aujourd'hui, mais vérifiez-le : un serveur de messagerie qui livre le courrier de n'importe qui vers n'importe qui. Dans Postfix, mynetworks ne doit contenir que le serveur lui-même et vos propres réseaux, et les restrictions de relais doivent se terminer par reject_unauth_destination :
postconf mynetworks smtpd_relay_restrictions smtpd_recipient_restrictionsEmpêcher que cela recommence
SPF, DKIM et DMARC
Ces trois enregistrements DNS indiquent aux autres serveurs de messagerie quels serveurs peuvent envoyer pour votre domaine et si un message vient vraiment de vous. Ils n'empêchent pas une boîte piratée d'envoyer du spam via votre serveur, mais ils empêchent les autres d'usurper votre domaine, et les grands fournisseurs les exigent désormais avant de livrer votre courrier. Un exemple pour un domaine dont le courrier part de 203.0.113.10 :
example.com. TXT "v=spf1 mx ip4:203.0.113.10 -all"
_dmarc.example.com. TXT "v=DMARC1; p=quarantine; rua=mailto:dmarc@example.com"DKIM nécessite une clé sur le serveur de messagerie (OpenDKIM pour Postfix, intégré à Exim ; des panels comme cPanel et Plesk s'en chargent pour vous) et sa partie publique dans le DNS. Vérifiez ce qui est publié :
dig +short TXT example.com
dig +short TXT _dmarc.example.com
dig +short TXT default._domainkey.example.comRemarque: dig se trouve dans le paquet dnsutils sur Debian et Ubuntu (bind9-dnsutils sur les versions récentes) et dans bind-utils sur la famille RHEL. Le sélecteur DKIM, ici default, dépend de votre configuration.
Limites d'envoi
Une limite transforme un compte compromis qui enverrait cent mille messages en quelques centaines. Postfix limite les messages par adresse client ; le courrier que PHP envoie par sendmail n'y passe pas, et les limites par utilisateur demandent un service de politique comme postfwd.
sudo postconf -e 'smtpd_client_message_rate_limit = 100' 'anvil_rate_time_unit = 3600s'
sudo postfix reloadExim peut limiter chaque utilisateur authentifié dans son ACL RCPT. Sur cPanel, utilisez plutôt **Max hourly emails per domain** dans les Tweak Settings de WHM.
# In the RCPT ACL (acl_check_rcpt), before the accept for authenticated users
deny authenticated = *
ratelimit = 200 / 1h / strict / per_rcpt / $authenticated_id
message = Sending rate limit exceededSeul le serveur de messagerie utilise le port 25
Sur un serveur web, rien d'autre que le serveur de messagerie n'a besoin de se connecter au port 25 d'autres serveurs. Cette règle nftables refuse les connexions sortantes vers le port 25 de tous les autres utilisateurs, ce qui arrête les scripts et malwares qui parlent SMTP directement. Remplacez postfix par l'utilisateur de votre serveur de messagerie : Debian-exim pour Exim sur Debian et Ubuntu, exim sur la famille RHEL, mailnull sur cPanel.
sudo nft add table inet smtpguard
sudo nft 'add chain inet smtpguard out { type filter hook output priority 0; policy accept; }'
sudo nft add rule inet smtpguard out tcp dport 25 meta skuid != { root, postfix } rejectAttention: Ne vous trompez pas de nom d'utilisateur : avec le mauvais, le serveur ne livre plus aucun courrier. Les applications qui envoient via un serveur SMTP externe sur le port 25 s'arrêtent aussi ; elles devraient de toute façon utiliser le 587 avec authentification. La table disparaît au redémarrage : une fois qu'elle fonctionne, ajoutez-la à la configuration de votre pare-feu. Sur cPanel, **SMTP Restrictions** dans WHM fait la même chose.
Beaucoup de fournisseurs cloud bloquent le port 25 sortant par défaut et l'ouvrent sur demande. Si vous n'envoyez pas du tout de courrier depuis le serveur, laissez-le bloqué et passez par un service de relais sur le 587.
Et le durcissement habituel
- Tenez WordPress, les extensions et les thèmes à jour, et supprimez ceux que vous n'utilisez pas.
- Protégez les connexions mail contre la force brute comme pour SSH : voir Comment stopper les attaques par force brute SSH.
- Gardez
mail.add_x_headeretmail.logactivés : la prochaine fois, le script sera connu en quelques secondes.
Sortir le serveur des listes noires
Ne demandez le retrait qu'une fois le spam arrêté et la cause corrigée : un serveur qui revient sur une liste juste après son retrait est traité plus sévèrement la seconde fois. Vérifiez les principales listes par DNS, avec l'adresse publique du serveur dans IP :
IP=203.0.113.10
REV=$(echo "$IP" | awk -F. '{print $4"."$3"."$2"."$1}')
for bl in zen.spamhaus.org bl.spamcop.net; do echo "$bl: $(dig +short "$REV.$bl" A)"; done
dig +short -x "$IP"Une réponse vide signifie non listé ; une adresse comme 127.0.0.2 signifie listé. Spamhaus refuse les requêtes envoyées via des résolveurs publics et y répond 127.255.255.254 : dans ce cas, utilisez son site. La dernière ligne affiche le DNS inverse (PTR) de l'adresse, qui doit être un nom d'hôte qui résout à nouveau vers elle.
- Spamhaus : cherchez l'adresse sur check.spamhaus.org, qui explique chaque inscription et comment demander le retrait.
- SpamCop : les inscriptions expirent d'elles-mêmes une fois les signalements arrêtés (spamcop.net).
- Microsoft (Outlook, Hotmail) : demandez le retrait sur sender.office.com.
- Gmail : pas de formulaire de retrait ; Postmaster Tools montre la réputation de votre domaine pendant qu'elle se rétablit.
Remarque: Procédures en vigueur en novembre 2026, d'après les pages des listes elles-mêmes. Le rétablissement prend des jours, pas des heures : la réputation auprès des grands fournisseurs ne s'améliore que si vous continuez à envoyer un courrier propre.
Ce que fait InfraFence contre le spam envoyé par votre serveur
InfraFence agit sur les causes plus que sur le courrier lui-même :
- Force brute sur la messagerie : l'agent lit les logs de Postfix, Exim, Dovecot et Roundcube (ou le journal systemd) et bannit une adresse après 5 échecs de connexion ou tentatives de relais en 5 minutes, sur SMTP, submission, IMAP, POP3 et le webmail. Chaque événement indique la boîte mail visée. Voir SSH et force brute.
- Scripts d'envoi : le scanner de malwares a des signatures pour les scripts PHP qui envoient ce qu'une requête demande (
mail()alimenté directement par$_POST, LeafMailer), les web shells et les portes dérobées, des règles YARA, et signale les fichiers PHP créés dans les dossiers d'upload. Avec les analyses automatiques activées, les nouveaux fichiers PHP des dossiers d'upload sont analysés en 30 secondes. Voir Malware. - Menaces sortantes : les connexions du serveur vers des adresses des listes Spamhaus DROP et Emerging Threats sont signalées comme critiques. Voir Menaces sortantes et DNS.
Ce qu'il ne fait pas : InfraFence ne lit pas la file d'attente du courrier, ne compte ni ne limite le courrier sortant, ne bloque pas le port 25 et ne vérifie pas si votre adresse est sur une liste noire. Une boîte mail utilisée avec son bon mot de passe ressemble pour lui à une connexion normale. La file, les limites et le retrait des listes de ce guide restent à votre charge.
Questions
- Le serveur n'a pas de serveur de messagerie. Comment peut-il envoyer du spam ?
- La fonction
mail()de PHP utilise lesendmailque presque toutes les distributions installent, et un malware peut se connecter lui-même au port 25 d'autres serveurs. Vérifiez les connexions sortantes de l'étape 1 et la règle qui réserve le port 25 au serveur de messagerie. - SPF, DKIM et DMARC vont-ils arrêter le spam ?
- Non. Ils prouvent quels serveurs peuvent envoyer pour votre domaine, et le spam envoyé par une boîte piratée sur votre serveur les passe. Ils protègent votre domaine contre l'usurpation et aident votre courrier légitime à être livré.
- Combien de temps faut-il pour sortir d'une liste noire ?
- Cela dépend de la liste. Les inscriptions SpamCop expirent d'elles-mêmes une fois les signalements arrêtés ; Spamhaus et Microsoft traitent une demande de retrait une fois le problème corrigé. La réputation chez Gmail et Outlook se rétablit au fil de jours d'envois propres.
Essayez gratuitement sur 1 serveur
Starter est gratuit pour un serveur, avec la protection complète et le blocage automatique. Sans carte bancaire.
Installez l'agent en root, avec votre jeton à la place de <TOKEN> :
curl -fsSL https://github.com/infrafence/infrafence-agent/releases/latest/download/install.sh | sudo bash -s -- --token <TOKEN>Le jeton se crée dans le tableau de bord, dans Serveurs › Ajouter un serveur.
