Délégation de la politique d'accès SMTP avec Postfix


But de la délégation de la politique d'accès SMTP

Le serveur SMTP de Postfix dispose de différents mécanismes intégrés pour bloquer ou accepter le courrier à différentes étapes du protocole SMTP. Depuis la version 2.1, Postfix peut déléguer ces décisions à un serveur extérieur à Postfix.

Avec ce mécanisme, une simple liste grise peut être implementée avec seulement une douzaine de lignes de Perl comme proposé à la fin de ce document. Un autre exemple de délégation de politique est le serveur SPF de Meng Wong disponible à l'adresse http://spf.pobox.com/. Des exemples de politiques peuvent être trouvées dans les sources de Postfix dans le répertoire examples/smtpd-policy.

La délégation de politique est maintenant la méthode préférée pour ajouter des politiques à Postfix. Il est plus aisé de développer une nouvelle fonctionnalité avec quelques lignes de Perl que d'essayer de faire la même chose en C. La différence en performance est imperceptible sauf dans les environnements les plus chargés.

Ce document couvre les sujets suivants :

Description du protocole

Le protocole de délégation de Postfix est vraiment simple. La requête client est une série de nom=valeur séparées par une nouvelle ligne et terminée par une ligne vide. La réponse du serveur est une ligne nom=valeur terminée elle aussi par une ligne vide.

Ci-dessous un exemple de tous les attributs que le serveur SMTP de Postfix envoie dans une requête de politique d'accès déléguée :

request=smtpd_access_policy
protocol_state=RCPT
protocol_name=SMTP
helo_name=un.domaine
queue_id=8045F2AB23
sender=foo@bar.tld
recipient=bar@foo.tld
recipient_count=0
client_address=1.2.3.4
client_name=un.autre.domaine.tld
reverse_client_name=un.autre.domaine.tld
instance=123.456.7
Postfix versions 2.2 et supérieures :
sasl_method=plain
sasl_username=vous
sasl_sender=
size=12345
ccert_subject=solaris9.porcupine.org
ccert_issuer=Wietse Venema
ccert_fingerprint=C2:9D:F4:87:71:73:73:D9:18:E7:C2:F3:C1:DA:6E:04
Postfix versions 2.3 et supérieures :
encryption_protocol=TLSv1/SSLv3
encryption_cipher=DHE-RSA-AES256-SHA
encryption_keysize=256
etrn_domain=
[ligne vide]

Notes :

Ce qui suit est spécifique aux requêtes de politique déléguées SMTPD 

Le serveur de politique répond par une action autorisée dans une table access(5) du serveur SMTPD de Postfix. Exemple :

action=defer_if_permit Service temporarily unavailable
[ligne vide]

Ceci entraîne le rejet de la requête avec un code d'erreur 450 et la mention"Service temporarily unavailable", si le serveur SMTP ne trouve aucune raison de rejeter la requête à titre permanent.

En cas de problème, le serveur ne doit pas renvoyer de réponse mais logger un avertissement et se déconnecter. Postfix retentera la requête ultérieurement.<

Configuration de la politique client/serveur

Le client de délégation de la politique de Postfix peut se connecter à une socket TCP ou UNIX. Exemples :

inet:127.0.0.1:9998
unix:/chemin/absolu
unix:chemin/relatif

Le premier exemple indique que le serveur écoute sur le port TCP 9998 de la boucle locale, le second sur une socket UNIX et le troisième sur une socket UNIX située dans le répertoire des files d'attentes de Postfix (/var/spool/postfix en général). Utilisez ce dernier pour les serveurs de politiques contrôlés par le démon master de Postfix.

Pour créer un service de politique qui écoute une socket UNIX appelée "policy" et fonctionne sous le contrôle du démon spawn(8) de Postfix, vous pouvez configurer Postfix comme suit :

 1 /etc/postfix/master.cf:
 2     policy  unix  -       n       n       -       -       spawn
 3       user=nobody argv=/chemin/vers/le/serveur/de/politique
 4 
 5 /etc/postfix/main.cf:
 6     smtpd_recipient_restrictions =
 7         ... 
 8         reject_unauth_destination 
 9         check_policy_service unix:private/policy 
