Login Logout

Howto Amavis

Amavis est un logiciel qui permet de filtrer les emails pour détecter des virus, des spams ou pièces jointes interdites. Il s’interface avec un serveur SMTP comme Postfix et sert d’interface avec des logiciels externes comme ClamAV ou SpamAssassin.

Installation

# apt install amavisd-new arc arj zoo pax bzip2 cabextract rpm lzop clamav-daemon

$ /usr/sbin/amavisd-new -V
amavisd-new-2.10.1 (20141025)

# systemctl status amavis
● amavis.service - LSB: Starts amavisd-new mailfilter
   Loaded: loaded (/etc/init.d/amavis; generated; vendor preset: enabled)
     Docs: man:systemd-sysv-generator(8)
    Tasks: 2 (limit: 4915)
   CGroup: /system.slice/amavis.service
           ├─16616 /usr/sbin/amavisd-new (master)
           └─18060 /usr/sbin/amavisd-new (ch16-avail)

Configuration

Fichiers de configuration :

/etc/amavis/
├── conf.d
│   ├── 01-debian
│   ├── 05-domain_id
│   ├── 05-node_id
│   ├── 15-av_scanners
│   ├── 15-content_filter_mode
│   ├── 20-debian_defaults
│   ├── 25-amavis_helpers
│   ├── 30-template_localization
│   └── 50-user
├── en_US
│   ├── charset
│   ├── template-auto-response.txt
│   ├── [...]
│   └── template-virus-sender.txt
└── README.l10n

La configuration se trouve dans les fichiers du répertoire /etc/amavis/conf.d/ et nous utilisons le fichier /etc/amavis/conf.d/49-evolinux-defaults pour notre configuration de base :

# expediteur des notifications
$mailfrom_notify_admin = "postmaster\@$mydomain";
$mailfrom_notify_recip = "postmaster\@$mydomain";
$mailfrom_notify_spamadmin = "postmaster\@$mydomain";

# Liste des domaines considérés comme locaux
#@local_domains_acl = qw(.);
@local_domains_acl = (".example.net","example.com");

# On customise la ligne ajoutée dans les entêtes
$X_HEADER_LINE = "by Amavis at $mydomain";

# Notifications de fichiers bannis / virus
$virus_admin = "postmaster\@$mydomain";
# Ne pas recevoir des notifications pour les mails UNCHECKED
#delete $admin_maps_by_ccat{&CC_UNCHECKED};

# Que faire avec les messages détectés
$final_virus_destiny      = D_DISCARD;
$final_banned_destiny     = D_BOUNCE;
$final_spam_destiny       = D_BOUNCE;
$final_bad_header_destiny = D_PASS;

# Pour recevoir des bounces (mails originals) des fichiers bloqués / virus
#$banned_quarantine_to = "banned\@$mydomain";
#$virus_quarantine_to = "virus\@$mydomain";

# Note tueuse
$sa_tag2_level_deflt = 6.31;
# Pour un comportement "normal" de SA
$sa_tag_level_deflt  = -1999;
$sa_kill_level_deflt = 1999;
$sa_dsn_cutoff_level = -99;
$sa_spam_subject_tag = '[SPAM] ';

# log
$log_level = 2;

# En fonction besoin/ressources, on ajuste le nbre de process
$max_servers = 5;

Note : attention, vous ne devez pas mettre de . dans votre nom de fichier de configuration, sinon il ne sera pas lu par Amavis (qui détecte les fichiers de configuration grâce à la commande run-parts --list /etc/amavis/conf.d/)

Configuration avec Postfix

Pour activer Amavis avec Postfix, on ajoutera dans le fichier /etc/postfix/master.cf :

smtp-amavis unix -  -   y -   2  lmtp
    -o lmtp_data_done_timeout=1200
    -o lmtp_send_xforward_command=yes

127.0.0.1:10025 inet n  -       y     -       -  smtpd
    -o content_filter=
    -o local_recipient_maps=
    -o relay_recipient_maps=
    -o smtpd_restriction_classes=
    -o smtpd_delay_reject=no
    -o smtpd_client_restrictions=permit_mynetworks,reject
    -o smtpd_helo_restrictions=
    -o smtpd_sender_restrictions=
    -o smtpd_recipient_restrictions=permit_mynetworks,reject
    -o smtpd_data_restrictions=reject_unauth_pipelining
    -o smtpd_end_of_data_restrictions=
    -o mynetworks=127.0.0.0/8
    -o strict_rfc821_envelopes=yes
    -o smtpd_error_sleep_time=0
    -o smtpd_soft_error_limit=1001
    -o smtpd_hard_error_limit=1000
    -o smtpd_client_connection_count_limit=0
    -o smtpd_client_connection_rate_limit=0
    -o receive_override_options=no_header_body_checks,no_unknown_recipient_checks,no_milters

pre-cleanup          unix      n      -      n      -      0      cleanup
  -o virtual_alias_maps=
  -o canonical_maps=
  -o sender_canonical_maps=
  -o recipient_canonical_maps=
  -o masquerade_domains=
  -o always_bcc=
  -o sender_bcc_maps=
  -o recipient_bcc_maps=

