OpenSMTPD sur OpenBSD 5.0 avec tls auth + relay
Rédigé par Xavier - -
OpenSMTPD
OpenSMTPD est un serveur SMTP ayant pour but de remplacer sendmail dans le système d'exploitation OpenBSD. Il n'a pas pour ambition d'offrir les mêmes possibilités, mais plutôt de simplifier la configuration et la sécurité via des audits plus faciles et du code plus simple. Voici un article récapitulatif.

Le projet est encore relativement peu avancé, son utilisation est sans risque mais il manque encore quelques fonctions essentielles comme l'alimentation de /var/log afin qu'il soit proposé par défaut dans OpenBSD. Il est actuellement fourni dans le système de base, mais c'est sendmail qui est utilisé.
Configuration
Réseau
Votre serveur doit avoir une entrée DNS (MX de préférence) ou au moins une ligne dans le fichier /etc/hosts, afin qu'il sache que le domaine auquel vous allez faire référence dans la configuration est bien le sien.
Remplacement de sendmail
Tout d'abord, il va falloir arrêter sendmail et le retirer du démarrage au lancement du système. Pour cela on commence par tuer le processus (seul moyen de l'arrêter visiblement sur OpenBSD) :
# pkill sendmail
Ensuite pour l'empêcher de se lancer au démarrage du système on va devoir modifier le flag associé dans le fichier rc.conf. On peut soit modifier directement ce fichier, soit passer par rc.conf.local et remettre les balises qui vont l'outrepasser. On en profite au passage pour autoriser le lancement d'OpenSMTPD (smtpd) :
# echo "sendmail_flags=NO" >> /etc/rc.conf.local # echo "smtpd_flags=" >> /etc/rc.conf.local
Ensuite il va falloir modifier le mailwrapper de OpenBSD. Son utilité est "d'intercepter" les commandes envoyées au MTA. Dans notre cas les commandes envoyées à sendmail seront "redirigées" vers smtpd. Après avoir effectué la manipulation, c'est bien plus clair à comprendre :
# mv /etc/mailer.conf /root/ # vi /etc/mailer.conf sendmail /usr/sbin/smtpctl send-mail /usr/sbin/smtpctl mailq /usr/sbin/smtpctl makemap /usr/libexec/smtpd/makemap newaliases /usr/libexec/smtpd/makemap
Configuration du daemon smtpd
Le fichier de configuration est /etc/mail/smtpd.conf. Il est vraiment très très simple à comprendre et vous pouvez trouver des exemples ici et ici. La documentation est disponible ici (manpage).
Dans mon cas je voulais que mon serveur soit capable de recevoir les mails, mais aussi de les relayer - en cas d'authentification réussie seulement (pour ne pas servir de relais à spam). L'envoi de mail en extérieur devra passer par un autre relais (smtp.gmail.com). La configuration de OpenSMTPD est calquée sur celle du parefeu d'OpenBSD, c'est à dire un système d'ACL dans un langage humain. Voici un schéma de fonctionnement de ce que j'ai obtenu au final :


Fichier alias
Jetez un œil et effectuez les modifications nécessaires dans le fichier /etc/mail/aliases. Vous pouvez notamment rediriger les mails de root vers l'utilisateur que vous voulez. Sinon il n'y a rien de particulier à changer. Puis créez le db :
# newaliases /etc/mail/aliases: 56 aliases
Authentification sur smtp.google.com
Il faut générer un fichier secrets qui sera lui aussi transformé en db. Il contiendra le nom d'utilisateur et le mot de passe pour le smtp.
# vi /etc/mail/secrets smtp.gmail.com user@gmail.com:password
Puis :
# chmod 640 /etc/mail/secrets # chown root:_smtpd /etc/mail/secrets
Et enfin :
# makemap /etc/mail/secrets
Authentification et chiffrement TLS
Nous devons générer une clé et un certificat qui serviront au chiffrement de l'authentification sur notre serveur. Remplacez re0 par le nom de votre interface réseau.
# mkdir -p /etc/mail/certs # openssl genrsa -out /etc/mail/certs/re0.key 4096 # openssl req -new -x509 -key /etc/mail/certs/re0.key -out /etc/mail/certs/re0.crt -days 365
Donner à la clé et au certificat le nom de l'interface réseau, et les placer dans /etc/mail/certs n'est pas obligatoire mais ce sont les valeurs par défaut que smtpd.conf va utiliser. Cela nous évite donc de spécifier les noms et chemins.
smtpd.conf et ACL
# vi /etc/mail/smtpd.conf
Remplir le fichier comme ceci :
# Interfaces listen on lo0 listen on re0 tls enable auth # Mapping map "aliases" { source db "/etc/mail/aliases.db" } map "secrets" { source db "/etc/mail/secrets.db" } # Generic parameters hostname "smtpd.my.domain" # ACL accept from all for domain "smtpd.my.domain" alias aliases deliver to maildir accept from local for all relay via smtp.gmail.com port 587 tls auth secrets
Et c'est tout, la configuration est aussi simple que ça, et clairement lisible par un humain. C'est tout l'intérêt d'OpenSMTPD. Il faut savoir qu'un utilisateur authentifié est alors considéré comme "local". Ce qui explique que dans la deuxième ligne des ACL nous ne prenons en compte que "local".
Essais
Nous devons maintenant valider le fonctionnement de notre serveur SMTPD, d'abord pour être sûr de bien recevoir les mails, et ensuite vérifier qu'il ne relaie pas les messages si l'authentification échoue (on ne veut pas devenir un relais public à spam).
Assurez-vous que votre serveur smtpd tourne. Vous pouvez soit le lancer depuis rc.d, soit le lancer de la manière suivante pour avoir les logs :
# smtpd -dv no DH parameters found in /etc/mail/certs/re0.dh using built-in DH parameters startup [debug mode] parent_send_config: configuring smtp parent_send_config_client_certs: configuring smtp ramqueue: offline queue loading in progress parent_send_config_ruleset: reloading rules and maps ramqueue: offline queue loading over ramqueue: queue loading in progress ramqueue: loading over runner: ramqueue is empty, wake me up. zZzZzZ smtp_setup_events: listen on 172.16.42.183 port 25 flags 0x5 cert "re0" ssl_setup: ssl setup finished for listener: 0x8294c800 smtp_setup_events: listen on IPv6:fe80::5054:ff:fee6:84a9%re0 port 25 flags 0x5 cert "re0" ssl_setup: ssl setup finished for listener: 0x863d2800 smtp_setup_events: listen on 127.0.0.1 port 25 flags 0x0 cert "lo0" smtp_setup_events: listen on IPv6:fe80::1%lo0 port 25 flags 0x0 cert "lo0" smtp_setup_events: listen on IPv6:::1 port 25 flags 0x0 cert "lo0" smtp: will accept at most 245 clients
Test local vers local
Sur le serveur créez un utilisateur et envoyez-lui un mail :
# useradd -m xavier # passwd xavier # mail -s test xavier@smtpd.my.domain TEST LOCAL TO LOCAL .
Vérifiez que "xavier" a bien reçu le message :
# cd /home/xavier/Maildir/new # ls 1321180177.15553.smtpd.my.domain # tail 1321180177.15553.smtpd.my.domain Received: from localhost (0@localhost [IPv6:::1]) by smtpd.my.domain (OpenSMTPD) with ESMTP id 84e0fc73 for; Sun, 13 Nov 2011 11:29:36 +0100 (CET) From: Charlie Root Date: Sun, 13 Nov 2011 11:29:35 +0100 (CET) Message-Id: <5674425643749194551.enqueue@smtpd.my.domain> To: xavier@smtpd.my.domain Subject: test TEST LOCAL TO LOCAL
Déjà, si le répertoire Maildir a été créé, c'est bon signe. Vous devez y trouver un fichier avec nom à rallonge contenant le message.
Test local vers extérieur
Envoyez un mail vers une adresse extérieure.
# mail -s test machin@free.fr TEST LOCAL TO EXT .
Vérifiez ensuite si la boite mail machin@free.fr a reçu le message ou non. Notez que si vous avez lancé smtpd avec l'option -dv, vous devez voir toute la procédure de connexion se dérouler.