10         ...
11     policy_time_limit = 3600

NOTES :

 1 /etc/postfix/master.cf:
 2     127.0.0.1:9998  inet  n       n       n       -       -       spawn
 3       user=nobody argv=/some/where/policy-server
 4 
 5 /etc/postfix/main.cf:
 6     smtpd_recipient_restrictions =
 7         ... 
 8         reject_unauth_destination 
 9         check_policy_service inet:127.0.0.1:9998
10         ...
11     127.0.0.1:9998_time_limit = 3600

Les autres paramètres de configuration qui contrôlent le coté client du protocole de délégation de politique sont :

Exemple: serveur de politique liste grise

Les listes grises sont une défense contre les courriers publicitaires non sollicités décrite à l'adresse http://www.greylisting.org/. Cette idée a été discutée sue la liste de diffusion postfix-users un an avant qu'elle ne soit popularisée.

Le fichier exemples/smtpd-policy/greylist.pl des sources de Postfix implémente un serveur simple de politique de liste grise. Il enregistre une marque de temps pour chaque tuple (client, expéditeur, destinataire). Par défaut, le message n'est accepté que si la marque de temps a plus de 60 secondes. Ceci arrête le pourriel venant d'adresses aléatoires et les messages envoyés et celui envoyé par un proxy ouvert sélectionné aléatoirement, ainsi que celui envoyé par des spammers qui changent leur adresse fréquemment.

Copiez exemples/smtpd-policy/greylist.pl dans le répertoire /usr/libexec/postfix ou un autre emplacement plus approprié à votre système.

Vous devez indiquer la l'emplacement du fichier de base de données de la liste grise dans le fichier greylist.pl, et combien de temps les messages doivent être retardés avant d'être acceptés. Les valeurs par défaut sont :

$database_name="/var/mta/greylist.db";
$greylist_delay=60;

Le répertoire /var/mta (ou celui que cous choisirez) doivent avoir les droits en écriture pour "nobody" ou pour l'utilisateur utilsé dans le fichier master.cf pour le service de politique.

Exemple :

# mkdir /var/mta
# chown nobody /var/mta

Note: ne créez PAS la base de données de la liste grise dans un répertoire positionné en écriture pour tout le monde tell /tmp ou /var/tmp et ne la créez PAS dans un système de fichiers susceptible d'être saturé. Postfix peut survivre dans des conditions de saturation de file d'attente ou de stockage des boîtes-aux-lettres mais pas avec une base corrompue. Dans ce dernier cas vous ne recevrez du courrier que lorsque vous aurez effacé ce fichier à la main.

Le script Perl greylist.pl peut être lancé sous le contrôle du démon master.cf. Par exemple pour le lancer sous le compte "nobody" en utilisant une socket UNIX accessible à Postfix, inscrivez simplement :

1 /etc/postfix/master.cf:
2     policy  unix  -       n       n       -       -       spawn
3       user=nobody argv=/usr/bin/perl /usr/libexec/postfix/greylist.pl
4 
5 /etc/postfix/main.cf:
6      policy_time_limit = 3600

Notes :

Sur Solaris vous devez utiliser des sockets TCP au lieu des sockets UNIX comme indiqué au paragraphe "Policy client/server configuration" ci-dessus.

1 /etc/postfix/master.cf:
2     127.0.0.1:9998  inet  n       n       n       -       -       spawn
3       user=nobody argv=/usr/bin/perl /usr/libexec/postfix/greylist.pl
4 
5 /etc/postfix/main.cf:
6      127.0.0.1:9998_time_limit = 3600

Pour appeler ce service, vous devez indiquer "check_policy_service inet:127.0.0.1:9998".

Mettre en liste grise le courrier des domaines fréquemment forgés

