Envoyer des mails depuis un serveur avec mSMTP
Rédigé par Marc GUILLAUME | 2 commentairesDans la section ISPMail/Mail façon FAI vous trouverez toutes les informations nécessaires à la configuration d'un serveur de mail de qualité professionnelle. Mais il existe de nombreux cas où vous pouvez désirer qu'un serveur puisse envoyer du courrier sans pour autant le transformer en serveur de courrier complet. Il faut alors utiliser un « smarhost », c'est à dire un serveur smtp pour relayer votre courrier.
Le MTA (Mail Transfer Agent) léger msmtp répond parfaitement à ce besoin. Si vous avez plusieurs serveurs et que vous avez sur l'un d'eux configuré un serveur de mail, il sera intéressant de faire en sorte que vos autres serveurs puissent l'utiliser pour acheminer leur courrier. Vous pouvez également vouloir utiliser le serveur de votre FAI, ou ceux d'une plateforme comme Gmail.
Dans un précédent article j'utilisais pour répondre à ce besoin un autre MTA léger, ssmtp. Mais ce dernier n'est plus maintenu et a été retiré des dépôts Debian pour la version 10 Stretch. Heureusement il est avantageusement remplacé par msmtp, dont la configuration est aussi simple mais qui est plus souple d'emploi.
Quand utiliser un MTA léger type msmtp ?
Vous pouvez vouloir utiliser un tel logiciel dans plusieurs situations :
- Vous voulez que votre serveur, ou un service de monitoring sur ce serveur vous envoie régulièrement des mails pour vous tenir informé d'éventuels problèmes ;
- pour pouvoir réaliser ces envois vous ne voulez cependant pas devoir transformer votre serveur en serveur mail (ce qui implique de la configuration, la déclaration de la machine dans le spf etc.) ;
- vous disposez déjà d'un serveur de mail complet doté d'un anti-spam, d'un anti-virus, sachant signer les messages avec une clé dkim et qui figure dans les enregistrements DNS de votre ou vos domaine(s) ;
- vous hébergez des sites web et vous voulez que vos sites puissent envoyer des courriers et que ceux-ci répondent aux normes modernes (signature dkim, enregistrements spf et dmarc).
Installation de msmtp
Le programme est dans les dépôts Debian, il suffit donc de lancer une commande :
apt install msmtp-mta
pour l'installer.
Configuration de msmtp
Les configurations de msmtp se font grâce à un fichier /etc/msmtprc
(facultatif) qui permet de définir une configuration par défaut pour les utilisateurs n'ayant pas de configuration personnalisée, puis par des fichiers .msmtprc situés dans le répertoire home de chaque utilisateur du système pour les configurations personnalisées. Ceci permet d'avoir une configuration générale pour le server et une configuration différente pour chaque utilisateur sans aucune difficulté.
Configuration par défaut
Une configuration typique consisterait à définir pour tout le serveur un smarthost à utiliser, un utilisateur par défaut pour se connecter à ce smarthost, le port auquel se connecter, l'adresse mail figuant dans l'entête from du mail et l'obligation d'utiliser le chiffrement TLS pour les connexions (ou STARTTLS). Pour tous les utilisateurs n'ayant pas de fichier .msmtprc
dans leur /home
msmtp utilisera ce fichier par défaut. Toute cette configuration se trouvant dans le fichier /ets/msmtprc
, quelque chose dans ce genre :
account default host mail.example.net from admin@example.net auto_from off add_missing_from_header on auth on port 587 user admin@example.net password Y8eqFDJNFPTp logfile ~/.msmtp.log tls on tls_starttls on tls_trust_file /etc/ssl/certs/ca-certificates.crt
Pour tous les utilisateurs qui n'ont pas une configuration spécifique, msmtp utilisera ce fichier pour acheminer le courrier. Les mails seront envoyés au serveur mail.example.net avec comme expéditeur admin@example.net. Il faut bien entendu que l'utilisateur utilisé pour l'authentification existe sur le smarthost (ici admin@example.net). Le mot de passe figure en clair dans le fichier, nous verrons plus bas comment éviter cela si cela vous chagrine (mais ça complique pas mal les choses).
Configuration spécifique à un utilisateur
On peut ensuite, selon les besoins, créer dans leur répertoire home un fichier /home/nomuser/.msmtprc
qui contiendra les informations nécessaires à l'envoi de mail (serveur smtp et informations de connexion).
Si par exemple vous hébergez un blog en utilisant le serveur Apache et le mode suexec, vous faites tourner Apache sous le nom de l'utilisateur à qui appartient l'arborescence de votre site de blog. En postulant que votre utilisateur s'appelle blog, le home de blog sera par exemple /var/www/monblog/
. Dans ce répertoire vous pourriez mettre un fichier .msmtprc de ce type :
account default host smtp.laposte.net from toto@laposte.net auto_from off add_missing_from_header on auth on port 587 user toto@laposte.net password Xu7OeboAyADn logfile ~/.msmtp.log tls on tls_starttls on tls_trust_file /etc/ssl/certs/ca-certificates.crt
Et si par exemple vous utilisez la fonction mail de php en ayant déclaré msmtp dans votre php.ini, votre blog enverra ses courriers via le smtp de la poste, sous l'identité toto@laposte.net.
Certains CMS utilisent des classes (comme PhpMailer) qui savent envoyer les mails directement à un smarthost. Mais si vous utilisez simplement la fonction mail de php, vous pouvez déclarer msmtp comme méthode d'envoi, ce qui vous permattra avec la fonction mail d'utiliser un smarthost. Il suffit de rajouter la ligne suivante dans le php.ini que vous utilisez :
sendmail_path = /usr/sbin/sendmail -t -icomme
/usr/sbin/sendmail
est en fait un lien symbolique sur/usr/bin/msmtp
php enverra ses courriers via msmtp.
Le stockage du mot de passe
Avec tous les serveurs smtp, sauf à être dans leur réseau de confiance, on ne peut faire relayer ses mails qu'une fois que l'on est authentifié (c'est à dire que l'on a prouvé au serveur qu'on avait accès à un de ses comptes capable d'envoyer des mails). Cette authentfication se fait généralement par nom d'utilisateur et mot de passe, et ces informations doivent être transmises chiffrées. La transmission chiffrée est assurée par TLS. Mais qu'en est-il du mot de passe qui doit figurer quelque part sur votre serveur pour que msmtp puisse le transmettre au serveur smtp ?
Jusqu'à présent dans nos exemples, le mot de passe figurait en clair dans le fichier .msmtprc.
C'est une possible faille de sécurité si vous ne soignez pas les droits de vos fichiers pour que personne d'autre que le possesseur du fichier puisse le lire. Dans sa documentation en ligne le développeur explique les 5 façons dont msmtp peut stocker le mot de passe d'identification, et les méthodes qu'il supporte pour le transmettre au serveur.
Il recommande les deux premières façons :
- l'utilisation d'un porte-clés (key ring), qui est un logiciel stockant les identifiants et mots de passe d'un système en mémoire. Mais les seuls systèmes supportés sont Gnome key ring et Keychain de Mac OSX. Ceci est envisageable si l'on utilise msmtp sur un poste de travail mais sur un serveur on ne va pas installer Gnome, et nous utilisons un serveur Debian et non un système Apple.
- L'utilisation de GPG pour chiffrer le mot de passe. Il faut pour cela installer GnuPG et son agent, générer une clé GPG et l'utiliser pour chiffrer votre mot de passe. À chaque démarrage du système il faudra fournir la passe-phrase de la clé à l'agent GPG. C'est assez contraignant, à vous de voir si vous en avez absolument besoin.
Pour ma part, j'ai tendance à penser que si vous donnez des droits 600 à votre fichier .msmtprc, le risque est acceptable (et si d'ailleurs vous ne le faites pas msmtp refusera d'envoyer vos mails).
Si votre serveur est compromis et que quelqu'un arrive à devenir root ou simplement exécuter un script en tant qu'un des utilisateurs de votre système, il pourra bien entendu voir tous les mots de passe ou le mot de passe figurant dans le fichier de l'utilisateur dont il usurpe l'identité. Mais si vous avez chiffré votre mot de passe avec GnuPG et que l'agent ait le mot de passe en clair en mémoire, l'intrus ne verra certes pas le mot de passe, mais pourra envoyer tous les courriers qu'il veut. La seule limitation pourra alors venir de votre smarthost qui peut refuser d'envoyer plus qu'un certain nombre de mail par période de temps pour un utilisateur.
Si vraiment la présence d'un mot de passe en clair vous est odieuse ou qu'il y ait beaucoup d'utilisateurs accédant à votre machine, voici comment utiliser GnuPG et la commande passwordeval de msmtp pour chiffrer vos mots de passe.
Chiffrement du mot de passe avec GnuPG
On commence par installer les programmes nécessaires :
apt install gnupg gnupg-agent
Ensuite commencent les choses sérieuses, il faut d'abord générer sa clé avec passphrase. Sans passphrase n'importe quel intrus pourrait déchiffre votre mot de passe comme le fait msmtp.
La passphrase est simplement un chaîne suffisemment longue et complexe qui sert à chiffrer la clé GnuPG elle-même et à la déchiffrer pour pouvoir l'utiliser. Comme nous sommes sur un serveur et que vous ne pouvez saisir la passphrase à chaque besoin d'envoi, la passphrase déchiffrée est gardée en mémoire par un programme gpg-agent qui fournit cette information à des programmes comme msmtp.
Lors de la génération vont vous être posées différentes questions. Voici à quoi ressemble le questionnaire :
[20:38:35] root@srv1.mydomain.net : [~] # gpg --full-generate-key gpg (GnuPG) 2.1.18; Copyright (C) 2017 Free Software Foundation, Inc. This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Please select what kind of key you want: (1) RSA and RSA (default) (2) DSA and Elgamal (3) DSA (sign only) (4) RSA (sign only) Your selection? 1 RSA keys may be between 1024 and 4096 bits long. What keysize do you want? (3072) Requested keysize is 3072 bits Please specify how long the key should be valid. 0 = key does not expire= key expires in n days w = key expires in n weeks m = key expires in n months y = key expires in n years Key is valid for? (0) 10y Key expires at Sat 08 Dec 2029 08:45:25 PM CET Is this correct? (y/N) y GnuPG needs to construct a user ID to identify your key. Real name: Toto LESBONNESHISTOIRES Email address: toto@laposte.net Comment: You selected this USER-ID: "Toto LESBONNESHISTOIRES " Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O We need to generate a lot of random bytes. It is a good idea to perform some other action (type on the keyboard, move the mouse, utilize the disks) during the prime generation; this gives the random number generator a better chance to gain enough entropy. gpg: key 9FC9759BD0EA2805 marked as ultimately trusted gpg: directory '/root/.gnupg/openpgp-revocs.d' created gpg: revocation certificate stored as '/root/.gnupg/openpgp-revocs.d/0BCD1DA5B34581AFF5F57ACB9FC9759BD0EA2805.rev' public and secret key created and signed. pub rsa3072 2019-12-11 [SC] [expires: 2029-12-08] 0BCD1DA5B34581AFF5F57ACB9FC9759BD0EA2805 0BCD1DA5B34581AFF5F57ACB9FC9759BD0EA2805 uid Toto LESBONNESHISTOIRES sub rsa3072 2019-12-11 [E] [expires: 2029-12-08]
En général pour générer de l'entropie je lance dans un autre terminal ssh la commande tree /
ça occupe le processeur et le disque. Lors de la génération de la clé (ça n'apparaît pas ici) vous sera demandée votre passphrase. Il faudra la garder bien précieusement (par exemple en utilisant le logiciel keepass), car elle vous sera demandée à chaque lancement de l'agent gpg. Pour générer une clé complexe vous pouvez par exemple lancer la commande :
pwgen -1sncy 40
Si vous n'avez pas installé pwgen :
apt install pwgen
Vous allez maintenant pouvoir créer dans le répertoire de votre user le fichier contenant le mot de passe, puis chiffrer ce fichier avec GnuPG. Nous avons dit que le mot de passe de toto@laposte.net était Xu7OeboAyADn. Vous créez donc un fichier contenant cette valeur :
echo 'Xu7OeboAyADn' > .msmtp-password
Puis vous allez lancer la commande de chiffrement :
gpg --encrypt .msmtp-password
Le programme va vous demander votre ID (ici votre nom soit Toto LESBONNESHISTOIRES) et vous allez obtenir un fichier .msmtp-password.gpg. Vous supprimerez .msmtp-password et vous vous assurerez de donner le fichier .msmtp-password.gpg à votre utilisateur avec les droits 600.
rm .msmtp-password chown toto:toto .msmtp-password.gpg chmod 600 .msmtp-password.gpg
Puis vous allez déclarer ce fichier dans votre fichier .msmtprc en remplaçant les lignes :
user toto@laposte.net password Xu7OeboAyADn
par la ligne :
passwordeval gpg --no-tty -q -d ~/.msmtp-password.gpg
Vous pouvez vérifier que l'agent gpg tourne :
# ps aux | grep gpg root 5929 0.0 0.0 91596 1332 ? Ss 20:37 0:01 gpg-agent --homedir /root/.gnupg --use-standard-socket --daemon
La passphrase de la clé est gardée par l'agent gpg qui la passe à la commande passwordeval de msmtp pour qu'il puisse déchiffrer le mot de passe. Si un intrus est sur la machine et que la passphrase figure dans l'agent il pourra utiliser msmtp comme le fait le code php de votre blog.
En fait, c'est un problème récurrent, il n'y a pas de façon parfaite de stocker sur un serveur une information secrète mais qui doit pourtant être parfois accessible à certains processus. Tout est affaire d'évalutation des risques et de compromis, comme tout ce qui concerne la sécurité informatique.
Il ne reste plus qu'à faire quelques tests en ligne de commande.
Tester l'envoi en ligne de commande
Pour ma part je n'utilise pas GnuPG pour chiffrer les mots de passe, donc vous ne verrez pas l'utilisation de passwordeval dans ces exemples.
echo -e "Subject: Un mail de test\r\n\r\nEnvoyé via msmtp" | msmtp -t moi@example.com
Vous pourrez voir le résultat dans le fichier .msmtp.log puisque dans la configuration nous avons demandé de logger dans ce fichier. Bien entendu remplacez moi@example.com un adresse sur laquelle vous pouvez recevoir du courrier. Car si les logs annoncent que le mail est parti, il ne peut savoir si il est arrivé !
Vous pouvez également employer l'option --debug pour voir ce qui se passe :
echo -e "Subject: Un mail de test\r\n\r\nEnvoyé via msmtp" | msmtp --debug -t moi@example.com
L'option --debug permet d'afficher tout l'échange SMTP avec le serveur distant et de vérifier que tout se passe bien. Il présente plusieurs sections. Tout d'abord il indique quels fichiers de configuration sont disponibles et lequel est utilisé. Puis il liste les options possibles et leur valeur (toutes ne sont bien entendu pas forcément utilisées), puis il affiche tout l'échange smtp avec le serveur distant. Si vous voulez en savoir plus sur le protocole d'échange smtp voyez l'explication figurant dans le guide Mail façon FAI pour Lenny et comment fonctionne l'authentification SMTP chiffrée.
Voici à quoi ressemble un envoi via un serveur demandant une authentification via le port 587 (soumission) et le protocole STARTTLS :
loaded system configuration file /etc/msmtprc loaded user configuration file /var/www/example.com/.msmtprc falling back to default account using account default from /var/www/example.com/.msmtprc host = smtp.example.net port = 587 proxy host = (not set) proxy port = 0 timeout = off protocol = smtp domain = localhost auth = choose user = noreply@example.com password = * passwordeval = (not set) ntlmdomain = (not set) tls = on tls_starttls = on tls_trust_file = /etc/ssl/certs/ca-certificates.crt tls_crl_file = (not set) tls_fingerprint = (not set) tls_key_file = (not set) tls_cert_file = (not set) tls_certcheck = on tls_min_dh_prime_bits = (not set) tls_priorities = (not set) auto_from = off maildomain = (not set) from = noreply@example.com add_missing_from_header = on add_missing_date_header = on remove_bcc_headers = on dsn_notify = (not set) dsn_return = (not set) logfile = /var/www/example.com//.msmtp.log syslog = (not set) aliases = (not set) reading recipients from the command line and the mail <-- 220 smtp.example.net ESMTP Postfix (Debian/GNU) --> EHLO localhost <-- 250-smtp.example.net <-- 250-PIPELINING <-- 250-SIZE 31457280 <-- 250-VRFY <-- 250-ETRN <-- 250-STARTTLS <-- 250-ENHANCEDSTATUSCODES <-- 250-8BITMIME <-- 250-DSN <-- 250 SMTPUTF8 --> STARTTLS <-- 220 2.0.0 Ready to start TLS TLS certificate information: Owner: Common Name: smtp.example.net Issuer: Common Name: Let's Encrypt Authority X3 Organization: Let's Encrypt Country: US Validity: Activation time: Thu 07 Nov 2019 07:26:59 AM CET Expiration time: Wed 05 Feb 2020 07:26:59 AM CET Fingerprints: SHA256: 3F:D1:C9:6D:F1:5D:50:A4:91:68:FC:69:FE:12:21:EB:08:34:50:67:DB:11:FF:F0:F3:5D:92:4A:4C:1B:82:AD SHA1 (deprecated): EF:C6:AB:25:F0:4A:64:59:37:89:52:A5:10:C9:F7:02:61:D8:58:87 --> EHLO localhost <-- 250-smtp.example.net <-- 250-PIPELINING <-- 250-SIZE 31457280 <-- 250-VRFY <-- 250-ETRN <-- 250-AUTH PLAIN LOGIN <-- 250-ENHANCEDSTATUSCODES <-- 250-8BITMIME <-- 250-DSN <-- 250 SMTPUTF8 --> AUTH PLAIN AG5vcmVwbHlAeWFrYXRpLmNvbQBWMVJ2Yzg2S0FTMTc2Snpo <-- 235 2.7.0 Authentication successful --> MAIL FROM:--> RCPT TO: --> DATA <-- 250 2.1.0 Ok <-- 250 2.1.5 Ok <-- 354 End data with . --> From: noreply@example.com --> Date: Thu, 12 Dec 2019 00:52:01 +0100 --> Subject: Un mail de test --> --> Envoyé via msmtp --> . <-- 250 2.0.0 Ok: queued as 3C495F1 --> QUIT <-- 221 2.0.0 Bye
Voilà, vous devriez maintenant pouvoir envoyer des mails depuis votre serveur en utilisant un serveur smtp de relais (smarthost) et bénéficier des enregistrements spf de vos DNS et de la signature dkim si ces sécurités existent sans plus de configuration.
En cas de besoin vous pouvez laisser un commentaire en bas de cette page.
- A lire pour connaître toutes les possibilités et options de msmtp :
- La documentation au format html : https://marlam.de/msmtp/msmtp.html
- Une très intéressante ressource publiée après la mise en ligne de ce billet :
- https://static.cinay.xyz/2020/03/msmtp-EnvoiMail-en-ligne-de-commande.html