---
categories: mail
title: Howto Amavis
...


* Documentation : <https://www.ijs.si/software/amavisd/#doc>
* Documentation avec Postfix : <https://www.ijs.si/software/amavisd/README.postfix.html>

[Amavis](https://www.ijs.si/software/amavisd/) 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](HowtoSMTP) comme [Postfix](HowtoPostfix) 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](HowtoPostfix), 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 :

* <https://blog.antoine-augusti.fr/2012/12/les-problemes-rencontres-avec-amavis/>
* <https://bugs.debian.org/569150>


### 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](https://www.clamav.net/) 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](HowtoSpamAssassin) 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](https://github.com/glensc/monitoring-plugin-check_amavis) :

~~~
$ /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
~~~

2. 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

3. 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.

~~~{.bash}
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.
