This file README.postfix is part of the amavisd-new distribution,
which can be found at http://www.ijs.si/software/amavisd/
Last updated: 2002-12-13


How to use amavisd-new with Postfix
***********************************

A quick recipe for the impatient first.

Your Postfix must not be ancient, it must support parameter content_filter.
Check for the purpose of this parameter in ./README_FILES/FILTER_README
of the Postfix distribution. This file was revised in postfix-1.1.9-20020512,
you may want to read the latest version. For compatibility with previous
versions of amavisd the choice of default port numbers is 10024 and 10025,
in contrast to 10025 and 10026 as used in FILTER_README examples.

1. Install and run amavisd (as explained in INSTALL - just a daemon,
you don't need helper programs amavis(.c) or amavisd-milter(.c)).

For the first time it is best to start it interactively and keep it
attached to the terminal:

    # /usr/local/sbin/amavisd debug

From another window check that it is listening on a local SMTP
port 10024 (default):

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

-->  quit

     221 Bye
     Connection closed by foreign host.


2. With a text editor add to the Postfix master.cf file 
the following two entries, e.g. near the end of the file:

smtp-amavis unix -	-	y/n	-	2  smtp
    -o smtp_data_done_timeout=1200
    -o disable_dns_lookups=yes

127.0.0.1:10025 inet n	-	y/n	-	-  smtpd
    -o content_filter=
    -o local_recipient_maps=
    -o smtpd_helo_restrictions=
    -o smtpd_client_restrictions=
    -o smtpd_sender_restrictions=
    -o smtpd_recipient_restrictions=permit_mynetworks,reject
    -o mynetworks=127.0.0.0/8

Of all the options specified above in the second entry, the one
that is essential is the '-o content_filter=' .

Change the 'y/n' to either 'y' or 'n', depending on how you prefer
the smtp and smtpd postfix services to run - either chroot-ed, or not.
See your other (normal) smtp and smtpd postfix services and use the same
setting here.

If you have an entry like 'vscan unix - n n - 2 pipe user=vscan ...'
from a prior amavisd installation, you don't need it anymore and
it may be removed, but keeping it does no harm.


3. Do a 'postfix reload' and test if it is listening on port 10025:

-->  $ telnet 127.0.0.1 10025
     Trying 127.0.0.1...
     Connected to 127.0.0.1.
     Escape character is '^]'.
     220 ewok.ijs.si ESMTP Postfix
-->  quit
     221 Bye
     Connection closed by foreign host.


4. Simulate a mail sent to amavisd and see if it gets delivered via Postfix
   to its recipient. Try first with a simple and clean message, then with
   an EICAR test virus pattern which should be recognized by all virus
   scanners (if you are using them):

-->  $ 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
-->  MAIL FROM:<test@example.com>
     250 2.1.0 Sender test@example.com OK
-->  RCPT TO:<postmaster>
     250 2.1.5 Recipient postmaster OK
-->  DATA
     354 End data with <CR><LF>.<CR><LF>
-->  Subject: test1
-->
-->  test1
-->  .

***  250 2.6.0 Ok, id=31859-01, from MTA: 250 Ok: queued as 90B7F16F

-->  RSET
     250 2.0.0 Ok RSET
-->  MAIL FROM:<test@example.com>
     250 2.1.0 Sender test@example.com OK
-->  RCPT TO:<postmaster>
     250 2.1.5 Recipient postmaster OK
-->  DATA
     354 End data with <CR><LF>.<CR><LF>
-->  Subject: test2 - virus test pattern
-->
-->  X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*
-->  .

***  250 2.7.0 Ok, discarded, id=31859-01-2 - VIRUS: EICAR-AV-Test

-->  QUIT
     221 2.0.0 [127.0.0.1] (amavisd) closing transmission channel
     Connection closed by foreign host.

You may need/want to use different sender and recipient addresses.
The test pattern must be entered exactly, starting at the beginning
of the line (no indentation).

Depending on the settings in amavisd.conf, the sender (test@example.com)
and the virus administrator should have been sent a virus notification,
the second message quarantined, and the first message must have been
successfully delivered to the recipient.


5. Tell Postfix to start forwarding all mail it receives
   to amavisd-new for content inspection.

To the Postfix main.cf file add a line:

content_filter = smtp-amavis:[127.0.0.1]:10024

either with a text editor, or preferably using a shell command:
  # postconf -e 'content_filter = smtp-amavis:[127.0.0.1]:10024'


6. Do a 'postfix reload' and watch the logs -
both the Postfix logs, and the amavisd log file.

If you get into trouble, you only need to undo the step 5 and reload postfix.
New mail will no longer be tagged with content filter routing (but the
messages that have been received while 'content_filter' was set will
still try to get delivered to amavisd-new, and will wait in the queue
until successful).

If all is fine, you may abort the process running 'amavisd debug', and
start amavisd without a 'debug' option, making it detach and daemonize.

This completes the integration of amavisd and Postfix. It uses the
SMTP protocol both for Postfix->amavisd and for amavisd->Postfix
communication. This is the fastest and recommended method, and simplest
to set up.


ALTERNATIVE:

If you have a recent Postfix version such as 2.0, and amavisd-new-20021116
or younger, Postfix can be told to feed mail to amavisd via LMTP protocol
instead of SMTP. This brings multi-session mail transaction capability and
per-recipient status responses. Just replace the service name (last item)
'smtp' with 'lmtp' in the:                         vvvv

smtp-amavis unix -	-	y/n	-	2  lmtp
    -o smtp_data_done_timeout=1200
    -o disable_dns_lookups=yes

It works with earlier version of Postfix as well, but there are one or two
minor bugs in the Postfix lmtp client code (finding LMTP port number,
and unnecessarily lowercasing addresses), so it is easiest to stick
to the fresh version.

Option 'max_use=10' should be added to main.cf to limit the session reuse.



OPTIONAL:

I also like to set up an e-mail addresses with Postfix to receive
all quarantined viruses, so that your mailer will deal with storing
(or forwarding) them, and you don't even have to set up a quarantine
directory directy accessible to amavisd. Here is one way of doing it,
but see 'local (8)' Postfix man page for more options.

To your aliases file add an entry for an e-mail address, e.g. 'infected',
either to forward its mail to some place, or do a local delivery
to a file or directory, e.g.:

infected: /var/spool/mail/infected

(append a '/' if you prefer qmail-compatible maildir delivery),
then run 'newaliases' (or 'postalias /etc/postfix/aliases').

In your amavisd.conf file specify:
  $virus_quarantine_to = 'infected@';  # forward to MTA for delivery

Reload amavisd (amavisd reload) if it is already running, to make it
re-read its config file, and check log file.  All set!  Send some
infected mail and watch it appear at the specified mailbox.


----------------------------------------------------------------------------
The next section is a heavily commented setup that can be directly
appended to the Postfix master.cf file instead of the item (2.) above,
just in case you need finer control or better understanding.

Happy amavising with Postfix.

  Mark Martinec <Mark.Martinec@ijs.si>



# Append this to the master.cf Postfix file and edit to will.
# It defaults to the standard settings as described in README.postfix .
#
# Instruct Postfix content filtering to SEND all mail TO amavisd:
# ===============================================================
#
# By default amavisd will listen to both protocols (SMTP/LMTP over TCP,
# as well as amavis helper protocol on a Unix socket). The older method
# using the helper program amavis.c still works, but is not recommended,
# and is not described here.
#
# NOTE1: match number of sending Postfix processes (the '2' below) with
#        $max_servers in amavisd.conf. Two or three per CPU should be enough.
# NOTE2: point the 'content_filter' hostname part to where amavisd is running,
#        and match the port number with $inet_socket_port in amavisd.conf, e.g:
#	   content_filter = smtp-amavis:my.amavisd.server:10024
# NOTE3: you should restrict amavisd to only accept connections from the
#        authorized Postfix host(s) by the @inet_acl access list in
#	 the amavisd.conf file, and/or by binding to specific interface, e.g.:
#	   $inet_socket_bind = '127.0.0.1';  # limit bind to loopback interface
# NOTE4: set the chroot field the same (y/n) as for your regular smtp service;
# NOTE5: set $child_timeout (in amavisd.conf) to a shorter time than
#        the Postfix parameter smtp_data_done_timeout - see rfc1047.
# NOTE6: the option '-o disable_dns_lookups=yes' is recommended for reducing
#	 latency, but make sure you specify the IP address and not the DNS name
#        in the main.cf 'content_filter = smtp-amavis:...' specification
#        (thanks to Victor Duchovni for the suggestion).
smtp-amavis unix -	-	n	-	2	smtp
    -o smtp_data_done_timeout=1200
    -o disable_dns_lookups=yes
#some more ideas:
#   -o smtp_line_length_limit=0
#   -o notify_classes=protocol,resource,software


# from amavisd back to Postfix:
# =============================
#
# variant 1A: via SMTP, same host - or see 1B for multihost setup
# In amavisd.conf choose the host running Postfix and its port number, e.g.:
#   $notify_method  = 'smtp:127.0.0.1:10025';
#   $forward_method = 'smtp:127.0.0.1:10025';
#   $relayhost_is_client = 0;

#
# NOTE: set the chroot field the same (y/n) as for your regular smtp service
#
127.0.0.1:10025 inet n	-	n	-	-  smtpd
    -o content_filter=
    -o local_recipient_maps=
    -o smtpd_restriction_classes=
    -o smtpd_helo_restrictions=
    -o smtpd_client_restrictions=
    -o smtpd_sender_restrictions=
    -o smtpd_recipient_restrictions=permit_mynetworks,reject
    -o mynetworks=127.0.0.0/8
    -o strict_rfc821_envelopes=yes
#some more ideas:
#   -o virtual_maps=
#   -o virtual_mailbox_maps=
#   -o cleanup_service_name=cleanup2
#   -o notify_classes=protocol,resource,software
#   -o myhostname=localhost
#   -o always_bcc=user@example.com
#
# Specify the alternative cleanup service if you run Postfix snapshot
# version 1.1.7-20020331 or later, and have header_checks or body_checks
# enabled (contributed by Wayne Smith). It makes sense not to run Postfix
# content checks for the second time on the mail being passed back to MTA
# from amavisd. To disable them you need to specify an alternative
# cleanup service (or run two completely separate Postfix instances):
#
#cleanup2  unix	n	-	n	-	0	cleanup
#   -o header_checks=
#   -o body_checks=
#some more ideas:
#   -o header_checks=pcre:/etc/postfix/header_checks2
#   -o canonical_maps=
#   -o sender_canonical_maps=
#   -o recipient_canonical_maps=
#   -o masquerade_domains=
#   -o virtual_maps=
#   -o in_flow_delay=0s
#
# If you choose to have two cleanup services, you can have only one of them
# (or both by default) perform virtual and/or canonical mapping by specifying
# options '-o virtual_maps=', '-o canonical_maps=' ..., to selectively
# turn mappings off. For example the default cleanup can be replaced by:
#
#cleanup   unix  n  -  n  -  0  cleanup  -o virtual_maps=
#
# This influences whether amavisd is seeing and reporting addresses
# before or after being mapped. Decide for yourself which is more desirable
# and if it is worth the trouble (see NOTE2 below).
# NOTE1: if you turn off certain maps for cleanup2, make sure you do not rely
#        on them for internally generated notifications ($mailto, $mailfrom).
# NOTE2: if you turn off virtual maps for the first cleanup, make sure
#        the qmgr will not be rejecting mail claiming "unknown user".

# A note from Victor Duchovni: With just a single Postfix instance
# disable virtual_maps in the first cleanup, but not in the first "smtpd"
# (otherwise it will deny relay access to the virtual domains).

# variant 1B: via SMTP - with amavisd on a different host,
# also good for the case of several MTAs using the same amavisd server.
# - reinjection (forwarding)  if $forward_method is smtp:...
# - notification messages     if $notify_method  is smtp:...
# - quarantine                if $virus_quarantine_to contains '@'
# In amavisd.conf set port number where Postfix (one or more) is listening
# for reinjected mail and notifications, and optionally set 
# $relayhost_is_client to 1, if you want to have host field in the
# $forward_method and $notify_method specification dynamically replaced
# (but port number is still specified there). To prevent unauthorized use
# of the service you SHOULD restrict the set of IP addresses from which
# amavisd is willing to accept mail by specifying authorized Postfix host(s)
# with the access list @inet_acl in the amavisd.conf file. Bind must not be
# restricted to the loopback interface, so set $inet_socket_bind to undef.
#
# NOTE1: you SHOULD also restrict Postfix to only accept connections
#        on port 10025 from the amavisd host by '-o mynetworks = ...'
# NOTE2: set the chroot field the same (y/n) as for your regular smtp service.

#10025		inet n	-	n	-	-  smtpd
#   -o content_filter=
#   -o local_recipient_maps=
#   -o smtpd_restriction_classes=
#   -o smtpd_helo_restrictions=
#   -o smtpd_client_restrictions=
#   -o smtpd_sender_restrictions=
#   -o smtpd_recipient_restrictions=permit_mynetworks,reject
#   -o mynetworks=127.0.0.0/8,10.0.0.0/8,192.168.1.1
#   -o strict_rfc821_envelopes=yes
#some more ideas:
#   -o virtual_maps=
#   -o virtual_mailbox_maps=
#   -o cleanup_service_name=cleanup2
#   -o notify_classes=protocol,resource,software
#   -o myhostname=localhost
#   -o always_bcc=user@example.com




A tip from Wietse Venema (2002-12-12):

|  If you want to filter inbound SMTP mail only, then:
|
|  /etc/postfix/main.cf:
|     smtpd_recipient_restrictions = 
|        check_recipient_access hash:/etc/postfix/recipient_access
|        ...the usual stuff here...
|        reject_unauth_destination
|
|  /etc/postfix/recipient_access:
|     my.domain   FILTER foo:bar
|
|  That filters all the mail that has at least one recipient in your
|  domain, and does not filter mail with external recipients only.

(comment: the 'foo:bar' is what you would traditionally specify
in content_filter, i.e. smtp-amavis:[127.0.0.1]:10024)
