Postfix - Relay Mail
Configuration de Postfix en tant que relay SMTP pour centraliser et router les emails sortants des serveurs d'infrastructure.
Architecture Relay Mail
ARCHITECTURE RELAY MAIL
══════════════════════════════════════════════════════════════════════
┌─────────────────────────────────────────────────────────────────────┐
│ INFRASTRUCTURE │
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Serveur 1 │ │ Serveur 2 │ │ Serveur 3 │ │
│ │ (cron, │ │ (monitoring│ │ (apps, │ │
│ │ logs) │ │ alertes) │ │ scripts) │ │
│ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │
│ │ │ │ │
│ │ SMTP :25 │ SMTP :25 │ SMTP :25 │
│ └────────────────┼────────────────┘ │
│ ▼ │
│ ┌───────────────────────┐ │
│ │ POSTFIX RELAY │ │
│ │ relay.corp.local │ │
│ │ (port 25) │ │
│ └───────────┬───────────┘ │
│ │ │
└──────────────────────────┼──────────────────────────────────────────┘
│ SMTP :25/587
▼
┌───────────────────────┐
│ SERVEUR MAIL │
│ (Exchange, O365, │
│ Smarthost, SMTP │
│ externe) │
└───────────────────────┘
│
▼
┌─────────────┐
│ Destinataire│
└─────────────┘
Avantages du relay centralisé:
├── Point unique de sortie (firewall simplifié)
├── Logs centralisés
├── Configuration uniforme
├── Authentification centralisée vers le smarthost
├── Queue de retry en cas d'indisponibilité
└── Filtrage/rewriting possible
Installation
RHEL/Rocky/AlmaLinux
# Installer Postfix
sudo dnf install postfix mailx cyrus-sasl-plain -y
# Désactiver sendmail si présent
sudo systemctl stop sendmail
sudo systemctl disable sendmail
sudo alternatives --set mta /usr/sbin/sendmail.postfix
# Activer et démarrer Postfix
sudo systemctl enable --now postfix
# Vérifier
sudo systemctl status postfix
postconf mail_version
Debian/Ubuntu
# Installer Postfix
sudo apt update
sudo apt install postfix mailutils libsasl2-modules -y
# Pendant l'installation, choisir "Satellite system" ou "Internet with smarthost"
# Ou reconfigurer après
sudo dpkg-reconfigure postfix
# Activer
sudo systemctl enable --now postfix
Configuration Relay Simple
Configuration de Base
# /etc/postfix/main.cf
# Identification du serveur
myhostname = relay.corp.local
mydomain = corp.local
myorigin = $mydomain
# Interfaces d'écoute
# Écouter sur toutes les interfaces internes
inet_interfaces = all
inet_protocols = ipv4
# Réseaux autorisés à relayer
# IMPORTANT: Restreindre aux réseaux internes uniquement
mynetworks = 127.0.0.0/8, 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16
# Destination finale (ce serveur ne reçoit pas de mail)
mydestination = $myhostname, localhost.$mydomain, localhost
# Relay vers le smarthost
relayhost = [smtp.corp.local]:25
# Désactiver la réception de mail depuis l'extérieur
# Ce serveur est uniquement un relay sortant
smtpd_recipient_restrictions =
permit_mynetworks,
reject_unauth_destination
# Taille max des messages (50MB)
message_size_limit = 52428800
# Queue settings
maximal_queue_lifetime = 3d
bounce_queue_lifetime = 3d
# Logging
maillog_file = /var/log/maillog
Appliquer la Configuration
# Vérifier la syntaxe
sudo postfix check
# Recharger la configuration
sudo postfix reload
# Ou redémarrer
sudo systemctl restart postfix
# Vérifier les paramètres actifs
postconf -n
Relay avec Authentification (Smarthost)
Configuration SASL
# /etc/postfix/main.cf
# Smarthost avec port (587 pour submission)
relayhost = [smtp.office365.com]:587
# Authentification SASL
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_sasl_security_options = noanonymous
smtp_sasl_tls_security_options = noanonymous
# TLS obligatoire
smtp_use_tls = yes
smtp_tls_security_level = encrypt
smtp_tls_CAfile = /etc/pki/tls/certs/ca-bundle.crt
# Debian/Ubuntu: /etc/ssl/certs/ca-certificates.crt
# Logging TLS (debug)
smtp_tls_loglevel = 1
Fichier de Credentials
# Créer le fichier de mots de passe
sudo nano /etc/postfix/sasl_passwd
# Format: [serveur]:port utilisateur:mot_de_passe
[smtp.office365.com]:587 relay@corp.com:MotDePasseSecret
# Ou pour Gmail
[smtp.gmail.com]:587 compte@gmail.com:app-password
# Sécuriser et hasher
sudo chmod 600 /etc/postfix/sasl_passwd
sudo postmap /etc/postfix/sasl_passwd
# Vérifier que le fichier .db est créé
ls -la /etc/postfix/sasl_passwd*
# Recharger Postfix
sudo postfix reload
Exemple Office 365 / Microsoft 365
# /etc/postfix/main.cf - Configuration O365
myhostname = relay.corp.local
mydomain = corp.local
myorigin = $mydomain
inet_interfaces = all
inet_protocols = ipv4
mynetworks = 127.0.0.0/8, 10.0.0.0/8
mydestination = $myhostname, localhost.$mydomain, localhost
# Office 365 SMTP
relayhost = [smtp.office365.com]:587
# SASL Authentication
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_sasl_security_options = noanonymous
# TLS
smtp_use_tls = yes
smtp_tls_security_level = encrypt
smtp_tls_CAfile = /etc/pki/tls/certs/ca-bundle.crt
# Important pour O365: vérifier le certificat
smtp_tls_verify_cert_match = hostname
smtp_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
smtpd_recipient_restrictions = permit_mynetworks, reject_unauth_destination
Exemple Gmail
# /etc/postfix/main.cf - Configuration Gmail
relayhost = [smtp.gmail.com]:587
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_sasl_security_options = noanonymous
smtp_use_tls = yes
smtp_tls_security_level = encrypt
smtp_tls_CAfile = /etc/pki/tls/certs/ca-bundle.crt
# Gmail nécessite un "App Password" si 2FA activé
# https://myaccount.google.com/apppasswords
Relay Interne (Sans Auth)
Vers un Serveur Exchange Interne
# /etc/postfix/main.cf
myhostname = relay.corp.local
mydomain = corp.local
myorigin = $mydomain
inet_interfaces = all
inet_protocols = ipv4
# Réseaux internes autorisés
mynetworks = 127.0.0.0/8, 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16
mydestination = $myhostname, localhost.$mydomain, localhost
# Relay vers Exchange interne (pas d'auth nécessaire si IP whitelistée)
relayhost = [exchange.corp.local]:25
# Pas de TLS si réseau interne sécurisé
# smtp_use_tls = no
# Ou TLS opportuniste
smtp_tls_security_level = may
smtpd_recipient_restrictions = permit_mynetworks, reject_unauth_destination
Configuration Exchange pour Accepter le Relay
# Sur Exchange, créer un Receive Connector pour le relay Linux
New-ReceiveConnector -Name "Linux Relay" `
-TransportRole FrontendTransport `
-Usage Custom `
-Bindings 0.0.0.0:25 `
-RemoteIPRanges 10.0.0.0/8 `
-AuthMechanism None `
-PermissionGroups AnonymousUsers
# Autoriser le relay
Set-ReceiveConnector "Linux Relay" -RelayControlEnabled $true
Réécriture d'Adresses
Réécriture de l'Expéditeur
# /etc/postfix/main.cf
# Réécrire le From pour tous les mails sortants
smtp_generic_maps = hash:/etc/postfix/generic
# Optionnel: réécrire aussi l'enveloppe
sender_canonical_maps = hash:/etc/postfix/sender_canonical
# /etc/postfix/generic
# Format: adresse_locale adresse_reelle
root@relay.corp.local noreply@corp.com
www-data@relay.corp.local noreply@corp.com
cron@relay.corp.local noreply@corp.com
nagios@relay.corp.local monitoring@corp.com
@relay.corp.local noreply@corp.com
# Hasher
sudo postmap /etc/postfix/generic
sudo postfix reload
Réécriture par Expression Régulière
# /etc/postfix/main.cf
smtp_generic_maps = regexp:/etc/postfix/generic_regexp
# /etc/postfix/generic_regexp
# Réécrire tous les mails de serveurs internes
/^(.*)@srv[0-9]+\.corp\.local$/ ${1}@corp.com
/^root@(.*)$/ admin@corp.com
/^(.*)@localhost$/ noreply@corp.com
Header Rewriting
# /etc/postfix/main.cf
smtp_header_checks = regexp:/etc/postfix/header_checks
# /etc/postfix/header_checks
# Modifier le header From
/^From:.*<.*@localhost>$/ REPLACE From: "Server Notifications" <noreply@corp.com>
# Supprimer les headers sensibles
/^X-Originating-IP:/ IGNORE
/^Received:.*localhost/ IGNORE
Transport Maps (Routage Conditionnel)
Router selon le Domaine
# /etc/postfix/main.cf
transport_maps = hash:/etc/postfix/transport
# /etc/postfix/transport
# Format: domaine transport:destination
# Mails internes vers Exchange
corp.local smtp:[exchange.corp.local]:25
corp.com smtp:[exchange.corp.local]:25
# Partenaires via relay spécifique
partner.com smtp:[smtp.partner.com]:25
# Tout le reste via le smarthost par défaut
* smtp:[smtp.office365.com]:587
# Hasher
sudo postmap /etc/postfix/transport
sudo postfix reload
Router selon l'Expéditeur
# /etc/postfix/main.cf
sender_dependent_relayhost_maps = hash:/etc/postfix/sender_relay
# /etc/postfix/sender_relay
# Les alertes monitoring passent par un autre relay
nagios@corp.local [smtp-alerts.corp.local]:25
zabbix@corp.local [smtp-alerts.corp.local]:25
# Hasher
sudo postmap /etc/postfix/sender_relay
Sécurité
Restrictions d'Accès
# /etc/postfix/main.cf
# Restrictions sur les clients SMTP
smtpd_client_restrictions =
permit_mynetworks,
reject_unknown_client_hostname,
reject_rbl_client zen.spamhaus.org
# Restrictions sur les commandes HELO
smtpd_helo_required = yes
smtpd_helo_restrictions =
permit_mynetworks,
reject_invalid_helo_hostname,
reject_non_fqdn_helo_hostname
# Restrictions sur l'expéditeur
smtpd_sender_restrictions =
permit_mynetworks,
reject_non_fqdn_sender,
reject_unknown_sender_domain
# Restrictions sur le destinataire
smtpd_recipient_restrictions =
permit_mynetworks,
reject_unauth_destination,
reject_non_fqdn_recipient,
reject_unknown_recipient_domain
# Limiter le rate
smtpd_client_message_rate_limit = 100
smtpd_client_recipient_rate_limit = 100
# Banner personnalisé (masquer la version)
smtpd_banner = $myhostname ESMTP
TLS pour les Connexions Entrantes
# /etc/postfix/main.cf
# Certificat du serveur
smtpd_tls_cert_file = /etc/pki/tls/certs/relay.corp.local.crt
smtpd_tls_key_file = /etc/pki/tls/private/relay.corp.local.key
# TLS opportuniste pour les clients
smtpd_tls_security_level = may
# Protocoles et ciphers
smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
smtpd_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
# Logging
smtpd_tls_loglevel = 1
smtpd_tls_received_header = yes
Firewall
# Firewalld (RHEL/Rocky)
sudo firewall-cmd --permanent --add-service=smtp
sudo firewall-cmd --reload
# Ou limiter aux réseaux internes
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="10.0.0.0/8" service name="smtp" accept'
sudo firewall-cmd --reload
# UFW (Debian/Ubuntu)
sudo ufw allow from 10.0.0.0/8 to any port 25 proto tcp
sudo ufw reload
# iptables
iptables -A INPUT -p tcp --dport 25 -s 10.0.0.0/8 -j ACCEPT
iptables -A INPUT -p tcp --dport 25 -j DROP
Configuration des Clients
Configuration Linux (Serveurs Internes)
# /etc/postfix/main.cf (sur les serveurs clients)
# Relay via le serveur Postfix central
relayhost = [relay.corp.local]:25
# Identification
myhostname = serveur1.corp.local
myorigin = $myhostname
# Écouter uniquement en local
inet_interfaces = loopback-only
# Pas de réception de mail
mydestination =
Alternative: Utiliser msmtp (Léger)
# Installation
sudo dnf install msmtp msmtp-mta # RHEL
sudo apt install msmtp msmtp-mta # Debian
# /etc/msmtprc
defaults
auth off
tls off
logfile /var/log/msmtp.log
account default
host relay.corp.local
port 25
from %U@serveur1.corp.local
# Lier à sendmail
sudo ln -sf /usr/bin/msmtp /usr/sbin/sendmail
Configuration Applicative
# PHP (php.ini)
sendmail_path = "/usr/sbin/sendmail -t -i"
# Python
import smtplib
server = smtplib.SMTP('relay.corp.local', 25)
server.sendmail(from_addr, to_addr, message)
# Cron (envoyer les sorties par mail)
MAILTO=admin@corp.com
* * * * * /path/to/script.sh 2>&1
Monitoring et Logs
Analyse des Logs
# Voir les logs en temps réel
sudo tail -f /var/log/maillog # RHEL
sudo tail -f /var/log/mail.log # Debian
# Chercher les erreurs
sudo grep -i "error\|warning\|fatal\|reject" /var/log/maillog
# Statistiques avec pflogsumm
sudo dnf install postfix-perl-scripts # RHEL
sudo apt install pflogsumm # Debian
sudo pflogsumm /var/log/maillog
# Messages en queue
mailq
postqueue -p
# Nombre de messages en queue
mailq | tail -1
# Forcer le traitement de la queue
sudo postqueue -f
# Supprimer un message de la queue
sudo postsuper -d MESSAGE_ID
# Vider toute la queue (attention!)
sudo postsuper -d ALL
Script de Monitoring
#!/bin/bash
# /usr/local/bin/check_postfix.sh
# Vérifier le service
if ! systemctl is-active --quiet postfix; then
echo "CRITICAL: Postfix is not running"
exit 2
fi
# Vérifier la queue
QUEUE_SIZE=$(mailq | grep -c "^[A-F0-9]" 2>/dev/null || echo 0)
DEFERRED=$(mailq | grep -c "deferred" 2>/dev/null || echo 0)
if [ "$QUEUE_SIZE" -gt 1000 ]; then
echo "WARNING: Mail queue has $QUEUE_SIZE messages ($DEFERRED deferred)"
exit 1
fi
# Vérifier la connectivité vers le smarthost
SMARTHOST=$(postconf -h relayhost | tr -d '[]' | cut -d: -f1)
if [ -n "$SMARTHOST" ]; then
if ! nc -z -w5 "$SMARTHOST" 25 2>/dev/null; then
echo "CRITICAL: Cannot connect to smarthost $SMARTHOST"
exit 2
fi
fi
echo "OK: Postfix running, queue size: $QUEUE_SIZE"
exit 0
Intégration Prometheus
# Avec postfix_exporter
# https://github.com/kumina/postfix_exporter
# Installation
wget https://github.com/kumina/postfix_exporter/releases/download/v0.3.0/postfix_exporter-0.3.0.linux-amd64.tar.gz
tar xzf postfix_exporter-*.tar.gz
sudo mv postfix_exporter /usr/local/bin/
# Service systemd
# /etc/systemd/system/postfix_exporter.service
[Unit]
Description=Postfix Exporter
After=network.target
[Service]
Type=simple
ExecStart=/usr/local/bin/postfix_exporter --postfix.logfile_path=/var/log/maillog
Restart=always
[Install]
WantedBy=multi-user.target
Troubleshooting
Commandes de Diagnostic
# Tester l'envoi de mail
echo "Test message" | mail -s "Test from $(hostname)" admin@corp.com
# Test avec mailx verbose
echo "Test" | mailx -v -s "Test" admin@corp.com
# Tester la connexion SMTP manuellement
telnet relay.corp.local 25
# ou
nc -v relay.corp.local 25
# Test avec openssl (TLS)
openssl s_client -connect smtp.office365.com:587 -starttls smtp
# Vérifier la configuration
postconf -n # Paramètres modifiés
postconf -d # Paramètres par défaut
postconf mail_version # Version
# Vérifier la syntaxe
sudo postfix check
# Voir les maps
postmap -q "test@corp.local" hash:/etc/postfix/generic
Problèmes Courants
# ERREUR: "Relay access denied"
# → Vérifier mynetworks inclut l'IP du client
postconf mynetworks
# ERREUR: "Connection timed out"
# → Vérifier le firewall et la connectivité
telnet smtp.office365.com 587
traceroute smtp.office365.com
# ERREUR: "SASL authentication failed"
# → Vérifier les credentials
cat /etc/postfix/sasl_passwd
sudo postmap -q "[smtp.office365.com]:587" hash:/etc/postfix/sasl_passwd
# ERREUR: "TLS required but not available"
# → Vérifier smtp_use_tls et les certificats CA
openssl s_client -connect smtp.office365.com:587 -starttls smtp
# Messages bloqués en queue "deferred"
mailq
postcat -q MESSAGE_ID # Voir le contenu
sudo postsuper -r MESSAGE_ID # Retenter
# Voir les détails d'un message en queue
sudo find /var/spool/postfix -name "MESSAGE_ID*" -exec cat {} \;
Debug Mode
# Activer le debug pour un domaine
# /etc/postfix/main.cf
debug_peer_list = smtp.office365.com
debug_peer_level = 3
# Recharger et tester
sudo postfix reload
echo "test" | mail -s "debug test" user@office365.com
sudo tail -f /var/log/maillog
Haute Disponibilité
Deux Relays avec MX
# DNS
relay1.corp.local A 10.0.0.10
relay2.corp.local A 10.0.0.11
relay.corp.local MX 10 relay1.corp.local
relay.corp.local MX 20 relay2.corp.local
# Configuration identique sur les deux serveurs
# Les clients utilisent relay.corp.local
Avec Keepalived (VIP)
# /etc/keepalived/keepalived.conf (sur relay1 - MASTER)
vrrp_instance POSTFIX_VIP {
state MASTER
interface eth0
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass secret123
}
virtual_ipaddress {
10.0.0.100/24
}
track_script {
check_postfix
}
}
vrrp_script check_postfix {
script "/usr/local/bin/check_postfix.sh"
interval 5
weight -20
}
Bonnes Pratiques
Checklist Postfix Relay:
Configuration:
- [ ] mynetworks restreint aux IPs internes
- [ ] relayhost configuré vers smarthost
- [ ] TLS activé (smtp_use_tls)
- [ ] Credentials sécurisés (chmod 600)
Sécurité:
- [ ] smtpd_recipient_restrictions configuré
- [ ] Firewall limitant l'accès au port 25
- [ ] Banner personnalisé (masquer version)
- [ ] Pas d'open relay!
Réécriture:
- [ ] Adresses From cohérentes
- [ ] generic_maps si nécessaire
- [ ] Headers sensibles supprimés
Monitoring:
- [ ] Alertes sur queue > seuil
- [ ] Monitoring service Postfix
- [ ] Logs centralisés
- [ ] Rotation des logs
Maintenance:
- [ ] Test d'envoi régulier
- [ ] Purge queue si nécessaire
- [ ] Mises à jour de sécurité
- [ ] Documentation des flux
Voir aussi :
- Boot & Services - Gestion systemd
- SSH Hardening - Sécurisation
- Firewall UFW - Configuration firewall
- NXLog - Envoi de logs (alertes mail)