Il est relativement sécurisé d'activer la mise en liste grise pour des domaines apparaissant souvent dans les messages forgés. Une liste des domaines fréquemment utilisés dans les commandes MAIL FROM est disponible à l'adresse suivante : http://www.monkeys.com/anti-spam/filtering/sender-domain-validate.in.

 1 /etc/postfix/main.cf:
 2     smtpd_recipient_restrictions =
 3         reject_unlisted_recipient
 4         ...
 5         reject_unauth_destination 
 6         check_sender_access hash:/etc/postfix/sender_access
 7         ...
 8     restriction_classes = greylist
 9     greylist = check_policy_service unix:private/policy
10 
11 /etc/postfix/sender_access:
12     aol.com     greylist
13     hotmail.com greylist
14     bigfoot.com greylist
15     ... etc ...

NOTES :

Mettre en liste grise tout le courrier

Si vous activez la liste grise pour tout le courrier, vous souhaiterez probablement faire des exceptions pour les listes de distributions qui utilisent une adresse d'expédition changeante car de telles listes peuvent polluer relativement rapidement la base de données de la liste grise.

 1 /etc/postfix/main.cf:
 2     smtpd_recipient_restrictions =
 3         reject_unlisted_recipient
 4         ...
 5         reject_unauth_destination 
 6         check_sender_access hash:/etc/postfix/sender_access
 7         check_policy_service unix:private/policy
 8         ...
 9 
10 /etc/postfix/sender_access:
11     securityfocus.com OK
12     ...

NOTES :

Routine de maintenance des listes grises

La base de données de la liste grise s'accroît au fil du temps car le serveur de politique ne retire jamais d'entrées. Sans surveillance, elle risque de saturer votre système.

Lorsque ce fichier dépasse un certain seuil, vous pouvez simplement le renommer ou le détruire sans effet nuisible; Postfix le recrééra automatiquement. Dans le pire des cas, les nouveaux messages seront retardés d'une heure. Pour minimiser cet impact, effectuez cette opération au milieu de la nuit ou le week-end.

Exemple de serveur Perl de liste grise

Ci-dessous une sous-routine Perl qui implémente la politique liste grise citée en exemple. C'est une partie de l'exemple inclus dans les sources de Postfix (exemples/smtpd-policy/greylist.pl).

#
# greylist status database and greylist time interval. DO NOT create the
# greylist status database in a world-writable directory such as /tmp
# or /var/tmp. DO NOT create the greylist database in a file system
# that can run out of space.
#
$database_name="/var/mta/greylist.db";
$greylist_delay=60;

#
# Demo SMTPD access policy routine. The result is an action just like
# it would be specified on the right-hand side of a Postfix access
# table.  Request attributes are available via the %attr hash.
#
sub smtpd_access_policy {
    my($key, $time_stamp, $now);

    # Open the database on the fly.
    open_database() unless $database_obj;

    # Lookup the time stamp for this client/sender/recipient.
    $key =
        lc $attr{"client_address"}."/".$attr{"sender"}."/".$attr{"recipient"};
    $time_stamp = read_database($key);
    $now = time();

    # If new request, add this client/sender/recipient to the database.
    if ($time_stamp == 0) {
        $time_stamp = $now;
        update_database($key, $time_stamp);
    }

    # The result can be any action that is allowed in a Postfix access(5) map.
    #
    # To label the mail, return ``PREPEND headername: headertext''
    #
    # In case of success, return ``DUNNO'' instead of ``OK'', so that the
    # check_policy_service restriction can be followed by other restrictions.
    #
    # In case of failure, return ``DEFER_IF_PERMIT optional text...'',
    # so that mail can still be blocked by other access restrictions.
    #
    syslog $syslog_priority, "request age %d", $now - $time_stamp if $verbose;
    if ($now - $time_stamp > $greylist_delay) {
        return "dunno";
    } else {
        return "defer_if_permit Service temporarily unavailable";
    }
}

Valid HTML 4.01! traduction par Xavier Guimard - Retour au menu