postmax

The ultimate postfix configuration fully tricked out with amavis, clamd, domainkeys, dpsam or spamassassin

Created by: spiderr, Last modification: 30 May 2008 (11:33 UTC)
This installation guide is intended to walk you through completely setting up a postfix smtp mail server with the maximum spam and anti-virus protection available from the open-source community. This technique is similar to that provided Mac OS X Server Mail with IP and DNS protection. It is an amalgamation of several online tutorials available throughout the net and from the software vendors, but all in one neat and tidy place. Our sincere thanks to all who contributed such wonderful software to make this world a better place.

1. Software Install


yum install postfix spamassassin amavisd-new clamav
chkconfig postfix on
chkconfig clamd on
chkconfig freshclam on
chkconfig amavisd on


For RedHat / CentOS, you might need to get the RPM's from DAG

For Suse/SLES, you should get the latest clamd to prevent an odd 5+ minute startup hang. Also, you should upgrade amavis to 2.4 or later to prevent errors as listed in troubleshooting.

2. Anti-Virus Configuration

Tweak /etc/amavisd.conf with your host information, and uncomment the clamd scanner

# For very high volume servers, disable db support
$enable_db = 0;
***snip***
['ClamAV-clamd',
  \&ask_daemon, ["CONTSCAN {}\n", "127.0.0.1:3310"],
  qr/\bOK$/, qr/\bFOUND$/,
  qr/^.*?: (?!Infected Archive)(.*) FOUND$/ ],

You might need to change the socket listed with "127.0.0.1:3310" as listed above. SpamAssassin settings are made in this file. Also, make sure $inet_socket_port = 10024; See detailed explanation of amavisd.conf for more information. db support has limited impact on features and performance.


<?php
/etc/init.d/clamd start
service amavisd start
service clamd start
# If you are behind a proxy, you need adjust /etc/freshclam.conf
freshclam
service freshclam start
?>


postconf -e 'content_filter = amavis:127.0.0.1:10024'
postconf -e 'receive_override_options = no_address_mappings'

Append these lines to /etc/postfix/master.cf

amavis unix - - - - 2 smtp
        -o smtp_data_done_timeout=1200
        -o smtp_send_xforward_command=yes
        -o disable_dns_lookups=yes
127.0.0.1:10025 inet n - - - - smtpd
        -o content_filter=
        -o local_recipient_maps=
        -o relay_recipient_maps=
        -o smtpd_restriction_classes=
        -o smtpd_client_restrictions=
        -o smtpd_helo_restrictions=
        -o smtpd_sender_restrictions=
        -o smtpd_recipient_restrictions=permit_mynetworks,reject
        -o mynetworks=127.0.0.0/8
        -o strict_rfc821_envelopes=yes
        -o receive_override_options=no_unknown_recipient_checks,no_header_body_checks
        -o smtpd_bind_address=127.0.0.1

Restart postfix

If you run a server for a significant number of users, you will want to run several virus scans at once. Change the 2 in two places: "- - - - 2" as above in master.cf, and "$max_servers = 2;" in amavisd.conf. These numbers should always match.

3. Test Setup

Use telnet to see if the appropriate ports are open:

telnet yourhost.com 25
telnet localhost 3310
telnet localhost 10025
telnet localhost 10024

4. IP Address Spam Prevention

RBLDNSD

