Maniatux's Blog

Welcome to the internet

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.

Classé dans : Sysadmin - Mots clés : aucun