Paramétrer son propre serveur mail, version 2
Pas à pas
Version en travail reprenant les points clés vu dans les divers tutos et adaptés à ma propre façon de fonctionner.
Tirons parti de ce qui a été appris avant, et reprenons en améliorant…
Ici, je pars d'une VM sur un hyperviseur Xen. Dans un premier temps, je ne bidouille pas les DNS et certbot parce que je vais devoir bouger la machine… donc on finalise quand cette dernière est au bon endroit. De même mes tests se font sur le réseau local. J'ouvre quand même le port 80 parce qu'il me faut un certificat valide…
La machine étant au bon endroit, je met à jour le tuto. C'est très galère en fait, de faire une installation sans la bonne adresse…
Concernant les domaines :
- poste.example.org sera le relai mail
- example.org sera le nom de domaine du mail, avec des adresses en machin@example.org
Un premier tour sur les DNS
Ça peut se faire par la suite1) mais comme ça met toujours un peu de temps à se propager… et autant avoir rapidement le nom de domaine dispo.
Ce qu'il faut :
- Nom de sous-domaine pour le serveur mail, MX en A et AAAA vers lui depuis le domaine principal.
- ReverseDNS sur la machine.
- Tester tout ça.
Quelque chose dans ce genre :
poste.example.org. IN A a.b.c.d poste.example.org. IN AAAA 2001:a::b example.org. IN MX 10 mail.example.org.
Le faire sur ipv6 si possible… Aujourd'hui tous les serveurs devraient le permettre.
Pour MX, une priorité plus basse veut dire que ce sera choisi en premier. Donc si on a un relai paramétré à 10 et un second à 20, le courrier sera d'abord envoyé à 10. Si plusieurs relais ont le même chiffre, ça sera l'un ou l'autre.
Il faut aussi configurer son Reversedns et ça, c'est permis ou non par l'hébergeur (dans l'interface web de gestion de la machine). La machine prend le “nom” du serveur mail.
- Sur Oneprovider, pas de souci.
- Depuis OVH telecom, ça se fait aussi, dans la partie telecom justement. Mais autant leur interface web permet ce qu'il faut, autant ma box à la maison galère sur la gestion de l'ipv6 (trop vieille…).
- Chez Free, dans “Ma freebox” sur https://adsl.free.fr, on a l'option “Personnaliser mon reverse DNS”. Cependant, en 2024, cela n'est possible que sur l'ipv4, ce qui posera souci pour la délivrance du mail avec les acteurs qui forcent à l'ipv6 (genre, gmail).
Ensuite, pour tester :
dig +short -x "a.b.c.d" @9.9.9.9 dig +short -x "2001:a::b" @9.9.9.9
L'un et l'autre doivent donner le nom de domaine configuré pour les ip en question. Le “@9.9.9.9” à la fin permet de passer par l'extérieur, si on teste en local sur un ordi local, dig ne retourne rien…
Ports et nftables
La VM est derrière un proxy (ici une box), ce dernier aura besoin de certains ports ouverts. Il y a aussi un proxy web sur une autre machine du réseau afin de répartir ce qui arrive sur le port 80 extérieur vers les diverses machines internes.
Aide-mémoire :
Certains sont non-chiffrés :
- 25 : SMTP
- 143 : IMAP
- 110 : POP (plus vraiment utilisé)
Et d'autres pour les échanges chiffrés :
- 587 (ou 467) : SMTP ; 587 est “TLS”, 465 est “SSL”.
- 993 (ou 220) : IMAP, 993 en SSL
- 995 : POP (SSL)
Et suivant les besoins :
- 4190 : Sieve
- 10025 ? : Antivirus ? Vérifier, je ne suis pas sûre de l'intérêt.
En réalité on ne va ouvrir que ceci : 25, 587, 993, 4190.
Idem sur le nftables de la machine.
On ouvre les ports sur le proxy quand tout le reste est fini…
Vérifier l'host
Vérifier que /etc/hosts a un nom de domaine cohérent (si renseigné) avec notre reversedns. Dans mon cas il avait doublé “poste” ce qui faisait un domaine en “poste.poste.example.org”.
Cela donne un fichier de ce genre comme ceci :
- /etc/hosts
127.0.0.1 localhost 127.0.1.1 poste.example.org poste # The following lines are desirable for IPv6 capable hosts ::1 localhost ip6-localhost ip6-loopback ff02::1 ip6-allnodes ff02::2 ip6-allrouters
Logiciels à installer
Configuration classique avec postfix, dovecot, mariadb, et postfixadmin pour gérer graphiquement les détails. Ainsi que phpmyadmin le temps des bidouilles (désactivé ensuite pour réduire les surfaces d'attaque).
Il y a plein de possibilité de panachages. J'ai fait un choix, ça m'aura pris des jours à me décider, plus des jours à adapter… Je vais essayer d'expliquer mais ce qui est fait pour un logiciel, peut s'adapter à un autre.
Je fais le choix de Postfix (avec postfix-mysql pour parler à Mariadb) ; aujourd'hui pas mal de gens apprécieront plus Opensmtpd et c'est legit. Pourquoi j'ai finalement pris Postfix ?
- Énormément plus de tutos, à destination des noobs et des experts, sur tous les cas de figures
- J'aime la doc plus organique que des manpages
- En discutant avec des sysadmin connaissant les deux logiciels, leur avis n'est pas absolument tranché en faveur de l'un ou l'autre. Opensmtpd est effectivement considéré comme un challenger pertinent, mais la réputation de difficulté à paramétrer Postfix est un peu usurpée (et je confirme, c'est comme plein de logiciels…).
- Leur avis est aussi que Postfix est extrêmement puissant. Il permet de faire “tout” (y compris des conneries), c'est sa force et son risque. Opensmtpd est encore jeune et certaines options ne sont pas (encore?) possibles ; ceci dit rien qui bloquera la sysadmin hébergeant du mail familial.
Dovecot, tout le monde le plébiscite, et ce n'est pas celui qui m'aura posé de souci.
- dovecot-mysql : pour communiquer avec mysql et donc partager la même base d'utilisateurs
- dovecot-imapd : pour utiliser l'IMAP donc obligé
- dovecot-lmtpd : une fois arrivé sur le serveur, va aiguiller les mails aux bons utilisateurs (MDA)
- dovecot-managesieved : permet aux utilisateurs de définir leurs règles de filtre.
La chasse aux spams se fera avec rspamd, un logiciel tiers qui traite les spams. Il gère aussi la signature automatique des clés de domaine (DKIM).
Mariadb ne sert qu'à stocker les utilisateurs donc très peu de données, sa perfomance ne sera pas un souci. Je vais avoir la surcouche graphique avec Postfixadmin, qui permettra à mes utilisateurs de gérer leurs propres alias et mot de passe.
Quelques outils pratiques à avoir :
- swaks : “couteau suisse du mail”, fournit divers utilitaires
- bsd-mailx : permet de lire/envoyer les mails sur le serveur, en ligne de commande, utile lors des tests.
- mutt : autre logiciel pour voir les mails, plus “graphique” (mais en console), et pratique aussi à d'autres moment. Voir ma doc associée en cas de souci.
Le certificat SSL sera géré avec certbot, classique et fonctionnel.
On va avoir un peu d'apache pour quelques outils visuels de gestion (adminer, rspamd).
Finalement :
sudo apt install mariadb-server redis-server apache2 php postfix postfix-mysql dovecot-mysql dovecot-imapd dovecot-lmtpd dovecot-managesieved rspamd swaks mutt certbot
Quand Postfix demande sa configuration, répondre “Site Internet”. Vérifier le nom de domaine, par exemple “poste.example.org”.
puis (une fois mariadb configuré)
sudo apt install phpmyadmin postfixadmin
Ces deux-là peuvent s'installer plus tard.
Mon apt est configuré pour ne pas installer par défaut les recommandés et suggérés, ce qui demande de voir la liste et de compléter au besoin. Ici, à installer en complément pour se simplifier la vie :
sudo apt install shared-mime-info xdg-user-dirs php-curl php-gd php-cli
et enfin (parce qu'il est un chouïa pénible sinon)
sudo apt install rkhunter
Faire de nouveau un petit sudo grep -nri "poste" /etc/ --exclude-dir=lvm
pour vérifier qu'il n'y a pas de doublon ou de nom bizarre qui traîne.
Refaire un snapshot parce que c'est long d'installer ces logiciels.
sudo lvcreate -L 20g -s -n snap_courrier_$(date --iso)_logicielsOK /dev/VgPoste/courrier
Un peu de web
Avec Apache, parce que je le connais, mais vu ce qu'il y a à faire, Nginx suffira aussi. Ou Lighttpd. Faites votre vie, adaptez. En vrai faudra que je vois à mettre Lighttpd qui serait parfait pour le job.
Si on utilise Apache, en profiter pour le sécuriser d'après https://khaganat.net/wikhan/fr:apache.
C'est plus pour voir si ça marche… et par la suite, si un bot (voir une vraie curieuse) regarde la page principale, y'aura un bout d'info. Actuellement je vais aussi servir Phpmyadmin (mais ce dernier va disparaitre une fois les bidouilles finies) et Postfixadmin, ceui-ci pouvant sans souci être sur un autre serveur (et ce serait peut-être mieux !).
sudo mkdir /var/www/poste
Une page web “propre” quand même…
sudo nano /var/www/poste/index.html
- /var/www/poste/index.html
<!DOCTYPE html> <head> <html class="js desktop" lang="fr" dir="ltr"> <meta http-equiv="Content-Type" content="text/html; charset=utf8" /> <!-- meta --> <meta name="description" content="Mail server."> <meta name="author" content="Zatalyz"> </head> <body> Ceci est un serveur mail. En cas de problème, merci de contacter l'adresse en abuse@. <br>This is a mail server. If you have any problems, please contact the abuse@ address. </body>
Puis les droits
sudo chown -R www-data: /var/www/poste
On va demander un certificat à certbot, en “standalone”, puisqu'il servira à l'ensemble du domaine (dont les mails !), donc avec Apache éteint :
sudo service apache2 stop sudo certbot certonly --standalone -d example.org sudo service apache2 start
Ici il y a une difficulté si on a un proxy.
Dans le cas où le serveur mail est tout seul sur la machine (ce qui est mieux, dans l'absolu), on peut demander un certificat directement. Mais si une partie du trafic passe par un proxy (par exemple, le web, parce que vous avez plusieurs services qui tournent derrière la même ipv4), alors il va falloir demander le certificat sur le proxy, puis copier le certificat en question sur le serveur final. Ce qui est moche puisqu'il faudra refaire ça à chaque mise à jour. Bref, y'a un truc pourri dans l'affaire, mais je n'ai pas encore trouvé comment faire ça proprement.
On met en place la configuration Apache sur le proxy :
- /etc/apache2/sites-enabled/poste.conf
<VirtualHost *:80> ServerName poste.example.org RewriteEngine On RewriteCond %{REQUEST_URI} !.well-known/acme-challenge RewriteRule ^(.*)$ https://%{SERVER_NAME}$1 [R=301,L] </VirtualHost>
- /etc/apache2/sites-enabled/poste-ssl.conf
<VirtualHost *:443> ServerName poste.example.org #IP de la Poste : ProxyPass / http://192.168.1.90/ ProxyPassReverse / http://192.168.1.90/ ProxyRequests off ProxyPreserveHost on <Proxy *> Options FollowSymLinks MultiViews AllowOverride All Order allow,deny allow from all </Proxy> SSLEngine on SSLCertificateFile /etc/letsencrypt/live/poste.example.org/fullchain.pem SSLCertificateKeyFile /etc/letsencrypt/live/poste.example.org/privkey.pem </VirtualHost>
Sans oublier d'activer les modules proxy, de faire le remote ip, etc…
La configuration d'Apache sur la machine terminale (avec ou sans let's encrypt…) :
sudo a2dissite 000-default.conf sudo nano /etc/apache2/sites-available/poste.conf
<VirtualHost *:80> ServerName poste.example.org DocumentRoot /var/www/poste Alias /postfixadmin /usr/share/postfixadmin/public RewriteEngine On RewriteCond %{REQUEST_URI} !.well-known/acme-challenge RewriteRule ^(.*)$ https://%{SERVER_NAME}$1 [R=301,L] </VirtualHost>
- /etc/apache2/sites-enabled/poste-ssl.conf
<VirtualHost *:443> ServerName poste.example.org DocumentRoot /var/www/poste Alias /postfixadmin /usr/share/postfixadmin/public SSLEngine on SSLCertificateFile /etc/letsencrypt/live/poste.example.org/fullchain.pem SSLCertificateKeyFile /etc/letsencrypt/live/poste.example.org/privkey.pem </VirtualHost> <WRAP center round todo 60%> C'est vraiment hyper basique, on peut faire mieux, mais ce n'est pas le sujet principal ici. </WRAP> Puis les commandes suivantes. <code> sudo a2ensite poste.conf sudo systemctl reload apache2
Se rendre sur le site et voir que la page “poste” est bien là.
Base de donnée
Phpmyadmin et postfixadmin étant installés avec les paquets, avec des mots de passe, ça va marcher direct ? Bon, non…
Il va falloir créer une base de donnée où ces deux logiciels pourront aller ensuite, mais aussi permettre à Dovecot de l'utiliser. C'est donc mieux, à cette étape, de paramétrer la base de donnée. Mais on configurera les logiciels web réellement plus tard.
On reste en console pour créer un user ayant le droit de bidouiller les tables depuis l'interface web de phpmyadmin :
sudo -i mysql GRANT ALL PRIVILEGES ON *.* TO admin@localhost IDENTIFIED BY 'motdepasse' WITH GRANT OPTION;
Évidement pas “admin” et “motdepasse”…
À noter que phpmyadmin crée un utilisateur “phpmyadmin” avec le mot de passe entré de la configuration initiale ; utilisateur qui n'a pas le droit de faire grand chose. Un superuser, vu nos besoins, c'est plus simple. Une fois créé, on peut utiliser Phpmyadmin pour bidouiller nos tables graphiquement.
Et on peut voir que postfixadmin a une base de donnée à son nom, et un utilisateur qui a les privilèges dessus. Et c'est tout, c'est bien vide sinon.
Postfix
Ça se passe dans /etc/postfix/
, en particulier main.cf
et master.cf
. Il va y aussi y avoir des petits fichiers de configurations, pour cela je crée le dossier mycfg
qui va éviter de s'éparpiller trop.
Mycfg
Rien n'oblige à y mettre dans un dossier, mais je trouve ça mieux rangé. Ces divers petits fichiers de config vont compléter le fichier principal et ont une syntaxe assez particulière. Il y en a un certain nombres qui concernent mysql et à chaque fois, il faut déclarer les mêmes infos. Comme je suis une sysadmin fainéante, j'ai commis un petit script bash qui va me générer tout ça. Et puis si jamais j'ai besoin de changer le mot de passe de la BDD, ça sera plus facile aussi.
- postfix_cfg.sh
#!/bin/bash # Chemin où les fichiers seront créés, sans slash final output_dir="/etc/postfix/mycfg" # Vérifier si le dossier existe, sinon le créer if [ ! -d "$output_dir" ]; then mkdir -p "$output_dir" fi # Début commun à tous les fichiers (infos de la BDD) common_start="user = postfixadmin password = XXXX hosts = 127.0.0.1 dbname = postfixadmin" # Noms des fichiers # Attention, dans le même ordre que leurs query filenames=("mysql-virtual-mailbox-domains.cf" "mysql-virtual-mailbox-maps.cf" "mysql-virtual-alias-maps.cf" ) # Les variations spécifiques à chaque fichier variations=("query = SELECT domain FROM domain WHERE domain='%s' AND backupmx = 0 AND active = 1" "query = SELECT maildir, quota FROM mailbox WHERE username='%s' AND active = 1" "query = SELECT goto FROM alias WHERE address='%s' AND active = 1" ) # Boucle pour créer les fichiers # Attention, adapter au nombre de fichier, sachant qu'on compte dès 0 ! # 2 fichiers = {0..1}, 3 = {0..2}, etc for i in {0..2}; do filename="${filenames[$i]}" full_path="$output_dir/$filename" # Écrire le contenu dans chaque fichier echo "$common_start" > "$full_path" echo "${variations[$i]}" >> "$full_path" echo "$filename a été créé avec la ligne : ${variations[$i]}" done
Et à quoi ça sert ? C'est mieux d'expliquer pour retrouver les infos quand on a besoin de modifier…
- virtual_mailbox_domains permet de savoir si le mail est associé à un domaine qu'on gère, ou non
- virtual_mailbox_maps vérifie de son côté que l'utilisateur (avant le @ ) existe bien.
- virtual_alias_maps permet de transférer ce qui est envoyé à une adresse, à une autre. Pour les redirections (que ce soit avec des vrais boites, ou avec les alias).
Sur Workaround, on paramètre mysql-email2email.cf
, mais il me semble que postfixadmin règle ça directement en base de donnée. Pour tester, un message envoyé à alias@ sera reçu par moi@ ; et les messages à moi@ continuent d'arriver normalement.
main.cf
/etc/postfix/main.cf
:
- /etc/postfix/main.cf
À venir, une fois validé...
master.cf
Attention, dans ce fichier, les espaces et tabulations ne sont pas anodines.
- Il y a deux espaces entre dovecot, unix, etc.
- Le tiret est spécial, je crois… dans le doute copiez ce qu'il y a dans le fichier, avant.
- Il y a deux espaces avant “flags”.
- ensuite il n'y a qu'un espace entre DRhu, user, etc.
Il manque pas mal de choses dans cette zone, mais on avance.
Touche finale
S'assurer des droits sur les fichiers :
sudo chgrp -R postfix /etc/postfix/mycfg sudo chmod -R u=rw,g=r,o= /etc/postfix/mycfg
Pour vérifier si tout va bien :
postfix check
Et enfin
service postfix restart
Dovecot
À présent, on va aider Dovecot à gérer la suite. Toutes les commandes en sudo/root.
Primo créer un user spécialement pour gérer les mails, et stocker ces derniers sur /var/vmail :
groupadd -g 5000 vmail useradd -g vmail -u 5000 vmail -d /var/vmail -m chown -R vmail:vmail /var/vmail
Ensuite on va modifier des fichiers. Veiller à ce que les lignes suivantes existent et soient commentés/décommentées comme indiqué.
Les fichiers Dovecot se terminant par “ext” sont analysés différemment par le logiciel. On ne touche pas à l'extension et on n'essaie pas de mettre n'importe quoi, n'importe où…
Pour l'authentification, “plain” peut faire peur, en réalité on se connecte en ssl donc, ça va aller. Utiliser un autre truc peut complexifier la prise en charge des clients. Ceci dit, je n'ai pas tout compris, donc ça demandera à être approfondi ; mais plain ne semble pas si grave. L'autre ligne (une à commenter, une à décommenter) permet d'utiliser une base de donnée pour stocker des infos.
- /etc/dovecot/conf.d/10-auth.conf
auth_mechanisms = plain #!include auth-system.conf.ext !include auth-sql.conf.ext #!include auth-ldap.conf.ext #!include auth-passwdfile.conf.ext #!include auth-checkpassword.conf.ext #!include auth-static.conf.ext
On indique à Dovecot où sont réellement les boites mails, d'utiliser les quotas et de pouvoir lire les fichiers compressés.
- /etc/dovecot/conf.d/10-mail.conf
mail_location = maildir:/var/vmail/%d/%n/Maildir mail_plugins = quota zlib
On ajoute aussi quelques plugins sur imap afin d'améliorer les choses :
- la compression (imap_zlib), ce qui va économiser la bande passante,
- l'affichage des quotas dans les clients qui le permettent (imap_quota)
- la gestion de sieve avec imap_sieve
- /etc/dovecot/conf.d/20-imap.conf
protocol imap { mail_plugins = $mail_plugins imap_zlib imap_quota imap_sieve }
La suite, on lui dit comment gérer la partie authentification (en lien avec postfix), et puis on va activer des infos pour que le module de statistiques ne nous fasse pas d'erreurs.
- /etc/dovecot/conf.d/10-master.conf
# Pour l'imap service imap-login { inet_listener imap { } inet_listener imaps { } } # Si on veut utiliser pop3 service pop3-login { inet_listener pop3 { } inet_listener pop3s { } } service submission-login { inet_listener submission { } } # Pour utiliser lmtp, plus robuste que LDA dans la délivrance des mails # LMTP gère la réception et la livraison des e-mails dans les boîtes aux lettres. service lmtp { unix_listener /var/spool/postfix/private/dovecot-lmtp { mode = 0600 user = postfix group = postfix } } # Cette partie peut être remplie pour mettre des limites service imap { } service pop3 { } service submission { } service auth { unix_listener auth-userdb { } # Postfix smtp-auth (chercher ce morceau !) # authentification SMTP via Dovecot SASL utilisé lors de l'envoi des mails unix_listener /var/spool/postfix/private/auth { mode = 0666 user = postfix group = postfix } } service dict { unix_listener dict { } } # fix Error: net_connect_unix(/var/run/dovecot/stats-writer) failed: Permission denied)) service stats { unix_listener stats-reader { user = vmail group = vmail mode = 0660 } unix_listener stats-writer { user = vmail group = vmail mode = 0660 } }
Changer le certificat suivant la poste locale, et utiliser des paramètres un peu mieux que “rien” :
- /etc/dovecot/conf.d/10-ssl.conf
ssl = required ssl_cert = </etc/letsencrypt/live/poste.example.org/fullchain.pem ssl_key = </etc/letsencrypt/live/poste.example.org/privkey.pem ssl_client_ca_dir = /etc/ssl/certs ssl_dh = </etc/dovecot/dh.pem ssl_min_protocol = TLSv1.2 ssl_prefer_server_ciphers = yes ssl_cipher_list = HIGH:!eNULL:!LOW:!MEDIUM:!EXP:!RC4:!3DES:!MD5:!SHA1:!SHA256:!SHA384:!PSK:!kRSA:!SRP:-DH:+ECDH
Par défaut, ssl_cipher_list est paramétré avec divers protocoles autorisés/interdits :
ssl_cipher_list = ALL:!kRSA:!SRP:!kDHd:!DSS:!aNULL:!eNULL:!EXPORT:!DES:!3DES:!MD5:!PSK:!RC4:!ADH:!LOW@STRENGTH
C'est sans doute pas si mal, mais je teste la version Tycho. On verra si ça bloque avec des clients légitimes.
On va aussi générer un fichier utile (je crois, d'après ce qui est écrit…) :
openssl dhparam -out /etc/dovecot/dh.pem 4096
Vérifier la configuration suivante (utile pour savoir où sont les mails mais aussi les quotas, etc) :
- /etc/dovecot/conf.d/auth-sql.conf.ext
passdb { driver = sql args = /etc/dovecot/dovecot-sql.conf.ext } userdb { driver = sql args = /etc/dovecot/dovecot-sql.conf.ext }
SIEVE
SIEVE permet de créer des règles de filtre sur le serveur et donc de trier automatiquement les emails sans lien avec le client courriel. Pratique quand on switche entre webmail et divers thunderbird. Snappymail permet de gérer ces filtres ; il y avait un module thunderbird mais actuellement indisponible.
Activer la gestion de sieve via lmtp
- /etc/dovecot/conf.d/20-lmtp.conf
protocol lmtp { mail_plugins = $mail_plugins sieve }
Et indiquer que Sieve a le droit de marcher :
- /etc/dovecot/conf.d/20-managesieve.conf
protocols = $protocols sieve service managesieve-login { inet_listener sieve { port = 4190 } service_count = 1 }
Relancer Dovecot, puis vérifier que les ports sont bien ouverts :
service dovecot restart lsof -i :4190 -P
Cela devrait donner ce genre de retour
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME dovecot 371602 root 15u IPv4 487495 0t0 TCP *:4190 (LISTEN) dovecot 371602 root 16u IPv6 487496 0t0 TCP *:4190 (LISTEN)
</WRAP>
TODO : il va falloir ouvrir le port 4190 mais je garde ça sur la partie pare-feu.
Quotas
C'est tout un chantier.
Activer et paramétrer la gestion des quotas :
- /etc/dovecot/conf.d/90-quota.conf
plugin { quota = maildir:User quota quota_rule = *:storage=5G # Ajouter 100M pour ce qui est dans la corbeille, ça permet de faire du tri sans "ranger" dans la corbeille. quota_rule2 = Trash:storage=+100M # Quota plugin can also limit the maximum accepted mail size. quota_max_mail_size = 5M quota_vsizes = yes quota_status_success = DUNNO quota_status_nouser = DUNNO quota_status_overquota = "452 4.2.2 Mailbox is full and cannot receive any more emails" } service quota-status { executable = /usr/lib/dovecot/quota-status -p postfix unix_listener /var/spool/postfix/private/quota-status { user = postfix } # Connexion avec mysql dict { quota = mysql:/etc/dovecot/dovecot-dict-sql.conf.ext } # Warning plugin { quota_warning = storage=95%% quota-warning 95 %u quota_warning2 = storage=80%% quota-warning 80 %u } service quota-warning { executable = script /usr/local/bin/quota-warning.sh unix_listener quota-warning { user = vmail group = vmail mode = 0660 } }
Ne pas oublier de faire le script appelé. Changer l'adresse d'envoi du mail !!! :
- /usr/local/bin/quota-warning.sh
#!/bin/sh PERCENT=$1 USER=$2 cat << EOF | /usr/lib/dovecot/dovecot-lda -d $USER -o "plugin/quota=maildir:User quota:noenforcing" From: postmaster@example.org Subject: Quota warning - $PERCENT% reached FR : Votre boîte aux lettres ne peut stocker qu'un nombre limité d'e-mails. Actuellement, elle est pleine à $PERCENT%. Si vous atteignez 100 %, les nouveaux courriels ne pourront plus être stockés. Merci de votre compréhension. EN : Your mailbox can only store a limited amount of emails. Currently it is $PERCENT% full. If you reach 100% then new emails cannot be stored. Thanks for your understanding. EOF
Et rendre le fichier exécutable :
chmod +x /usr/local/bin/quota-warning.sh
Il faut aussi faire en sorte que la base de donnée soit réellement contactée, et donc déclarer les infos de cette dernière. Dans /etc/dovecot/dovecot-dict-sql.conf.ext
, décommenter et adapter la ligne suivante :
- /etc/dovecot/dovecot-dict-sql.conf.ext
connect = host=localhost dbname=postfixadmin user=postfixadmin password=password
Par exemple :
- /etc/dovecot/dovecot-dict-sql.conf.ext
connect = host=127.0.0.1 dbname=postfixadmin user=postfixadmin password=Nonmaisrêvepas
Et un peu plus
Enfin, en dehors de conf.d
, il y a des fichiers où indiquer les infos de connexion à la base de donnée. On ajoute ceci tout à la fin, en mettant les infos propres à chaque bdd/user/mot de passe :
- /etc/dovecot/dovecot-sql.conf.ext
######### Modifs Postfixadmin driver = mysql default_pass_scheme = BLF-CRYPT connect = host=127.0.0.1 dbname=postfixadmin user=postfixadmin password=MOT_DE_PASSE_A_CHANGER user_query = SELECT username as user, concat('*:bytes=', quota) AS quota_rule, '/var/vmail/%d/%n' AS home, 5000 AS uid, 5000 AS gid FROM mailbox WHERE username='%u' password_query = SELECT password, '%w' AS userdb_plain_pass, CONCAT('/home/vmail/', maildir) AS userdb_home, concat('*:bytes=', quota) AS userdb_quota_rule FROM mailbox WHERE username = '%u' AND domain = '%d' AND active iterate_query = SELECT username as user FROM mailbox WHERE active = '1'
C'est sans doute redondant de l'indiquer aussi dans ce fichier, mais dans le doute, je met (parce que là, ça marche, mais j'ai bidouillé de partout).
- /etc/dovecot/dovecot-dict-sql.conf.ext
connect = host=127.0.0.1 dbname=postfixadmin user=postfixadmin password=MOT_DE_PASSE_A_CHANGER # CREATE TABLE quota ( # username varchar(100) not null, # bytes bigint not null default 0, # messages integer not null default 0, # primary key (username) # ); map { pattern = priv/quota/storage table = quota username_field = username value_field = bytes } map { pattern = priv/quota/messages table = quota username_field = username value_field = messages }
Utile ou non ? https://neptunet.fr/messagerie-debian/ précise :
Modifiez les droits sur le fichier « dovecot.conf » situé dans /etc/dovecot pour que Dovecot soit lancé en tant qu’utilisateur « vmail » : chgrp vmail /etc/dovecot/dovecot.conf chmod g+r /etc/dovecot/dovecot.conf
On va faire quelques tests… pour le moment c'est à root. Et ça semble aller. Donc on ne touche pas.
S'assurer que les droits sur /etc/dovecot/dovecot-sql.conf.ext
empêcheront des malveillants de lire le mot de passe de la BDD :
chown root:root /etc/dovecot/dovecot-sql.conf.ext chmod go= /etc/dovecot/dovecot-sql.conf.ext
On vérifie que la configuration n'a pas d'erreur ; si tout va bien, elle s'affiche en retour, sinon ça liste les erreurs à corriger :
doveconf -n
Et après ça on peut redémarrer Dovecot.
service dovecot restart
Si besoin de plus de détail, la doc officielle est là.
Postfixadmin
Comme on passe par le paquet Debian (ce qui facilite les mises à jour, mais pas l'installation), il va falloir adapter un peu pour servir postfixadmin. La config est dans /etc/postfixadmin/
et les fichiers de la partie “site web” dans /usr/share/postfixadmin/
.
Donc on ajoute ce qui suit (si ce n'est déjà fait) dans notre config Apache, et on redémarre le service Apache :
Alias /postfixadmin /usr/share/postfixadmin/public
Puis créer le fichier de configuration dans /etc/postfixadmin/config.local.php
; les options par défaut sont dans /etc/postfixadmin/config.inc.php
.
- /etc/postfixadmin/config.local.php
<?php // Partie nécessaire pour que ça marche $CONF['configured'] = true; $CONF['database_type'] = 'mysqli'; $CONF['database_host'] = '127.0.0.1'; $CONF['database_user'] = 'postfixadmin'; $CONF['database_password'] = 'XXXX'; $CONF['database_name'] = 'postfixadmin'; $CONF['encrypt'] = 'php_crypt:BLOWFISH'; // Delimiter pour les alias, genre "+". $CONF['recipient_delimiter'] = "."; // Ce qui suit tient de la personnalisation $CONF['default_language'] = 'fr'; $CONF['page_size'] = '30'; $CONF['default_aliases'] = array ( 'abuse' => 'abuse@example.org', 'postmaster' => 'postmaster@example.org', ); // Apparait sur la page web $CONF['show_header_text'] = 'Yes'; $CONF['header_text'] = ':: Gestion des mails ::'; $CONF['show_footer_text'] = 'YES'; $CONF['footer_text'] = 'Retour à example.org'; $CONF['footer_link'] = 'example.org'; // Y'a d'autres options qu'il sera sympa de personnaliser... genre "theme". ?>
Ce fichier et la personnalisation du site vont demander un peu plus de boulot. Mais, ça, ça marche déjà.
Concernant encrypt
, choisir “php_crypt:BLOWFISH” permet de passer outre certains messages d'erreur avec dovecot et est un choix sécuritaire sérieux.
Et aller ensuite sur http://192.168.1.XX/postfixadmin/setup.php ; on va pouvoir ainsi générer un mot de passe haché afin d'installer la suite. À ce stade, il suffit de régler les potentiels soucis dont postfixadmin nous prévient (et qui devraient être limités).
Postfixadmin étant un clicodrôme parfait, je vous laisse explorer.
Paramétrer les alias systèmes vers admin@
C'est bien beau tout ça, mais quand un mail interne au système (par exemple à root) est envoyé, il arrive où ? Nul part, et cette fois pas question de jouer avec Msmtp : le relai, ça sera “nous”. Mais, la logique n'est pas très différente.
On commence par éditer /etc/aliases
:
- /etc/aliases
mailer-daemon: postmaster postmaster: root nobody: root hostmaster: root usenet: root news: root webmaster: root www: root ftp: root abuse: root noc: root security: root default: admin@example.org root: admin@example.org
Oui, sans le @ à la fin des alias, cette fois. Et vers admin@example.org ou autre, hein, tant que c'est un utilisateur présent sur le système.
Puis on régénère le fichier de postfix à propos des alias :
postalias /etc/aliases
Et on peut tester l'envoi d'un mail. J'ai craqué, installé bsd-mailx
(dont la syntaxe pour l'envoi d'un mail test ne me pose pas de souci) et hop :
echo "Test" | mail -s "Test " root
Cela arrive bien dans la boite mail configurée !
Tester
On va pouvoir voir à quel point ça marche (ou pas).
Les infos ici peuvent être utilisées à divers stade du tutoriel pour voir ce qui marche.
Ajoutez un domaine sur l'interface de postfixadmin, et un utilisateur (ici, moi@example.org). En théorie, déjà, c'est possible…
Si ce n'est pas déjà fait, installez bsd-mailx pour tester l'envoi de mail :
apt install bsd-mailx
N'oubliez pas de vérifier les configurations de Postfix et Dovecot puis de les relancer :
postfix check doveconf -n service postfix restart service dovecot restart
Ce qui permet de lancer la commande suivante :
echo test | mail moi@example.org
Il n'y aura “rien” en réponse dans le terminal, si ça ne va pas trop mal. On va voir si elle a eu de l'effet de la façon suivante :
tail -f /var/log/mail.log
pour voir s'il y a des erreurs- Vérifier que
/var/vmail/
s'est peuplé d'une nouvelle boite. Et avec mutt on peut lire le “message”.
Jusque là, tout s'est passé en interne, et c'est déjà pas si mal.
Pour tester les limites de quota, créez un utilisateur avec un quota très bas (par exemple 1 Mo), puis créer un fichier à joindre “volumineux”, et enfin envoyez-le (avec mutt) :
dd if=/dev/zero of=/root/400kb.txt bs=1K count=400 echo "Test de quota" | mutt -s "Test de quota" -a ./400kb.txt -- quota@example.org
Pour vérifier que tout se passe bien quand on tente de se connecter (donc que les mots de passe sont les mêmes dans la bdd et avec dovecot…) :
doveadm auth test moi@example.org
Et on peut aussi tenter de se connecter en imap (avec dans l'ordre : nom d'utilisateur
@domaine du mail
@domaine du relai
) :
mutt -f imaps://moi@exemple.org@mail.exemple.org
Envie de tester encore et encore, en changeant le sujet seulement pour voir ce qui passe ou pas ? J'ai un petit script bash pour ça :
- mailtest.sh
#!/bin/bash # Vérifie si le sujet a été fourni en argument if [ -z "$1" ]; then echo "Usage: $0 <sujet>" exit 1 fi # Assigne le sujet à une variable subject="$1" # Définis le corps du message body="Test de quota" # Chemin vers le fichier à joindre (quand on teste les quotas) #attachment="./fauxfichiers/400kb.txt" # Adresse e-mail du destinataire recipient="moi@example.org" # Envoie l'e-mail avec pièce jointe # echo "$body" | mutt -s "$subject" -a "$attachment" -- "$recipient" # OU sans la pièce jointe echo "$body" | mutt -s "$subject" -- "$recipient" echo "Yep"
Il suffit ensuite de lancer le script en lui filant un sujet entre guillemets :
./mailtest.sh "sujet de 12h02"
Todo
Prochain test : envoyer un mail à l'extérieur. Ce qui demande que j'ouvre des ports sur la box, c'est pas de suite. : fait :)
Il va falloir configurer dkim et tout l'toutim.
Tester aussi si je peux envoyer un message avec un de mes alias ET si je suis bloquée si je tente d'utiliser un autre alias du domaine sans le bon compte.
Problème pour envoyer un message à “nimporte qui sauf moi”. Revoir la conf…
vieux tuto
Ici on suit très bêtement https://workaround.org/ispmail/bullseye/making-postfix-get-its-information-from-the-mariadb-database/ sans oublier de changer “example.org” par notre nom de domaine. La partie dite “facultative” n'est pas facultative (on ne crée pas d'alias catch-all mais on crée quand même de quoi gérer les alias et les redirections entre eux…).
Idem sur la suite avec Dovecot et LMTP, rien de nouveau face au tuto.
En fait à ce stade, j'ai suivi sans diverger les pages suivantes :
- https://workaround.org/ispmail/bullseye/quotas-2/ Modulo la petite modif notée plus bas
-
- Sur ce dernier, j'ai mis de coté le petit encadré final “Allow aliases?”. On y revient bien plus tard. Mais cela veut dire qu'à ce stade, les alias ne peuvent pas répondre.
J'ai sauté le chapitre sur le webmail, il n'est pas question de l'avoir sur cette machine et c'est juste un client.
Je pense tout de même que ça serait bien de reprendre ça à ma sauce, à un moment. La façon dont les modifs sont faites dans /etc/postfix/main.cf
donne un fichier assez illisible.
Autodécouverte par Thunderbird et autres
Les logiciels de courriel correctement fichus peuvent chercher leur info à https://example.org/.well-known/autoconfig/mail/config-v1.1.xml
. Notez la subtilité : pas le relais mais bien le domaine de base.
Donc, on ajoute ce fichier, soit directement “là”, soit dans un autre dossier et on fait un joli alias dans apache
- /etc/apache2/sites-enabled/monsite.conf
Alias /.well-known/autoconfig/mail /var/www/example.org/autoconfig-mail
Redémarrer Apache.
Dans ce dossier, on va donc mettre config-v1.1.xml
qui va contenir ceci (copié directement de https://workaround.org/ispmail/bullseye/mail-client-auto-configuration-2/ ) :
<?xml version="1.0" encoding="UTF-8"?> <clientConfig version="1.1"> <emailProvider id="workaround.org"> <domain>workaround.org</domain> <displayName>Christoph's Mail Service</displayName> <displayShortName>ISPmail</displayShortName> <incomingServer type="imap"> <hostname>webmail.workaround.org</hostname> <port>143</port> <socketType>STARTTLS</socketType> <authentication>password-cleartext</authentication> <username>%EMAILADDRESS%</username> </incomingServer> <outgoingServer type="smtp"> <hostname>webmail.workaround.org</hostname> <port>587</port> <socketType>STARTTLS</socketType> <authentication>password-cleartext</authentication> <username>%EMAILADDRESS%</username> </outgoingServer> </emailProvider> </clientConfig>
- Changez
workaround.org
par votre domaine principal - Changez
webmail.workaround.org
par votre relais - Adaptez
displayName
etdisplayShortName
- Vérifiez que c'est bien ces ports chez vous… par défaut ça devrait. Et que c'est ouvert sur le pare-feu !
À noter, il y a potentiellement d'autres procédures, avec entre autre des ajouts à faire dans la zone DNS. Voir ceci :
Mais, je m'embêterais avec ça si j'ai des soucis… pour le moment, ça suffit.
Oui ben, des soucis, y'en a… Faudra revoir la chose. En tout cas sur l'ajout d'un autre sous-domaine ça a bien cafouillé…
SPF, DKIM et DMARC : retour au DNS
Voir la page dédiée : DNS, SPF, DKIM, DMARC et autres choses à configurer sur le mail
Alias avec joker
On en arrive au point vital. Et on va voir que ce n'est pas si simple.
Mais de quoi je cause ?
Il faut savoir que Gandi a une fonctionnalité épatante : l'alias avec joker.
Extrait de leur doc :
Entrez le nom de d'alias, sans inclure le @. Vous pouvez également utiliser le caractère joker “*” pour, par exemple, avec “pierre*”, rediriger tout ce qui commence par pierre dans votre boite (ex.: pierre@ → pierremartin@, pierreafeu@, etc.). Cette option ne fonctionne toutefois qu'avec un minimum de 2 caractères avant ou après le joker.
Un peu plus d'exemples. J'ai la boite mail vilain@example.org
, qui me sert à recevoir les inscriptions des sites, newsletters, commandes internet… autant dire que c'est bien rempli. vilain@
n'est jamais exposé sur le net2), au lieu de ça, je donne des alias, dont voici une liste :
- nom.prenom@example.org
- autrealias@example.org
- news.*@example.org
- marchand.*@example.org
- wtf.*@example.org
Les deux premiers (nom.prenom@
et autrealias@
) n'ont pas de joker, il faut avoir l'adresse exacte pour leur écrire. Les suivants par contre, je les adapte à la volée ; je donne marchand.site1@example.org
à un premier site marchand et marchand.site2@example.org
à un second site marchand, sans avoir besoin de créer les alias explicitement. Ensuite je m'en sert pour filtrer ce que je reçois dans ma boite mail et voir qui a revendu mon adresse (elles le sont rarement, en fait).
Je peux non seulement recevoir des mails à ces adresses avec joker, mais aussi répondre avec au besoin, bien que dans ce cas je sois dans l'obligation de déclarer l'alias dans Thunderbird (mais pas chez le fournisseur mail !).
Voilà la killer feature de Gandi, si difficile à trouver ailleurs.
Coup de bol pour moi, tous mes alias fonctionnels sont de la forme chaine.joker
; sans le point, j'allais avoir des soucis.
On va bidouiller quelque chose d'équivalent en deux temps :
- D'abord avec postfix : il y a moyen d'imiter ça. Ce n'est pas exactement pareil mais assez proche pour dépanner.
- Ensuite, on utilisera un service du type anonaddy. Mais c'est pour plus tard, on a pas mal de choses à vérifier avant.
Recevoir les alias avec joker de type "point"
Dans ces manipulations, n'importe quelle adresse gagne son “joker” en fin… donc john@example.org va recevoir aussi tout les possibles john.*@example.org sans rien avoir à déclarer de plus. Ce qui est un peu gênant, ouvrant la porte à du potentiel flood de spam…
Cela se réglera, chez nous, par l'usage d'Anonaddy. Mais, en attendant, il faut s'assurer de pouvoir tout recevoir.
C'est Dovecot qui débloque la solution.
sudo nano /etc/dovecot/conf.d/15-lda.conf
Il y a là la ligne recipient_delimiter = .
(à décommenter et à mettre avec un point, donc).
Lors de mes premiers tests, ça ne permettait pas de répondre.
Mais… Au fil des bidouilles “là ça marche” et je ne suis pas sûre de ce que j'ai changé. J'ai tout de même </WRAP>recipient_delimiter = .
dans /etc/postfix/main.cf
en plus. Pas sûr que ça serve à grand chose car postfix ne reconnait pas le point comme caractère valide, dans mes précédents tests, mais c'est là…
J'ai aussi mes alias déclarés. Par exemple “spam@example.org” est un alias du vrai mail ; si je tente d'envoyer avec “spam.moi@example.org” (sans avoir déclarer cet alias par ailleurs), ça envoie.
Par contre tous les alias déclarés sont sans point ; c'est peut-être ça qui bloquait dans mes précédents tests… je n'ai pas déclaré un spam.moi@example.org“ officiellement et il n'est renseigné nul part. Mais il peut envoyer.
Tout cela demandera plus d'investigation quand je referais un autre serveur mail.
Recharger dovecot et postfix.
Recevoir les alias avec plusieurs jokers
En plus de la manipulation précédente, si on veut utiliser le +
en plus du .
.
Dans /etc/postfix/main.cf
, modifier virtual_alias_maps
pour ajouter regexp:/etc/postfix/point_addressing
. Ça devrait ressembler à ça :
virtual_alias_maps = regexp:/etc/postfix/point_addressing, mysql:/etc/postfix/mysql-virtual-alias-maps.cf,mysql:/etc/postfix/mysql-email2email.cf
Modifier /etc/postfix/point_addressing
en mettant les regexp suivantes (à adapter aux noms de domaines servis) :
/^(.*)\.(.*)@(example\.org|other_example\.fr)$/ $1+$2@$3 /^(.*)\+(.*)@(example\.org|other_example\.fr)$/ $1@$3
Le fait de déclarer des noms de domaine évitera qu'on permette n'importe quel alias à tous les domaines, cela offre un peu plus de contrôle.
Recharger postfix.
- Source (entre autre) : https://wiki.fiat-tux.fr/books/administration-syst%C3%A8mes/page/postfix
Permettre aux alias d'envoyer
À la fin de https://workaround.org/ispmail/bullseye/relay-outoing-email-through-postfix/, il y a une note assez sibylline sur le sujet :
Allow aliases?
If you want to allow users to send as one of their aliases you could create a new *.cf file with a mapping query like this: SELECT email FROM virtual_users WHERE email='%s' UNION SELECT destination FROM virtual_aliases WHERE source='%s'
Dans un premier temps, j'ai laissé ça de côté.
Mais, il faut que nos alias puissent répondre. Si John reçoit un mail via son alias Jack, il faut qu'il puisse répondre avec Jack ; et je confirme qu'à ce stade, le serveur refuse que Jack envoie un mail.
Voici la méthode plus détaillée.
J'ai créé /etc/postfix/mysql-allow-alias-send.cf
:
user = mailserver password = hosts = 127.0.0.1 dbname = mailserver query = SELECT email FROM virtual_users WHERE email='%s' UNION SELECT destination FROM virtual_aliases WHERE source='%s'
Pour le faire prendre en compte, modifions smtpd_sender_login_maps
dans /etc/postfix/main.cf
pour que ça ressemble à ça :
smtpd_sender_login_maps=mysql:/etc/postfix/mysql-email2email.cf,mysql:/etc/postfix/mysql-allow-alias-send.cf
Et ça marche. Mieux, si je déclare un alias forgé dans Thunderbird, par exemple si je lui dis que “joe” est un alias de John et que je tente d'envoyer un mail avec joe, le serveur éjecte Joe avec le message suivant dans les logs :
<joe@example.org>: Sender address rejected: not owned by user john@example.org; from=<joe@example.org> to=<admin@example.org> proto=ESMTP helo=<[192.168.1.89]>
Ouf ! Ça, ça marche !
Alias avec joker, version améliorée
Ce sera avec Anonaddy, mais c'est pour une autre fois. Voir la page dédiée.
Anonaddy va permettre d'anonymiser complètement l'adresse mail réelle, d'avoir uniquement les adresses jokers sur certains alias, et même de bloquer l'envoi vers certains alias avec joker. C'est encore mieux que Gandi.
Améliorer des détails de sécurité
L'outil https://nstools.fr/ liste divers points qui peuvent être améliorés.
(à vérifier, là je teste)
Désactiver la commande VRFY
Cela sert à avoir la liste des mails valides sur un serveur. Utilisé par les spammeurs pour contacter les gens… Donc, le désactiver n'est pas vu comme une mauvaise pratique.
Dans /etc/postfix/main.cf
, ajoutez la ligne
disable_vrfy_command = yes
Cacher la version du serveur et autres infos indiscrètes
Il faut camoufler les infos sur les versions des logiciels, pas besoin qu'on sache sur quelles failles compter. Rien de compliqué, il suffit de revoir le paramètre smtpd_banner
dans /etc/postfix/main.cf
.
On passe de ceci :
smtpd_banner = $myhostname ESMTP $mail_name (Debian/GNU)
à cela :
smtpd_banner = $myhostname ESMTP
Ça devrait suffire.
Cacher les infos envoyées dans les mails
Ce morceau n'est pas fait ni testé.
Créer le fichier /etc/postfix/check/header_checks_out et mettre ces regexp dedans (source) :
/^\s*Received: from \S+ \(\S+ \[\S+\]\)(.*)/ REPLACE Received: from [127.0.0.1] (localhost [127.0.0.1])$1 /^X-Originating-IP:/ IGNORE /^X-Mailer:/ IGNORE /^Mime-Version:/ IGNORE /^User-Agent:/ IGNORE
Là il faut regarder plus en détail… attends, on n'active pas de suite !
Activer/désactiver ipv6
Dans l'absolu, ipv6, c'est mieux.
J'ai cependant rencontré un souci de taille : mon routeur n'est pas tout jeune, et ne me permet pas de déclarer l'ipv6 de ma machine. Pour le dire autrement, le réseau local n'est qu'en ipv4 (si j'ai bien compris), et je ne peux rien y faire. En attendant d'acheter un routeur plus optimum et de me former un peu plus à la partie réseau… il va falloir désactiver ipv6 sur mon service, au risque de rencontrer de vrais gros soucis.
La première chose à faire est d'éviter d'avoir une entrée AAAA vers le serveur dans son DNS ; ça, c'est facile.
Mais par défaut, postfix va quand même tenter d'envoyer certains mails en ipv6 (puisque notre serveur, lui, ne sais pas qu'on est fâché avec la technologie moderne). Cela va créer des erreurs de distributions… Car le reverse dns ne peux pas fonctionner sur l'adresse ipv6 à cause de ce fichu routeur !
Je note ça plusieurs jours après l'avoir fait donc, j'ai pu oublier des détails…
Il faut donc ajouter ces lignes dans /etc/postfix/main.cf
:
# Forcer ipv4 tant que je n'ai pas un routeur me permettant d'indiquer mon ipv6 smtp_address_preference = ipv4 inet_protocols = ipv4
Et déclarer uniquement le réseau en ipv4 (mais commentez la partie en ipv6, on espère un jour l'activer…) :
#mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 mynetworks = 127.0.0.0/8
Personnalisation suivant les GAFAMS
Cette partie risque d'être augmentée au fil du temps.
Je garde trace ici de la manip, mais ce n'est pas pertinent à ce stade, puisque le souci d'ipv6 avec Google venait du routeur et non d'en face…
On peut indiquer des règles spécifiques suivant la destionation. Par exemple pour forcer les communications avec Google à passer par ipv4, créer le fichier /etc/postfix/transport
avec la ligne suivante :
gmail.com smtp4:
Ajouter la ligne suivante dans /etc/postfix/main.cf
:
transport_maps = hash:/etc/postfix/transport
Il faut aussi générer un fichier /etc/postfix/transport.db
, avec cette commande :
postmap /etc/postfix/transport
Redémarrer Postfix.
Limiter l'envoi de mail dans un temps donné
Là on est dans un truc entre sécurité et mesures antispam. Il est toujours possible qu'un compte mail se fasse pirater, et que le compte serve alors à flooder du spam à fond. Et ça, ce sera très, trèèès mauvais pour nous, parce qu'on va se faire bannir de partout et inscrire en block-list.
Bref, il est temps de paramétrer la chose.
La limite du nombre de mail envoyé à la minute est vraiment facile. Dans /etc/postfix/main.cf
, ajouter quelque chose comme :
smtpd_client_message_rate_limit = 10 anvil_rate_time_unit = 60s smtpd_recipient_limit = 40
Ce qui ici, veut dire qu'on a le droit d'envoyer 10 mails à la minute, chacun à 40 destinataires au maximum. Faut arriver à les écrire, quand même.
anvil_rate_time_unit
: par défaut c'est de toute façon 60 secondes donc on pourrait aussi bien ne pas le déclarer. Cela sert à diverses choses, pas juste à la limite d'envoi de mail.smtpd_client_message_rate_limit
: le nombre de messages autorisé dans cette limite. 2 est évidement mauvais pour la prod, mais cela permet de tester que tout marche : envoyez 3 mails différents depuis la même adresse, en moins d'une minute, et admirez le résultat. Postfix ne met pas vraiment de limite par défaut…smtpd_recipient_limit
: Nombre maximum de destinataires qu'un serveur SMTP de Postfix accepte par requête de livraison de message (défaut : 1000). Il me semble que 40 est déjà énorme, mais ça arrive qu'on envoie un mail collectif à une grosse partie de notre carnet d'adresse.
Il y a d'autres options similaires (cf http://www.postfix.org/TUNING_README.html#conn_limit ) mais cela me semble inutile.
Limiter les tentatives de connexions des crackbots
En regardant les logs on peut voir que tout le net tente de se connecter à notre pauvre serveur.
Fail2ban éjecte les plus nuisibles (et stupides) mais on peut ajouter aussi ceci dans /etc/postfix/main.cf
:
smtpd_error_sleep_time = 5s smtpd_soft_error_limit = 3 smtpd_hard_error_limit = 10
smtpd_error_sleep_time
: la réponse du serveur SMTP n'est envoyée qu'après un délai lorsque le client a fait plus de $smtpd_soft_error_limit et moins de $smtpd_hard_error_limit erreurs, sans livrer de courrier (1s par défaut).smtpd_soft_error_limit
: Nombre d'erreurs qu'un client SMTP distant est autorisé à faire sans livrer de messages avant d'être ralenti par le serveur SMTP de Postfix (10 par défaut).smtpd_hard_error_limit
: Nombre maximum d'erreurs qu'un client SMTP distant est autorisé à commettre sans livrer de message. Le serveur SMTP de Postfix coupe la connexion au delà de cette limite (20 par défaut).
Là je me fais plaisir à bien baisser la limite… parce que les serveurs sérieux ne font pas d'erreurs. On verra si cela complexifie ma réception de mails.
Attention cependant car cela peut aussi ralentir tout postfix et donc appliquer des délais à des clients légitimes.
Avertir l'admin si y'a des abus/problèmes
Dans /etc/postfix/main.cf
:
error_notice_recipient = postmaster@example.org notify_classes = resource, software,policy,bounce,delay
error_notice_recipient
: par défaut les notifications sont délivrées à “postmaster” (en local), donc ça devrait arriver, mais on peut aussi indiquer une autre adresse mail, vu que de toute façon… ben on a un serveur d'envoi de mail…notify_classes
: qu'est-ce qui va être notifié. Par défaut,resource
(problème de ressources) etsoftware
(problème de logiciel). On peut ajouter ce qui suit :bounce
: détails des en-têtes pour les messages rejetés à la livraison. Inclut le paramètre2bounce
donc pas besoin de le mettre aussi.2bounce
: avis de rejets non-livrablesdelay
: à propos des messages retardéspolicy
: à propos des messages rejetés pour cause de restriction. Genre trop d'envoi à la minute.protocol
: erreur de protocole du client ou du serveur. Et là je crains que ça floode à mort sur les gens qui tentent de se connecter de façon non autorisée, alors je ne l'ai pas mis dans ma configuration.
Cela peut faire pas mal de flood sur postmaster, mais permet aussi de voir rapidement si le serveur a un souci.
Cf https://postfix.traduc.org/index.php/postconf.5.html#notify_classes pour la doc officielle traduite.
Postscreen, pour filtrer plus de bandits
Doc de référence : https://www.postfix.org/postconf.5.html.
Attention, c'est pas au point parce que je n'ai pas encore mis en place “subcleanin” comme proposé dans https://blog.debugo.fr/serveur-messagerie-optimisation-postfix/ et donc ben… c'est le bordel !
Postscreen va appliquer des vérifications sur les domaines (entre autre) et faciliter le tri. On pourra ainsi déclarer certains domaines comme bloqués, et d'autres comme de confiance, et en mettre certains en liste grise. Pour chaque contrôle, on peut au choix :
ignore
: on ne fait rienenforcer
: on bloque et on enverra un retourRCPT TO: 550 5.3.2 Service currently unavailable
drop
: on répondra521 5.3.2 Service currently unavailable
Dans le fichier /etc/postfix/master.cf
, commentez la ligne :
smtp inet n - y - - smtpd
et décommenter
smtp inet n - y - 1 postscreen smtpd pass - - y - - smtpd -o cleanup_service_name=subcleanin dnsblog unix - - y - 0 dnsblog tlsproxy unix - - y - 0 tlsproxy
Qu'est-ce qu'on est en train de faire ?
Les colonnes se réfèrent aux informations suivantes :
- Nom du service (smtp, dnsblog, etc)
- Type de service : sur quel port/socket ce dernier écoute.
inet
passe par TCP/IP et est accessible depuis le réseauunix
etpass
sont des processus locaux.pass
ne reçoit qu'une connexion par requête.
- Private : si le service est interne à postfix ou public.
inet
est forcément public. Par défaut sur “y” et par déduction je dirais que “y” veut dire “privé”. - Unprivileged : si le service tourne avec les privilèges root ou avec l'utilisateur postfix. Par défaut “y” et aucune idée de si c'est root ou pas, mais on va faire confiance aux tutos.
- Chroot : si le service tourne en version chrooté. Pour certains, il ne faut pas (cf manpage), sinon par défaut ça semble “y”.
- Wake up time (default: 0) : réveille le service après ce nombre de secondes. Si on ajoute
?
ça indique qu'il ne faut pas le réveiller tant qu'il n'a pas été appelé par ailleurs. 0 indique qu'on ne fait pas de réveil automatique. - Limite de processus : nombre maximum de processus simultanés sur ce service, défini par défaut ailleurs ; 0 indique de ne pas mettre de limite.
- Commande et arguments : la commande à exécuter. Les arguments demandent de revenis à la ligne.
-o name=value
(forme raccourcie, sinon il y a une façon longue de le raconter) : surcharge le paramètre en question demain.cf
. La doc conseille de ne pas en abuser.
Source : le manpage et configuration de postcreen par Debugo.
Ici, donc, on va activer l'usage de postscreen (utile pour bloquer pas mal de spam), dnsblog pour filtrer les dns bloqués, et tls proxy pour le support de STARTTLS dans postscreen.
On ajoute les lignes suivantes dans /etc/postfix/main.cf
:
postscreen_access_list = permit_mynetworks, cidr:/etc/postfix/mycfg/postscreen_access.cidr postscreen_blacklist_action = drop
/etc/postfix/mycfg/postscreen_access.cidr
permet de bloquer des ip, selon cette forme :
xxx.xxx.xxx.xxx reject
Mais bon, ce travail est surtout réalisé par fail2ban en principe. Ne pas oublier de créer le fichier quand même !
On ajoute ensuite une grande subtilité de postscreen : un petit temps de délai avant de répondre. Un serveur mail bien configuré attend poliment qu'on lui donne la parole… cela éjecte donc un certain nombre de “zombies”. La “greet_banner” est le message envoyé lors de l'attente. Le temps d'attente (ici 3 secondes) permet aussi d'interroger si l'ip est blacklistée.
postscreen_greet_wait = 3s postscreen_greet_banner = Cool, we have time... postscreen_greet_action = drop
Listes de blocage
Ensuite, on va ajouter des listes à interroger pour savoir si l'ip ne serait pas bloquée. Si oui, alors… on vire
postscreen_dnsbl_sites = zen.spamhaus.org*2, bl.spamcop.net, b.barracudacentral.org*2 postscreen_dnsbl_threshold = 3 postscreen_dnsbl_action = drop
Ici, quelques subtilités (si j'ai compris, ce qui n'est pas certain !) :
- Si on rejette le mail, l'expéditeur aura l'information du nom de domaine ayant servi à la blocklist. Cela peut se cacher (via postscreen_dnsbl_sites) , mais personnellement je juge plutôt correct de dire “je ne te veux pas car tu est bloqué ici” ; si l'expéditeur est légitime et que c'est une erreur, il peut se faire débloquer.
- Interroger les listes demande du temps, pas la peine d'en ajouter trop, mais, on va le voir ensuite, pas la peine d'en mettre trop peu non plus.
- Forcément, on fait appel à un prestataire externe, avec ce que ça peut questionner sur la confiance. Les listes en question peuvent parfaitement faire une liste des ip qui contactent notre serveur. Personnellement je me dis que l'intérêt de l'information reste limité, surtout si peu à peu j'ai plus d'utilisateurs.
postscreen_dnsbl_threshold
indique la limite inférieure inclusive du score du domaine testé qu'on peut accepter. Et là ça demande un peu de détails.
Si une ip est trouvée dans une des listes, ça va compter pour “1”. Sauf si on ajoute un chiffre après le nom du domaine et l'astérisque ; dans ce cas ça sera pondéré d'autant. Dans l'exemple ici, si une ip est trouvée sur zen.spamhaus.org, ça va compter pour “2”. Là, avec nos trois listes dont 2 pondérées à “2”, si l'ip est listée partout, elle obtiendra un score de 5. C'est plus haut que 3 ⇒ c'est probablement une adresse louche.
Interroger plusieurs listes augmente donc les chances que l'ip bloquée le soit pour des raisons légitimes.
Et c'est une partie que je dois améliorer dans ma config
Mais, attention. Ces listes ne sont pas toutes gratuites, elles ont des conditions d'utilisation, bref pour ne pas se faire ban soi-même… il faut aller voir tout ça.
Greylisting
Enfin, quelques manip qui passent les ip en “greylisting” en attente d'en savoir plus. Attention, cela peut éjecter des serveurs légitimes mais configurés de façon un peu légère (d'ailleurs, moi-même, je donnerais quoi ?). Enfin, bon, comme cela risque surtout de concerner des copains et qu'ils savent comment me contacter autrement… perso ça ne me stresse pas.
Ajout : ça risque aussi de foutre le boxon dans d'autres cas, car le serveur en face reçoit un message comme quoi “on peut pas recevoir” en premier. Et il doit retenter un envoi, ensuite, qui lui passera… si l'ip du serveur est ok. Or avec les gros, c'est bien possible que les ips tournent histoire d'arriver à envoyer. Bref, à tester mais c'est pas forcément une idée parfaite.
postscreen_pipelining_enable = yes postscreen_pipelining_action = enforce postscreen_non_smtp_command_enable = yes postscreen_non_smtp_command_action = enforce postscreen_bare_newline_enable = yes postscreen_bare_newline_action = enforce
Toutes ces actions demandent que le client en face agisse proprement : il passe le test, se déconnecte, et cause ensuite au vrai postfix. Cela ralentit les échanges et peut être coûteux en ressources (et en temps). Cependant une fois le test passé, l'ip est enregistrée comme “bonne” pendant un certain temps (paramètre postscreen_*_ttl
, 30 jours par défaut donc je ne change rien).
- pipelining : pour les clients qui envoient plusieurs commandes en même temps, au lieu d'attendre la réponse à chacune avant d'envoyer la suivante. Le mail n'est pas fait pour se presser ; ceux qui sont pressés sont souvent mal intentionnés.
- non_smtp_command : si le client envoie une commande qui n'est pas SMTP (voir https://www.postfix.org/postconf.5.html#postscreen_forbidden_commands). Et ça, quand on regarde les logs, on sait qu'ils testent et que ce n'est jamais légitime.
- bare_newline : quand le client envoie un caractère de retour à la ligne, sans retour chariot avant. Ça doit filtrer ce qui est scripté avec les pieds ? Si on suit la norme, chaque ligne doit se terminer par <CR><LF> ; s'il n'y a que <LF> c'est sale !
Un petit postfix reload
et… On espère que tout va bien !
Rspamd (à faire)
À présent, la gestion des spams.
Vu que j'étais un peu fâchée avec rspamd, s'assurer qu'il a tout ce qu'il lui faut :
apt --install-recommends install rspamd
Et… je vais avoir un souci parce que opendkim a besoin de ceci dans postfix :
smtpd_milters = inet:localhost:8891
non_smtpd_milters = $smtpd_milters
Et rspamd de cela…
smtpd_milters=inet:127.0.0.1:11332
non_smtpd_milters=inet:127.0.0.1:11332
la grande question… peut-on déclarer plusieurs milters ? ça sent les ennuis ça.
Tant qu'on a opendkim, y'a ça à faire
nano /etc/rspamd/local.d/dkim_signing.conf
enabled = false;
Je pense que rspamd donne les infos : https://www.rspamd.com/doc/modules/dkim_signing.html
Et donc on envoie à rspamd qui délègue à opendkim… bon… pas certain que ça soit au top tout ça. Pause, hélas.
https://workaround.org/bullseye/filtering-out-spam-with-rspamd/
Encore à faire
- Paramétrage de rspamd, juste pour gérer les spams.
- S'il gonfle on fera sans, il y a d'autres méthodes pour gérer (cf Evolix)
- Commenter postfix et nettoyer afin que ce soit plus facile à maintenir. Déplacer les fichiers personnalisés dans un dossier ? (fait mais à documenter)
- Voir les infos récupérés dans le pdf pour améliorer les choses, ainsi que les autres blogs. pas urgent, quand on aura le temps.
- Mettre en place le backup
Transférer mes vrais noms de domaines ?
Documenter :
- S'assurer que l'adresse mail pour les infos systèmes est bien configurée…
- Mettre en place anonaddy et voir si ça permet de gérer les users
- Sinon ajouter de quoi gérer les users aussi…
- Vérifier que ça fait ce qu'on veut sur les alias
- Notes sur cette page, ça commence à faire long ici et c'est un truc particulier.
- test imapsync ou autre.
- reprendre ici et harmoniser les noms de domaine entre autre
- Mise en place du webmail, à la fois plus pratique en déplacement
- J'ai mis imapS (993) en place mais pas noté les détails. En même temps ça va avec la reprise de la config de dovecot et postfix en version plus détaillée ici.