This is a local DNS server database that performs local (e.g. FAST) DNS lookups against a list of dynamic and blacklisted IP's. Successful local lookup means it's on the blacklist and will be rejected.

  1. Install the rbldns RPM (available in Fedora Extras, or source)
  2. Edit your named.conf and add:
    
    zone "clients.blocked.rbl" IN {
            type forward;
            forward first;
            forwarders { 127.0.0.1 port 530; };
    };
    zone "hosts.blocked.rbl" IN {
            type forward;
            forward first;
            forwarders { 127.0.0.1 port 530; };
    };
  3. Edit /etc/sysconfig/rbldnsd and add the following lines:
    
    RBLDNSD="dsbl -r/var/lib/rbldnsd -b 127.0.0.1/530 \
    clients.blocked.rbl:ip4set:clients,dynamic \
    hosts.blocked.rbl:dnset:hosts \
    "
  4. Get the latest RBLDNS databases and move database files to /var/lib/rbldnsd
  5. Gentlepeople, start your daemons: "service restart named; service restart rbldnsd;" Test with telnet localhost 53; and telnet locahost 530;
  6. Edit your /etc/resolv.conf to include 127.0.0.1 so lookups are performed on the local server first.
  7. Preform a test lookup:
    
    $dig @localhost 223.61.83.162.clients.blocked.rbl -t txt
    ;; ANSWER SECTION:
    223.61.83.162.clients.blocked.rbl. 2048 IN TXT "DNSBL. 162.83.61.223 is a known spam source. Mail from 162.83.61.223 is NOT accepted on this server!"
  8. Update the following line of your /etc/postfix/main.cf
    
    smtpd_recipient_restrictions = permit_mynetworks,reject_unauth_destination,reject_rbl_client clients.blocked.rbl,reject_rhsbl_client hosts.blocked.rbl,reject_rhsbl_sender hosts.blocked.rbl

Spamassassin DNS Blocklists


En-masse IP Block Here is a tutorial for Blocking E-mail from China and Korea using Postfix and the Okean CIDR Blocks

5. DNS Spam Prevention

There are two main options DomainKeys, and SenderID.
DomainKeys were invented by Yahoo, SenderID was invented by Microsoft. These are arguably competing techniques, however, implementing both seems to have no ill-effect. Given SenderID was invented by Microsoft, you can be assured Outlook Server SMTP gateways employ SenderID, and are unlikely to support DomainKeys any time soon. In early 2005 when these proposals came out simultaneously, they were seen as competing techniques. As time has passed, they are now seen as more complementary, and typically both are implemented.

DomainKeys Identified Mail

Domain Keys Identified Mail is the newest open-standard e-mail authentication specification. To use DomainKeys, typically a filter or "plugin" is needed for your SMTP gateway. There is a postfix filter that is fairly easy to install and configure. Several perl modules need to be installed:

