Security pour mailcow — guide
Installation
- Le module est livré avec le mailcow Toolkit 0.6.0 ou plus récent (un paquet, une licence par produit). Sur l’hôte mailcow, en root, lancez l’installateur du Toolkit comme d’habitude :
sudo ./install.sh --mailcow-dir /opt/mailcow-dockerized --name <instance>, ou mettez à jour le Toolkit depuis System → Updates (Toolkit). L’installateur copiedata/web/mlw-security/, crée les tables du module dans la base de données de mailcow, ajoute l’entrée de menu et le minuteurmlw-mailcow-security-<instance>.timer(une fois par minute), puis recharge php-fpm. - Ouvrez System → Security dans le menu d’administration de mailcow.
Licence
Ouvrez System → Updates (Toolkit) et repérez la carte Security for mailcow : collez la clé et activez-la, ou démarrez l’essai de 30 jours. En ligne de commande : php /web/mlw-toolkit/cli.php activate mailcow-security <KEY> dans php-fpm-mailcow. La licence est vérifiée chaque jour ; sans internet, le module fonctionne 7 jours après la dernière vérification réussie.
Sans licence valide, rien n’est lu, détecté, banni ni envoyé ; les bannissements faits auparavant sont tout de même levés à leur expiration, et l’historique reste. Rien n’est supprimé.
Le premier passage
Le premier passage importe ce que mailcow garde encore dans ses journaux (en général les dernières heures) et ne bannit ni n’alerte. Ensuite, la tâche ne lit que les nouvelles lignes, chaque minute. Overview → Status affiche le dernier passage ; si une ligne indique que des lignes ont été perdues, mailcow a tronqué ses journaux avant qu’ils soient lus (un serveur très chargé) : augmentez LOG_LINES dans mailcow.conf.
Ce qui est lu
| Source | Ce qui devient un enregistrement |
|---|---|
dovecot (redis DOVECOT_MAILLOG) |
connexions IMAP / POP3 / ManageSieve échouées (avec le nombre de tentatives), connexions qui ne s’authentifient jamais, connexions réussies |
postfix (redis POSTFIX_MAILLOG) |
SMTP AUTH échoués, envois authentifiés, rejets rspamd, rejets par liste de blocage DNS, tentatives de relais, sondages de protocole (connexion perdue après EHLO, pipelining, erreurs TLS, postscreen) |
SOGo (redis SOGO_LOG) |
connexions webmail échouées et réussies |
fail2ban (redis NETFILTER_LOG) |
chaque bannissement fait par le fail2ban de mailcow |
| serveur web (journal docker, via l’agent hôte) | réponses 4xx : chemins d’exploits connus (/.env, /.git, wp-login.php, phpMyAdmin, …) et autres 404 |
| php-fpm (journal docker, via l’agent hôte) | connexions échouées à l’interface et à l’API de mailcow |
Les enregistrements des adresses privées (les conteneurs de mailcow, un reverse proxy devant mailcow) et des réseaux que vous ignorez sont écartés. Les enregistrements sont comptés par minute, adresse, boîte aux lettres et source ; l’historique est conservé 90 jours par défaut (Settings).
Vue d’ensemble
- Totaux des dernières 24 heures par type ; un clic ouvre les événements correspondants.
- 14 derniers jours : connexions échouées, scans et spam par jour (les valeurs sont sous Values).
- Status : mode (surveillance seule ou protection automatique), bannissements actifs, bannissements du fail2ban de mailcow, incidents ouverts, dernier passage.
- Adresses les plus actives avec un bouton Ban, boîtes aux lettres visées, incidents actifs.
Règles et incidents
Une règle compte les enregistrements dans une fenêtre glissante. Quand le seuil est atteint, elle ouvre un incident ; tant que l’attaque continue, le même incident est prolongé, pas répété.
| Règle | Compte | Par défaut |
|---|---|---|
| Force brute sur connexion web | connexions SOGo / interface mailcow / API échouées par adresse | 5 en 15 min → bannissement 24 h |
| Force brute lente | connexions échouées par adresse sur une journée | 20 en 24 h → bannissement 24 h |
| Password spraying | boîtes aux lettres distinctes sur lesquelles une adresse a échoué | 5 en 60 min → bannissement 7 jours |
| Récidiviste | bannissements d’une adresse par le fail2ban de mailcow | 3 en 7 jours → bannissement 30 jours |
| Scan d’exploits web | requêtes vers des chemins d’exploit / de fuite | 3 en 30 min → bannissement 7 jours |
| Scan web de 404 | réponses 404 par adresse | 40 en 30 min → alerte |
| Sondage de relais | « Relay access denied » par adresse | 3 en 60 min → bannissement 7 jours |
| Scan de protocole | connexions qui ne s’authentifient jamais ou violent le protocole | 30 en 60 min → alerte |
| Vague de spam | rejets rspamd et par liste de blocage par adresse | 20 en 60 min → alerte |
| Boîte aux lettres visée | échecs sur une boîte depuis au moins 5 adresses | 30 en 60 min → alerte |
| Pic d’envois | messages envoyés par une boîte | 300 en 60 min → alerte |
| Connexions depuis beaucoup d’adresses | adresses distinctes depuis lesquelles une boîte se connecte | 8 en 60 min → alerte |
| Connexion après des échecs | une première connexion depuis une adresse qui a échoué sur la boîte | 3 échecs en 24 h → alerte (critical) |
Dans Rules, vous pouvez désactiver chaque règle et modifier son seuil, sa fenêtre, son action et la durée du bannissement (0 = permanent). Les règles d’adresse peuvent alert ou ban ; les règles de boîte aux lettres peuvent alert, limit sending ou disallow login. Reset to defaults les rétablit toutes.
Incidents les liste par état (ouvert, vu, résolu, faux positif), gravité minimale et règle. False positive met l’adresse sur la liste d’autorisation et lève ses bannissements.
Actions automatiques
L’interrupteur en haut de Rules est d’abord désactivé : le module se contente d’observer, et chaque incident indique ce qui aurait été fait (« would ban »). Laissez-le ainsi quelques jours, examinez les incidents, ajustez les règles, puis activez-le. Les incidents dont l’attaque continue sont traités au passage suivant.
Jamais bannis automatiquement :
- les adresses privées et réservées ;
- la liste d’autorisation du module (Settings) et celle du fail2ban de mailcow (Configuration → Fail2ban) ;
- les adresses publiques du serveur lui-même (d’après la vérification du reverse DNS du Toolkit) ;
- avec protect known addresses activé (par défaut), les adresses qui se sont connectées avec succès à une boîte aux lettres au cours des 30 derniers jours — un collègue qui se trompe de mot de passe n’est pas bloqué.
Bannissements
Un bannissement place l’adresse ou le réseau dans la liste de blocage du fail2ban de mailcow. Le netfilter de mailcow l’applique dans le pare-feu, sur tous les ports de mailcow, en moins d’une minute, et vous le voyez sur la page Fail2ban de mailcow. Le module le lève à son expiration ; un bannissement que vous supprimez sur la page Fail2ban de mailcow compte comme levé.
Bans affiche les bannissements du module (motif, auteur, échéance, état Cloudflare), les bannissements temporaires du fail2ban de mailcow (Lift ou Make it longer), le reste de la liste de blocage de mailcow et l’historique. Le formulaire en haut bannit une adresse ou un réseau (CIDR) pour 1 heure à 30 jours, ou de façon permanente ; votre propre adresse actuelle est refusée.
Si Manage external est activé dans les réglages fail2ban de mailcow, netfilter ne touche pas au pare-feu : la page vous prévient, et votre propre pare-feu doit appliquer la liste de mailcow.
Cloudflare
Quand les hôtes web de mailcow (l’interface, le webmail) sont derrière le proxy de Cloudflare, les attaques web arrivent à mailcow depuis les adresses de Cloudflare, et netfilter ne peut pas les arrêter. Dans Settings → Cloudflare, choisissez bans of the web rules and ticked manual bans ou every ban : chaque bannissement devient alors aussi une IP Access Rule Cloudflare (« block ») au niveau du compte, qui couvre toutes les zones du compte et disparaît avec le bannissement. Le module utilise les identifiants Cloudflare enregistrés dans System → DNS & Cloudflare ; le jeton doit avoir Account → Account Firewall Access Rules → Edit (la Global API Key le peut). Cloudflare bloque des adresses isolées et les plages /16 et /24 (IPv4), /32, /48 et /64 (IPv6).
Une adresse, une boîte aux lettres
Cliquez sur une adresse pour voir ses enregistrements, les boîtes qu’elle a essayées, ses connexions réussies, ses incidents et bannissements, son reverse DNS et des liens vers AbuseIPDB, ipinfo et Shodan ; bannissez-la, levez son bannissement ou mettez-la sur la liste d’autorisation (éventuellement aussi sur celle de mailcow).
Cliquez sur une boîte aux lettres pour voir les adresses qui l’ont essayée, avec les échecs et les connexions réussies côte à côte (un signe d’avertissement marque une adresse qui a les deux), ainsi que ses envois, ses connexions et ses incidents. Actions, toutes via les fonctions propres à mailcow et journalisées aussi par mailcow :
- Disallow login : la boîte continue de recevoir le courrier, personne ne peut s’y connecter (le « disallow login » de mailcow) ; Allow login again l’annule.
- End IMAP / POP3 sessions : dovecot coupe les sessions immédiatement (via l’agent hôte).
- Require a password change à la prochaine connexion.
- Limit sending à N messages par heure (Settings), ou retirer la limite.
Alertes
Dans Settings → Alerts : l’adresse e-mail (vide = l’adresse de notification du Toolkit), le jeton du bot Telegram (chiffré ; « - » le supprime) et l’id du chat, la gravité minimale (par défaut : high), le nombre maximal d’alertes par heure (le reste est compté dans l’alerte suivante), la langue (anglais ou roumain) et le résumé quotidien (après 07:00). Send a test alert vérifie les deux canaux. Chaque nouvel incident d’une gravité égale ou supérieure donne une alerte, avec un lien vers lui.
Journal d’audit et ligne de commande
Audit log liste chaque action : bannissements, levées, changements de la liste d’autorisation, états des incidents, actions sur les comptes, modifications des règles et des réglages — par un administrateur ou par une règle.
Dans php-fpm-mailcow (docker compose exec -u www-data php-fpm-mailcow …) :
php /web/mlw-security/cli.php status
php /web/mlw-security/cli.php ban 203.0.113.7 48 "reason"
php /web/mlw-security/cli.php unban 203.0.113.7
Désinstallation
sudo ./uninstall.sh lève d’abord tous les bannissements du module, puis supprime les fichiers et les minuteurs. Les tables mlw_sec_* restent dans la base de données de mailcow (et dans ses sauvegardes).