Réseau - Web - GNU/Linux

2019 09 décembre

Envoyer des mails depuis un serveur avec mSMTP

Rédigé par Marc GUILLAUME | 2 commentaires

Dans 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 -i

comme /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 :

  1. 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.
  2. 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

2 commentaires

#1  - Jean-Luc a dit :

Merci pour ce HOWTO. Une petite remarque cependant : dans msmtprc, la ligne `user` est requise. et ne peut donc pas être remplacée par `passwordeval` comme précisé dans ton intéressant article, du moins dans mon cas (msmtp version 1.8.11). Bonne continuation. ^_^

Répondre
#2  - Marc GUILLAUME a dit :

Bonjour,

Merci de la remarque. Il faudra que je regarde ça, en fait je trouve toute cette manip un peu fastidieuse et sur mon serveur je ne l'utilise pas. Cependant il me semble que j'avais testé et que cela fonctionnait.
Mais un serveur avec plusieurs sites ou faisant tourner des CMS passeoir comme WP il faut mieux utiliser GPG pour, non pas empêcher un pirate d'envoyer des mails epuis le serveur , mais pour qu'au moins il ne puisse pas lire le mot de passe du compte et ne l'utilise depuis une autre machine et compromette la réputation de notre smtp.

Répondre

Écrire un commentaire

Quelle est la deuxième lettre du mot hvqb ?

Fil RSS des commentaires de cet article

À propos

Yakati.com - Réseau - Web - GNU/Linux © 2017

Généré par PluXml en 0.027s  - Administration

Mes coordonnées

Marc Guillaume
contact[at]yakati.com
79150 ÉTUSSON

Crédits

Pour la gestion du contenu

Généré par PluXml, le Blog ou Cms sans base de données

Pour le contenu

Licence Creative Commons
Ce(tte) œuvre est mise à disposition selon les termes de la Licence Creative Commons Attribution - Pas d’Utilisation Commerciale - Partage dans les Mêmes Conditions 4.0 International.

Pour le thème

Thème SOLID de blacktie.co adapté pour PluXml