DKIMproxy

  1. Install necessary perl modules (make sure you have openssl-devel installed):
    
    cpan -i Crypt::OpenSSL::RSA Mail::Address MIME::Base64 Net::DNS Net::Server Test::More Mail::DKIM Error
  2. download source, extract tarball, cd into directory, and compile source with ./configure --prefix=/usr/local/dkimproxy ; make install
  3. For outbound mail signing, you will need a public/private key combo.
    
    openssl genrsa -out private_domainkey.key 1024
    openssl rsa -in private.key -pubout -out public_domainkey.key
  4. Tweak sample-dkim-init-script.sh and copy to /etc/init.d/dkim - Either make a dkimproxy user or change DKIMPROXYUSER and DKIMPROXYGROUP to postfix. The following are line changes made, adjust to your liking...
    
    *snip*
    DKIMPROXYUSER=postfix
    DKIMPROXYGROUP=postfix
    *snip*
    DKIMPROXY_IN_CFG="/etc/dkimproxy_in.conf"
    DKIMPROXY_OUT_CFG="/etc/dkimproxy_out.conf"
  5. Customize the default in confiugration cp /usr/local/dkimproxy/etc/dkimproxy_in.conf.example /etc/dkimproxy_in.conf and modify /etc/dkimproxy_in.conf
    
    # specify what address/port DKIMproxy should listen on
    listen    127.0.0.1:10026

    # specify what address/port DKIMproxy forwards mail to
    relay     127.0.0.1:10027
  6. Customize the default out confiugration cp /usr/local/dkimproxy/etc/dkimproxy_out.conf.example /etc/dkimproxy_out.conf and modify /etc/dkimproxy_out.conf
    
    # specify what address/port DKIMproxy should listen on
    listen    127.0.0.1:10028

    # specify what address/port DKIMproxy forwards mail to
    relay     127.0.0.1:10029






    # specify what domains DKIMproxy can sign for (comma-separated, no spaces)
    domain    yourdomain.com

    # specify what signatures to add
    signature dkim(c=relaxed)
    signature domainkeys(c=nofws)

    # specify location of the private key
    keyfile   /etc/pki/domainkeys/private.key

    # specify the selector (i.e. the name of the key record put in DNS)
    selector  selector1
  7. start dkim with service dkim start. Test ports are up and running with telnet localhost 10026 and telnet localhost 10028
  8. Add inbound dkim postfix configuration to /etc/postfix/master.cf
    
    #
    # The main SMTP server. It receives incoming mail from the network
    # and passes it to the content filter on localhost port 10026.
    #
    smtp      inet  n       -       n       -       -       smtpd
        -o smtpd_proxy_filter=127.0.0.1:10026
        -o smtpd_client_connection_count_limit=10
    #
    # After-filter SMTP server. Receive mail from the DKIM verifying proxy on
    # localhost port 10027.
    #
    127.0.0.1:10027 inet n  -       n       -        -      smtpd
        -o smtpd_authorized_xforward_hosts=127.0.0.0/8
        -o smtpd_client_restrictions=
        -o smtpd_helo_restrictions=
        -o smtpd_sender_restrictions=
        -o smtpd_recipient_restrictions=permit_mynetworks,reject
        -o smtpd_data_restrictions=
        -o mynetworks=127.0.0.0/8
        -o receive_override_options=no_unknown_recipient_checks
  9. Add outbound filter to sign outgoing messages in postfix configuration /etc/postfix/master.cf
    
    <?php
    #
    # modify the default submission service to specify a content filter
    # and restrict it to local clients and SASL authenticated clients only
    #
    submission  inet  n     -       n       -       -       smtpd
        
    -o smtpd_etrn_restrictions=reject
        
    -o smtpd_sasl_auth_enable=yes
        
    -o content_filter=dksign:[127.0.0.1]:10028
        
    -o receive_override_options=no_address_mappings
        
    -o smtpd_recipient_restrictions=permit_mynetworks,permit_sasl_authenticated,reject

    #
    # specify the location of the DKIM signing proxy
    # Note: the smtp_discard_ehlo_keywords option requires a recent version of
    # Postfix. Leave it off if your version does not support it.
    #
    dksign    unix  -       -       n       -       10      smtp
        
    -o smtp_send_xforward_command=yes
        
    -o smtp_discard_ehlo_keywords=8bitmime,starttls

    #
    # service for accepting messages FROM the DKIM signing proxy
    #
    127.0.0.1:10029 inet  n  -      n       -       10      smtpd
        
    -o content_filter=
        -
    o receive_override_options=no_unknown_recipient_checks,no_header_body_checks
        
    -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 smtpd_authorized_xforward_hosts=127.0.0.0/8
    ?>

SenderID (and SPF)

SenderID merged with a smaller group called Sender Policy Framework (SPF). SPF is a very simple mechanism for specifying which servers are valid for sending your email and is much simpler to implement than DomainKeys. Microsoft holds several patents in relation to the SenderID framework, however it released those patents in the "public domain" this past october. Beyond the typical cynicism of Microsoft's ulterior motives, SPF has a significant amount of technical criticism. Regardless, many major ISP's are using SPF to filter mail, including AOL (and RoadRunner) which has in some reports exclusively implemented SPF to some degree. (Spamassassin reports SOFT_FAIL reports from bogus .rr.com emails.)

Spamassassin SPF Support

  1. Install SPF perl module
    
    cpan -i Mail::SPF::Query

SPF Outbound support

The quickest way to get the DNS entries up and running is to follow the wizard.

Spam Detection

There are two top spam tools - DSPAM and spamassassin.

