24 janvier 2021

Tuto Messagerie, partie II : Postfix

Seconde partie du tutoriel consacré à l’installation d’un serveur de messagerie.

Préalablement, nous avons installé et configuré le serveur Ldap. Dans cette partie, nous allons mettre en place nos certificats et procéder à la configuration de base de Postfix.

 

I – Préparatifs

Avant de se lancer, il faut faire quelques manipulations.

A – Une nouvelle IP

Au niveau messagerie, si vous voulez que votre serveur puisse envoyer des mails sans que les autres le jette comme un malpropre, il y a un premier point important.

Il est nécessaire que son reverse dns soit correctement configuré : si on demande l’adresse de mail.domaine1.fr et qu’on a XXX.XXX.XXX.XXX, il faut qu’en demandant le reverse de XXX.XXX.XX.XXX on obtienne mail.domaine1.fr

Si vous avez déjà un autre reverse sur l’adresse, soit vous changez, mais bon… Soit vous prenez une nouvelle IP.

Étant chez Online, j’ai donc pris une nouvelle IP Failover ou j’ai configuré le reverse en mail.domaine1.fr.
Ensuite, elle est branché sur ma VM routeur sur le bridge br0 (avec la mac bien renseignée !).

Cette manipulation est identique à ce que je fais dans cet article (au final, mon routeur aura deux IPFO)

 

B – DNS

Sur le serveur dns, on va renseigner les nouveaux enregistrements dans le fichier de zone correspondant :

      IN  MX  10 mail.domaine1.fr
mail  IN  A   IP.FO2

Le champ MX indique qu’il s’agit d’un serveur mail. Et ensuite, on définit simplement l’IP de mail.domaine1.fr.

Si on gère son dns (voir ici), on pense à incrémenter le serial et à recharger avec :

# rndc reload

Pour tester :

# dig domaine1.fr MX +short

C – Routeur

Au niveau de notre routeur, on va indiquer les ports qu’on redirige en entrée :

iptables -t nat -A PREROUTING -d IP.FO2 -p tcp -m multiport --dports 25,80,143,465,587,993,4190 -j DNAT --to-destination ip.interne
iptables -t filter -A FORWARD -p tcp -d ip.interne -m multiport --dports 25,80,143,465,587,993,4190 -j ACCEPT
  • 25 -> SMTP
  • 465 -> SMTPS
  • 587 -> SUBMISSION
  • 143 -> IMAP
  • 993 -> IMAPS
  • 4190 -> Managesieve

Et pour terminer, on redirige aussi le port 80 (Web) car pour le certificat Let’s Encrypt, le serveur aura besoin de monter un serveur web temporaire accessible de l’extérieur.

En sortie :

iptables -t filter -A FORWARD -p tcp -s ip.interne -m multiport --dports 25,53,80,443 -j ACCEPT
iptables -t nat -A POSTROUTING -s ip.interne -p tcp -m multiport --dports 25,53,80,443 -j SNAT --to IP.FO2

Juste le port SMTP et les ports Web. Ajoutez aussi le DNS si vous n’avez pas de resolver interne (dans ce cas, corrigez moi ça en suivant ceci )

II – Les ports dans le domaine du mail

On peut dire que la, c’est un peu le boxon…

Nous avons:

  • Le port 25, SMTP, utilisé pour l’envoi de mail vers le serveur depuis d’autres serveurs.
  • Le port 110, POP, désuet, utilisé pour rapatrier les mails sur un logiciel client.
  • Le port 143, IMAP, permet de consulter sa messagerie, depuis un logiciel client, un webmail, un smartphone, etc…

A cela se rajoute leurs pendants sécurisés :

  • Le port 465, SMTPS (chiffrement SSL/TLS), utilisé par les logiciels clients pour envoyer des mails vers le serveur.
  • Le port 587, SUBMISSION (chiffrement STARTLS), lui aussi utilisé par les logiciels clients pour envoyer des mails vers le serveur.
  • Le port 995, POPS (chiffrement SSL/TLS)
  • Le port 993, IMAPS (chiffrement SSL/TLS)

Les ports 110 et 143 peuvent voir leur connexion chiffré avec STARTTLS, aussi appelé EXPLICIT SSL/TLS.

Le client se connecte au serveur en non chiffrée et il négocie le chiffrement juste après. Cette phase se produisant au tout début, toutes les infos sont ensuite chiffrées.

Sur les ports 465 et 587, utilisant le chiffrement SSL/TLS, la sécurité est établie dès le début. On parle aussi de IMPLICIT SSL/TLS.