Pour éviter les doublons, il est conseillé d’ajouter l’option -o cleanup_service_name=pre-cleanup aux services smtp, cleanup, submission et smtps.

Et enfin, pour activer Amavis, on ajoute dans le fichier /etc/postfix/main.cf :

content_filter = smtp-amavis:[127.0.0.1]:10024
smtp-amavis_destination_concurrency_failed_cohort_limit = 0
smtp-amavis_destination_concurrency_negative_feedback = 0
smtp-amavis_destination_concurrency_limit = 2

Il faut alors comprendre que tous les messages, après passages dans les différents filtres de Postfix, seront envoyés en LMTP à Amavis qui écoute sur le port 10024 (la ligne smtp-amavis dans master.cf est un « simple » client LMTP). Amavis renverra ensuite (si tout va bien) le message en SMTP sur le port 10025, grâce à la ligne 127.0.0.1:10025 dans master.cf qui active un serveur SMTP (smtpd avec l’option content_filter= pour éviter une boucle infinie).

Il existe une possibilité d’intercepter un message avant content_filter c’est d’utiliser une action FILTER dans une table Postfix. Ainsi, on pourra rajouter la ligne suivant dans smtpd_recipient_restrictions :

    check_recipient_access hash:/etc/postfix/unprotected_users

avec le fichier /etc/postfix/unprotected_users qui peut contenir des adresses qui vont contourner Amavis en renvoyant directement en SMTP vers le port 10025 :

je-contourne-amavis@example.com FILTER smtp:[127.0.0.1]:10025

Nettoyage régulier des mails bloqués par Amavis

On peut mettre en place un cron daily, ajustant la durée de rétention en fonction du besoin de récupération de ces mails, mais aussi de l’espace occupé par /var/lib/amavis/virusmails/ :

$ cat /etc/cron.daily/amavis_purge_virusmails
#!/bin/bash
find /var/lib/amavis/virusmails/ -type f -mtime +30 -delete

$ chmod 755 /etc/cron.daily/amavis_purge_virusmails

Voir aussi :

Fichiers bannis

On peut bannir des fichiers en fonction de leur extension ou de leur type.

On ajustera la direction $banned_filename_re si besoin, voici son comportement par défaut :

$banned_filename_re = new_RE(
  qr'\.[^./]*\.(exe|vbs|pif|scr|bat|cmd|com|cpl|dll)\.?$'i,
  qr'\{[0-9a-f]{8}(-[0-9a-f]{4}){3}-[0-9a-f]{12}\}?$'i,
  qr'^application/x-msdownload$'i,
  qr'^application/x-msdos-program$'i,
  qr'^application/hta$'i,
  qr'.\.(exe|vbs|pif|scr|bat|cmd|com|cpl)$'i,
  qr'^\.(exe-ms)$',
);

Filtres externes

ClamAV

L’usage principal d’Amavis est de lancer un antivirus, notamment ClamAV qui est libre et gratuit.

# apt install clamav-daemon
# adduser clamav amavis
# adduser amavis clamav

Il faut aussi modifier ce paramètre via /etc/clamav/clamd.conf :

AllowSupplementaryGroups true

Et enfin on active l’antivirus dans la configuration Amavis via la ligne :

@bypass_virus_checks_maps = (
   \%bypass_virus_checks, \@bypass_virus_checks_acl, \$bypass_virus_checks_re);

SpamAssassin

On peut aussi lancer SpamAssassin avec Amavis.

# apt install spamassassin spamc

Puis on active SpamAssassin dans la configuration Amavis via la ligne :

@bypass_spam_checks_maps = (
   \%bypass_spam_checks, \@bypass_spam_checks_acl, \$bypass_spam_checks_re);

Administration

Notifications

Le comportement des notifications par défaut est de :

  • si un virus est détecté, mise en quarantaine sans notification à part pour $virus_admin (D_DISCARD)
  • si un spam est détecté ($sa_kill_level_deflt), génère un mail de rejet à l’expéditeur si sa note est en dessous de $sa_dsn_cutoff_level (D_BOUNCE)
  • si un fichier banni est détecté, génère un mail de rejet à l’expéditeur (D_BOUNCE)

Note : Si le domaine de l’expéditeur est dans @local_domains_acl, alors l’expéditeur est toujours notifié !

On peut modifier ce comportement avec les directives :

$final_virus_destiny      = D_DISCARD;
$final_banned_destiny     = D_BOUNCE;
$final_spam_destiny       = D_BOUNCE;
$final_bad_header_destiny = D_PASS;

On conseille de modifier $sa_dsn_cutoff_level afin de ne générer aucun rejet pour un spam (où l’expéditeur est souvent usurpé).

Ressortir un mail de quarantaine

Lorsqu’un mail est mis en quarantaine, Amavis logue un message du type :

amavis[31262]: (31262-05) Blocked BANNED [...] quarantine: 5/banned-5VspXCi2iNIn, [...]

Pour le ressortir de la quarantaine et le renvoyer au destinataire :

# amavisd-release 5/banned-5VspXCi2iNIn

