Postfix¶
Rôle¶
Point d'entrée SMTP interne (MTA minimal) de l'infrastructure Indio : reçoit le courrier applicatif adressé à @infra.indio (notifications, tickets, alertes) et le livre localement dans la boîte Unix root sur le nœud qui l'a reçu.
Ce n'est pas un relais SMTP sortant
Aucun relayhost n'est configuré dans main.cf : ce service ne relaie aucun courrier vers une messagerie externe (Gmail, etc.) ni vers Internet. C'est un MTA de livraison locale pour le domaine interne, restreint aux réseaux internes (mynetworks) — pas un smarthost sortant.
Architecture¶
- 2 nœuds, zone service (
seg-service) : INDSERV009 (10.100.2.138), INDSERV010 (10.100.2.139) (nomméspostfix-01/postfix-02avant la migration vers la conventionIND<SEGMENT><NNN>, comme en atteste le journalapply.logdu dépôt), 1 vCPU / 2 Go chacun, clones du template Rocky 9.6 durci. - Détruites le 2026-07-07 (round de décommissionnement SOC/service, voir Historique des décommissionnements), redéployées le 2026-07-17 (VM nues d'abord, code Terraform inchangé), puis dotées d'un rôle Ansible applicatif le même jour (
postfix_relay) suite à l'alerting Zabbix SLA qui a mis en évidence l'absence de service mail fonctionnel. - IP allouées dynamiquement via NetBox (
data netbox_ip_addresses, une entrée par nœud). - Aucune répartition de charge ni haute disponibilité (pas de VIP keepalived) : les 2 nœuds sont des instances Postfix indépendantes et identiques, un client doit choisir explicitement l'un des deux — aucun mécanisme de bascule automatique.
mynetworks=127.0.0.0/8,10.100.0.0/16(zone admin),10.15.0.0/16(zone management) — tout le reste est rejeté (reject_unauth_destination).mydestinationinclutinfra.indio: Postfix se considère responsable de la livraison finale pour ce domaine (livraison locale, pas de relais vers un MX externe).
Structure du dépôt¶
| Fichier / dossier | Contenu |
|---|---|
main.tf |
Ressource vsphere_virtual_machine.postfix, for_each sur var.nodes |
variables.tf |
nodes par défaut [INDSERV009, INDSERV010], cpu=1, ram=2048 |
ansible/site.yml |
Rôle unique postfix_relay |
ansible/roles/postfix_relay/tasks/main.yml |
Paquet, main.cf, alias, firewalld |
ansible/roles/postfix_relay/templates/main.cf.j2 |
Config Postfix (mynetworks, mydestination, restrictions) |
ansible/group_vars/postfix.yml |
Domaine, réseaux autorisés, alias |
Flux de courrier¶
flowchart LR
App["Applications internes<br/>(GLPI, Zabbix, scripts...)"] -->|"SMTP 25<br/>mynetworks 10.100.0.0/16 + 10.15.0.0/16"| PFX1["INDSERV009<br/>10.100.2.138"]
App -->|"SMTP 25<br/>(nœud alternatif, pas de VIP/LB)"| PFX2["INDSERV010<br/>10.100.2.139"]
PFX1 -->|"mydestination = infra.indio<br/>livraison locale"| MB1[("/var/mail/root<br/>sur INDSERV009")]
PFX2 -->|"mydestination = infra.indio<br/>livraison locale"| MB2[("/var/mail/root<br/>sur INDSERV010")]
NoRelay["Aucun relayhost —<br/>pas de sortie vers Internet"]
PFX1 -.- NoRelay
PFX2 -.- NoRelay
Provisioning Terraform¶
main.tf: ressourcevsphere_virtual_machine.postfixavecfor_eachsurvar.nodes(2 objetsname), même schéma multi-nœuds que le dépôt k8s.- Variables clés (
variables.tf) :nodespar défaut[INDSERV009, INDSERV010],vsphere_network=seg-service,vm_cpu= 1,vm_ram= 2048. - Providers (
versions.tf) :hashicorp/vsphere+e-breuninger/netbox. - Sortie
vms: map nom de VM → adresse IP.
Configuration Ansible¶
Playbook ansible/site.yml, rôle unique postfix_relay sur le groupe postfix (inventory.ini) :
- Installe le paquet distro
postfix(pas de tarball ni de source tierce). - Déploie
main.cf(templatemain.cf.j2) :myhostnamedérivé deinventory_hostname | lower(Postfix n'exige pas de hostname minuscule comme FreeIPA, mais la convention est appliquée par cohérence),mydomain=infra.indio,myorigin = $mydomain,inet_interfaces = all,inet_protocols = ipv4,mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain,mynetworks= listepostfix_mynetworks(group_vars),smtpd_relay_restrictions/smtpd_recipient_restrictions=permit_mynetworks, reject_unauth_destination,compatibility_level = 2. - Alias locaux (
/etc/aliases,ansible.builtin.lineinfilepar entrée depostfix_aliases) :bjeyakumar → root— régénération de la base (newaliases) uniquement si un alias a changé. - Ouvre le service
smtpen firewalld (zonedrop). - Démarre et active le service.
Variables (group_vars/postfix.yml) : postfix_domain: infra.indio, postfix_mynetworks (3 CIDR), postfix_aliases (liste name/dest).
Aucun secret ansible-vault dans ce rôle — pas d'authentification SMTP, pas de TLS configuré (smtpd_tls_* absent de main.cf), cohérent avec un service restreint aux réseaux internes uniquement.
Procédure de déploiement¶
- Réservation IP NetBox préalable obligatoire : la data source
netbox_ip_addressesdumain.tféchoue (no result) siINDSERV009.infra.indio/INDSERV010.infra.indion'ont pas déjà une IP réservée côté NetBox —terraform plan/applyne créent aucune IP eux-mêmes. Script dédié idempotent :python3 /root/netbox/seed/add_postfix_vms.py(ne rejoue pas tout le seed, voir NetBox). terraform apply→ provisionne les 2 VM nues.ansible-playbook site.yml→ installe et configure Postfix (mynetworks, alias, firewalld) sur les 2 nœuds.
Contrôle de santé / Vérification¶
systemctl status postfix
postqueue -p # file d'attente
journalctl -u postfix -f # ou /var/log/maillog selon la distro
# Test d'envoi depuis un hôte du réseau mynetworks :
echo "test" | mail -s "test postfix" root@infra.indio -S smtp=10.100.2.138:25
ssh indio-adm@10.100.2.138 'sudo tail /var/mail/root' # confirme la livraison locale
Testé bout en bout le 2026-07-17 (curl SMTP depuis INDSUPV001 → queue → livraison confirmée dans /var/mail/root).
Points d'attention¶
- Consommateur identifié mais non branché : le rôle Ansible GLPI (
glpi/ansible/roles/glpi/tasks/main.yml) active le booléen SELinuxhttpd_can_sendmailpar anticipation pour ses notifications de tickets par email, mais aucun relayhost n'est configuré côté GLPI vers Postfix à ce jour — l'intégration reste à faire (voir GLPI). - Pas de TLS sur le SMTP interne (
smtpd_tls_*absent demain.cf) — acceptable tant que le service reste restreint aux réseaux internes de confiance (mynetworks), mais toute extension future (SMTP authentifié, exposition plus large) nécessiterait de l'ajouter. - Aucune haute disponibilité réelle malgré 2 nœuds : pas de VIP keepalived ni de round-robin DNS documenté — un client doit choisir explicitement un nœud, sans bascule automatique en cas de panne.
- Courrier consultable uniquement par SSH (
/var/mail/root, format mailbox Unix) — pas de webmail, pas d'IMAP/POP3 : décision volontairement laissée au user plutôt que prise à sa place, un vrai relais vers une messagerie externe reste un gap fonctionnel identifié si le besoin se présente. - Aucune autre référence croisée à Postfix/SMTP trouvée dans les autres dépôts examinés (Zabbix, HAProxy) au-delà de GLPI : si d'autres services (alertes Zabbix, notifications diverses) doivent utiliser ce relais, l'intégration reste à faire au cas par cas.