Post

🟢 📩 OVH Stalwart Mail Server yannig.net

🟢 📩 OVH Stalwart Mail Server yannig.net

Stalwart Mail Server est une solution open source conçue pour simplifier l’auto-hébergement des serveurs de mail, en mettant l’accent sur la sécurité et la confidentialité. Écrit en Rust, il offre une alternative moderne aux logiciels de serveurs de mail existants, souvent complexes et obsolètes.

Stalwart Mail Server

Exigences :

  • VPS avec un port 25 ouvert : OVH vps-1780de45 yannig.net
    • IPV6: 2001:41d0:305:2100::c1c
      • IPV4: 51.38.37.240
  • Un nom de domaine enregistré : yannig.net
  • Domaine mail: mail.yannig.net

OVH vps-1780de45

DNS OVH yannig.net

Avant modifications

1
2
3
4
5
6
7
8
9
$TTL 3600
@	IN SOA dns14.ovh.net. tech.ovh.net. (2076760362 86400 3600 3600000 60)
        IN NS     dns14.ovh.net.
        IN NS     ns14.ovh.net.
        IN MX     1 mx1.mail.ovh.net.
        IN MX     5 mx2.mail.ovh.net.
        IN MX     100 mx3.mail.ovh.net.
        IN A     51.38.37.240
        IN TXT     "v=spf1 include:mx.ovh.com -all"

Configuration DNS OVH basique domaine yannig.net

1
2
3
4
5
6
7
$TTL 3600
@	IN SOA dns14.ovh.net. tech.ovh.net. (2076760577 86400 3600 3600000 60)
        IN NS     dns14.ovh.net.
        IN NS     ns14.ovh.net.
        IN A     51.38.37.240
        IN AAAA     2001:41d0:305:2100::c1c
        IN TXT     "v=spf1 include:mx.ovh.com -all"

Reverse DNS

Network → Adresses IP publiques


Outils

1
sudo apt install dnsutils

Vérification

1
2
dig -x 51.38.37.240 +short            # → yannig.net.
dig -x 2001:41d0:305:2100::c1c +short       # → yannig.net.

SMTP Port 25

Vérifier que le fournisseur d’accès internet ne bloque pas le trafic SMTP port TCP 25

Depuis un poste externe :