Note : Vous remarquerez que l'expéditeur apparaît comme étant... l'identifiant de connexion GMail utilisé pour s'authentifier sur le relais. En théorie cela devrait être root@smtpd.my.domain. En regardant la procédure de connexion et d'envoi avec smtpd -dv j'ai remarqué que le serveur donne la bonne adresse d'expéditeur, la modification est donc probablement faite par le serveur GMail. Pourquoi ? Selon moi l'explication est la suivante : le domaine smtpd.my.domain utilisé dans l'exemple n'existe pas. A la réception d'un mail, un serveur smtp effectue une vérification DNS. Il s'assure que le serveur qui se présente comme machin.com n'usurpe pas l'identité d'un autre. Dans notre cas, vu que le domaine smtpd.my.domain n'existe pas, bon nombre de serveurs vont refuser nos mails. GMail prend donc soin de modifier l'expéditeur. J'ai essayé en changeant de relais, en utilisant ceux de 1and1. Ils ne modifient pas l'expéditeur et refusent simplement le message au motif qu'il n'y a pas d'entrée DNS. Ce problème n'existe donc normalement pas lorsque vous utilisez un vrai nom de domaine.
Test extérieur vers local
Envoyez simplement un mail vers votre serveur, et vérifiez qu'il a été reçu. Sinon vous pouvez utiliser telnet (depuis une autre machine). Bien sûr assurez-vous que vous avez bien redigiré le port 25 sur votre routeur, si votre serveur est situé derrière une couche de NAT.
# telnet smtpd.my.domain 25 HELO moi MAIL FROM: expediteur@domaine RCPT TO: xavier@smtpd.my.domain DATA TEST EXT TO LOCAL . QUIT
Le message devrait être reçu.
Test extérieur vers extérieur (relais)
Cette fois on envoie un message vers une adresse quelconque mais en passant par le serveur. On peut là aussi tester en telnet:
# telnet smtpd.my.domain 25 HELO moi MAIL FROM: expediteur@domaine RCPT TO: moi@gmail.com
Le comportement attendu est une erreur (refus) puisque vous n'êtes pas encore authentifié et que l'adresse cible n'appartient pas au serveur. Pour tester l'authentification on peut passer par Thunderbird, et spécifier notre machine comme serveur SMTP par défaut.
- Description : mon smtp
- Nom : smtpd.my.domain
- Port : 25
- Sécurité : STARTTLS
- Authentification : Mot de passe normal
- Nom : xavier
Envoyez maintenant un mail et celui-ci devrait être correctement relayé et transmis au destinataire.
Conclusion
OpenSMTPD est un serveur simple à utiliser car disposant d'un seul fichier de configuration lisible par un humain, avec des mécanismes d'authentification et chiffrements simples à mettre en place. On attend avec impatience sa maturation qui comblera quelques manques et en feront probablement un excellent remplaçant à Sendmail sur OpenBSD.
EDIT (06/05/2012) - Astuce port 25 / 465
Mettre en place l'écoute sur le port 465 pour l'authentification : voir ici.