Pour donner une image, en SSL/TLS, on a une conversion normal dans une canal chiffrée et en STARTTLS, on a une conversation chiffrée dans un canal en clair…

Alors pourquoi garder les deux ?

Les RFC recommandent maintenant de tout faire en SSL/TLS (un potentiel Man-in-the-middle est possible en STARTTLS.)

Mais de vieux clients peuvent encore nécessiter la présence des ports avec TLS explicite… Du coup, bah, vous faites comment vous le sentez…

Pour le tuto, j’ai choisie de tout mettre dans la configuration pour vous montrer. Perso, en prod, je pars sur du SSL/TLS.

Pour le port 25, Le STARTTLS est proposé si le MX distant le supporte.

Pour plus de détails sur comment on en est arrivés la, je vous conseille de lire cet article.

 

III – Installation

Sur une nouvelle VM :

# apt-get install postfix postfix-ldap ca-certificates

Lors de l’installation de Postfix, répondez :

Internet Site
mail.domaine1.fr

Pour ca-certificates, il est toujours bon de l’avoir, et il nous sera utile pour l’installation de Rspamd plus tard.

Et on installe dans la foulée Dovecot :

# apt-get install dovecot-core dovecot-imapd dovecot-ldap dovecot-managesieved dovecot-sieve dovecot-lmtpd

A vrai dire, je l’installe de suite car le script de mise à jour du certificat redémarre les services postfix et dovecot , donc autant éviter des erreurs dès le début…

 

IV – Certificat

On va de suite gérer le certificat avec acme.sh (client pour Let’s Encrypt, plus d’informations dans mon article) :

# apt-get install git socat

Installons maintenant acme.sh :

# cd
# mkdir sources
# cd sources/
# git clone https://github.com/Neilpang/acme.sh.git
# cd ./acme.sh
# ./acme.sh --install

On recharge le bash :

# source /root/.bashrc

Et on lance la création du certificat :

# acme.sh --issue -k 4096 --standalone -d mail.domaine1.fr --log

On installe le certificat :

# mkdir /etc/ssl/private/domaine1.fr
# acme.sh --installcert -d mail.domaine1.fr --cert-file /etc/ssl/private/domaine1.fr/cert.pem --key-file /etc/ssl/private/domaine1.fr/key.pem --ca-file /etc/ssl/private/domaine1.fr/ca.pem --fullchain-file /etc/ssl/private/domaine1.fr/fullcert.pem --reloadCmd 'service postfix reload && service dovecot reload'

On génère nos clés DH :

# openssl dhparam -out /etc/ssl/private/domaine1.fr/dh512.pem 512
# openssl dhparam -out /etc/ssl/private/domaine1.fr/dh2048.pem 2048
# chmod 644 /etc/ssl/private/domaine1.fr/dh{512,2048}.pem

La commande installcert met également en place une tache cron pour le renouvellement automatique de votre certificat qui du coup, renouvelle, copie ou il faut et relance, parfait !

V – Postfix

A – La base

On va éditer le fichier /etc/postfix/main.cf pour le mettre à notre sauce :

mynetworks = 10.0.0.0/8
inet_interfaces = all
inet_protocols = ipv4
smtpd_banner = $myhostname ESMTP $mail_name (Debian/GNU)
biff = no
append_dot_mydomain = yes
readme_directory = no
compatibility_level = 2

notify_classes = bounce, delay, policy, protocol, resource, software
myhostname = mail.domaine1.fr
mydestination = $myhostname, mail, localhost.localdomain, localhost
myorigin = $myhostname
disable_vrfy_command = yes
strict_rfc821_envelopes = yes
show_user_unknown_table_name = no
message_size_limit = 0
mailbox_size_limit = 0
allow_percent_hack = no
swap_bangpath = no
recipient_delimiter = +
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases

broken_sasl_auth_clients=yes

smtp_tls_security_level = may
smtp_tls_session_cache_database  = btree:${data_directory}/smtp_tlscache

smtpd_tls_loglevel = 1
smtpd_tls_security_level = may
smtpd_tls_auth_only = yes
smtpd_tls_key_file = /etc/ssl/private/domaine1.fr/key.pem
smtpd_tls_cert_file = /etc/ssl/private/domaine1.fr/cert.pem
smtpd_tls_CAfile = /etc/ssl/private/domaine1.fr/fullcert.pem
smtpd_tls_protocols = !SSLv2 !SSLv3
smtpd_tls_mandatory_protocols = !SSLv2 !SSLv3
smtpd_tls_mandatory_ciphers = high
smtpd_tls_eecdh_grade = strong
smtpd_tls_dh512_param_file  = /etc/ssl/private/domaine1.fr/dh512.pem
smtpd_tls_dh1024_param_file = /etc/ssl/private/domaine1.fr/dh2048.pem
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_tlscache
smtpd_tls_session_cache_timeout = 3600s
smtpd_tls_received_header = yes

