# Email — Relay SMTP via Postfix → Gmail ## Architecture ``` Hermes / AlertManager / cron / kubectl │ ▼ Postfix (storage-01 :25) smtp_generic_maps → réécrit l'expéditeur en aliyesilkaya93@gmail.com │ SASL + TLS (App Password) ▼ smtp.gmail.com:587 │ ▼ aliyesilkaya93@gmail.com ``` Postfix est configuré en **relay-only** sur storage-01 : aucune livraison locale, tous les mails transitent vers Gmail SMTP. Les réseaux autorisés à relayer : `127.0.0.0/8`, `192.168.10.0/24`, pods k8s (`10.42.0.0/16`), services k8s (`10.43.0.0/16`). **Pourquoi Gmail et pas Brevo ?** Brevo exige de posséder un domaine vérifié (SPF/DKIM) pour relayer. Gmail SMTP avec App Password ne nécessite aucun domaine. --- ## Prérequis — Google App Password La vérification en 2 étapes Google doit être activée sur le compte. 1. `myaccount.google.com` → Sécurité → Validation en 2 étapes → Activer 2. `myaccount.google.com/apppasswords` → Nouveau → nom `funk-postfix` → Créer 3. Google génère un code 16 caractères (ex: `abcd efgh ijkl mnop`) — c'est le mot de passe SMTP --- ## Installation ### 1. Ajouter le App Password dans le vault ```bash make vault-edit ``` Modifier ou ajouter : ```yaml vault_postfix_relay_password: "xxxx xxxx xxxx xxxx" # App Password Google 16 caractères (avec espaces, OK) ``` ```bash make vault-encrypt ``` ### 2. Vérifier les vars gateway Dans `ansible/group_vars/gateway/vars.yml` : ```yaml postfix_relay_host: smtp.gmail.com postfix_relay_port: 587 postfix_relay_user: "aliyesilkaya93@gmail.com" postfix_sender_email: "aliyesilkaya93@gmail.com" ``` ### 3. Déployer ```bash make apply-storage # ou cibler uniquement le rôle : ansible-playbook -i inventory.yml playbooks/storage-01.yml --tags postfix_relay ``` --- ## Vérification ### Test depuis storage-01 ```bash echo "Test Funk Lab - $(date)" | sudo mail -s "[Funk] Test postfix" aliyesilkaya93@gmail.com ``` ### Suivre les logs en temps réel ```bash sudo journalctl -u postfix -f --no-pager --output=cat ``` Résultat attendu : `status=sent (250 2.0.0 OK ... - gsmtp)` ### Vérifier / vider la file d'attente ```bash sudo mailq # lister les mails en attente sudo postqueue -f # forcer le flush sudo postsuper -d ALL # vider la queue (mails échoués) ``` ### Vérifier la réécriture expéditeur ```bash sudo postconf smtp_generic_maps sudo cat /etc/postfix/generic ``` --- ## Utilisation depuis les services ### Depuis storage-01 (shell / cron / Hermes) ```bash echo "Corps du mail" | sudo mail -s "[Funk] Sujet" aliyesilkaya93@gmail.com ``` Via Python (dans un skill Hermes) : ```python import smtplib from email.message import EmailMessage msg = EmailMessage() msg['Subject'] = '[Funk] Alerte' msg['From'] = 'aliyesilkaya93@gmail.com' msg['To'] = 'aliyesilkaya93@gmail.com' msg.set_content('Contenu du mail') with smtplib.SMTP('127.0.0.1', 25) as s: s.send_message(msg) ``` ### Depuis AlertManager (k8s) Dans `k8s/infra/monitoring/values.yaml` : ```yaml alertmanager: config: receivers: - name: email email_configs: - to: aliyesilkaya93@gmail.com from: aliyesilkaya93@gmail.com smarthost: "192.168.10.1:25" require_tls: false # TLS géré par Postfix vers Gmail, pas sur le LAN interne route: receiver: email ``` ### Depuis n'importe quel pod k8s SMTP relay accessible sur `192.168.10.1:25` depuis tout le cluster. --- ## Dépannage | Symptôme | Cause probable | Action | |---|---|---| | `Connection refused` sur :25 | postfix non démarré | `sudo systemctl status postfix` | | `Relay access denied` | IP source hors mynetworks | `sudo postconf mynetworks` | | `Authentication failed` | App Password révoqué ou 2FA désactivé | Régénérer dans `myaccount.google.com/apppasswords` | | Mail jamais reçu | Réécriture expéditeur manquante | Vérifier `/etc/postfix/generic` et `postconf smtp_generic_maps` | | Mail en spam | Expéditeur non reconnu | Normal si From ≠ aliyesilkaya93@gmail.com | | Queue bloquée | Ancien mail échoué en retry | `sudo postsuper -d ALL` puis retester | --- ## Configuration Ansible - **Rôle** : `ansible/roles/postfix_relay/` - **Vars** : `ansible/group_vars/gateway/vars.yml` → `postfix_relay_*`, `postfix_sender_email` - **Secret** : `vault_postfix_relay_password` dans `ansible/group_vars/all/vault.yml` - **Templates** : `main.cf.j2`, `sasl_passwd.j2` - **Sender rewrite** : `/etc/postfix/generic` (déployé par le rôle, postmap automatique) - **nftables** : port 25 ouvert automatiquement depuis `192.168.10.0/24` --- ## État vérifié — 2026-06-05 - **postfix.service** : Actif (running) depuis 3 jours, 4 processus, 12.260s CPU - **Relayhost** : smtp.gmail.com:587 (TLSv1.3, cipher TLS_AES_256_GCM_SHA384) - **SASL** : Authentification activée, options sécurisées - **TLS** : Chiffrement encrypté, CAfile=/etc/ssl/certs/ca-bundle.crt - Aucune divergence avec la documentation, état conforme