1
sudo nmap -sS -p25 51.38.37.240
1
2
3
4
5
6
7
8
Starting Nmap 7.99 ( https://nmap.org ) at 2026-04-22 14:30 +0200
Nmap scan report for yannig.net (51.38.37.240)
Host is up (0.013s latency).

PORT   STATE SERVICE
25/tcp open  smtp

Nmap done: 1 IP address (1 host up) scanned in 0.16 seconds

ACME.sh

Création des certificats SSL Let’s encrypt via Acme

1
2
3
4
5
6
# Git
git clone https://github.com/acmesh-official/acme.sh.git
cd ./acme.sh
# Installation sans crontab --force
./acme.sh --install --force

Se reconnecter pour prise en charge

Les clé OVH

1
2
export OVH_AK="wxxxxxxxxxxxxxxxx"
export OVH_AS="yxxxxxxxxxxxxxxxxxxxxxxx"

Créer les certificats

1
acme.sh --dns dns_ovh --server letsencrypt --issue --keylength ec-384 -d 'yannig.net' -d '*.yannig.net'

Ouvrir le lien généré pour valider l’authentification OVH
puis relancer la commande

1
acme.sh --dns dns_ovh --server letsencrypt --issue --keylength ec-384 -d 'yannig.net' -d '*.yannig.net'

Les certificats

1
2
3
4
[mar. 21 avril 2026 16:10:41 CEST] Your cert is in: /home/yann/.acme.sh/yannig.net_ecc/yannig.net.cer
[mar. 21 avril 2026 16:10:41 CEST] Your cert key is in: /home/yann/.acme.sh/yannig.net_ecc/yannig.net.key
[mar. 21 avril 2026 16:10:41 CEST] The intermediate CA cert is in: /home/yann/.acme.sh/yannig.net_ecc/ca.cer
[mar. 21 avril 2026 16:10:41 CEST] And the full-chain cert is in: /home/yann/.acme.sh/yannig.net_ecc/fullchain.cer

Installation des certificats

Droits dossier

1
2
sudo chown $USER:stalwart /etc/ssl/private/ 
sudo chmod 750 /etc/ssl/private/

Si vous utilisez acme.sh pour gérer vos certificats, vous pouvez simplement exécuter

1
2
3
4
acme.sh --ecc --install-cert -d 'yannig.net' \
  --key-file       /etc/ssl/private/privkey.pem  \
  --fullchain-file /etc/ssl/private/fullchain.pem \
  --reloadcmd      "sudo systemctl restart stalwart"

Mise à jour des certificats

Le VPS n’a pas crontab installé, on va utiliser systemd timer

Le fichier de service

1
sudo nano /etc/systemd/system/update-certificat.service

contenu

1
2
3
4
[Unit]
Description="Update certificat"
[Service]
ExecStart="/home/yann/.acme.sh"/acme.sh --cron --home "/home/yann/.acme.sh"

Le fichier minuteur

1
sudo nano /etc/systemd/system/update-certificat.timer

Exécution service tous les jours (lundi au dimanche) à 1h20

1
2
3
4
5
6
7
[Unit]
Description="Renouvellement certificat si date validité atteinte"
[Timer]
OnCalendar=Mon..Sun *-*-* 1:20:00
Unit=update-certificat.service
[Install]
WantedBy=multi-user.target

Activer le minuteur

1
sudo systemctl enable update-certificat.timer --now

Vérification

1
systemctl list-timers

Résultat

1
2
NEXT                            LEFT LAST                               PASSED UNIT                         ACTIVATES                     
Wed 2026-04-22 01:20:00 CEST      9h -                                       - update-certificat.timer      update-certificat.service

Tester la mise à jour des certificats

On va forcer (--force) la procédure et voir le résultat

1
"/home/yann/.acme.sh"/acme.sh --force --cron --home "/home/yann/.acme.sh"

Résultat

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
[mer. 22 avril 2026 15:29:27 CEST] ===Starting cron===
[mer. 22 avril 2026 15:29:27 CEST] Renewing: 'yannig.net'
[mer. 22 avril 2026 15:29:27 CEST] Renewing using Le_API=https://acme-v02.api.letsencrypt.org/directory
[mer. 22 avril 2026 15:29:28 CEST] Using CA: https://acme-v02.api.letsencrypt.org/directory
[mer. 22 avril 2026 15:29:28 CEST] Multi domain='DNS:yannig.net,DNS:*.yannig.net'
[mer. 22 avril 2026 15:29:31 CEST] Getting webroot for domain='yannig.net'
[mer. 22 avril 2026 15:29:31 CEST] Getting webroot for domain='*.yannig.net'
[mer. 22 avril 2026 15:29:32 CEST] yannig.net is already verified, skipping dns-01.
[mer. 22 avril 2026 15:29:32 CEST] *.yannig.net is already verified, skipping dns-01.
[mer. 22 avril 2026 15:29:32 CEST] Verification finished, beginning signing.
[mer. 22 avril 2026 15:29:32 CEST] Let's finalize the order.
[mer. 22 avril 2026 15:29:32 CEST] Le_OrderFinalize='https://acme-v02.api.letsencrypt.org/acme/finalize/3261565761/503263123221'
[mer. 22 avril 2026 15:29:34 CEST] Downloading cert.
[mer. 22 avril 2026 15:29:34 CEST] Le_LinkCert='https://acme-v02.api.letsencrypt.org/acme/cert/06f1d2dce6d6abf103b51aeacd877777dced'
[mer. 22 avril 2026 15:29:34 CEST] Cert success.
-----BEGIN CERTIFICATE-----
MIIDqzCCAzKgAwIBAgISBvHS3ObWq/EDtRrqzYd3d9ztMAoGCCqGSM49BAMDMDIx
................................................................
wlGN9+2d/jpHlXCDhVKto+dTRvSOSWpI4LLnyujefQ==
-----END CERTIFICATE-----
[mer. 22 avril 2026 15:29:34 CEST] Your cert is in: /home/yann/.acme.sh/yannig.net_ecc/yannig.net.cer
[mer. 22 avril 2026 15:29:34 CEST] Your cert key is in: /home/yann/.acme.sh/yannig.net_ecc/yannig.net.key
[mer. 22 avril 2026 15:29:34 CEST] The intermediate CA cert is in: /home/yann/.acme.sh/yannig.net_ecc/ca.cer
[mer. 22 avril 2026 15:29:34 CEST] And the full-chain cert is in: /home/yann/.acme.sh/yannig.net_ecc/fullchain.cer
[mer. 22 avril 2026 15:29:35 CEST] Installing key to: /etc/ssl/private/privkey.pem
[mer. 22 avril 2026 15:29:35 CEST] Installing full chain to: /etc/ssl/private/fullchain.pem
[mer. 22 avril 2026 15:29:35 CEST] Running reload cmd: sudo systemctl restart stalwart
[mer. 22 avril 2026 15:29:36 CEST] Reload successful
[mer. 22 avril 2026 15:29:36 CEST] ===End cron===

Les certificats ont été mis à jour et installés dans le dossier /etc/ssl/private/ puis le service stalwart est redémarré.

Parefeu

Ports essentiels à maintenir ouverts :

  • Port 25 (SMTP) : Pour la réception d’e-mails d’autres serveurs de messagerie.
  • Port 465 (SMTPS) : Recommandé pour l’envoi sécurisé d’e-mails sortants des clients utilisateurs avec TLS implicite. À privilégier par rapport au port 587.•
  • Port 993 (IMAPS) : Pour l’accès sécurisé aux e-mails via les clients IMAP avec TLS implicite.
  • Port 443 (HTTPS) : Pour l’administration web, JMAP, l’API REST, OAuth, le provisionnement de certificats TLS (ACME) et d’autres services web sécurisés.

Ports non essentiels à désactiver si non utilisés :

  • Port 587 (SMTP Submission) : Si tous vos clients utilisent le port 465, ce port peut être désactivé.
  • Port 143 (IMAP4) : Le port IMAP standard sans chiffrement. Il devrait généralement être désactivé au profit du port 993 (IMAPS).
  • Port 4190 (ManageSieve) : À garder ouvert uniquement si vos utilisateurs gèrent activement des scripts Sieve.
  • Port 110 (POP3) et Port 995 (POP3S) : POP3 est largement obsolète au profit d’IMAP. Désactivez-les sauf en cas de besoin spécifique.
  • Port 8080 (HTTP) : Principalement fourni pour la configuration initiale. Il est fortement recommandé de désactiver ce port après la configuration pour prévenir les accès non authentifiés et non chiffrés.

Installation Debian / Ubuntu

1
sudo apt install ufw

Les règles à ajouter pour le serveur de messagerie

1
2
sudo ufw allow 53240 # ssh
sudo ufw allow 443

Activer le parefeu

1
sudo ufw enable
1
2
3
4
# Ouvrir les ports 25,465 et 993 pour le serveur messagerie
sudo ufw allow 25
sudo ufw allow 465
sudo ufw allow 993

Parefeu final

1
2
3
4
5
6
7
8
9
10
11
12
55240/tcp                  ALLOW       Anywhere                  
443                        ALLOW       Anywhere                  
25                         ALLOW       Anywhere                  
993                        ALLOW       Anywhere                  
465                        ALLOW       Anywhere                  
587/tcp                    ALLOW       Anywhere                  
55240/tcp (v6)             ALLOW       Anywhere (v6)             
443 (v6)                   ALLOW       Anywhere (v6)             
25 (v6)                    ALLOW       Anywhere (v6)             
993 (v6)                   ALLOW       Anywhere (v6)             
465 (v6)                   ALLOW       Anywhere (v6)             
587/tcp (v6)               ALLOW       Anywhere (v6)             

Applications Stalwart

Stalwart Web UI

Stalwart est livré avec un script d’installation qui télécharge la dernière version, crée un compte de service dédié, installe le binaire sous les chemins Unix standard, écrit une unité de service et démarre le démon. L’accès root sur la machine cible et la connectivité HTTPS sortante sont nécessaires pour les étapes ci-dessous.

Ouvrez un terminal sur l’hôte cible et récupérez le script d’installation en mode utilisateur (PAS root):

1
curl --proto '=https' --tlsv1.2 -sSf https://get.stalw.art/install.sh -o install.sh

Exécutez le script comme root:

1
sudo sh install.sh

Aucun argument n’est requis. Le script suit la norme de hiérarchie du système de fichiers et place le binaire sous /usr/local/bin/stalwart, le fichier de configuration sous /etc/stalwart/config.json, variables d’environnement sous /etc/stalwart/stalwart.env, données d’application sous /var/lib/stalwart/et de journaux fichiers sous /var/log/stalwart/.

Un dédié stalwartUn compte de service est créé s’il n’existe pas déjà. Le script écrit alors l’unité de service appropriée (systemd, SysV init.d, ou launchden fonction du système d’exploitation), active le service au démarrage et le démarre immédiatement.

En utilisant les identifiants fournis, connectez-vous à votre Stalwart

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
⏳ Downloading stalwart for x86_64-unknown-linux-gnu...
Warning: Not enforcing strong cipher suites for TLS, this is potentially less secure
Warning: Not enforcing TLS v1.2, this is potentially less secure
📝 Writing env file at /etc/stalwart/stalwart.env...
🔐 Setting permissions...
🚀 Starting service...
Created symlink '/etc/systemd/system/multi-user.target.wants/stalwart.service' → '/etc/systemd/system/stalwart.service'.

🎉 Installation complete!

Stalwart is running in bootstrap mode. A temporary administrator
password was generated at startup and printed to the service logs.

👉 To find the password, inspect the service logs:
     journalctl -u stalwart -n 200 | grep -A8 'bootstrap mode'

   Or set STALWART_RECOVERY_ADMIN=admin:<password> in
   /etc/stalwart/stalwart.env and restart the service to pin a credential.

   Finish setup at: http://yannig.net:8080/admin

Les fichiers log

1
2
sudo mkdir /var/log/stalwart
sudo chown stalwart:stalwart /var/log/stalwart

Stalwart Web UI - Mises à jour

Stalwart suit le versioning sémantique (semver), qui utilise un numéro de version dans le format MAJOR.MINOR.PATCH (par exemple, 0.16.3). Ce système indique la nature et l’impact de chaque rejet:

  • Les versions de patch (le dernier numéro) n’incluent que de petites corrections rétrocompatibles. Mise à niveau entre les versions de patch, telles que à partir de 0.16.1 à 0.16.3, est sûr et ne nécessite pas de lire les notes de libération au préalable.
  • Les versions mineures (le numéro moyen) peuvent introduire de nouvelles fonctionnalités ou des ajustements qui pourraient nécessiter des modifications de configuration ou des migrations. Il est essentiel de lire attentivement les notes de publication avant la mise à niveau pour comprendre ce qui a pu changer.
  • Les versions principales (le premier numéro) peuvent inclure des changements de rupture, en particulier avant la version 1.0.0, et nécessitent toujours un examen et une planification avant la mise à niveau.

[0.16.3] - 2026-04-30
If you are upgrading from v0.16.x, replace the binary (or run docker pull). If you are upgrading from v0.15.x and below, please read the upgrading documentation for more information on how to upgrade from previous versions.

1
2
3
4
5
6
7
8
9
10
11
12
Version="v0.16.8"
mkdir -p ~/temp
cd ~/temp
wget https://github.com/stalwartlabs/stalwart/releases/download/$Version/stalwart-x86_64-unknown-linux-gnu.tar.gz
tar xzvf stalwart-x86_64-unknown-linux-gnu.tar.gz
chmod +x stalwart
sudo systemctl stop stalwart
sudo cp stalwart /usr/local/bin/stalwart 
sudo systemctl start stalwart
stalwart -V 
rm ~/temp/stalwart*
cd ..

stalwart-cli

stalwart-cli est un petit outil de ligne de commande axé sur les schémas pour l’administration d’un serveur de messagerie et de collaboration Stalwart. Il s’adresse exclusivement à l’API JMAP et fonctionne sur les objets de gestion/configuration (ceux dont les noms de type JMAP sont préfixés avec x:) exposé par le biais de la urn:stalwart:jmapcapacité.

L’outil est piloté par schéma: d’abord, il télécharge (et cache) un schéma JSON à partir du serveur qui décrit chaque objet, ses champs, les formulaires utilisés pour le rendre et les listes utilisées pour rendre des requêtes. Tout le comportement de commande, la validation et la sortie lisible par l’homme sont dérivés de ce schéma, de sorte que le même binaire fonctionne contre tout déploiement compatible de Stalwart sans recompilation.

Capacités

Tâche Commande Titre
Inspectez les objets et les énums que le serveur expose describe Explorer le schéma
Lire un seul objet par id (ou un singleton) get Aller chercher un seul objet
Liste ou filtre des objets d’un type donné query Recherche et liste
Créer un ou plusieurs objets create Création d’objets
Modifier un objet existant (ou singleton) update Mise à jour des objets
Détruire un ou plusieurs objets delete Enlever des objets
Appliquer un plan en gros à partir d’un fichier JSON apply Opérations en vrac déclaratives
Exporter l’état du serveur en direct comme plan d’application snapshot Exportation de l’état du serveur

Installation Linux (installateur shell)

Les binaires pré-construits sont produits pour macOS (Intel et Apple Silicon), Linux (x86_64 et aarch64, glibc et musl), et Windows (x86_64 et aarch64). Choisissez l’installateur qui correspond à la plate-forme.

1
2
curl --proto '=https' --tlsv1.2 -LsSf \
  https://github.com/stalwartlabs/cli/releases/latest/download/stalwart-cli-installer.sh | sh

Résultat commande

1
2
3
4
5
6
7
8
9
downloading stalwart-cli 1.0.8 x86_64-unknown-linux-gnu
installing to /home/yann/.cargo/bin
  stalwart-cli
everything's installed!

To add $HOME/.cargo/bin to your PATH, either restart your shell or run:

    source $HOME/.cargo/env (sh, bash, zsh)
    source $HOME/.cargo/env.fish (fish)

Exécuter

1
source $HOME/.cargo/env

Version: stalwart-cli --version → stalwart-cli 1.0.8

Clé API

Settings → Credentials → API Keys

Connexion serveur

Chaque invocation a besoin d’une URL de serveur et d’un identifiant. Les mêmes drapeaux sont globaux et peuvent apparaître avant ou après la sous-commande.

Drapeau| Variable environnement| But ——-|—————————-|————– –url | STALWART_URL| Le point de terminaison du serveur Stalwart (requis). --user | STALWART_USER| Nom d'utilisateur de base-auth. --password | STALWART_PASSWORD| Mot de passe de base-auth. Provoqué de manière interactive si absent et stdin est un ATS. --api-key | STALWART_TOKEN| Jeton de porteur. Mutuellement exclusif avec --user. --insecure/ -k| (aucun) |Vérifier le certificat TLS (matchs curl -k). --no-color| (aucun)| Désactivez la sortie couleur ANSI. Le NO_COLORLa variable d'environnement désactive également les couleurs.

Une invocation typique contre un serveur de développement local:

1
stalwart-cli --url http://localhost:8080 --user admin --password admin describe

Équivalent avec les variables d’environnement (recommandées pour les scripts et l’IC):

1
2
3
4
export STALWART_URL=https://yannig.net
export STALWART_USER=admin
export STALWART_PASSWORD='changeme'
stalwart-cli describe

Pour une utilisation sans surveillance, préférez un jeton API:

1
2
3
export STALWART_URL=https://yannig.net
export STALWART_TOKEN='eyJhbGciOi...'
stalwart-cli describe

MX yannig.net

Administration

Le serveur n’a pas de carte graphique, on utilise le proxy ssh depuis un poste linux ayant les accès

1
ssh -L 9500:localhost:8080 -p 55240 -i ~/.ssh/vps-1780de45 yann@51.38.37.240

Ouvrir le lien http://localhost:9500/admin sur le poste appelant

Les fichiers log "info"

Les fichiers log "debug"

DNS OVH Auto

Mise à jour automatique des enregistrements DNS OVH

Settings -> Network -> DNS -> DNS Providers OVH

Relancer stalwart

Relever les information de connexion et redémarrer le service stalwart

1
sudo systemctl restart stalwart

TLS Certificats Manuels

Connexion sur le lien https://yannig.net/admin

Les certificats ne sont pas au bon endroits, il faut forcer la connexion

Se rendre dans settings

On copie le certificat /home/yann/.acme.sh/yannig.net_ecc/fullchain.cer et la clé /home/yann/.acme.sh/yannig.net_ecc/yannig.net.key

Lecture certificats par stalwart

on doit utiliser les ACLs

1
2
sudo apt install acl # si non installé
sudo setfacl -R -m u:stalwart:rX /etc/ssl/private/privkey.pem /etc/ssl/private/fullchain.pem

Vérification: sudo getfacl /etc/ssl/private/*.pem

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
getfacl : suppression du premier « / » des noms de chemins absolus
# file: etc/ssl/private/fullchain.pem
# owner: yann
# group: yann
user::rw-
user:stalwart:r--
group::rw-
mask::rw-
other::r--

# file: etc/ssl/private/privkey.pem
# owner: yann
# group: yann
user::rw-
user:stalwart:r--
group::---
mask::r--
other::---

“Settings” → “TLS” → “Certificates”

Vérifications Management → Domains
Domain yannig.net

Zonefile

Management → Domains → yannig.net

  • Les options
    • DKIM public keys
    • TLSA records
    • SPF records
    • MX records
    • DMARC policy
    • SRV records
    • MTA-STS policy record
    • TLS reporting record
    • CAA records
    • Autoconfig records
    • Legacy Autoconfig records
    • Microsoft Autodiscover records

Submission port 587

L’accès smtp via le port 587 est ajouté pour une utilisation dans le serveur de notification ntfy

Préalable:
Ouvrir le port 587 sur le parefeu UFW

1
sudo ufw allow 587

Stalwart, ajouter un listener:
“Settings → Network → Listeners” et “+ Create listener”


Cliquer sur “Save”

Redémarrer le service

1
sudo systemctl restart stalwart

Account


Configurez les préférences de votre compte, notamment les paramètres régionaux, le fuseau horaire, le cryptage au repos et une description personnelle

Utilisateur yann

Compte de messagerie

Nous ajoutons un compte email.

Allez à Management > Directory > Accounts

ATTENTION Username est le nom sans extension , yann et NON yann@yannig.net



Calendrier et contacts

Accès Settings › Calendar & Contacts

Ne pas oublier de cliquer sur “Save”


Ne pas oublier de cliquer sur “Save”

Thunderbird

Stalwart n’a pas d’email web, donc nous devons utiliser un client de messagerie externe.

Aller dans Paramètre des comptes et ajouter






Test messagerie

Maintenant que nous avons connecté notre Stalwart à Thunderbird, laissez-nous tester notre e-mail.

Allez au testeur de courrier https://www.mail-tester.com/.
Je vais envoyer un e-mail de test.

⚠️ Il faut saisir un sujet et du contenu

Importer un agenda






Importer un carnet d’adresse





yick.eu

Certificats TLS

On a une création de certificats existante pour le domaine yannig.net, regénérer les certificats en ajoutant le domaine yick.eu

Les clé OVH

1
2
export OVH_AK="wxxxxxxxxxxxxxxxx"
export OVH_AS="yxxxxxxxxxxxxxxxxxxxxxxx"

Générer les certificats des domaines

1
acme.sh --dns dns_ovh --server letsencrypt --issue --keylength ec-384 -d 'yannig.net' -d '*.yannig.net' -d 'yick.eu' -d 'cinay.eu'

Les certificats

1
2
3
4
[jeu. 23 avril 2026 16:40:34 CEST] Your cert is in: /home/yann/.acme.sh/yannig.net_ecc/yannig.net.cer
[jeu. 23 avril 2026 16:40:34 CEST] Your cert key is in: /home/yann/.acme.sh/yannig.net_ecc/yannig.net.key
[jeu. 23 avril 2026 16:40:34 CEST] The intermediate CA cert is in: /home/yann/.acme.sh/yannig.net_ecc/ca.cer
[jeu. 23 avril 2026 16:40:34 CEST] And the full-chain cert is in: /home/yann/.acme.sh/yannig.net_ecc/fullchain.cer

Installer les certificats et redémarrer le service stalwart

1
2
3
4
acme.sh --ecc --install-cert -d 'yannig.net' \
  --key-file       /etc/ssl/private/privkey.pem  \
  --fullchain-file /etc/ssl/private/fullchain.pem \
  --reloadcmd      "sudo systemctl restart stalwart"

Résultat commande ci-dessus

1
2
3
4
[jeu. 23 avril 2026 16:50:28 CEST] Installing key to: /etc/ssl/private/privkey.pem
[jeu. 23 avril 2026 16:50:28 CEST] Installing full chain to: /etc/ssl/private/fullchain.pem
[jeu. 23 avril 2026 16:50:28 CEST] Running reload cmd: sudo systemctl restart stalwart
[jeu. 23 avril 2026 16:50:30 CEST] Reload successful

Domaine yick.eu

Connectez-vous au panneau d’administration de Stalwart avec un compte administrateur.
Dans la section Management → Domains → Domains
Ajouter un domaine, Cliquer sur “Create domain”



Management → Domains → yick.eu

  • Les options
    • DKIM public keys
    • TLSA records
    • SPF records
    • MX records
    • DMARC policy
    • SRV records
    • MTA-STS policy record
    • TLS reporting record
    • CAA records
    • Autoconfig records
    • Legacy Autoconfig records
    • Microsoft Autodiscover records

Créer un utilisateur yick@yick.eu

Ajout utilisateur à Thunderbird

Test https://www.mail-tester.com

cinay.eu

Certificats TLS

On a une création de certificats existante pour le domaine yannig.net, regénérer les certificats en ajoutant le domaine cinay.eu

Les clé OVH

1
2
export OVH_AK="wxxxxxxxxxxxxxxxx"
export OVH_AS="yxxxxxxxxxxxxxxxxxxxxxxx"

Générer les certificats des domaines

1
acme.sh --dns dns_ovh --server letsencrypt --issue --keylength ec-384 -d 'yannig.net' -d '*.yannig.net' -d 'yick.eu' -d 'cinay.eu'

Installer les certificats et redémarrer le service stalwart

1
2
3
4
acme.sh --ecc --install-cert -d 'yannig.net' \
  --key-file       /etc/ssl/private/privkey.pem  \
  --fullchain-file /etc/ssl/private/fullchain.pem \
  --reloadcmd      "sudo systemctl restart stalwart"

Domaine cinay.eu

Connectez-vous au panneau d’administration de Stalwart avec un compte administrateur.
Dans la section Management → Domains → Domains
Ajouter un domaine, Cliquer sur “Create domain”





“View Zone File”

Les enregistrements du domaine cinay.eu sont mises à jour automatiquement par API DNS OVH

Management → Domains → cinay.eu

  • Les options
    • DKIM public keys
    • TLSA records
    • SPF records
    • MX records
    • DMARC policy
    • SRV records
    • MTA-STS policy record
    • TLS reporting record
    • CAA records
    • Autoconfig records
    • Legacy Autoconfig records
    • Microsoft Autodiscover records

Compte de messagerie “yani”

Nous ajoutons un compte email.

Allez à Management > Directory > Accounts
Cliquer sur “Create user”

ATTENTION Username est le nom sans extension , yani et NON yani@cinay.eu



Ajout utilisateur à Thunderbird



Test https://www.mail-tester.com

TLS Certificats Automatiques

Ouvrir Stalwart en mode administrateur

1. Settings → TLS → ACME Providers (ACME Provider)

ACME providers -> Create provider

| Champ | Valeur | | :—————— | :———————————————– | | Directory URL* | https://acme-v02.api.letsencrypt.org/directory | | Challenge type* | DNS-01 | | Contact Email | staladmin@yannig.net ✅ | | Renew before* | R23 (par défaut : 2/3 de la durée) | | Key ID | (vide) | | HMAC Key | (vide) | | Max retries* | 10 (par défaut) | Sauvegarder la configuration

Puis Management -> Actions -> Server settings pour recharger la configuration

2. Management → Domains → domains

Editer un domaine pour effectuer la modification
Sauvegarder

Répéter cette opération pour tous les domaines

Stalwart va maintenant :

  1. Générer une demande de certificat Let’s Encrypt via ACME
  2. Créer automatiquement l’enregistrement TXT _acme-challenge.yourdomain.com via l’API OVH
  3. Valider le challenge DNS-01 avec Let’s Encrypt
  4. Récupérer le certificat signé
  5. Supprimer l’enregistrement TXT _acme-challenge après validation
  6. Rénover automatiquement avant expiration (2/3 de la durée)

Votre DNS provider OVH est déjà configuré avec les clés API (Application Key, Application Secret, Consumer Key), donc Stalwart pourra utiliser directement ce provider pour les enregistrements TXT ACME.

3. Warning Multiple TLS certificates available

Le serveur est dans le domaine principal yannig.net IN MX 10 yannig.net. avec 2 autres domaines cinay.eu et yick.eu avec un enregistrement DNS IN MX 10 yannig.net.
L’accès administration web se fait sur le lien https://yannig.net
Les certificats TLS sont gérés automatiquent via API OVH
TOUT FONCTIONNE PARFAITEMENT à un détail près., j’ai validé la mise à jour des certificats TLS pour les 3 domaines et je reçois un avertissement de stalwart:
Warning Multiple TLS certificates available Total=3
Je pense que j’ai fait une erreur, je dois valider TLS Auto pour le domaine yannig.net UNIQUEMENT ?
Si OUI, je supprime le TLS pour les domaines cinay.eu et yick.eu ?

Oui, vous avez fait une erreur : vous devez valider TLS Auto uniquement pour le domaine principal yannig.net, et supprimer/annuler TLS Auto pour cinay.eu et yick.eu

Pourquoi cet avertissement apparaît

Stalwart détecte 3 certificats TLS différents pour le même IP/hostname, ce qui génère le warning visible (Management → Observability → Logs)

Dans votre configuration :

  • Les 3 domaines (yannig.net, cinay.eu, yick.eu) ont le même enregistrement MX pointing vers yannig.net
  • L’accès WebUI se fait via https://yannig.net (un seul hostname)
  • Stalwart utilise SNI pour sélectionner le certificat, mais pour un seul hostname d’accès, un seul certificat est nécessaire[^1_1]

Ce que vous devez faire

Action Domaine
Maintenir TLS Auto yannig.net (domaine principal)
Supprimer TLS Auto cinay.eu
Supprimer TLS Auto yick.eu

Étapes dans la WebUI Stalwart

1- Aller dans Settings → TLS → Certificates

2- Pour cinay.eu et yick.eu : désactiver/supprimer la configuration ACME/TLS Auto

3- Pour yannig.net : conserver TLS Auto activé

4- Recharger la configuration Stalwart (Management → Actions → Server settings)

Un redémarrage de stalwart est préférable: sudo systemctl restart stalwart

Explication technique

Puisque votre MX est yannig.net. et que vous accédez à l’administration via https://yannig.net, un seul certificat TLS pour yannig.net est suffisant. Les autres domaines n’ont pas besoin de certificats séparés car :

  • Ils utilisent le même serveur MX ()
  • Le certificat de yannig.net couvre le hostname d’accès
  • Stalwart sélectionnera automatiquement le certificat correspondant via SNI

Après cette correction, l’avertissement “Multiple TLS certificates available” devrait disparaître.

Test et vérification serveur mail

L’outil web le plus complet pour vérifier et tester un serveur de messagerie est MXToolbox (MXTool.net) — il offre une suite exhaustive de tests tous regroupés sur une plateforme unique. clientarea.itinsell

Pourquoi MXToolbox est le plus complet

Catégorie Outils disponibles
DNS MX Lookup, SPF Lookup, DKIM Lookup, TXT Lookup, DNSBL (liste noire)
SMTP SMTP Diagnostic (6 tests : durée, open relay, reverse DNS PTR, bannière, EHLO/HELO, STARTTLS)
Sécurité SPF validateur, DKIM vérificateur, DMARC check
Autre Ping, Port Check, Whois, Trace Route

Le SMTP Diagnostic réalise 6 tests différents et fournit une transcription complète de la session SMTP avec tous les codes serversmtp

Autres excellents outils complémentaires

Outil Spécialité
mail-tester.com Score de qualité email (spam, format, syntaxe) — vous envoyez un email vers une adresse temporaire et obtenez un score détaillé levillage
GlockApps Test de livraison + scoring anti-spam (considéré comme “le gagnant absolu” après test de 7 outils) wpmailsmtp
Diagnostic SMTP (NTool) Test connexion SMTP, TLS/STARTTLS, open relay, temps de réponse ntool
DMARCian Vérification complète DMARC, SPF, DKIM reddit
MX Lookup (EXPERTE.com) Vérification rapide enregistrements MX experte

Définition SPF DKIM DMARC

SPF

SPF est une norme pour vérifier l’adresse IP expéditrice d’un email. La vérification se fait en utilisant le nom de domaine de l’expéditeur d’enveloppe (MAIL FROM:) et en récupérant un enregistrement DNS qui va lister les adresses IP autorisées. La vérification peut aussi se faire par rapport au FQDN annoncé dans le HELO (cf (RFC 7208, 2.3)

Voici un exemple d’enregistrement DNS pour du SPF :

1
@ IN TXT "v=spf1 mx ip4:192.0.2.142 ip4:192.0.2.0/24 ip6:2001:db8::/32 -all"

Voici un exemple d’enregistrement DNS n’autorisant aucun envoi (à mettre pour vos domaines voire sous-domaines qui n’envoient jamais d’emails) :

1
@ IN TXT "v=spf1 -all"

On peut utiliser des include: vers un autre enregistrement TXT.

Chez Evolix, on utilise ainsi include:spf.protection.evolix.net. Si vous utilisez Mailchimp vous devez ajouter include:spf.mandrillapp.com par exemple.

Il faut savoir que l’on peut contourner la longueur maximale de 255 caractères pour un enregistrement TXT en concatener plusieurs chaînes. On notera qu’au moins une des deux chaînes doit contenir une espace. Voici un exemple :

1
@ IN TXT "v=spf1 mx ip4:192.0.2.142 ip4:192.0.2.0/24" " ip6:2001:db8::/32 ~all"

En pratique il est conseillé d’éviter une longueur totale du champ TXT (FQDN compris) de plus de 450 octets (à vérifier via MSG SIZE rcvd: avec dig).

Il est également conseillé de ne pas mettre plus de 101 adresses ou préfixes IP (Gmail refuserait au-delà et de ne pas avoir besoin de plus de 10 résolutions DNS pour savoir si l’IP expéditrice est incluse dans l’enregistrement SPF.

Attention, la RFC 7208 spécifie que le mot clé PTR ne devrait pas être utilisé même si en pratique ça semble toujours utilisé (OVH l’utilise par exemple).

Enfin, on se demande souvent si l’on doit mettre “~all” ou “-all” : on a tendance à privilégier de plus en plus -all car cela donnera davantage de rejets explicites (au niveau SMTP par exemple, au lieu d’aller en Spam ou Quarantaine).

DKIM

DKIM est une norme pour ajouter une signature cryptographique dans les entêtes d’un email envoyé. La signature se fait à partir à de l’expéditeur d’entête (From: d’un email), des entêtes au choix (sujet, date, etc.) et le corps du message. Cela utilise aussi une clé publique stockée dans un enregistrement DNS TXT.

Voir https://wiki.evolix.org/HowtoOpenDKIM

DMARC

DMARC est une spécification qui vient en complément de DKIM et SPF. Cela permet de spécifier aux serveurs de messagerie comment traiter les emails reçus non conformes aux vérifications SPF et/ou DKIM. Cela permet également de récupérer des informations voire des emails complets si ils ne sont pas conformes. Encore une fois, cela se fait avec un enregistrement DNS TXT.

Attention, l’enregistrement DMARC recherché est celui du domaine de l’expéditeur d’entête (From:), appelé aussi “RFC5322.From”.

Pour que la vérification DMARC passe, il suffit que l’un des cas soit rempli :

  • DKIM passe (et le “RFC5322.From” aligné, mais c’est le principe de base sauf cas tordu)
  • SPF passe ET le “RFC5321.MailFrom” est aligné avec le “RFC5322.From”.

DMARC n’exige pas que DKIM et SPF soit valide. Ainsi DMARC peut ainsi très bien être “PASS” avec un SPF invalide ou avec une signature DKIM invalide !

Plus d’infos dans la RFC7489 : Domain-based Message Authentication, Reporting, and Conformance (DMARC)

Voici un exemple d’enregistrement DNS basique :

1
_dmarc IN TXT "v=DMARC1; p=reject; sp=reject; aspf=s; adkim=s"

On pourra spécifier :

  • p=none si l’on ne veut pas que les emails non conformes soient rejetés
  • p=reject si l’on veut que les emails non conformes soient rejetés (rarement utilisé)
  • p=quarantine si l’on veut que les emails non conformes soient mis de côté (dans une sous-boîte Spam en général)

De façon similaire, on peut spécifier la politique par défaut pour les sous-domaines avec sp=. En effet, si un enregistrement _dmarc n’est pas trouvé pour un sous-domaine, il interrogera le « top-level domain » (ou encore appelé « organizational domain »).

Attention, si vous spécifiez rua=mailto:dmarc@example.com vous recevrez pas mal de rapports Report domain de Google, Outlook, etc. vous notifiant des emails non conformes. Les rapports incluent un fichier XML, on peut le lire via des outils comme mxtoolbox ou easydmarc.

On pourra aussi spécifier que l’on veut un alignement entre l’expéditeur d’enveloppe (MAIL FROM: utilisé par SPF) et l’expéditeur d’entête (From:) :

  • aspf=r : relaxed, on exige un alignement mais cela peut-être des sous-domaines
  • aspf=s : strict, on exige que cela soit exactement le même FQDN

De façon similaire, on peut aussi spécifier que la signature DKIM corresponde bien à l’expéditeur d’entête (From:) :

  • adkim=r : relaxed, on exige que cela correspond à un domaine ou sous-domaine
  • adkim=s : strict, on exige que cela soit exactement le même FQDN

Voici un exemple d’un enregistrement DNS plus avancé :

1
_dmarc IN TXT "v=DMARC1;p=reject;sp=none;rua=mailto:dmarc+aggr@example.com;ruf=mailto:dmarc+forensic@example.com;fo=1;adkim=s;aspf=s;pct=100"

Un outil génial pour tester DMARC est https://www.learndmarc.com/ : il faut envoyer un email et l’on a toutes les explications sur SPF / DKIM / DMARC et notamment l’alignement.

Recommandation pour un test complet

Pour vérifier votre serveur Stalwart de manière exhaustive :

  1. MXToolbox → SMTP Diagnostic + MX/SPF/DKIM/DNSBL
  2. mail-tester.com → Envoyer un email réel pour score de qualité
  3. GlockApps → Test de livraison vers les grands fournisseurs (Gmail, Outlook, etc.)

Cette combinaison couvre configuration DNS, sécurité SMTP, livraison réelle et scoring anti-spam.

Sauvegarde RocksDB

Stalwart Mail Server utilise RocksDB pour la gestion des paramètres dans le dossier /var/lib/stalwart. J’ai testé la sauvegarde puis la restauration de ce dossier en stoppant le service systemd stalwart. Est il possible de faire une sauvegarde du dossier /var/lib/stalwart sans arrêter le service. Si oui , une procédure de sauvegarde avec roulement, le tout gérer par un systemd timer

Il est possible de sauvegarder /var/lib/stalwart sans arrêter le service, mais il faut utiliser la fonctionnalité de checkpoint de RocksDB plutôt qu’une copie directe du dossier, car une copie simple pendant que le service est actif peut entraîner une base corruptible car RocksDB écrit continuellement dans ses fichiers (.sst, log, manifest). Copier ces fichiers pendant que le service tourne risque de capturer un état incohérent.

rsync avec arrêt bref (2-3 secondes)

Script backup stalwart: /usr/local/bin/stalwart-backup.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#!/bin/bash
set -e

# Configuration
DB_PATH="/var/lib/stalwart"
BACKUP_BASE="/var/backups/stalwart"
RETENTION_DAYS=7

# Création des répertoires
mkdir -p "$BACKUP_BASE"

# Date de la sauvegarde
DATE=$(date +%Y-%m-%d_%H-%M-%S)
BACKUP_DIR="${BACKUP_BASE}/${DATE}"
PARTIAL_DIR="${BACKUP_DIR}/partial"

echo "=== Sauvegarde Stalwart (rsync avec arrêt bref) ==="
echo "Source : $DB_PATH"
echo "Destination : $BACKUP_DIR"

# Créer le répertoire de sauvegarde
mkdir -p "$BACKUP_DIR"
mkdir -p "$PARTIAL_DIR"

# Première synchronisation (service en cours)
echo "Pass 1 : synchronisation initiale (service en cours)"
rsync -a --delete "$DB_PATH/" "$PARTIAL_DIR/"

# Arrêter brièvement le service (2-3 secondes)
echo "Arrêt du service stalwart (2-3 secondes)"
systemctl stop stalwart

# Synchronisation finale avec checksum ( fichiers inchangés)
echo "Pass 2 : synchronisation finale avec checksum"
rsync -a --delete --checksum "$DB_PATH/" "$BACKUP_DIR/"

# Redémarrer le service
echo "Redémarrage du service stalwart"
systemctl start stalwart

# Attendre que le service soit démarré
sleep 2

# Supprimer le répertoire partiel
rm -rf "$PARTIAL_DIR"

# Roulement : suppression des anciennes sauvegardes
echo "Roulement : suppression des sauvegardes > $RETENTION_DAYS jours"
find "$BACKUP_BASE" -maxdepth 1 -type d -mtime +$RETENTION_DAYS -exec rm -rf {} +

# Afficher les sauvegardes restantes
BACKUPS=$(ls -1 "$BACKUP_BASE" | wc -l)
echo ""
echo "Sauvegardes restantes : $BACKUPS"
ls -la "$BACKUP_BASE"

# Afficher la taille de la sauvegarde
SIZE=$(du -sh "$BACKUP_DIR" | cut -f1)
echo "Taille de la sauvegarde : $SIZE"

echo ""
echo "=== Sauvegarde terminée ==="
echo "Répertoire : $BACKUP_DIR"
# Message
curl --ipv4 \
-H "X-Email: ntfy@cinay.eu" \
-H "Title: 🖂 Sauvegarde Stalwart" \
-H "Authorization: Bearer tk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-H prio:low \
-d "=== Sauvegarde terminée ===
Répertoire : $BACKUP_DIR" \
https://ntfy.rnmkcy.eu/yan_infos

Service et Timer systemd

/etc/systemd/system/stalwart-backup.service

1
2
3
4
5
6
7
8
9
[Unit]
Description=Sauvegarde Stalwart Mail Server
After=local-fs.target

[Service]
Type=oneshot
ExecStart=/usr/local/bin/stalwart-backup.sh
User=root
Group=root

/etc/systemd/system/stalwart-backup.timer

1
2
3
4
5
6
7
8
9
10
11
12
[Unit]
Description=Planification sauvegarde Stalwart quotidienne

[Timer]
OnCalendar=daily
OnCalendar=*-*-* 01:10:00
RandomizedDelaySec=30m
Persistent=true
Unit=stalwart-backup.service

[Install]
WantedBy=timers.target

Création script + services + activation

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# Créer les scripts pour rsync :
#sudo cp stalwart-backup-rsync.sh /usr/local/bin/stalwart-backup.sh
sudo tee /usr/local/bin/stalwart-backup.sh > /dev/null << 'EOF'
#!/bin/bash
set -e

# Configuration
DB_PATH="/var/lib/stalwart"
BACKUP_BASE="/var/backups/stalwart"
RETENTION_DAYS=7

# Création des répertoires
mkdir -p "$BACKUP_BASE"

# Date de la sauvegarde
DATE=$(date +%Y-%m-%d_%H-%M-%S)
BACKUP_DIR="${BACKUP_BASE}/${DATE}"
PARTIAL_DIR="${BACKUP_DIR}/partial"

echo "=== Sauvegarde Stalwart (rsync avec arrêt bref) ==="
echo "Source : $DB_PATH"
echo "Destination : $BACKUP_DIR"

# Créer le répertoire de sauvegarde
mkdir -p "$BACKUP_DIR"
mkdir -p "$PARTIAL_DIR"

# Première synchronisation (service en cours)
echo "Pass 1 : synchronisation initiale (service en cours)"
rsync -a --delete "$DB_PATH/" "$PARTIAL_DIR/"

# Arrêter brièvement le service (2-3 secondes)
echo "Arrêt du service stalwart (2-3 secondes)"
systemctl stop stalwart

# Synchronisation finale avec checksum ( fichiers inchangés)
echo "Pass 2 : synchronisation finale avec checksum"
rsync -a --delete --checksum "$DB_PATH/" "$BACKUP_DIR/"

# Redémarrer le service
echo "Redémarrage du service stalwart"
systemctl start stalwart

# Attendre que le service soit démarré
sleep 2

# Supprimer le répertoire partiel
rm -rf "$PARTIAL_DIR"

# Roulement : suppression des anciennes sauvegardes
echo "Roulement : suppression des sauvegardes > $RETENTION_DAYS jours"
find "$BACKUP_BASE" -maxdepth 1 -type d -mtime +$RETENTION_DAYS -exec rm -rf {} +

# Afficher les sauvegardes restantes
BACKUPS=$(ls -1 "$BACKUP_BASE" | wc -l)
echo ""
echo "Sauvegardes restantes : $BACKUPS"
ls -la "$BACKUP_BASE"

# Afficher la taille de la sauvegarde
SIZE=$(du -sh "$BACKUP_DIR" | cut -f1)
echo "Taille de la sauvegarde : $SIZE"

echo ""
echo "=== Sauvegarde terminée ==="
echo "Répertoire : $BACKUP_DIR"
EOF
sudo chmod +x /usr/local/bin/stalwart-backup.sh

# Créer le service et le timer
sudo tee /etc/systemd/system/stalwart-backup.service > /dev/null << 'EOF'
[Unit]
Description=Sauvegarde Stalwart Mail Server
After=local-fs.target

[Service]
Type=oneshot
ExecStart=/usr/local/bin/stalwart-backup.sh
User=root
Group=root
EOF

sudo tee /etc/systemd/system/stalwart-backup.timer > /dev/null << 'EOF'
[Unit]
Description=Planification sauvegarde Stalwart quotidienne

[Timer]
OnCalendar=daily
OnCalendar=*-*-* 01:10:00
RandomizedDelaySec=30m
Persistent=true
Unit=stalwart-backup.service

[Install]
WantedBy=timers.target
EOF

# Activer
sudo systemctl daemon-reload
sudo systemctl enable --now stalwart-backup.timer

# Vérifier
sudo systemctl list-timers stalwart-backup.timer

Le service est actif

1
2
NEXT                         LEFT LAST PASSED UNIT                  ACTIVATES              
Sat 2026-06-13 00:27:02 CEST  10h -         - stalwart-backup.timer stalwart-backup.service

Pour info: comparaison des méthodes

Méthode Arrêt service Cohérence Dépendances
btrfs snapshot ❌ Non ✅ 100% cohérent btrfs seulement
rsync + arrêt bref ⚠️ 2-3 sec ✅ Cohérent rsync (déjà installé)
Arrêt complet ✅ 10-30 sec ✅ 100% cohérent cp (déjà installé)

btrfs snapshot n’est pas disponible, on utilise rsync avec arrêt bref (2-3 secondes d’arrêt est acceptable pour une sauvegarde quotidienne à 1h10 du matin).

Lancement manuel

On va lancer la procédure manuellement pour vérifier son fonctionnement

1
sudo /usr/local/bin/stalwart-backup.sh

Déroulement du script

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
=== Sauvegarde Stalwart (rsync avec arrêt bref) ===
Source : /var/lib/stalwart
Destination : /var/backups/stalwart/2026-06-12_14-08-05
Pass 1 : synchronisation initiale (service en cours)
Arrêt du service stalwart (2-3 secondes)
Pass 2 : synchronisation finale avec checksum
Redémarrage du service stalwart
Roulement : suppression des sauvegardes > 30 jours

Sauvegardes restantes : 1
total 12
drwxr-xr-x 3 root     root     4096 12 juin  14:08 .
drwxr-xr-x 3 root     root     4096 12 juin  14:08 ..
drwxr-x--- 2 stalwart stalwart 4096 12 juin  10:48 2026-06-12_14-08-05
Taille de la sauvegarde : 88M

=== Sauvegarde terminée ===
Répertoire : /var/backups/stalwart/2026-06-12_14-08-05

Simuler rotation des dossiers

Le find ne supprime que les dossiers dont le mtime est strictement supérieur à 30 jours (-mtime +30).

Pour afficher ce qui serait supprimé sans rien effacer :

1
2
3
BACKUP_BASE="/var/backups/stalwart"
RETENTION_DAYS=7
find "$BACKUP_BASE" -maxdepth 1 -type d -mtime +$RETENTION_DAYS -printf '%p %TY-%Tm-%Td %TH:%TM:%TS\n'

Maintenance

Configuration Active Stalwart web UI

Actualisation: 19/06/2026

Settings → Sieve → System scripts

reject-forged-recipients

Rejeter si adresse visible différente adresse réelle

Settings → Sieve → System scripts reject-forged-recipients

Test sur le serveur de messagerie

1
swaks   --server yannig.net:25   --from idcywlf@zirenma.tech   --to yani@cinay.eu   --data @Message-FORGED-2026-06-18-1414.eml

Résultat commande

1
<** 550 5.7.1 Message rejected due to excessive spam score.

Chercher dans les logs en mode debug

1
grep "reject" /var/log/stalwart/stalwart.2026-06-19

Résultat de la recherche

1
2026-06-19T04:33:38Z DEBUG Classifying message for spam (spam.classify) listenerId = "smtp", localPort = 25, remoteIp = fe80::f816:3eff:fe25:b53a, remotePort = 37708, queueId = 313657628479717376, result = "reject", reason = "Message rejected due to excessive spam score."

phishing_gouv

Filtrer/rejeter automatiquement les e-mails de phishing prétendant provenir de gouv.fr

Settings → Sieve → System scripts phishing_gouv

Test sur le serveur de messagerie

1
2
3
4
5
6
7
swaks --server yannig.net:25 \
  --from "amendes-antai-gouv@oglix.ba" \
  --to "yani@cinay.eu" \
  --header "From: Agence Nationale de Traitement Automatisé des Infractions <amendes-antai-gouv@oglix.ba>" \
  --header "Subject: ANTAI - test phishing" \
  --header "Authentication-Results: yannig.net; dkim=pass header.d=oglix.ba; spf=pass smtp.mailfrom=oglix.ba; dmarc=none header.from=oglix.ba" \
  --data "Ceci est un test."

Settings → Spam Filter → General

Reject threshold

Settings → Spam Filter → General Reject threshold =1

Cet article est sous licence CC BY 4.0 par l'auteur.