smtpd_sasl_auth_enable = yes
smtpd_sasl_path = private/auth
smtpd_sasl_type = dovecot
smtpd_sasl_security_options = noanonymous, noplaintext
smtpd_sasl_tls_security_options = noanonymous

tls_preempt_cipherlist = yes
tls_high_cipherlist = ALL EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA RC4 !aNULL !eNULL !LOW !MEDIUM !3DES !MD5 !EXP !PSK !SRP !DSS !RC4
tls_ssl_options = no_ticket, no_compression
smtpd_helo_required = yes

smtpd_client_restrictions =
    permit_mynetworks,
    permit_sasl_authenticated,
    reject_unknown_reverse_client_hostname,
    reject_unauth_pipelining

smtpd_helo_restrictions =
    permit_mynetworks,
    permit_sasl_authenticated,
    reject_invalid_helo_hostname,
    reject_non_fqdn_helo_hostname,
    reject_unauth_pipelining

smtpd_sender_restrictions =
    permit_mynetworks,
    permit_sasl_authenticated,
    reject_non_fqdn_sender,
    reject_unknown_sender_domain,
    reject_unauth_pipelining

smtpd_relay_restrictions =
    permit_mynetworks,
    permit_sasl_authenticated,
    ###
    # VITAL, empêche l'open relay
    reject_unauth_destination
    ###

smtpd_recipient_restrictions =
    permit_mynetworks,
    permit_sasl_authenticated,
    reject_non_fqdn_recipient,
    reject_unknown_recipient_domain,
    reject_unauth_pipelining

smtpd_data_restrictions =
    permit_mynetworks,
    permit_sasl_authenticated,
    reject_multi_recipient_bounce,
    reject_unauth_pipelining

virtual_transport = lmtp:unix:private/dovecot-lmtp
virtual_mailbox_domains = ldap:/etc/postfix/ldap/virtual_domains.cf
virtual_mailbox_maps = ldap:/etc/postfix/ldap/virtual_mailbox.cf
virtual_alias_maps = ldap:/etc/postfix/ldap/virtual_alias.cf

 

Quelques explications :

append_dot_mydomain = yes

ajoute le domaine au mail locaux qui sont envoyés (si un mail local est envoyé depuis un service sur le serveur, genre cron, etc… il sera de la forme root@mail.domaine1.fr au lieu de root@mail).

Centralisant tous mes mails, éventuellement d’autres serveur, c’est une info dont j’ai besoin (on peut aussi réécrire l’expéditeur, etc..).

notify_classes = bounce, delay, policy, protocol, resource, software

Définit les messages d’erreurs que recoit le postmaster. A affiner selon ce que vous voulez. Voir la doc de Postfix pour plus de détails.

myhostname = mail.domaine1.fr
mydestination = $myhostname, mail, localhost.localdomain, localhost

Le nom de votre serveur de mail. Peut être différent, mais dans mon cas, vu ma config Dns, de l’extérieur ou de l’interieur, ca reste le meme nom.
Ensuite, les destinations qu’il accepte. On ne liste ici aucun domaine qu’on gère, ceux ci sont déclarés dans les alias virtuels.

Pour la partie SSL/TLS/SALS on remarque deux groupes d’options : smtp_* et smtpd_*

Smtp concerne la patie client de postfix, c’est à dire celle qui envoie les mails aux autres serveurs SMTP (aussi appelés MX).
Smtpd concerne la partie serveur, celle qui recoit les mails, soit des clients, soit des autres MX.

smtp_tls_security_level = may

indique que le client SMTP de postfix,  quand il se connecte à un autre MX, supporte le TLS.

smtpd_tls_security_level = may

indique que le serveur SMTP de Postfix, quand il reçoit une connexion d’un client (mx ou soumis), supporte le TLS.

On le laisse à may pour indiquer que c’est possible sans être obligatoire. On le surchargera dans le fichier master.cf

Ne pas confondre aussi _sasl_ et _tls_ ! _sasl_ concerne l’authentification de nos utilisateusr (via Dovecot) et _tls_ le chiffrement des communications.

smtpd_tls_auth_only = yes

