Amavisd-new

For CentOS 6.4, with Amavisd-new 2.8. Assuming you have ClamAV and SpamAssassin installed already.

Amavisd-new takes a message from Postfix, gives it to content checkers like ClamAV and SpamAssassin, and hands the message back to Postfix, which then decides what to do with it (i.e., reject, keep it in hold, and so on)1.

Installation

yum install amavisd-new
chkconfig amavisd on
service amavisd start


Setting up the Transport

Unless you changed the defaults, the amavisd daemon will run on localhost, on port 10024. Configuration is a two-step process.

Transport Messages from Postfix to Amavis

You can ask Postfix to filter a message through whatever you want after it is queued but before it is delivered to a mailbox. The filter can be a defined as a pipe, a unix socket, or a TCP/IP socket.

We have the Amavis daemon listening on 127.0.0.1:10024. Let’s tell Postfix to filter its messages through that TCP/IP socket. In /etc/postfix/main.cf, add the following:

content_filter = amavisd:[127.0.0.1]:10024


This is of the form transport:destination. The first part should correspond to a definition in /etc/postfix/master.cf. Let’s add it:

amavisd unix    -       -       n       -       2       smtp
-o smtp_data_done_timeout=1200
-o smtp_send_xforward_command=yes
-o disable_dns_lookups=yes
-o max_use=20


From Amavis back to Postfix

/etc/amavisd.conf contains two options, notify_method and forward_method. These are the destinations where Amavis will send notifications and/or messages after processing. The default is an SMTP host, listening at 127.0.0.1:10025. We can ask Postfix to listen at that port, thereby letting it get back the messages it sent to Amavis.

This is again the form transport:destination, and must be defined in /etc/postfix/master.cf.

127.0.0.1:10025 inet n  -       n       -       -       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 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


Since the usual SMTP server checks were already applied by Postfix, we set up an innocent/dumb/minimal SMTP daemon.

Setting up Amavis

Set the domain and hostnames

$mydomain = 'example.com';$myhostname = 'host.example.com';


Set the home directory

$MYHOME = '/var/amavis';  Tell Amavis where to look for SpamAssassin data $helpers_home = '$MYHOME/db'  Uncomment the notify and forward methods $notify_method  = 'smtp:[127.0.0.1]:10025';
$forward_method = 'smtp:[127.0.0.1]:10025';  Uncomment these lines from /etc/amavisd.conf ['ClamAV-clamd', \&ask_daemon, ["CONTSCAN {}\n", "/var/run/clamav/clamd.sock"], qr/\bOK$/m, qr/\bFOUND$/m, qr/^.*?: (?!Infected Archive)(.*) FOUND$/m ]


Restart Postfix and Amavis. Profit.

Miscellanous

Notes

• I was partial to MailScanner, another Perl-based interface which looks like a breeze to install. However, the Postfix docs say it uses “unsupported methods to manipulate Postfix queue files directly.” Okay.
• A big portion of configuration is setting up separate users for clamav, amavis, postfix, etc. for security. I don’t have to worry about this given Red Hat packages, but it definitely isn’t something to forget.

Errors

(!)WARN: all primary virus scanners failed, considering backups

Make sure that ClamAV is running, and that you’ve uncommented its definition in /etc/amavisd.conf

Footnotes

1. A lot of guides online talk about “injection” to Amavisd-new and “reinjection” back to Postfix. ↩︎
{"extraction_info": {"found_math": true, "script_math_tex": 0, "script_math_asciimath": 0, "math_annotations": 0, "math_alttext": 0, "mathml": 0, "mathjax_tag": 0, "mathjax_inline_tex": 1, "mathjax_display_tex": 0, "mathjax_asciimath": 1, "img_math": 0, "codecogs_latex": 0, "wp_latex": 0, "mimetex.cgi": 0, "/images/math/codecogs": 0, "mathtex.cgi": 0, "katex": 0, "math-container": 0, "wp-katex-eq": 0, "align": 0, "equation": 0, "x-ck12": 0, "texerror": 0, "math_score": 0.32724234461784363, "perplexity": 3045.0727181691004}, "config": {"markdown_headings": false, "markdown_code": true, "boilerplate_config": {"ratio_threshold": 0.18, "absolute_threshold": 10, "end_threshold": 15, "enable": true}, "remove_buttons": true, "remove_image_figures": true, "remove_link_clusters": true, "table_config": {"min_rows": 2, "min_cols": 3, "format": "plain"}, "remove_chinese": true, "remove_edit_buttons": true, "extract_latex": true}, "warc_path": "s3://commoncrawl/crawl-data/CC-MAIN-2023-14/segments/1679296949107.48/warc/CC-MAIN-20230330070451-20230330100451-00295.warc.gz"}