Renvoyer les emails bloqués vers une adresse email

Tous les emails bloqués (virus, fichiers bannis, etc.) peuvent être renvoyés sur une adresse. Pour cela, on configure le paramètre suivant :

$banned_quarantine_to = "quarantaine\@example.com";

Whitelister une adresse email

On peut mettre en liste blanche des adresses email via la directive :

@whitelist_sender_maps = ( new_RE(
   qr'jdoe@example.com$'i,
));

Intégration avec LDAP

Amavis a besoin d’avoir son propre schéma LDAP : https://amavis.org/LDAP.schema.txt

Il faut intégrer ce schéma à votre annuaire LDAP puis configurer Amavis :

$enable_ldap = 1;
$default_ldap = {
   hostname => '127.0.0.1', tls => 0,
   base => 'cn=%d,ou=people,dc=example,dc=com', scope => 'sub',
   query_filter => '(&(mailacceptinggeneralid=%m)(accountActive=TRUE))'
};

Évidemment, vous devez adapter la configuration à votre annuaire LDAP, notamment query_filter.

Vous pouvez ensuite ajouter la classe amavisAccount à vos objets et utiliser les différents attributs (amavisBypassVirusChecks, amavisBypassSpamChecks, amavisSpamTagLevel, etc.).

Monitoring

Nagios

Nous utilisons ce petit script Perl check_amavis.pl :

$ /usr/local/lib/nagios/plugins/check_amavis --server 127.0.0.1 --from monitoring@example.com --to postmaster@localhost --port 10024

Plomberie

Quand un email arrive, voici son cheminement :

  1. il entre avec le protocole SMTP par Postfix (qui écoute sur port 25 ou 465 ou 587) et il renvoyé en LMTP (ou SMTP) à Amavis grâce à l’option content_filter = smtp-amavis:[127.0.0.1]:10024

smtp-amavis signifie LMTP avec des options particulières grâce à la configuration dans /etc/postfix/master.cf :

smtp-amavis unix -  -   y -   5  lmtp
    -o lmtp_data_done_timeout=1200
    -o lmtp_send_xforward_command=yes
  1. Amavis écoute sur le port 10024 :
tcp        0      0 127.0.0.1:10024         0.0.0.0:*               LISTEN      119        1168881997 2664/amavisd-new (m 
tcp6       0      0 ::1:10024               :::*                    LISTEN      119        1168881998 2664/amavisd-new (m 

On peut lui parler en SMTP :

$ telnet 127.0.0.1 10024
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
220 [127.0.0.1] ESMTP amavisd-new service ready

Amavis fait son travail (antivirus, antispam, etc.) puis il réinjecte l’email à Postfix en SMTP qui écoute sur le port 10025

  1. Enfin Postfix écoute sur le port 10025 grâce à sa config dans /etc/postfix/master.cf :
127.0.0.1:10025 inet n  -       y     -       -  smtpd
    -o content_filter=
...

et de nombreuses options qui permettent d’éviter le travail en double (pas de résolution des alias car déjà fait à l’étape 1, pas de milter, pas de content-filter bien sûr sinon ça bouclerait à l’infini, etc.)

Et Postfix va ensuite faire son travail : livrer en local, à l’extérieur, etc.

FAQ

Erreur “Can’t connect to UNIX socket”

Si vous obtenez cette erreur, il est possible que la socket d’Amavis soit située dans /var/run/ à la place de /var/lib/. Dans ce cas il suffit de modifier la socket dans la configuration d’Amavis :

$unix_socketname = "/var/lib/amavis/amavisd.sock";

Erreur “cannot opendir /var/lib/spamassassin/3.004002: Permission denied”

Si Amavis refuse de démarrer et donne cette erreur :

Feb 30 02:27:18 hostname amavis[11691]: _WARN: config: cannot opendir /var/lib/spamassassin/3.004002: Permission denied

On peut alors essayer de changer le mode des fichiers dans le répertoire /var/lib/spamassassin/3.004002. Ce répertoire doit être en 755 et les fichiers qui s’y trouvent en 644.

chmod 755 /var/lib/spamassassin/3.004002
find /var/lib/spamassassin/3.004002 -type f -exec chmod 644 {} \;

Il reste à redémarrer les services Amavis et Postfix.

Erreur “Too many retries to talk to clamd.ctl”

Si vous obtenez cette erreur :

ClamAV-clamd av-scanner FAILED: run_av error: Too many retries to talk to /var/run/clamav/clamd.ctl
(All attempts (1) failed connecting to /var/run/clamav/clamd.ctl)

Vous pouvez essayer de stopper puis démarrer ClamAV-daemon, il est possible qu’il ait été OOM-killé.

UNCHECKED” dans le sujet

Quand un email n’arrive pas à passer dans l’antivirus ou une partie de son contenu est chiffré, Amavis va ajouter “UNCHECKED” dans le sujet. Pour éviter cela, on peut configurer :

$undecipherable_subject_tag=undef;

Évidemment, c’est un contournement du problème, il faut plutôt résoudre le problème avec l’antivirus en général.