indique que si l’authentification est utilisé, on doit forcement être en SSL (ou TLS, ca revient au meme.)

Pour le reste, c’est du classique.

J’ai hésité à commenter toutes les restrictions… mais la doc de Postfix à ce sujet vous aidera à ma place.
Ce sont de bonnes restrictions pour commencer: elles permettent déjà de rejeter quelques tentative de spams.

Dans la partie IV du tuto, nous verrons plus en détails comment améliorer cela.

Un point important à connaitre : les permit ou reject sont testés dans l’ordre et dès que l’un match, cela stop pour la restriction en cours. L’ordre à donc une importance.

Grosso modo, pour chaque restriction, à chaque fois, j’autorise mon réseau local, mes utilisateurs authentifiés (mails soumis) et rejete les trucs mal fagotés…

 

On va ensuite modifier le fichier /etc/postfix/master.cf au début  :

submission    inet    n    -    y    -    -    smtpd
  -o smtpd_tls_security_level=encrypt

On active submission, et on surchage (-o le parametre smtpd_tls_security_level à encrypt pour forcer le tls.

Un peu plus bas, on va activer le smtps :

smtps    inet    n    -    y    -    -    smtpd
  -o smtpd_tls_security_level=encrypt
  -o smtpd_tls_wrappermode=yes

Le reste ne change pas.

Pourquoi Postfix utilise deux fichiers de configuration ?

Le fichier main.cf définit les options générales de Postfix. Le fichier master.cf, lui sert à gérer les sous process de Postfix et permet de modifier certains paramètres du fichier main.cf en les surchargeant (option -o).

B – Le Ldap

On va créer nos fichiers chargé de faire la liaison avec le serveur ldap et les ranger :

# mkdir /etc/postfix/ldap
# cd /etc/postfix/ldap

Fichier virtual_domains.cf :

server_host = ldap://ip.ldap
version = 3
bind = yes
bind_dn = cn=viewer,ou=system,dc=debugo,dc=fr
bind_pw = passview
search_base = ou=mail,dc=debugo,dc=fr
scope = sub
query_filter = (&(maildomain=%s)(objectClass=maildomaindebugo)(maildomainactif=YES))
result_attribute = maildomain

Fichier virtual_mailbox.cf :

server_host = ldap://ip.ldap
version = 3
bind = yes
bind_dn = cn=viewer,ou=system,dc=debugo,dc=fr
bind_pw = passview
search_base = ou=people,dc=debugo,dc=fr
scope = sub
query_filter = (&(mail=%s)(objectClass=mailaccountdebugo)(mailaccountactif=YES))
result_attribute = mail

Et le fichier virtual_alias.cf :

server_host = ldap://ip.ldap
version = 3
bind = yes
bind_dn = cn=viewer,ou=system,dc=debugo,dc=fr
bind_pw = passview
search_base = ou=mail,dc=debugo,dc=fr
scope = sub
query_filter = (&(mailaliasfrom=%s)(objectClass=mailaliasdebugo)(mailaliasactif=YES))
result_attribute = mailaliasto

Pour des explications sur les filtres, vous en aurez dans la partie suivante, consacrée à Dovecot.

On sécurise :

# chmod 640 /etc/postfix/ldap/
# chown :postfix /etc/postfix/ldap/*

Puis on recharge Postfix :

# postfix reload

Et on peut tester les liens avec le ldap :

# postmap -q domaine1.fr ldap:/etc/postfix/ldap/virtual_domains.cf

nous retourne le domaine s’il existe.

# postmap -q postmaster@domaine1.fr ldap:/etc/postfix/ldap/virtual_alias.cf

donne le compte vers le lequel est envoyé l’alias.

# postmap -q toto@domaine1.fr ldap:/etc/postfix/ldap/virtual_mailbox.cf

nous retourne le mail s’il existe.

C – Alias locaux

Il reste un dernier petit point, les alias locaux de la machine.

Comme je l’ai dis avant, je veux qu’à terme, ce serveur mail gère également les mails de mes autres vm pour tout centraliser.

Et je veux tout rapatrier sur mon adresse mail toto@domaine1.fr.

On édite le fichier /etc/aliases pour y mettre :

postmaster: postmaster@domaine1.fr
root: toto@domaine1.fr

Pour mémoire, postmaster@domaine1.fr est défini comme un alias de toto@domaine1.fr dans le ldap.

On exécute la commande :

# newaliases

pour convertir cela en fichier un fichier compréhensible de postfix et on le recharge :

# postfix reload

 

IV – Conclusion

Postfix est opérationnel. Vous voyez, ce n’est pas si terrible ! On ne fait qu’effleurer la configuration, la documentation de Postfix  est très complète et on peut configurer plein de scénarios…

Maintenant pour le tester, comme nous n’avons pas encore Dovecot derriere, on va se contenter de juste tester la communication d’un MX vers le nôtre :

Le site https://www.checktls.com/TestReceiver permet de faire cette vérification, et l’on voit de suite si le TLS est bon. On peut aussi classiquement en telnet, mais c’est… long…

Le site https://mxtoolbox.com/ est très pratique également.

Ha oui, au passage, le fichier clé pour debug, c’est bien évidement le fidèle :

/var/log/mail.log

 

Voila qui termine pour le moment le sujet Postfix. Dans la partir suivant, nous allons mettre en place Dovecot.

 

 

7 réflexions sur « Tuto Messagerie, partie II : Postfix »

  1. Hello,

    J’ai une question. En l’état j’ai 4 enregistrements MX, chacun pointant vers un A record avec une IP distincte par enregistrement, soit :

    IP1 mail.domaine1.org
    IP2 mail.domaine2.org
    IP3 mail.domaine3.org
    IP4 mail.domaine3.org

    En plus de l’ip du VPS OVH, j’ai donc ces 4 ip qui sont montées sur mon VPS. Côté reverse, dans l’interface d’OVH, je fais bien pointer ces ips vers les reverses des enregistrements correspondants. Donc côté DNS, je suis normalement propre.

    Par contre, grosse inquiétude côté /etc/hostset /etc/hostname . Que doivent exactement contenir ces fichiers à présent ? Car dans postfix, j’ai gardé comme FQDN le nom de la machine OVH par défaut, ce qu’on retrouve d’ailleurs dans hostsname et hosts. Mais ne devrais-je pas y faire apparaître aussi les noms de mes serveurs de mails ? Si oui, sous quelle forme, tout dans la ligne 127.0.0.1 ou alors une ligne pour un domaine+ip publique ?

    Comment faire pour que ça soit bien propre ? Car en l’état, même si sur mail-tester j’obtiens un 10/10, j’ai quand même un retour me disant ceci :

    Votre adresse IP 51.83.*.* est associée au nom de domaine ns1.site1.org.
    Néanmoins votre message semble être envoyé de vps692***.ovh.net.

    Vous devriez modifier l’enregistrement du pointeur DNS (Type PTR) et le nom d’hôte (host name) de votre serveur avec la même valeur

    Voici les valeurs testées pour cette vérification:
    IP: 51.83.*.*
    HELO: vps692***.ovh.net
    rDNS: ns1.site1.org

    (a savoir que le primaire DNS est aussi sur la même machine, mais je vais bouger ça plus tard)

    Merci (j’espère ne pas avoir été trop brouillon dans mon explication)

    1. Si j’ai bien suivi, t’as juste à modifier le fqdn sur le serveur pour qu’il soit égale au rDNS : ns1.site1.org

      En fait, c’est ca qui est important : que le rdns soit égale au helo que donne ton serveur mail.

  2. Ok, ça doit être ça, oui.
    Mais alors du coup, si je modifie le FQDN pour qu’il soit identique au rDNS, je vais donc le faire pointer vers le nom de mon premier serveur de courrier, correspondant uniquement à mon premier domaine.
    Quid du coup des autres domaines ? Chaque domaine a enregistrement MX qui pointe vers une IP distincte, tout est monté sur le même serveur. Ça ne posera pas de problème ? Bon, je vais tenter 🙂 merci

    1. Deux solutions alors : Multiple instance de postfix.
      Ou, et c’est ce que je ferais, utiliser master.cf pour faire d’autres smtp d’écoute :
      newsmtp unix – – n – – smtp
      -o myhostname=le.host.name
      -o smtp_bind_address=ip.qui.va.avec
      -o smtp_helo_name=le.helo

  3. Bonjour à tous,

    je tiens à souligner que ce tutoriel et super pratique et bien expliqué bravo!

    J’ai cependant un petit soucis de compréhension, à quoi correspond IP.FO2 (je crois comprendre qu’il s’agit de l’ip du serveur smtp par exemple)et à quoi correspond ip.interne ?

    1. Bonjour et merci 😉
      PI.FO2, c’est en effet l’ip de mon service smtp mais cette IP est montée sur un routeur en amont. Du coup, ip.interne correspond à l’ip de mon serveur mail dans le réseau local 10.10.1.0/24.
      J’espère être clair 🙂

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *