Un phishing daté du 28/09 usurpait postmaster@ et est passé sans aucun contrôle : la liste blanche que l'installeur d'ISPConfig pose sur postmaster/hostmaster/abuse (want_spam) coupe SPF et DMARC. Le document décrit les trois protections mises en place, comment les vérifier, et ce qu'elles laissent de côté. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KdfUCdensc9bEAtnNvQmS2
7.3 KiB
Courrier entrant d'owni : l'usurpation du domaine
Comment owni refuse un message qui se fait passer pour @alpinux.org, et
pourquoi postmaster@ était la seule adresse qu'on pouvait usurper sans aucun
contrôle. Le pendant sortant est
courrier-sortant.md.
État au 29/09/2026.
L'incident du 28/09/2026
Un phishing (« Modification d'un e-mail envoyé », lien vers
*.web.core.windows.net) est arrivé dans la boîte postmaster@, avec
From: et To: tous deux à postmaster@alpinux.org. Il ne portait aucun
en-tête X-Spam-* ni Authentication-Results.
Received: from [171.249.196.126] (unknown [171.249.196.126])
by owni.alpinux.org (Postfix) with ESMTP id 79115207A0
L'expéditeur était une ADSL Viettel, qui s'est connectée directement au port
25, sans authentification. Pourtant, le SPF -all et le DMARC
p=quarantine du domaine auraient suffi à l'arrêter. Aucun des deux n'a été
consulté.
Pourquoi il est passé
Postfix l'a accepté. Le destinataire est local, et l'expéditeur
postmaster@ existe, donc reject_unlisted_sender le laisse passer. Il n'y
avait pas de reject_sender_login_mismatch. Et même activé, celui-ci n'aurait
rien vu : la boîte postmaster@ a le SMTP désactivé
(mail_user.disablesmtp = 'y'), elle est donc absente de
smtpd_sender_login_maps.
rspamd ne l'a pas analysé. Dans /var/log/rspamd/rspamd.log :
apply static settings whitelist; rcpt matched; priority high
task is whitelisted
(default: S (no action): [0.00/15.00] []) ... settings_id: whitelist
L'installeur d'ISPConfig écrit dans /etc/rspamd/local.d/users.conf :
whitelist {
priority = 5;
rcpt = "postmaster"; rcpt = "hostmaster"; rcpt = "abuse";
want_spam = yes;
}
L'intention est bonne : la RFC 2142 veut que ces adresses reçoivent toujours
les plaintes. Mais want_spam = yes coupe toutes les vérifications, SPF
et DMARC compris, pour tout ce qui leur est adressé.
Les trois protections en place
1. rspamd : liste noire sur l'enveloppe (interface ISPConfig)
Dans Email → Spamfilter → Blacklist, deux entrées : postmaster@alpinux.org
et abuse@alpinux.org (table spamfilter_wblist).
ISPConfig génère /etc/rspamd/local.d/users/spamfilter_wblist_N.conf : si
l'expéditeur d'enveloppe est cette adresse et le destinataire
@alpinux.org, alors reject = 0.2. La priorité (50) l'emporte sur la liste
blanche (5).
À ne pas confondre avec Email → Global Filters → Blacklist, qui
alimente la table Postfix mail_access. Celle-ci est lue avant
permit_sasl_authenticated : un expéditeur ajouté là serait refusé même
authentifié.
2. Postfix : expéditeur local ⇒ authentification (interface ISPConfig)
Dans System → Server Config → owni → Mail, l'option « Reject sender and recipient login mismatch » est cochée. ISPConfig réécrit alors :
smtpd_sender_restrictions = reject_authenticated_sender_login_mismatch,
permit_mynetworks,
check_sender_access proxy:mysql:/etc/postfix/mysql-virtual_sender.cf,
reject_sender_login_mismatch, permit_sasl_authenticated,
reject_non_fqdn_sender, reject_unlisted_sender
- Un client non authentifié qui envoie avec une boîte existante (SMTP activé) est refusé.
- Un client authentifié ne peut envoyer qu'avec sa propre adresse, ou avec un alias marqué « Allow send as ».
Avant d'activer l'option, j'ai vérifié sur 3 jours de logs que tous les envois
SASL utilisaient leur propre adresse (git_app.noreply, alpid.noreply).
localhost envoie avec alpinux@ et secretaire@, mais passe par
permit_mynetworks.
3. rspamd : analyser sans jamais rejeter (fichier, hors interface)
want_spam = yes est remplacé dans /etc/rspamd/local.d/users.conf :
rcpt = "abuse";
- want_spam = yes;
+ # Plus de want_spam : on analyse (SPF/DMARC), on ne rejette jamais (RFC 2142)
+ apply {
+ actions {
+ reject = null;
+ greylist = null;
+ }
+ }
L'ancien fichier est sauvegardé dans users.conf.bak-20260929. Pour que la
correction survive à une mise à jour d'ISPConfig, une copie est placée dans
/usr/local/ispconfig/server/conf-custom/install/rspamd_users.conf.master.
Pourquoi pas « destination locale ⇒ authentification »
Ce serait refuser toute la réception : le port 25 est le MX, et aucun serveur extérieur (Gmail, Orange, les listes) ne s'y authentifie. La règle porte sur l'expéditeur local (protection 2).
Celle-ci ne suffit pas seule : elle lit l'enveloppe (MAIL FROM), pas
l'en-tête From:. Un MAIL FROM:<x@bidon.ru> accompagné de
From: postmaster@alpinux.org passe Postfix. C'est DMARC, dans rspamd, qui
l'arrête, et il ne le peut que si la liste blanche ne l'en empêche pas
(protection 3).
Où finit le spam de postmaster@
Dans Junk. La chaîne :
- rspamd, via
milter_headers, poseX-Spam: YesetX-Spam-Status: Yes, score=…. - Dovecot exécute
sieve_before = /var/vmail/%d/%n/.ispconfig-before.sieve, généré par ISPConfig parce quemail_user.move_junk = 'y':if header :matches "X-Spam-Status" "Yes, *" { fileinto :create "Junk"; stop; } - En secours,
sieve_before2 = /var/lib/dovecot/sieve/spam-to-junk.sievefait la même chose.
La relève de la messagerie lit INBOX,Junk (IMAP_PM_DOSSIER) : un rapport
DMARC classé à tort reste donc traité.
Vérifier
# Rejouer une usurpation dans rspamd, depuis l'IP de l'attaquant
rspamc -h localhost:11333 -i 171.249.196.126 \
-F <enveloppe> -r <destinataire> < test.eml
# Le tri sieve, à sec, sur une copie du script et un maildir jetable
# ($W doit être lisible par vmail ; -u postmaster@… échoue sur l'auth)
rspamc -h localhost:11333 --mime -i 171.249.196.126 -F bidon@example.ru \
-r postmaster@alpinux.org < test.eml > $W/out.eml
sudo sieve-test -o mail_uid=vmail -o mail_gid=vmail \
-o mail_location=maildir:$W/md $W/before.sieve $W/out.eml
# Un utilisateur qui envoie avec une adresse qui n'est pas la sienne
sudo grep "not owned by user" /var/log/mail.log
Résultats relevés le 29/09/2026 :
| Scénario | Avant | Après |
|---|---|---|
Enveloppe et From: = postmaster@, vers postmaster@ |
accepté, 0.00 | rejeté |
Enveloppe bidon, From: = postmaster@, vers postmaster@ |
accepté, 0.00 | Junk, 17.80 (SPF, DMARC) |
| Même chose vers president@ | rejeté | rejeté |
| Rapport externe légitime vers postmaster@ | accepté | accepté, -0.40 |
Pièges
- Un refus
not owned by user: quelqu'un envoie avec un alias sans « Allow send as ». Cocher la case sur l'alias dans ISPConfig ; ne pas décocher l'option globale. - Après une mise à jour d'ISPConfig, vérifier que
users.confn'a pas retrouvéwant_spam: la copie dansconf-custom/install/doit l'éviter. - Les boîtes au SMTP désactivé et les redirections sans « Allow send as »
(
abuse@,kernel@,cedric.a5l@) ne sont pas couvertes par la protection 2. Seuls DMARC et, pourabuse@, la liste noire les protègent.
Retour arrière
sudo cp -a /etc/rspamd/local.d/users.conf.bak-20260929 /etc/rspamd/local.d/users.conf
sudo rm /usr/local/ispconfig/server/conf-custom/install/rspamd_users.conf.master
sudo systemctl reload rspamd
Les protections 1 et 2 s'annulent depuis l'interface ISPConfig.