Référence : Serveur SMTP
Documentation complète du serveur SMTP SendAs.me : commandes supportées, capacités, TLS et limites.
Informations de connexion
| Paramètre | Valeur |
|---|---|
| Hôte | Configuré via SMTP_HOST (exposé via DNS) |
| Port | 587 (configurable via SMTP_PORT) |
| Sécurité | STARTTLS (obligatoire en production) |
| Authentification | LOGIN obligatoire |
| Port 25 | Non supporté (pas d'open relay) |
| Port 465 | Non supporté (SSL implicite) |
Bannière SMTP
Lors de la connexion, le serveur répond :
220 sendas.me ESMTP SendAs.me Gateway 1.0
Le nom d'hôte dans la bannière est configurable via SMTP_HOSTNAME.
Commandes SMTP supportées
EHLO
Annonce les capacités du serveur. Réponse typique avant STARTTLS :
250-sendas.me
250-SIZE 26214400
250-STARTTLS
250-AUTH LOGIN
250 HELP
Réponse après STARTTLS :
250-sendas.me
250-SIZE 26214400
250-AUTH LOGIN PLAIN
250 HELP
Le serveur n'autorise pas l'authentification avant STARTTLS. Si un client tente d'envoyer AUTH LOGIN avant de démarrer TLS, il recevra une erreur 530 5.7.0 Must issue a STARTTLS command first.
STARTTLS
Démarre la négociation TLS sur la connexion existante.
Client: STARTTLS
Server: 220 2.0.0 Ready to start TLS
[Négociation TLS]
Client: EHLO votreapp
Server: 250-sendas.me
250-AUTH LOGIN PLAIN
...
Protocoles TLS supportés : TLSv1.2, TLSv1.3
Suites cryptographiques : Définies par la bibliothèque Python ssl (recommandations NIST)
AUTH LOGIN
Méthode d'authentification principale. Les credentials sont envoyés en base64.
Client: AUTH LOGIN
Server: 334 VXNlcm5hbWU6 (base64 de "Username:")
Client: bW9uYXBw (base64 de l'app_id)
Server: 334 UGFzc3dvcmQ6 (base64 de "Password:")
Client: c2VrX3h4eHh4eA== (base64 de la send_key)
Server: 235 2.7.0 Authentication successful
AUTH PLAIN
Méthode alternative supportée (moins courante).
Client: AUTH PLAIN <base64(\0username\0password)>
Server: 235 2.7.0 Authentication successful
MAIL FROM
Définit l'expéditeur. L'adresse doit correspondre au compte OAuth connecté.
Client: MAIL FROM:<alice@gmail.com>
Server: 250 2.1.0 OK
Vérification : Le serveur vérifie que l'adresse MAIL FROM correspond à un oauth_credential.email actif pour cette application.
RCPT TO
Définit un ou plusieurs destinataires.
Client: RCPT TO:<bob@example.com>
Server: 250 2.1.5 OK
Client: RCPT TO:<charlie@example.com>
Server: 250 2.1.5 OK
DATA
Transmit le contenu du message MIME.
Client: DATA
Server: 354 End data with <CR><LF>.<CR><LF>
Client: From: alice@gmail.com
To: bob@example.com
Subject: Test
Corps du message.
.
Server: 250 2.0.0 OK: queued
QUIT
Ferme proprement la connexion.
Client: QUIT
Server: 221 2.0.0 Bye
RSET
Réinitialise la session sans fermer la connexion. Permet d'envoyer plusieurs messages dans une même session.
Client: RSET
Server: 250 2.0.0 OK
NOOP
Vérifie que la connexion est toujours active. Utile comme keepalive.
Client: NOOP
Server: 250 2.0.0 OK
Commandes non supportées
| Commande | Raison |
|---|---|
VRFY | Désactivé (prévient l'énumération d'adresses) |
EXPN | Désactivé |
ETRN | Non applicable |
BDAT | Non implémenté (utiliser DATA) |
Codes de réponse
| Code | Signification |
|---|---|
220 | Service prêt |
221 | Service fermant la connexion |
235 | Authentification réussie |
250 | Commande OK |
334 | Défi AUTH (intermédiaire) |
354 | Début du contenu DATA |
421 | Service temporairement indisponible |
450 | Boîte mail temporairement indisponible |
451 | Erreur locale — réessayez plus tard |
500 | Syntaxe de commande invalide |
501 | Syntaxe des paramètres invalide |
503 | Mauvaise séquence de commandes |
530 | Authentification requise / STARTTLS requis |
535 | Authentification échouée (credentials invalides) |
550 | Action impossible — boîte invalide |
552 | Message trop grand |
Limites et contraintes
| Paramètre | Valeur | Variable d'environnement |
|---|---|---|
| Taille max d'un message | 25 Mo | SMTP_MAX_MESSAGE_SIZE |
| Connexions simultanées | 100 | SMTP_MAX_CONNECTIONS |
| Timeout de session | 300 secondes | SMTP_TIMEOUT |
| Destinataires par message | 100 | Non configurable |
| Longueur maximale d'une ligne | 998 caractères (RFC 5321) | — |
Flux d'authentification détaillé
1. Client se connecte sur port 587
2. Postfix envoie la bannière 220
3. Client envoie EHLO
4. Postfix liste les capabilities (incluant STARTTLS)
5. Client envoie STARTTLS
6. Postfix répond 220 — négociation TLS (TLSv1.2 ou 1.3)
7. Client renvoie EHLO (sur la connexion chiffrée)
8. Postfix liste les capabilities (incluant AUTH LOGIN PLAIN)
9. Client envoie AUTH LOGIN
10. Postfix (via Dovecot SASL) demande le username (base64)
11. Client envoie l'app_id en base64
12. Dovecot demande le password (base64)
13. Client envoie la send_key en base64
14. Dovecot vérifie dans /conf/dovecot.passwd (format {PLAIN})
- Si OK : 235 Authentication successful
- Si KO : 535 Authentication credentials invalid
15. Postfix passe l'email au transport pipe (send.py)
16. send.py appelle l'API interne (/internal/*) pour identifier le plugin OAuth
17. Le plugin Gmail ou Office 365 envoie l'email via l'API REST
Implémentation technique
Le serveur SMTP est implémenté avec Postfix + Dovecot :
- Postfix gère le protocole SMTP (port 587, STARTTLS)
- Dovecot gère l'authentification SASL (via
/conf/dovecot.passwd) - Le fichier
dovecot.passwdest régénéré automatiquement à chaque création/modification/suppression d'app (viareload_server.pysur le port 8081 interne) - Le transport
default_transport = gatewaydélègue chaque message au scriptsend.py send.pyutiliseinternal_clientpour accéder aux users, tokens et credentials OAuth via l'API interne- Les tokens OAuth sont chiffrés (Fernet) et jamais écrits en clair
Postfix (587) → Dovecot SASL → AUTH OK
↓
Transport pipe → send.py
↓
internal_client → /internal/users, /internal/tokens
↓
Plugin Gmail / Office 365 → Gmail API / Graph API