debconf
. Les réponses permettront de générer un premier fichier /etc/postfix/main.cf
.
@
»). Pour Falcot, la réponse est mail.falcot.com
. C'est la seule question posée en standard, mais elle ne suffit pas pour avoir une configuration satisfaisante, les administrateurs exécutent donc dpkg-reconfigure postfix
afin de pouvoir personnaliser plus de paramètres.
localhost
, mais pas le domaine principal falcot.com
, qu'il faut ajouter manuellement. D'une manière générale, il convient habituellement de donner ici tous les noms de domaines pour lesquels cette machine fait office de serveur MX (c'est-à-dire tous ceux pour lesquels le DNS indique qu'elle est apte à accepter du courrier). Ces informations sont ensuite stockées dans la variable mydestination
du fichier /etc/postfix/main.cf
(principal fichier de configuration de Postfix).
192.168.0.0/16
à la réponse par défaut. Si la question n'est pas posée, il faut modifier le fichier de configuration et y changer la variable mynetworks
, comme on le voit sur l'exemple plus loin.
procmail
. This tool allows users to sort their incoming email according to rules stored in their ~/.procmailrc
file. Both Postfix and Exim4 suggest procmail by default, but there are alternatives like maildrop or Sieve filters.
Exemple 11.1. Fichier /etc/postfix/main.cf
initial
# See /usr/share/postfix/main.cf.dist for a commented, more complete version # Debian specific: Specifying a file name will cause the first # line of that file to be used as the name. The Debian default # is /etc/mailname. #myorigin = /etc/mailname smtpd_banner = $myhostname ESMTP $mail_name (Debian/GNU) biff = no # appending .domain is the MUA's job. append_dot_mydomain = no # Uncomment the next line to generate "delayed mail" warnings #delay_warning_time = 4h readme_directory = no # See http://www.postfix.org/COMPATIBILITY_README.html -- default to 2 on # fresh installs. compatibility_level = 2 # TLS parameters smtpd_tls_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem smtpd_tls_key_file=/etc/ssl/private/ssl-cert-snakeoil.key smtpd_tls_security_level=may smtp_tls_CApath=/etc/ssl/certs smtp_tls_security_level=may smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated defer_unauth_destination myhostname = mail.falcot.com alias_maps = hash:/etc/aliases alias_database = hash:/etc/aliases mydestination = mail.falcot.com, falcot.com, localhost.localdomain, localhost relayhost = mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 192.168.0.0/16 mailbox_size_limit = 0 recipient_delimiter = + inet_interfaces = all default_transport = smtp relay_transport = smtp inet_protocols = all myorigin = /etc/mailname
virtual_alias_domains
et indiquer le fichier stockant les correspondances d'adresses dans la variable virtual_alias_maps
.
virtual_alias_domains = marqueafalcot.tm.fr virtual_alias_maps = hash:/etc/postfix/virtual
/etc/postfix/virtual
, décrivant les correspondances, emploie un format relativement simple. Chaque ligne contient deux champs séparés par une série de blancs, dont le premier est le nom de l'alias et le second une liste d'adresses électroniques vers lesquelles il pointe. La syntaxe spéciale @domaine.fr
englobe tous les alias restants d'un domaine.
[email protected] [email protected] [email protected] [email protected], [email protected] # The alias below is generic and covers all addresses within # the falcotsbrand.com domain not otherwise covered by this file. # These addresses forward email to the same user name in the # falcot.com domain. @falcotsbrand.com @falcot.com
/etc/postfix/virtual
the postfix table /etc/postfix/virtual.db
needs to be updated using sudo postmap /etc/postfix/virtual
.
virtual_mailbox_domains
et préciser le fichier donnant les boîtes aux lettres avec la variable virtual_mailbox_maps
. Le paramètre virtual_mailbox_base
indique le répertoire sous lequel les différentes boîtes aux lettres seront stockées.
virtual_mailbox_domains = falcot.org virtual_mailbox_maps = hash:/etc/postfix/vmailbox virtual_mailbox_base = /var/mail/vhosts
virtual_uid_maps
et virtual_gid_maps
définissent des tables de correspondances entre l'adresse électronique, l'utilisateur et le groupe Unix propriétaire de la boîte aux lettres. Pour indiquer systématiquement le même propriétaire, la syntaxe static:5000
dénote un UID/GID fixe.
/etc/postfix/vmailbox
est de nouveau très simple : deux champs séparés par des blancs. Le premier indique une adresse électronique de l'un des domaines virtuels et le second l'emplacement relatif de la boîte aux lettres associée (par rapport au répertoire donné par virtual_mailbox_base). Si le nom de la boîte aux lettres se termine par une barre de division (/
), cette boîte sera stockée au format maildir ; dans le cas contraire, c'est le traditionnel mbox qui sera retenu. Le format maildir emploie un répertoire complet pour représenter la boîte aux lettres et chaque message est stocké dans un fichier. A contrario, une boîte aux lettres au format mbox est stockée dans un seul fichier et chaque ligne débutant par From
(From
suivi d'une espace) marque le début d'un nouveau message électronique.
# le courrier de jean est stocké au format maildir # (1 fichier par courrier dans un répertoire privé) [email protected] falcot.org/jean/ # le courrier de sophie est stocké dans un fichier # "mbox" traditionnel (tous les courriers concaténés # dans un fichier) [email protected] falcot.org/sophie
soft_bounce = yes
directive. By prepending a reject-type directive with warn_if_reject
only a log message will be recorded instead of rejecting the request.
smtpd_client_restrictions
contrôle les machines autorisées à communiquer avec le serveur de courrier électronique.
Exemple 11.2. Restrictions en fonction de l'adresse du client
smtpd_client_restrictions = permit_mynetworks, warn_if_reject reject_unknown_client_hostname, check_client_access hash:/etc/postfix/access_clientip, reject_rhsbl_reverse_client dbl.spamhaus.org, reject_rhsbl_reverse_client rhsbl.sorbs.net, reject_rbl_client zen.spamhaus.org, reject_rbl_client dnsbl.sorbs.net
permit_mynetworks
, placée en tête de la liste des règles, accepte inconditionnellement toute machine du réseau local (tel que défini par la variable mynetworks
dans la configuration).
warn_if_reject
modifier to the reject_unknown_client
directive: this modifier turns the rejection into a simple warning recorded in the logs. The administrators can then keep an eye on the number of messages that would be rejected if the rule were actually enforced, and make an informed decision later if they wish to enable such enforcement.
check_client_access
directive allows the administrator to set up a blacklist and a whitelist of email servers, stored in the /etc/postfix/access_clientip
file. Servers in the whitelist are considered as trusted, and the emails coming from there therefore do not go through the following filtering rules.
HELO
(or EHLO
) command, followed by the name of the sending email server. Checking the validity of this name can be interesting. To fully enforce the restrictions listed in smtpd_helo_restrictions
the smtpd_helo_required
option needs to be enabled. Otherwise clients could skip the restrictions by not sending any HELO
/EHLO
command.
Exemple 11.3. Restrictions sur le nom annoncé lors du EHLO
smtpd_helo_required = yes smtpd_helo_restrictions = permit_mynetworks, reject_invalid_helo_hostname, reject_non_fqdn_helo_hostname, warn_if_reject reject_unknown_helo_hostname, check_helo_access hash:/etc/postfix/access_helo, reject_rhsbl_helo multi.surbl.org
permit_mynetworks
autorise toutes les machines du réseau local à s'annoncer librement. C'est important car certains logiciels de courrier électronique respectent mal cette partie du protocole SMTP et peuvent donc annoncer des noms fantaisistes.
reject_invalid_helo_hostname
rule rejects emails when the EHLO
announce lists a syntactically incorrect hostname. The reject_non_fqdn_helo_hostname
rule rejects messages when the announced hostname is not a fully-qualified domain name (including a domain name as well as a host name). The reject_unknown_helo_hostname
rule rejects messages if the announced name does not exist in the DNS. Since this last rule unfortunately leads to a lot of rejections, the administrators turned its effect to a simple warning with the warn_if_reject
modifier as a first step; they may decide to remove this modifier at a later stage, after auditing the results of this rule.
reject_rhsbl_helo
allows to specify a black list to check the hostname against an RHSBL.
permit_mynetworks
au début a l'effet secondaire intéressant de n'appliquer les règles suivantes qu'à des machines extérieures au réseau local. Il est ainsi possible de mettre en liste noire tous ceux qui s'annoncent membres du réseau falcot.com
... ce qui s'effectue en ajoutant la ligne falcot.com REJECT You're not in our network!
au fichier /etc/postfix/access_helo
.
MAIL FROM
du protocole SMTP, information qu'il est possible de vérifier de plusieurs manières.
Exemple 11.4. Vérifications sur l'expéditeur
smtpd_sender_restrictions = check_sender_access hash:/etc/postfix/access_sender, reject_unknown_sender_domain, reject_unlisted_sender, reject_non_fqdn_sender, reject_rhsbl_sender rhsbl.sorbs.net
/etc/postfix/access_sender
associe des traitements particuliers à certains expéditeurs. En général, il s'agit simplement de les placer dans une liste blanche ou noire.
reject_unknown_sender_domain
rule requires a valid sender domain, since it is needed for a valid address. The reject_unlisted_sender
rule rejects local senders if the address does not exist; this prevents emails being sent from an invalid address in the falcot.com
domain, and messages emanating from [email protected]
are only accepted if such an address really exists.
reject_non_fqdn_sender
refuse les messages en provenance d'adresses électroniques sans nom de domaine complètement qualifié. Concrètement, elle refusera un courrier provenant de utilisateur@machine
: celui-ci doit s'annoncer comme [email protected]
ou [email protected]
.
reject_rhsbl_sender
rule reject senders based on a (domain-based) RHSBL service.
RCPT TO
du protocole SMTP. On pourra également vérifier ces informations, même si c'est moins intéressant que pour l'expéditeur.
Exemple 11.5. Vérifications sur le destinataire
smtpd_recipient_restrictions = permit_mynetworks, reject_unauth_destination, reject_unlisted_recipient, reject_non_fqdn_recipient, permit
reject_unauth_destination
est la règle de base imposant à tout courrier provenant de l'extérieur de nous être destiné ; dans le cas contraire, il faut refuser de relayer le message. Sans cette règle, votre serveur est un relais ouvert qui permet aux spammeurs d'envoyer des courriers non sollicités par son intermédiaire. Elle est donc indispensable et on la placera de préférence en début de liste pour qu'aucune autre règle ne risque d'autoriser le passage du courrier avant d'avoir éliminé les messages ne concernant pas ce serveur.
reject_unlisted_recipient
refuse les messages à destination d'utilisateurs locaux inexistants (ce qui est logique). Enfin, la règle reject_non_fqdn_recipient
refuse les adresses électroniques non qualifiées. Il est ainsi impossible d'écrire à jean
ou à jean@machine
; il faut employer la forme complète de l'adresse : [email protected]
ou [email protected]
.
permit
directive at the end is not necessary. But it can be useful at the end of a restriction list to make the default policy explicit.
DATA
du protocole SMTP précède l'envoi des données contenues dans le message. Elle ne fournit aucune information en soi, mais prévient de ce qui va suivre. Il est pourtant possible de lui mettre en place des contrôles.
reject_unauth_pipelining
refuse le message si le correspondant envoie une commande sans avoir attendu la réponse à la commande précédente. Les robots des spammeurs font régulièrement cela : pour travailler plus vite, ils se moquent des réponses et visent seulement à envoyer un maximum de courriers, dans le laps de temps le plus court.
RCPT TO
command by default.
EHLO
invalide, Postfix connaîtra l'émetteur et le destinataire lorsqu'il annoncera le refus. Il peut donc enregistrer un message de log plus explicite que s'il avait interrompu la connexion dès le début. De plus, beaucoup de clients SMTP ne s'attendent pas à subir un échec sur l'une des premières commandes du protocole SMTP et les clients mal programmés seront moins perturbés par ce refus tardif.
smtpd_delay_reject
rule.
Exemple 11.7. Activation des filtres sur le contenu
header_checks = regexp:/etc/postfix/header_checks body_checks = regexp:/etc/postfix/body_checks
Exemple 11.8. Exemple de fichier /etc/postfix/header_checks
/^X-Mailer: GOTO Sarbacane/ REJECT I fight spam (GOTO Sarbacane) /^Subject: *Your email contains VIRUSES/ DISCARD virus notification
GOTO Sarbacane
(un logiciel d'envoi en masse de courriers), elle refuse le message. La seconde expression contrôle le sujet du message : s'il indique une notification de virus sans intérêt, elle accepte le message mais le supprime immédiatement.
check_policy_service
comme restriction supplémentaire :
smtpd_recipient_restrictions = permit_mynetworks, [...] check_policy_service inet:127.0.0.1:10023
postgrey
daemon and send it information concerning the relevant message. On its side, Postgrey considers the IP address/sender/recipient triplet and checks in its database whether that same triplet has been seen recently. If so, Postgrey replies that the message should be accepted; if not, the reply indicates that the message should be temporarily rejected, and the triplet gets recorded in the database.
smtpd_restriction_classes
et on les définit par simple affectation tout comme on définirait smtpd_recipient_restrictions
. Ensuite la directive check_recipient_access
permet d'employer une table de correspondances pour définir les restrictions à employer pour un destinataire donné.
Exemple 11.9. Définir des classes de restriction dans main.cf
smtpd_restriction_classes = greylisting, aggressive, permissive greylisting = check_policy_service inet:127.0.0.1:10023 aggressive = reject_rbl_client sbl-xbl.spamhaus.org, check_policy_service inet:127.0.0.1:10023 permissive = permit smtpd_recipient_restrictions = permit_mynetworks, reject_unauth_destination, check_recipient_access hash:/etc/postfix/recipient_access
Exemple 11.10. Fichier /etc/postfix/recipient_access
# Adresses sans filtrage [email protected] permissive [email protected] permissive [email protected] permissive # Filtrage agressif pour quelques privilégiés [email protected] aggressive # Règle spéciale pour le robot de gestion de listes [email protected] reject_unverified_sender # Par défaut, le greylisting falcot.com greylisting
clamav
from the homonymous package.
clamav-milter
. Un milter (terme dérivé de l'expression mail filter) est un logiciel de filtrage de courriers spécialement conçu pour s'interfacer avec les serveurs de courrier électronique. Les milters exploitent une interface de programmation (API) dédiée qui assure de bien meilleures performances comparé aux filtres gérés en dehors des serveurs de courrier. Sendmail a été le premier à introduire cette technologie mais Postfix lui a emboîté le pas.
dpkg-reconfigure clamav-milter
, il s'agit de répondre inet:[email protected]
à la question portant sur l'interface de communication avec Sendmail.
clamav
convient dans la majorité des situations mais dpkg-reconfigure clamav-base
permet de personnaliser les paramètres les plus importants.
/etc/postfix/main.cf
:
# Virus check with clamav-milter smtpd_milters = inet:[127.0.0.1]:10002
systemctl reload postfix
pour faire prendre en compte cette modification.
include
directive it must have one.
Name: example.org Type: TXT TTL: 3600 Data: v=spf1 a mx -all
falcot.org
entry.
#
host -t TXT falcot.org
falcot.org descriptive text "v=spf1 ip4:199.127.61.96 +a +mx +ip4:206.221.184.234 +ip4:209.222.96.251 ~all"
postfix
mail server can check the SPF record for incoming emails using the postfix-policyd-spf-python package, a policy agent written in Python. The file /usr/share/doc/postfix-policyd-spf-python/README.Debian
describes the necessary steps to integrate the agent into postfix, so we won't repeat it here.
/etc/postfix-policyd-spf-python/policyd-spf.conf
, which is fully documented in policyd-spf.conf(5) and /usr/share/doc/postfix-policyd-spf-python/policyd-spf.conf.commented.gz
. The main configuration parameters are HELO_reject
and Mail_From_reject
, which configure if emails should be rejected (Fail
) or accepted with a header being appended (False
), if checks fail. The latter is often useful, when the message is further processed by a spam filter.
Header_Type
must be set to AR
.
postfix
, adds a digital signature associated with the domain name to the header of outgoing emails. The receiving party can validate the message body and header fields by checking the signature against a public key, which is retrieved from the senders DNS records.
opendkim-genkey -s SELECTOR -d DOMAIN
. SELECTOR must be a unique name for the key. It can be as simple as "mail" or the date of creation, if you plan to rotate keys.
Exemple 11.11. Create a private key for signing E-Mails from falcot.com
#
opendkim-genkey -s mail -d falcot.com -D /etc/dkimkeys
#
chown opendkim.opendkim /etc/dkimkeys/mail.*
/etc/dkimkeys/mail.private
and /etc/dkimkeys/mail.txt
and set the appropriate ownership. The first file contains the private key, and the latter the public key that needs to be added to the DNS:
Name: mail._domainkey Type: TXT TTL: 3600 Data: "v=DKIM1; h=sha256; k=rsa; s=email; p=[...]"
-b 1024
to chose a smaller keysize. If opendkim-testkey
succeeds, the entry has been successfully set up. The syntax of the entry is explained here:
SOCKET
and RUNDIR
must be chosen in /etc/default/opendkim
. Please note that SOCKET
must be accessible from postfix
in its chrooted environment. The further configuration is done in /etc/opendkim.conf
. The following is a configuration excerpt, which makes sure that the Domain
"falcot.com" and all subdomains (SubDomain
) are signed by the Selector
"mail" and the single private key (KeyFile
) /etc/dkimkeys/mail.private
. The "relaxed" Canonicalization
for both the header and the body tolerates mild modification (by a mailing list software, for example). The filter runs both in signing ("s") and verification ("v") Mode
. If a signature fails to validate (On-BadSignature
), the mail should be quarantined ("q").
[...] Domain falcot.com KeyFile /etc/dkimkeys/mail.private Selector mail [...] Canonicalization relaxed/relaxed Mode sv On-BadSignature q SubDomains yes [...] Socket inet:12345@localhost [...] UserID opendkim
KeyTable
), domains (SigningTable
) and to specify internal or trusted hosts (InternalHosts
, ExternalIgnoreList
), which may send mail through the server as one of the signing domains without credentials.
/etc/postfix/main.cf
make postfix
use the filter:
milter_default_action = accept non_smtpd_milters = inet:localhost:12345 smtpd_milters = inet:localhost:12345
/etc/postfix/master.cf
instead.
/usr/share/doc/opendkim/
directory and the manual pages opendkim(8) and opendkim.conf(5).
_dmarc
and the action that should be taken when emails that contain your domain as the sending host fail to validate using DKIM and SPF.
#
host -t TXT _dmarc.gmail.com
_dmarc.gmail.com descriptive text "v=DMARC1; p=none; sp=quarantine; rua=mailto:[email protected]"
#
host -t TXT _dmarc.yahoo.com
_dmarc.yahoo.com descriptive text "v=DMARC1; p=reject; pct=100; rua=mailto:[email protected]; ruf=mailto:[email protected];"
reject
all emails pretending to be sent from a Yahoo account but missing or failing DKIM and SPF checks. Google Mail (Gmail) propagates a very relaxed policy, in which such messages from the main domain should still be accepted (p=none
). For subdomains they should be marked as spam (sp=quarantine
). The addresses given in the rua
key can be used to send aggregated DMARC reports to. The full syntax is explained here:
postfix
mail server can use this information too. The opendmarc package contains the necessary milter. Similar to opendkim SOCKET
and RUNDIR
must be chosen in /etc/default/opendmarc
(for Unix sockets you must make sure that they are inside the postfix chroot to be found). The configuration file /etc/opendmarc.conf
contains detailed comments and is also explained in opendmarc.conf(5). By default, emails failing the DMARC validation are not rejected but flagged, by adding an appropriate header field. To change this, use RejectFailures true
.
smtpd_milters
and non_smtpd_milters
. If we configured the opendkim and opendmarc milters to run on ports 12345 and 54321, the entry in /etc/postfix/main.cf
looks like this:
non_smtpd_milters = inet:localhost:12345,inet:localhost:54321 smtpd_milters = inet:localhost:12345,inet:localhost:54321
/etc/postfix/master.cf
instead.
saslpasswd2
. L'option -u
précise le domaine d'authentification, il doit correspondre au paramètre smtpd_sasl_local_domain
de Postfix. L'option -c
sert à créer un utilisateur et l'option -f
permet de modifier une base SASL située ailleurs qu'à son emplacement standard (/etc/sasldb2
).
#
saslpasswd2 -h `postconf -h myhostname` -f /var/spool/postfix/etc/sasldb2 -c jean
[... saisir deux fois le mot de passe de jean ...]
/etc/sasldb2
vers la base employée par Postfix. Cela s'effectue avec la commande ln -sf /var/spool/postfix/etc/sasldb2 /etc/sasldb2
.
postfix
dans le groupe sasl
afin qu'il puisse accéder à la base de données des comptes SASL. Ensuite, il faut ajouter quelques paramètres pour activer SASL, puis modifier le paramètre smtpd_recipient_restrictions
pour autoriser les clients authentifiés par SASL à envoyer des courriels à tous les destinataires.
Exemple 11.12. Modification de /etc/postfix/main.cf
pour activer SASL
# Enable SASL authentication smtpd_sasl_auth_enable = yes # Define the SASL authentication domain to use smtpd_sasl_local_domain = $myhostname [...] # Adding permit_sasl_authenticated before reject_unauth_destination # allows relaying mail sent by SASL-authenticated users smtpd_recipient_restrictions = permit_sasl_authenticated, permit_mynetworks, reject_unauth_destination, [...]
/etc/postfix/master.cf
file. To turn off authentication at all for port 25 (smtpd
service) add the following directive:
smtp inet n - y - - smtpd [..] -o smtpd_sasl_auth_enable=no [..]
AUTH
command (some very old mail clients do), interoperability with them can be enabled using the broken_sasl_auth_clients
directive.