Documenter le courrier entrant : l'usurpation de postmaster@
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
This commit is contained in:
parent
b7c05a6feb
commit
4d8dee3ecf
2 changed files with 203 additions and 0 deletions
12
README.md
12
README.md
|
|
@ -174,6 +174,7 @@ OVH, sinon il décrit un état qui n'existe plus.
|
|||
| Document | Sujet |
|
||||
|---|---|
|
||||
| [`docs/courrier-sortant.md`](docs/courrier-sortant.md) | relais, SPF/DKIM/DMARC, plafonds, boîtes du service |
|
||||
| [`docs/courrier-entrant.md`](docs/courrier-entrant.md) | usurpation du domaine, liste blanche postmaster d'ISPConfig, tri dans Junk |
|
||||
| [`docs/certificats.md`](docs/certificats.md) | les deux mécanismes TLS, leurs pièges, les réparations |
|
||||
| [`docs/sauvegardes.md`](docs/sauvegardes.md) | sauvegarder les bases, et surtout les restaurer |
|
||||
|
||||
|
|
@ -206,6 +207,17 @@ les pièges qui vont avec :
|
|||
|
||||
---
|
||||
|
||||
## Courrier entrant
|
||||
|
||||
Un message qui se fait passer pour `@alpinux.org` doit être refusé ou rangé
|
||||
dans `Junk`. Le 28/09/2026, un phishing usurpant `postmaster@` est passé sans
|
||||
aucun contrôle, à cause d'une liste blanche posée par ISPConfig. Les trois
|
||||
protections mises en place, et comment les vérifier :
|
||||
|
||||
→ **[`docs/courrier-entrant.md`](docs/courrier-entrant.md)**
|
||||
|
||||
---
|
||||
|
||||
## Certificats TLS
|
||||
|
||||
Deux mécanismes coexistent — un certificat certbot multi-domaines pour huit
|
||||
|
|
|
|||
191
docs/courrier-entrant.md
Normal file
191
docs/courrier-entrant.md
Normal file
|
|
@ -0,0 +1,191 @@
|
|||
# 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`](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` :
|
||||
|
||||
```diff
|
||||
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 :
|
||||
|
||||
1. rspamd, via `milter_headers`, pose `X-Spam: Yes` et
|
||||
`X-Spam-Status: Yes, score=…`.
|
||||
2. Dovecot exécute `sieve_before = /var/vmail/%d/%n/.ispconfig-before.sieve`,
|
||||
généré par ISPConfig parce que `mail_user.move_junk = 'y'` :
|
||||
`if header :matches "X-Spam-Status" "Yes, *" { fileinto :create "Junk"; stop; }`
|
||||
3. En secours, `sieve_before2 = /var/lib/dovecot/sieve/spam-to-junk.sieve`
|
||||
fait 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
|
||||
|
||||
```sh
|
||||
# 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.conf` n'a pas
|
||||
retrouvé `want_spam` : la copie dans `conf-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, pour `abuse@`, la liste noire les protègent.
|
||||
|
||||
## Retour arrière
|
||||
|
||||
```sh
|
||||
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.
|
||||
Loading…
Reference in a new issue