6. Spamassassin Configuration

  1. The spamassassin site has a review on integrating amavis and spamassassin, which is mostly ready to go by default.symlinking the bayes databases ( ln -s /var/spool/amavis/.spamassassin /root ) is a good idea so you can use sa-learn by hand to stock you bayes database. Review amavis + spamassassin FAQ to tweak your configuration parameters.
  2. Configure sa-update - add OpenProtect Rules to update daily.
    
    $ wget http://saupdates.openprotect.com/pub.gpg
    $ sa-update --nogpg --import pub.gpg
    $ crontab -e
    ... add ...
    1 5 0 0 0 sa-update --gpgkey D1C035168C1EBC08464946DA258CDB3ABDE9DC10 --channel saupdates.openprotect.com --channel updates.spamassassin.org

Razor

  1. Get the latest SDK source and install
    
    wget http://unc.dl.sourceforge.net/sourceforge/razor/razor-agents-sdk-2.07.tar.gz
    tar xvzf razor-agents-sdk-2.07.tar.gz
    cd razor-agents-sdk-2.07
    perl Makefile.PL && make && make install # Or, if not root: perl Makefile.PL PREFIX=$HOME && make && make install
  2. Get the latest agents source and register agents
    
    wget http://unc.dl.sourceforge.net/sourceforge/razor/razor-agents-2.84.tar.gz
    tar xvzf razor-agents-2.84.tar.gz
    cd razor-agents-2.84
    perl Makefile.PL PREFIX=$HOME && make && make install # Or, if installing system-wide as root: perl Makefile.PL && make && make install
    razor-admin -create
    razor-admin -discover
    razor-admin -register
  3. Disable razor logging, else you will quickly fill up /var/. Edit /var/spool/amavisd/.razor/razor-agent.conf and add: debuglevel = 0

Troubleshooting

  • Be sure to watch your logs, such as: tail -f /var/log/maillog
  • Config tinkering can lead to one of the services being down..
  • On SLES 10, it seems clamd can take up to 10 minutes to begin accepting connections. Reason currenly unknown. Please chime in if you have any ideas.
  • Check your open ports with netstat -lp and you should see somthing like:
    
    # netstat -lp
    Active Internet connections (only servers)
    Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
    tcp        0      0 localhost:10024         *:*                     LISTEN      2011/amavisd (maste
    tcp        0      0 localhost:10025         *:*                     LISTEN      19755/master
    tcp        0      0 localhost:10026         *:*                     LISTEN      19221/perl
    tcp        0      0 localhost:10027         *:*                     LISTEN      19755/master
    tcp        0      0 localhost:10028         *:*                     LISTEN      19229/perl
    tcp        0      0 localhost:10029         *:*                     LISTEN      19755/master
    tcp        0      0 localhost:dyna-access   *:*                     LISTEN      1803/clamd
    tcp        0      0 localhost:domain        *:*                     LISTEN      1875/named
    tcp        0      0 *:smtp                  *:*                     LISTEN      19755/master
    tcp        0      0 *:domain                *:*                     LISTEN      1875/named
    tcp        0      0 *:ssh                   *:*                     LISTEN      2064/sshd
    tcp        0      0 *:smtp                  *:*                     LISTEN      19755/master
    *snip*
  • Error like :
    
    child process [20099]: Error closing main::stdin: Bad file descriptor at /usr/sbin/amavisd line 1872, <GEN8> line 74.\n
    Net: :Server 0.91 (or later) introduced a change which makes it incompatible with amavisd-new-2.3.3 (or earlier). Either upgrade amavis or downgrade your perl Net: :Server

References and Other tutorails

http://www.akadia.com/services/postfix_amavisd.html Similar setup to postmax with mysql and quarantining web app.
http://wiki.apache.org/spamassassin/SingleUserUnixInstall
http://devnull.com/kyler/dspam.20040512.html
http://howtoforge.com/virtual-users-domains-postfix-courier-mysql-squirrelmail-mandriva2008.1-p3

Comments

Bw

by Kozuch, 01 Jun 2008 (23:08 UTC)
How is this related to bitweaver? (:wink:)