Installation et configuration¶
Ce chapitre couvre le déploiement de Stalwart Mail Server avec Podman, la configuration des domaines, l'authentification, la génération des cles DKIM, le reglage du filtre anti-spam et la découverte automatique des clients.
Prerequis¶
| Composant | Version minimum | Vérification |
|---|---|---|
| Podman | 4.0+ | podman --version |
| Réseau | Ports 25, 465, 587, 993, 4190, 8080 libres | ss -tlnp \| grep -E '25\|465\|587\|993\|4190\|8080' |
| Stockage | 50 Go minimum (SSD recommande) | df -h |
| DNS | Enregistrements MX, SPF, DKIM, DMARC | Voir Architecture |
| Certificats | TLS pour mail.company.io | Let's Encrypt ou CA interne |
| Reverse DNS | PTR record pour l'IP du serveur | dig -x <IP> +short |
Structure des fichiers¶
/opt/stalwart/
├── config/
│ └── config.toml # Configuration principale
├── data/ # Donnees RocksDB (boites, index)
├── certs/
│ ├── mail.company.io.crt
│ └── mail.company.io.key
└── logs/ # Journaux (optionnel, stdout par defaut)
Déploiement avec Podman¶
Lancement du conteneur¶
podman run -d \
--name stalwart-mail \
--restart unless-stopped \
-p 25:25 \
-p 465:465 \
-p 587:587 \
-p 993:993 \
-p 4190:4190 \
-p 8080:8080 \
-v /opt/stalwart/config:/opt/stalwart-mail/etc:Z \
-v /opt/stalwart/data:/opt/stalwart-mail/data:Z \
-v /opt/stalwart/certs:/opt/stalwart-mail/certs:ro \
docker.io/stalwartlabs/stalwart-mail:latest
Vérification du demarrage¶
# Verifier que le conteneur est en cours d'execution
podman ps --filter name=stalwart-mail
# Verifier les logs de demarrage
podman logs stalwart-mail | head -20
# Verifier les ports ouverts
podman port stalwart-mail
Première connexion a l'interface d'administration¶
Au premier demarrage, Stalwart génère un mot de passe administrateur dans les logs :
Accéder a http://localhost:8080 pour ouvrir l'interface d'administration web.
Configuration principale¶
Fichier config.toml¶
# /opt/stalwart/config/config.toml
# === Serveur ===
[server]
hostname = "mail.company.io"
max-connections = 1024
# === TLS ===
[certificate.default]
cert = "/opt/stalwart-mail/certs/mail.company.io.crt"
private-key = "/opt/stalwart-mail/certs/mail.company.io.key"
# === Listeners ===
[server.listener.smtp]
bind = ["0.0.0.0:25"]
protocol = "smtp"
tls.implicit = false
[server.listener.submission]
bind = ["0.0.0.0:587"]
protocol = "smtp"
tls.implicit = false
[server.listener.submissions]
bind = ["0.0.0.0:465"]
protocol = "smtp"
tls.implicit = true
[server.listener.imaps]
bind = ["0.0.0.0:993"]
protocol = "imap"
tls.implicit = true
[server.listener.jmap]
bind = ["0.0.0.0:8080"]
protocol = "http"
[server.listener.sieve]
bind = ["0.0.0.0:4190"]
protocol = "managesieve"
# === Stockage ===
[store.rocksdb]
type = "rocksdb"
path = "/opt/stalwart-mail/data"
[storage]
data = "rocksdb"
blob = "rocksdb"
fts = "rocksdb"
lookup = "rocksdb"
Configuration des domaines¶
Ajouter un domaine¶
Via l'API REST :
# Ajouter le domaine principal
curl -X POST http://localhost:8080/api/domain/company.io \
-H "Authorization: Bearer <admin-token>" \
-H "Content-Type: application/json"
Ou via la configuration TOML :
Domaines multiples¶
Stalwart supporte nativement plusieurs domaines sur une même instance :
# Ajouter un domaine secondaire
curl -X POST http://localhost:8080/api/domain/subsidiary.io \
-H "Authorization: Bearer <admin-token>"
Configuration des comptes¶
Annuaire interne¶
Pour les petits déploiements, Stalwart peut gérer les comptes en interne :
# Creer un compte utilisateur
curl -X POST http://localhost:8080/api/principal \
-H "Authorization: Bearer <admin-token>" \
-H "Content-Type: application/json" \
-d '{
"type": "individual",
"name": "alice",
"secrets": ["$plain$M0tDeP4sse!"],
"emails": ["alice@company.io"],
"description": "Alice Dupont"
}'
Backend LDAP (Keycloak / FreeIPA)¶
Pour une authentification centralisee, configurer un backend LDAP connecte a Keycloak ou FreeIPA :
# /opt/stalwart/config/config.toml
[directory.ldap]
type = "ldap"
url = "ldaps://iam.enterprise.internal.company.io:636"
base-dn = "dc=company,dc=io"
[directory.ldap.bind]
dn = "cn=stalwart,ou=services,dc=company,dc=io"
secret = "%{env:LDAP_BIND_PASSWORD}%"
[directory.ldap.filter]
name = "(&(objectClass=inetOrgPerson)(uid=?))"
email = "(&(objectClass=inetOrgPerson)(mail=?))"
[directory.ldap.attributes]
name = "uid"
class = "objectClass"
description = "cn"
secret = "userPassword"
email = "mail"
quota = "mailQuota"
groups = "memberOf"
[storage]
directory = "ldap"
Backend OIDC (Keycloak)¶
Pour le SSO via OIDC (accès webmail sans re-authentification) :
[directory.oidc]
type = "oidc"
issuer-url = "https://iam.enterprise.internal.company.io/realms/company"
client-id = "stalwart-mail"
client-secret = "%{env:OIDC_CLIENT_SECRET}%"
LDAP + OIDC : deux usages complementaires
Le backend LDAP est utilisé pour la résolution des comptes (recherche d'adresse, vérification de quota). Le backend OIDC est utilisé pour l'authentification SSO des clients web (JMAP, webmail). Les deux peuvent coexister.
Génération des cles DKIM¶
Générer une cle ed25519¶
# Generer la cle DKIM via l'API Stalwart
curl -X POST "http://localhost:8080/api/dkim/generate" \
-H "Authorization: Bearer <admin-token>" \
-H "Content-Type: application/json" \
-d '{
"domain": "company.io",
"selector": "default",
"algorithm": "ed25519-sha256"
}'
La réponse contient l'enregistrement DNS TXT a ajouter :
{
"dnsRecord": "default._domainkey.company.io. IN TXT \"v=DKIM1; k=ed25519; p=MCowBQYDK2VwAyEA...\"",
"privateKey": "-----BEGIN PRIVATE KEY-----\n..."
}
Ajouter une cle RSA en complement¶
Certains serveurs anciens ne supportent pas ed25519. Ajouter une cle RSA en complement :
curl -X POST "http://localhost:8080/api/dkim/generate" \
-H "Authorization: Bearer <admin-token>" \
-H "Content-Type: application/json" \
-d '{
"domain": "company.io",
"selector": "rsa",
"algorithm": "rsa-sha256",
"bits": 2048
}'
Publier les enregistrements DNS¶
; Cle ed25519 (prioritaire)
default._domainkey.company.io. 300 IN TXT "v=DKIM1; k=ed25519; p=MCowBQYDK2VwAyEA..."
; Cle RSA (fallback compatibilite)
rsa._domainkey.company.io. 300 IN TXT "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA..."
Configuration des enregistrements DNS¶
Enregistrements SPF et DMARC¶
; SPF — autoriser uniquement le serveur MX
company.io. 300 IN TXT "v=spf1 mx -all"
; DMARC — rejeter les emails non authentifies
_dmarc.company.io. 300 IN TXT (
"v=DMARC1; p=reject; "
"rua=mailto:dmarc-reports@company.io; "
"adkim=s; aspf=s; pct=100"
)
; MTA-STS — forcer TLS
_mta-sts.company.io. 300 IN TXT "v=STSv1; id=20260416"
Déploiement progressif de DMARC¶
Pour eviter de perdre des emails legitimes lors de la mise en place :
| Étape | Politique DMARC | Duree | Action |
|---|---|---|---|
| 1 | p=none; pct=100 | 2 semaines | Observer les rapports, pas de rejet |
| 2 | p=quarantine; pct=25 | 2 semaines | Quarantine sur 25% des echecs |
| 3 | p=quarantine; pct=100 | 2 semaines | Quarantine sur tous les echecs |
| 4 | p=reject; pct=100 | Permanent | Rejeter tous les emails non authentifies |
Configuration du filtre anti-spam¶
Reglage du scoring¶
# /opt/stalwart/config/config.toml
[spam.header]
# En-tete ajoute aux emails avec le score spam
is-spam = "X-Spam-Status"
[spam.threshold]
# Score au-dessus duquel un email est considere comme spam
spam = 5.0
# Score au-dessus duquel un email est rejete
discard = 8.0
[spam.dnsbl]
# Listes de blocage DNS
lists = [
"zen.spamhaus.org",
"bl.spamcop.net",
"b.barracudacentral.org"
]
Allowlists et blocklists¶
[spam.list.allowlist]
# Domaines de confiance (jamais marques comme spam)
domains = [
"partner.io",
"government.gouv.fr"
]
[spam.list.blocklist]
# Domaines toujours rejetes
domains = [
"known-spam.example",
"phishing-domain.xyz"
]
Autoconfig et Autodiscover¶
Configuration pour Mozilla Autoconfig¶
Stalwart sert nativement le fichier autoconfig. Ajouter l'enregistrement DNS :
Le fichier XML est automatiquement génère par Stalwart et accessible sur :
Configuration pour Microsoft Autodiscover¶
Stalwart expose le endpoint Autodiscover sur :
Vérification de la découverte automatique¶
# Tester Mozilla Autoconfig
curl -s https://autoconfig.company.io/mail/config-v1.1.xml | head -20
# Tester Microsoft Autodiscover
curl -s -X POST https://mail.company.io/autodiscover/autodiscover.xml \
-H "Content-Type: text/xml" \
-d '<?xml version="1.0"?>
<Autodiscover xmlns="http://schemas.microsoft.com/exchange/autodiscover/outlook/requestschema/2006">
<Request>
<EMailAddress>alice@company.io</EMailAddress>
<AcceptableResponseSchema>http://schemas.microsoft.com/exchange/autodiscover/outlook/responseschema/2006a</AcceptableResponseSchema>
</Request>
</Autodiscover>'
Vérification de l'installation¶
Checklist post-installation¶
# 1. Verifier que Stalwart repond sur tous les ports
for port in 25 465 587 993 4190 8080; do
echo -n "Port $port: "
timeout 3 bash -c "echo | openssl s_client -connect mail.company.io:$port 2>/dev/null | head -1" || echo "OK (no TLS)"
done
# 2. Tester l'envoi d'un email
swaks --to test@gmail.com \
--from alice@company.io \
--server mail.company.io:587 \
--auth LOGIN \
--auth-user alice@company.io \
--tls
# 3. Verifier la signature DKIM
# Envoyer un email a check-auth@verifier.port25.com
# La reponse automatique contient les resultats SPF/DKIM/DMARC
# 4. Tester la deliverabilite
# Utiliser https://www.mail-tester.com/ pour un score complet
Vérification des services externes¶
| Service | URL | Vérification |
|---|---|---|
| MX Toolbox | https://mxtoolbox.com/ | MX, SPF, DKIM, DMARC, blacklist |
| mail-tester.com | https://www.mail-tester.com/ | Score de deliverabilite |
| DMARC Analyzer | https://dmarcanalyzer.com/ | Rapports DMARC |
| SSL Labs | https://www.ssllabs.com/ssltest/ | Configuration TLS |
Tester avant de passer en p=reject
Utilisez p=none dans DMARC pendant les premières semaines et analysez les rapports avant de passer a p=reject. Un SPF ou DKIM mal configure avec p=reject peut entraîner la perte d'emails legitimes.
Synthese¶
L'installation de Stalwart avec Podman se résumé a un conteneur, un fichier de configuration TOML et des enregistrements DNS. Les points critiques sont la configuration DNS (SPF, DKIM, DMARC) et le reverse DNS (PTR). Le chapitre suivant couvre l'integration avec les services d'infrastructure (IAM, monitoring, calendrier).