Postfix OpenLDAP Courier-imap Amavisd-new SpamAssassin and clamav HowTo

This is a step by step guide on how to configure GNU/Linux system with Postfix, OpenLDAP, Courier-imap, Amavisd-new, SpamAssassin and clamav. Even though this setup was configured on Centos 5, with minor tweaks you should get it working on any GNU/Linux distribution.

Building necessary software

I wanted to compile courier-imap one myself, and here are steps on how to do it.

Building a new Courier RPM package.

Courier-Imap does not allow ‘root’ user to build the package so you’ll have to add one regular user account and create RPM development hierarchy:

# useradd mockbuild
# passwd mockbuild
# /bin/su - mockbuild
$ mkdir $HOME/rpm
$ mkdir $HOME/rpm/SOURCES
$ mkdir $HOME/rpm/SPECS
$ mkdir $HOME/rpm/BUILD
$ mkdir $HOME/rpm/SRPMS
$ mkdir $HOME/rpm/RPMS
$ mkdir $HOME/rpm/RPMS/i386
$ echo "%_topdir    $HOME/rpm" >> $HOME/.rpmmacros

Obtain the newest courier-imap tarball from URL listed in Appendix: Package Repositories, save it in /home/test/rpm/SOURCES directory and unpack it.

$ cp courier-imap-4.0.1.tar.bz2 /home/test/rpm/SOURCES
$ cd /home/rpm/SOURCES
$ tar xjf courier-imap-4.0.1.tar.bz2

Now ‘cd’ to newly created directory and edit courier-imap.spec using your favorite text editor:

$ cd courier-imap-4.0.1
$ vi courier-imap.spec

I like having things in more standard places ( eg. /etc ) so i changed following lines, and i suggest you to do the same:

%define _sysconfdir /etc/courier
%define _mandir /usr/share/man
%define _prefix /etc/courier
%define _localstatedir /var/run

%configure 
--with-redhat 
--enable-workaround-for-imap-client-bugs 
%{?xflags: %{xflags}}

#%{__make} check

Once you have finished with modification of the ‘courier-imap.spec’ file, copy it to /home/test/rpm/SPECS directory and build RPM package ( NOTE: You will need to install development packages of the services u wish to include support for, plus other requiremnts ( openldap-devel, courier-authlib, courier-authlib-devel ), before you start building RPM package for Courier-imap):

$ rpmbuild -bb courier-imap.spec

When compilation process finnishes you should have a new courier-imap RPM package in RPMS/i386 directory, so ‘cd’ to the RPMS/i386 directory and install new Courier-imap RPM package. But you install courier-imap RPM package download and install ‘courier-authlib’ packages ( courier-authlib-ldap ) from URL listed in Appendix: Package Repositories:

# rpm -ivh courier-authlib-*
# cd /home/test/rpm/RPMS/i386
# rpm -ivh courier-imap-4.0.1-1.3ES.i386.rpm

Server Setup

Postfix Setup

Using your favorite text editor, edit ‘main.cf’ file in /etc/postfix directory and modify or add these lines to it ( i recommend you to build main.cf file from scratch ):

# Some basic Directives
####################################################
myhostname = mail.mohancheema.net
mydomain =  mohancheema.net
mydestination =  $myhostname, $mydomain, localhost.$mydomain
mynetworks = 192.168.2.0/24, 10.0.2.0/24, 10.0.4.0/24, 127.0.0.1
relay_domain = $mydomain

# Preventing multiple deliveries to the same account
#####################################################
default_destination_concurrency_limit =1
local_destination_concurrency_limit = 1

# Defining Banner for our Mailer
#####################################################

smtpd_banner = $myhostname ESMTP $mail_name (RHEL3)

# Anti UCE ( Spam ) restrictions
#####################################################

smtpd_helo_required = yes
disable_vrfy_command = yes

smtpd_recipient_restrictions =
reject_non_fqdn_sender,
reject_non_fqdn_recipient,
reject_unknown_sender_domain,
reject_unknown_recipient_domain,
permit_mynetworks,
reject_unauth_destination,
reject_rbl_client opm.blitzed.org,
reject_rbl_client list.dsbl.org,
reject_rbl_client sbl.spamhaus.org,
reject_rbl_client cbl.abuseat.org,
reject_rbl_client dul.dnsbl.sorbs.net,
check_policy_service inet:127.0.0.1:10040,
permit

smtpd_data_restrictions =
reject_unauth_pipelining,
permit

alias_maps = hash:/etc/postfix/aliases, ldap:/etc/postfix/ldap-groups.cf, ldap:/etc/postfix/ldap-aliases.cf

# OpenLDAP stuff
#################################################

virtual_alias_maps = ldap:/etc/postfix/ldap-groups.cf, ldap:/etc/postfix/ldap-aliases.cf
virtual_mailbox_maps = ldap:/etc/postfix/ldap-mailbox.cf
local_recipient_maps = $alias_maps, ldap:/etc/postfix/ldap-users.cf

# User mailbox destination
################################################

home_mailbox = Maildir/

That is how ‘main.cf’ file should look like. Now to test your newly configured MTA execute:

# telnet YOUR_IP 25
Trying YOUR_IP...
Connected to YOUR_IP (YOUR_IP).
Escape character is '^]'.
s: 220 host.mohancheema.net ESMTP Postfix (RHEL3)
c: EHLO mohancheema.net
s: 250-mail.examlpe.org
s: 250-PIPELINING
s: 250-SIZE 10240000
s: 250-ETRN
s: 250-XVERP
s: 250 8BITMIME
c: QUIT

Letter ‘s’ means server and it represents what server replies on your commands, letter ‘c’ are command you need to execute. Wow !!! we made it and our Postfix Server is Up and Ready :D.

OpenLDAP Setup

Using your favorite text editor, edit ‘slapd.conf’ file in /etc/openldap directory and modify or add these lines to it ( i recommend you to build slapd.conf file from scratch ):

# Defining schemas and schema file locations
################################################################

include         /etc/openldap/schema/core.schema
include         /etc/openldap/schema/cosine.schema
include         /etc/openldap/schema/nis.schema
include         /etc/openldap/schema/inetorgperson.schema
include         /etc/openldap/schema/qmail.schema
include         /etc/openldap/schema/courier.schema
include         /etc/openldap/schema/openldap.schema
schemacheck     on
pidfile         /var/run/openldap/slapd.pid
argsfile        /var/run/openldap/slapd.args

# Defining our database and admin user + password
################################################################

database        bdb
directory       /var/lib/ldap
suffix          "dc=mohancheema,dc=net"
rootdn          "cn=manager,dc=mohancheema,dc=net"
rootpw          {SSHA}qnvflYeey2IjCT5vjmWHEkPqGcLbPxFH

# Indexing for faster queries ( bad indexes can slow things up )
#################################################################

index objectClass,uidNumber,uid eq
index mailAlternateAddress,MailForwardingAddress,mail eq
index givenname,sn,cn pres,eq
defaultaccess read

# Defining Access Control Lists for access to various parts of our
# databse. We can live without ACL's aswell, but some security should
# be in place.
# preventng users from viewing passwords, employee number ... etc
######################################################################

access to attrs=userpassword,clearpassword
by anonymous auth
by self write
by * none
access to attrs=accountstatus
by dn="cn=daemon,dc=mohancheema,dc=net" read
access to *
by dn="cn=daemon,dc=mohancheema,dc=net" read
by users read
by self write
by * read

Once you have modified file to look like the one presented above, you will need to copy qmail and courier schema files in /etc/openldap/schema directory

Get the qmail.schema file from http://www.qmail-ldap.org/wiki/index.php/Qmail.schema. Copy /usr/share/doc/courier-authlib-ldap-0.63.0/authldap.schema to /etc/openldap/schema/courier.schema

Next step in our OpenLDAP backend configuration we need to create hierarchy of our OpenLDAP domain. So using you favorite text editor create file called ‘example.ldif; in /etc/openldap directory and add these lines to it:

dn: dc=mohancheema,dc=net
objectClass: top
objectClass: organization
objectClass: dcObject
dc: mohancheema
o: Arrkgroup Company Users Group
description: Our nifty mohancheema OpenLDAP company

dn: cn=manager,dc=mohancheema,dc=net
objectclass: organizationalRole
cn: manager
description: OpenLDAP Administrator ( Manager )

dn: ou=Users,dc=mohancheema,dc=net
objectClass: top
objectClass: organizationalUnit
ou: Users
description: Organizational Unit for our users

dn: cn=readmail,dc=mohancheema,dc=net
cn: readmail
sn: readmail
objectClass: top
objectClass: person
objectClass: simpleSecurityObject
description: This account is used to read info from openLDAP database.
userPassword: vision

dn: ou=Group,dc=mohancheema,dc=net
ou: Group
objectClass: top
objectClass: organizationalUnit

dn: ou=Aliases,dc=mohancheema,dc=net
ou: Aliases
objectClass: top
objectClass: organizationalUnit

dn: ou=AddressBook,dc=mohancheema,dc=net
ou: AddressBook
objectClass: top
objectClass: organizationalUnit

dn: cn=vmail,ou=Group,dc=mohancheema,dc=net
gidNumber: 1001
cn: vmail
objectClass: posixGroup
objectClass: top
userPassword: vision

dn: cn=wheel,ou=Group,dc=mohancheema,dc=net
gidNumber: 1002
cn: wheel
memberUid: someadmin
objectClass: posixGroup
objectClass: top
userPassword: vision

Now once you have made the above file, you need to add info from it to you LDAP database and you do it like this:

# ldapadd -x -v -w vision -D "cn=manager,dc=mohancheema,dc=net" -f start.ldif

You should see output scrolling across the screen informing you what entries it is adding to LDAP databse.

Now comes the part where we add a user to the LDAP databse. So once again prepare your typing skills and create a file named ‘user.ldif’ and add following entries in it:

dn: uid=mohanc,ou=Users,dc=mohancheema,dc=net
cn: Mohan Cheema
givenName: mohanc
sn: Cheema
uid: mohanc
gecos: mohanc
mail: mohanc@mohancheema.net
mailAlternateAddress: mohanc@mohancheema.net
mailAlternateAddress: mohanc@mohancheema.net
userPassword: {MD5}9CCHBZs3rn9Nnw06R1gBqA==
uidNumber: 1021
homeDirectory: /home/mohanc
mailMessageStore: /home/mohanc/Maildir
gidNumber: 1001
shadowMax: 99999
shadowWarning: 7
shadowLastChange: 12416
loginShell: /bin/bash
ou: Users
o: ArrkGroup
accountStatus: active
mailQuotaSize: 2480000
mailQuotaCount: 10
employeeNumber: 2
title: Mr.
objectClass: top
objectClass: posixAccount
objectClass: shadowAccount
objectClass: qmailUser
objectClass: CourierMailAccount
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson

Now once you have made the above file, you need to add info from it to you LDAP database and you do it like this:

# ldapadd -x -v -w vision -D "cn=manager,dc=mohancheema,dc=net" -f user.ldif

That concludes the part where we configured OpenLDAP to be used as out backend database.

All we need to do is set up system to use OpenLDAP for our users information. RedHat provides CLI tool called ‘authconfig’ which can be used to setup system authentication from various sources. Other distributions have their own tools, however if your using distribution which does not have tools like that, you will need to edit ‘nsswitch.conf’ file located in /etc directory and add these changes to it:

passwd:     files ldap
group:      files ldap
shadow:      files ldap
hosts:          files dns
networks:       files
protocols:      db files
services:       db files
ethers:         db files
rpc:            db files
netgroup:       nis

Addtitional thing that you should do is modify ‘login’ file in /etc/pam.d directory and modify it or add these entries to it:

auth       required     pam_securetty.so
auth       required     pam_stack.so service=system-auth
auth       required     pam_nologin.so
account    required     pam_stack.so service=system-auth
password   required     pam_stack.so service=system-auth
session    required     pam_stack.so service=system-auth
session    optional     pam_console.so
session    required     /lib/security/pam_mkhomedir.so skel=/etc/skel umask=0022

Now run following command:

# authconfig --enableldap --enableldapauth --update
# authconfig --enablemkhomedir --update

The line with ‘pam_mkhomedir.so’ tells your system to create users home directory if it doesnt exist and pull settings from skel directory alongside with setting umask for user.

Courier-IMAP

Using your favorite text editor, edit ‘imapd’ file in /etc/courier directory and modify or add these lines to it ( i recommend you to build imapd file from scratch ):

ADDRESS=0
PORT=143
MAXDAEMONS=40
MAXPERIP=4
IMAPDSTART=YES

Using your favorite text editor, edit ‘authdaemonrc’ file in /etc/authlib directory and modify or add these lines to it:

authmodulelist="authldap"
daemons=5
DEBUG_LOGIN=2

Using your favorite text editor, edit ‘authldaprc’ file in /etc/authlib directory and modify or add these lines to it:

LDAP_SERVER             127.0.0.1
LDAP_PORT               389
LDAP_BASEDN             ou=Users,dc=mohancheema,dc=net
LDAP_BINDDN             cn=readmail,dc=mohancheema,dc=net
LDAP_BINDPW             vision
LDAP_TIMEOUT            5
LDAP_AUTHBIND           1
LDAP_MAIL               mail
LDAP_DOMAIN             mohancheema.net
LDAP_GLOB_GID           vmail
LDAP_HOMEDIR            homeDirectory
LDAP_MAILDIR            mailMessageStore
LDAP_MAILDIRQUOTA       mailQuota
LDAP_FULLNAME           cn
LDAP_UID                uidNumber
LDAP_GID                gidNumber
LDAP_DEREF              never
LDAP_TLS                0

That about covers the Server configuration part, now you need to restart daemons:

# /etc/init.d/courier-authlib restart
# /etc/init.d/courier-imap restart
# /etc/init.d/postfix restart
# /etc/init.d/ldap restart

First try logging in to system as our LDAP user ( it should work as we made it a posix account aswell, home directory should get created by entry we made in ‘login’ file ). Now try sending mail to the user mohanc@mohancheema.net ( i assume that you have set your system authentication to use LDAP ):

# echo "testing ldap user" | mail -s TEST-MY-LDAP mohanc@mohancheema.net

Configure you MUA (Mail User Agent – eg. Evolution) to recieve mail from imap server ( if you configured DNS ‘a priori’ use hostname, otherwise u can use IP ADDRESS )

  1. Webmail
  2. SquirrelMail

Install SquirrelMail Package.

First we shall need to make SquirrelMail talk to the LDAP server, so ‘cd’ to the /usr/share/squirrelmail/config directory and run ‘config.pl’ file:

# cd /usr/share/squirrelmail/config
# ./config.pl

You should get a menu that looks like this:

SquirrelMail Configuration : Read: config.php (1.4.0)
---------------------------------------------------------

Main Menu --
1.  Organization Preferences
2.  Server Settings
3.  Folder Defaults
4.  General Options
5.  Themes
6.  Address Books (LDAP)
7.  Message of the Day (MOTD)
8.  Plugins
9.  Database

D.  Set pre-defined settings for specific IMAP servers
C.  Turn color off
S   Save data
Q   Quit

Command >>

Entering 6 as option should bring you to the following screen output:

SquirrelMail Configuration : Read: config.php (1.4.0)
---------------------------------------------------------

Address Books (LDAP)
1.  Change Servers
>  localhost
2.  Use Javascript Address Book Search  : false
R   Return to Main Menu
C.  Turn color off
S   Save data
Q   Quit

Command >>

Enter 1 as option and set these:

hostname: localhost
base: cn=Users,dc=mohancheema,dc=net
binddn: cn=readmail,dc=mohancheema,dc=net
bindpw: vision

Once it is finnished choose ‘S’ to save data and ‘Q’ to Quit.

Now you need to start ‘httpd’ daemon (apache):

# /etc/init.d/httpd restart

Now point your favorite web browser to the URL:

http://127.0.0.1/webmail

Use Login name and password of the LDAP user you earlier added to LDAP

Security

SASL (Simple Authentication and Security Layer)

First install ‘cyrus-sasl’ packages.

To enable SASL support in postfix we need to edit ‘main.cf’ file in /etc/postfix directory and modify or add these lines:

# Some basic Directives
####################################################

myhostname = mail.mohancheema.net
mydomain =  mohancheema.net
mydestination =  $myhostname, $mydomain, localhost.$mydomain
mynetworks = 192.168.2.0/24, 10.0.2.0/24, 10.0.4.0/24, 127.0.0.1
relay_domain = $mydomain

# Preventing multiple deliveries to the same account
#####################################################

default_destination_concurrency_limit =1
local_destination_concurrency_limit = 1

# Defining Banner for our Mailer
#####################################################

smtpd_banner = $myhostname ESMTP $mail_name (RHEL3)

# Anti UCE ( Spam ) restrictions
#####################################################

smtpd_helo_required = yes
disable_vrfy_command = yes

smtpd_recipient_restrictions =
reject_non_fqdn_sender,
reject_non_fqdn_recipient,
reject_unknown_sender_domain,
reject_unknown_recipient_domain,
permit_mynetworks,
reject_unauth_destination,
reject_rbl_client opm.blitzed.org,
reject_rbl_client list.dsbl.org,
reject_rbl_client sbl.spamhaus.org,
reject_rbl_client cbl.abuseat.org,
reject_rbl_client dul.dnsbl.sorbs.net,
check_policy_service inet:127.0.0.1:10040,
permit

smtpd_data_restrictions =
reject_unauth_pipelining,
permit

alias_maps = hash:/etc/postfix/aliases, ldap:/etc/postfix/ldap-groups.cf, ldap:/etc/postfix/ldap-aliases.cf

# OpenLDAP stuff
#################################################

virtual_alias_maps = ldap:/etc/postfix/ldap-groups.cf, ldap:/etc/postfix/ldap-aliases.cf
virtual_mailbox_maps = ldap:/etc/postfix/ldap-mailbox.cf
local_recipient_maps = $alias_maps, ldap:/etc/postfix/ldap-users.cf

# User mailbox destination
################################################
home_mailbox = Maildir/

# Adding SASL Support
################################################

smtpd_sasl_auth_enable = yes
smtpd_sasl_security_options = noanonymous
smtpd_sasl_local_domain = $myhostname
broken_sasl_auth_clients = yes

Now you need to restart services ( postfix and saslauthd ), and test SASL authentication:

# /etc/init.d/postfix restart
# /etc/init.d/saslauthd restart
# testsaslauth -u mohanc -p vision
0: OK "Success."

First you will need to generate Base64 encoded string:

# perl -MMIME::Base64 -e 'print encode_base64("mohancmohancvision");'
bW9oYW5jAG1vaGFuYwB2aXNpb24=

Now lets try authenticating to our SMTP server:

# telnet IP_ADDRESS 25
Trying IP_ADDRESS...
Connected to IP_ADDRESS (IP_ADDRESS).
Escape character is '^]'.
s: 220 mail.mohancheema.net ESMTP Postfix (RHEL3)
c: EHLO mohancheema.net
s: 250-mail.mohancheema.net
s: 250-PIPELINING
s: 250-SIZE 10240000
s: 250-ETRN
s: 250-AUTH PLAIN LOGIN GSSAPI
s: 250-AUTH=PLAIN LOGIN GSSAPI
s: 250-XVERP
s: 250 8BITMIME
c: AUTH PLAIN bW9oYW5jAG1vaGFuYwB2aXNpb24=
s: 235 Authentication successful
c: QUIT

Again letter ‘s’ means server and it represents what server replies on your commands, letter ‘c’ are command you need to execute. If everything went smoothly as described above that means that were using SASL to authenticate to our server.

Open your favorite MUA (Mail User Agent eg. Evolution ) and set option where it says that server requires authentication.

TLS (Transport Layer Security)

When we implement this layer it encrypts the communication between two hosts.

Before we proceed you will need to install ‘openssl’ package.

Once you have installed ‘openssl’ package ‘cd’ to /usr/share/ssl directory, edit ‘openssl.cnf’ file and modify or add these lines (i will include an example below, change it to suit your preferences and needs):

countryName_default             = IN
stateOrProvinceName_default     = Maharashtra
localityName_default            = Mumbai
0.organizationName_default      = mohancheema.net
organizationalUnitName_default  = POSTFIX_HOWTO
commonName_default            = mail.mohancheema.net
emailAddress_default          = postmaster@mohancheema.net

Now ‘cd’ to /etc/pki/tls/misc/ directory and edit ‘CA’ file by adding ‘-nodes’ to the section ‘# create a certificate’:

-newcert)
# create a certificate
$REQ -new -nodes -x509 -keyout newreq.pem -out newreq.pem $DAYS
RET=$?
echo "Certificate (and private key) is in newreq.pem"
;;

-newreq)
# create a certificate request
$REQ -new -nodes -keyout newreq.pem -out newreq.pem $DAYS
RET=$?
echo "Request (and private key) is in newreq.pem"
;;

Now run the ‘CA’ file and generate new certificates:

# ./CA -newca
# ./CA -newreq
# ./CA -sign

The default values should be ok, since you have changed ‘openssl.cnf’ to reflect your needs.

Next step is to copy newly generated certificates to /etc/postfix directory:

# cp newcert.pem /etc/postfix/
# cp newreq.pem /etc/postfix/
# cp ../cert.pem /etc/postfix/cacert.pem

Now add or modify following lines in your ‘main.cf’ file in order to add TLS support in it:

# Some basic Directives
####################################################
myhostname = mail.mohancheema.net
mydomain =  mohancheema.net
mydestination =  $myhostname, $mydomain, localhost.$mydomain
mynetworks = 192.168.2.0/24, 10.0.2.0/24, 10.0.4.0/24, 127.0.0.1
relay_domain = $mydomain

# Preventing multiple deliveries to the same account
#####################################################

default_destination_concurrency_limit =1
local_destination_concurrency_limit = 1

# Defining Banner for our Mailer
#####################################################

smtpd_banner = $myhostname ESMTP $mail_name (RHEL3)

# Anti UCE ( Spam ) restrictions
#####################################################

smtpd_helo_required = yes
disable_vrfy_command = yes

smtpd_recipient_restrictions =
reject_non_fqdn_sender,
reject_non_fqdn_recipient,
reject_unknown_sender_domain,
reject_unknown_recipient_domain,
permit_mynetworks,
reject_unauth_destination,
reject_rbl_client opm.blitzed.org,
reject_rbl_client list.dsbl.org,
reject_rbl_client sbl.spamhaus.org,
reject_rbl_client cbl.abuseat.org,
reject_rbl_client dul.dnsbl.sorbs.net,
check_policy_service inet:127.0.0.1:10040,
permit

smtpd_data_restrictions =
reject_unauth_pipelining,
permit

alias_maps = hash:/etc/postfix/aliases, ldap:/etc/postfix/ldap-groups.cf, ldap:/etc/postfix/ldap-aliases.cf

# OpenLDAP stuff
#################################################

virtual_alias_maps = ldap:/etc/postfix/ldap-groups.cf, ldap:/etc/postfix/ldap-aliases.cf
virtual_mailbox_maps = ldap:/etc/postfix/ldap-mailbox.cf
local_recipient_maps = $alias_maps, ldap:/etc/postfix/ldap-users.cf

# User mailbox destination
################################################

home_mailbox = Maildir/

# Adding SASL Support
################################################

smtpd_sasl_auth_enable = yes
smtpd_sasl_security_options = noanonymous
smtpd_sasl_local_domain = $myhostname
broken_sasl_auth_clients = yes

# Adding TLS Support
###############################################

smtpd_use_tls = yes
smtpd_tls_auth_only = yes
smtpd_tls_key_file = /etc/postfix/newkey.pem
smtpd_tls_cert_file = /etc/postfix/newcert.pem
smtpd_tls_CAfile = /etc/postfix/cacert.pem
smtpd_tls_loglevel = 3
smtpd_tls_received_header = yes
smtpd_tls_session_cache_timeout = 3600s
tls_random_source = dev:/dev/urandom

Restart postfix service and try starting TLS by connecting to your server with telnet:

# /etc/init.d/postfix restart
# telnet IP_ADDRESS 25
Connected to IP_ADDRESS (IP_ADDRESS).
Escape character is '^]'.
s: 220 host.mohancheema.net ESMTP Postfix (RHEL3)
c: EHLO mohancheema.net
s: 250-host.mohancheema.net
s: 250-PIPELINING
s: 250-SIZE 10240000
s: 250-ETRN
s: 250-STARTTLS
s: 250-AUTH PLAIN LOGIN GSSAPI
s: 250-AUTH=PLAIN LOGIN GSSAPI
s: 250-XVERP
s: 250 8BITMIME
c: STARTTLS
s: 220 Ready to start TLS
c: QUIT

Letter ‘s’ means server and it represents what server replies on your commands, letter ‘c’ are command you need to execute.

Use Your favorite MUA (Mail User Agent eg. Evolution) and set the option where it says that the server requires secure connection (SSL).

Content Checking

Amavisd-new

amavisd-new is a high-performance and reliable interface between mailer (MTA) and one or more content checkers: virus scanners, and/or Mail::SpamAssassin Perl module. It is written in Perl, ensuring high reliability, portability and maintainability. It talks to MTA via (E)SMTP or LMTP protocols, or by using helper programs. No timing gaps exist in the design, which could cause a mail loss.

To install type following on command line:

yum install amavisd-new

Once install to configure amavis you need to edit ‘amavisd.conf’ file located in /etc directory and modify or add following lines:

use strict;

$inet_socket_bind = undef;
$max_servers = 10;
$daemon_user  = "amavis";
$daemon_group = "amavis";

$mydomain = 'mohancheema.net';

$MYHOME = '/var/amavis';
$TEMPBASE = "$MYHOME/tmp";
$ENV{TMPDIR} = $TEMPBASE;
$QUARANTINEDIR = "/var/virusmails";
$LOGFILE = "$MYHOME/var/amavis.log";

$quarantine_subdir_levels = 1;
$release_format = 'resend';
$report_format  = 'arf';
$db_home   = "$MYHOME/db";
$log_level = 5;
$log_recip_templ = undef;
$DO_SYSLOG = 1;
$syslog_facility = 'mail';
$syslog_priority = 'debug';
$enable_db = 1;
$enable_global_cache = 1;
$nanny_details_level = 2;
$enable_dkim_verification = 1;
$enable_dkim_signing = 1;

@local_domains_maps = ( [".$mydomain"] );
@mynetworks = qw( 127.0.0.0/8 [::1] [FE80::]/10 [FEC0::]/10
10.0.0.0/8 172.16.0.0/12 192.168.2.0/24 59.163.23.95 );

$unix_socketname = "$MYHOME/amavisd.sock";
$inet_socket_port = [10024,9998];
$policy_bank{'MYNETS'} = {
originating => 1,
os_fingerprint_method => undef,
};

$interface_policy{'10026'} = 'ORIGINATING';

$policy_bank{'ORIGINATING'} = {
originating => 1,
allow_disclaimers => 1,
virus_admin_maps => ["mohanc@$mydomain"],
spam_admin_maps  => ["mohanc@$mydomain"],
warnbadhsender   => 1,
forward_method => 'smtp:[127.0.0.1]:10025',
smtpd_discard_ehlo_keywords => ['8BITMIME'],
bypass_banned_checks_maps => [1],
bypass_banned_checks_maps => [1],
bypass_header_checks_maps => [1],
bypass_virus_checks_maps => [1],
bypass_header_checks_maps => [1],
terminate_dsn_on_notify_success => 0,
};

$interface_policy{'9998'} = 'AM.PDP';

$policy_bank{'AM.PDP'} = {
protocol => 'AM.PDP',
inet_acl => [qw( 127.0.0.1 [::1] 192.168.2.37 59.163.23.95 )],
auth_required_release => 0,
};

$sa_tag_level_deflt  = -999;
$sa_tag2_level_deflt = 5;
$sa_kill_level_deflt = 20;
$sa_dsn_cutoff_level = 22;
$sa_crediblefrom_dsn_cutoff_level = 18;

$penpals_bonus_score = 8;
$penpals_threshold_high = $sa_kill_level_deflt;

$bounce_killer_score = 100;
$sa_mail_body_size_limit = 400*1024;
$sa_local_tests_only = 0;

@lookup_sql_dsn =
( ['DBI:mysql:database=amavis;host=127.0.0.1;port=3306', 'amavis', 'amavis'] );
@storage_sql_dsn = @lookup_sql_dsn;

$virus_admin               = "virusalert@$mydomain";
$mailfrom_notify_admin     = "virusalert@$mydomain";
$mailfrom_notify_recip     = "virusalert@$mydomain";
$mailfrom_notify_spamadmin = "spam.police@$mydomain";
$mailfrom_to_quarantine = "";

@addr_extension_virus_maps      = ('virus');
@addr_extension_banned_maps     = ('banned');
@addr_extension_spam_maps       = ('spam');
@addr_extension_bad_header_maps = ('badh');

$path = '/usr/local/sbin:/usr/local/bin:/usr/sbin:/sbin:/usr/bin:/bin';

$MAXLEVELS = 14;
$MAXFILES = 1500;
$MIN_EXPANSION_QUOTA =      100*1024;
$MAX_EXPANSION_QUOTA = 300*1024*1024;

$sa_spam_subject_tag = '[SPAM] ';
$defang_virus  = 1;
$defang_banned = 1;
$defang_by_ccat{+CC_BADH.",3"} = 1;
$defang_by_ccat{+CC_BADH.",5"} = 1;
$defang_by_ccat{+CC_BADH.",6"} = 1;

$virus_quarantine_method = $spam_quarantine_method = $banned_files_quarantine_method = $bad_header_quarantine_method = 'sql:';
$myhostname = 'mail.mohancheema.net';

$notify_method  = 'smtp:[127.0.0.1]:10025';
$forward_method = 'smtp:[127.0.0.1]:10025';

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

@keep_decoded_original_maps = (new_RE(
qr'^MAIL$',   # retain full original message for virus checking
qr'^MAIL-UNDECIPHERABLE$', # recheck full mail if it contains undecipherables
qr'^(ASCII(?! cpio)|text|uuencoded|xxencoded|binhex)'i,
));

$banned_filename_re = new_RE(
qr'^.(exe-ms|dll)$',
[ qr'^.(rpm|cpio|tar)$'       => 0 ],
qr'..(pif|scr)$'i,
qr'^application/x-msdownload$'i,
qr'^application/x-msdos-program$'i,
qr'^application/hta$'i,
qr'.[^./]*[A-Za-z][^./]*.s*(exe|vbs|pif|scr|bat|cmd|com|cpl|dll)[.s]*$'i,
qr'..(exe|vbs|pif|scr|cpl)$'i,             # banned extension - basic
);

@score_sender_maps = ({
'.' => [  # the _first_ matching sender determines the score boost
new_RE(  # regexp-type lookup table, just happens to be all soft-blacklist
[qr'^(bulkmail|offers|cheapbenefits|earnmoney|foryou)@'i         => 5.0],
[qr'^(greatcasino|investments|lose_weight_today|market.alert)@'i=> 5.0],
[qr'^(money2you|MyGreenCard|new.tld.registry|opt-out|opt-in)@'i=> 5.0],
[qr'^(optin|saveonlsmoking2002k|specialoffer|specialoffers)@'i   => 5.0],
[qr'^(stockalert|stopsnoring|wantsome|workathome|yesitsfree)@'i  => 5.0],
[qr'^(your_friend|greatoffers)@'i                                => 5.0],
[qr'^(inkjetplanet|marketopt|MakeMoney)d*@'i                    => 5.0],
),

{ # a hash-type lookup table (associative array)

'nobody@cert.org'                        => -3.0,
'cert-advisory@us-cert.gov'              => -3.0,
'owner-alert@iss.net'                    => -3.0,
'slashdot@slashdot.org'                  => -3.0,
'securityfocus.com'                      => -3.0,
'ntbugtraq@listserv.ntbugtraq.com'       => -3.0,
'security-alerts@linuxsecurity.com'      => -3.0,
'mailman-announce-admin@python.org'      => -3.0,
'amavis-user-admin@lists.sourceforge.net'=> -3.0,
'amavis-user-bounces@lists.sourceforge.net' => -3.0,
'spamassassin.apache.org'                => -3.0,
'notification-return@lists.sophos.com'   => -3.0,
'owner-postfix-users@postfix.org'        => -3.0,
'owner-postfix-announce@postfix.org'     => -3.0,
'owner-sendmail-announce@lists.sendmail.org'   => -3.0,
'sendmail-announce-request@lists.sendmail.org' => -3.0,
'donotreply@sendmail.org'                => -3.0,
'ca+envelope@sendmail.org'               => -3.0,
'noreply@freshmeat.net'                  => -3.0,
'owner-technews@postel.acm.org'          => -3.0,
'ietf-123-owner@loki.ietf.org'           => -3.0,
'cvs-commits-list-admin@gnome.org'       => -3.0,
'rt-users-admin@lists.fsck.com'          => -3.0,
'clp-request@comp.nus.edu.sg'            => -3.0,
'surveys-errors@lists.nua.ie'            => -3.0,
'emailnews@genomeweb.com'                => -5.0,
'yahoo-dev-null@yahoo-inc.com'           => -3.0,
'returns.groups.yahoo.com'               => -3.0,
'clusternews@linuxnetworx.com'           => -3.0,
lc('lvs-users-admin@LinuxVirtualServer.org')    => -3.0,
lc('owner-textbreakingnews@CNNIMAIL12.CNN.COM') => -5.0,
'sender@example.net'                     =>  3.0,
'.example.net'                           =>  1.0,
},
],
});

@decoders = (
['mail', &do_mime_decode],
['asc',  &do_ascii],
['uue',  &do_ascii],
['hqx',  &do_ascii],
['ync',  &do_ascii],
['F',    &do_uncompress, ['unfreeze','freeze -d','melt','fcat'] ],
['Z',    &do_uncompress, ['uncompress','gzip -d','zcat'] ],
['gz',   &do_uncompress,  'gzip -d'],
['gz',   &do_gunzip],
['bz2',  &do_uncompress,  'bzip2 -d'],
['lzo',  &do_uncompress,  'lzop -d'],
['rpm',  &do_uncompress, ['rpm2cpio.pl','rpm2cpio'] ],
['cpio', &do_pax_cpio,   ['pax','gcpio','cpio'] ],
['tar',  &do_pax_cpio,   ['pax','gcpio','cpio'] ],
['deb',  &do_ar,          'ar'],
['zip',  &do_unzip],
['7z',   &do_7zip,       ['7zr','7za','7z'] ],
['rar',  &do_unrar,      ['rar','unrar'] ],
['arj',  &do_unarj,      ['arj','unarj'] ],
['arc',  &do_arc,        ['nomarch','arc'] ],
['zoo',  &do_zoo,        ['zoo','unzoo'] ],
['lha',  &do_lha,         'lha'],
['cab',  &do_cabextract,  'cabextract'],
['tnef', &do_tnef_ext,    'tnef'],
['tnef', &do_tnef],
['exe',  &do_executable, ['rar','unrar'], 'lha', ['arj','unarj'] ],
);

1;

First edit ‘main.cf’ file and add this line in it at the end of the file:

# Amavis Section
###############################################
content_filter = smtp-amavis:[127.0.0.1]:10024

Now edit ‘master.cf’ file in /etc/postfix directory and add these lines at the end of the file:

smtp-amavis unix        -       -       n       -       2       smtp
-o smtp_data_done_timeout=1200
-o disable_dns_lookups=yes
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_client_restrictions=
-o smtpd_helo_restrictions=
-o smtpd_sender_restrictions=
-o smtpd_recipient_restrictions=permit_mynetworks,reject
-o strict_rfc821_envelopes=yes

Now you need to restart amavisd and postfix daemons:

# /etc/init.d/amavisd start
# /etc/init.d/postfix restart

If you feel like testing use command ‘touch’ to create a file with ‘.exe’ extension and send that file using your favorite MUA ( Mail User Agent eg. Evolution ) as attachement, observe the actions by ‘tailing’ maillog file

# tail -f /var/log/maillog

SpamAssasin

Spamassassin is perl based tool used to detect spam in mail messages, it is detected by Amavisd-new by default making their integration as seamless as possible.

All you need to do in order to enable SpamAssassin is to install package and run the daemon, of course by default it will detect some spam, however you can always tweak it to your needs and desires.

In order to get the best of spamassassin edit ‘amavisd.conf’ file in /etc directory and modify or add these lines:

$sa_tag_level_deflt  = -999.0;
$sa_tag2_level_deflt = 5.0;
$sa_kill_level_deflt = 5.0;
$mailfrom_notify_admin     = "mohanc@$mydomain";
$mailfrom_notify_recip     = "mohanc@$mydomain";
$mailfrom_notify_spamadmin = "mohanc@$mydomain";
$mailfrom_to_quarantine = 'spam-quarantine';
$warnspamsender = 1;
$spam_quarantine_to = "mohanc@$mydomain";

Now edit ‘local.cf’ file in /etc/mail/spamassassin directory and modify or add these lines:

required_hits 5
rewrite_header Subject [SPAM]
report_safe 1
use_bayes 1
bayes_auto_learn 1
skip_rbl_checks 0
use_razor2 1
use_dcc 1
use_pyzor 1
ok_languages all
ok_locales all

Of course this is a sample ( working ) but it may not suit your need or preferences so browse the manual of spamassassin and amavisd-new for more information.

Restart spamassassin and amavisd-new daemon and enjoy.

# /etc/init.d/amavis restart
# /etc/init.d/spamassassin restart

ClamAV

Clam AntiVirus is an open source (GPL) anti-virus toolkit for UNIX, designed especially for e-mail scanning on mail gateways. It provides a number of utilities including a flexible and scalable multi-threaded daemon, a command line scanner and advanced tool for automatic database updates.

In order to enable ClamAV you need to install it as follows:

yum install clamav clamav-db clamd perl-Mail-ClamAV perl-ClamAV-Client

Once installed edit amavisd.con in /etc folder and add the following line at the end befor 1;

@av_scanners = (
['ClamAV-clamd',
&ask_daemon, ["CONTSCAN {}n", "/var/run/clamav/clamd.sock"],
qr/bOK$/m, qr/bFOUND$/m,
qr/^.*?: (?!Infected Archive)(.*) FOUND$/m ],
);

@av_scanners_backup = (
### http://www.clamav.net/   - backs up clamd or Mail::ClamAV
['ClamAV-clamscan', 'clamscan',
"--stdout --no-summary -r --tempdir=$TEMPBASE {}",
[0], qr/:.*sFOUND$/m, qr/^.*?: (?!Infected Archive)(.*) FOUND$/m ],
);

Postfwd

Postfwd is a very flexible Postfix policy server. It can check multiple RBLs and do all sorts of checking and scoring. It can be downloaded from http://www.postfwd.org/.

Once downloaded untar the application copy the postfwd perl excutable to /usr/sbin

cp postfwd-version/sbin/postfwd /usr/sbin/

once copied create a postfwd.cf in /etc/postfix and add following to it:

id=OK_DNSWL; 
rbl=list.dnswl.org/^127/43200; 
action=OK

id=SET_HELO; 
helo_name=^([|[^.]+$|.*?[0-9.-]{8}); 
action=set(HIT_helo=1)

id=SET_NODNS; 
client_name=^unknown$; 
action=set(HIT_nodns=1)

id=REJECT_HELO_NODNS; 
HIT_helo==1; HIT_nodns==1; 
action=REJECT Blocked - contact postmaster@mohancheema.net for help - Suspicious HELO [$$helo_name] and missing reverse DNS [$$client_address]

id=REJECT_RBL_ZEN; 
rbl=zen.spamhaus.org; 
action=REJECT Blocked - contact postmaster@mohancheema.net for help - DNSBL [$$dnsbltext]
&&DNSBLS { 
rbl=bl.spamcop.net; 
rbl=b.barracudacentral.org; 
rbl=bl.spameatingmonkey.net; 
rbl=dnsbl-1.uceprotect.net; 
rbl=psbl.surriel.com; 
rbl=combined.njabl.org; 
rbl=dnsbl.sorbs.net; 
rbl=ix.dnsbl.manitu.net; 
};

id=EVAL_DNSBLS; 
&&DNSBLS; rblcount=all; 
action=set(HIT_rbls=$$rblcount,HIT_dtxt=$$dnsbltext)

id=REJECT_RBL_MULTI; 
HIT_rbls>=2; 
action=REJECT Blocked - contact postmaster@mohancheema.net for help - Multiple DNSBLs [$$HIT_dtxt]
&&RHSBLS_REVERSE { 
rhsbl_reverse_client=dynamic.rhs.mailpolice.com; 
};
&&RHSBLS_SENDER { 
rhsbl_sender=dbl.spamhaus.org; 
rhsbl_sender=multi.uribl.com; 
rhsbl_sender=multi.surbl.org; 
rhsbl_sender=rhsbl.ahbl.org; 
rhsbl_sender=rhsbl.sorbs.net; 
rhsbl_sender=dsn.rfc-ignorant.org; 
};

id=EVAL_RHSBLS; 
&&RHSBLS_REVERSE; &&RHSBLS_SENDER; rhsblcount=all; 
action=set(HIT_rhsbls=$$rhsblcount,HIT_rtxt=$$dnsbltext)

id=REJECT_RHSBL_MULTI; 
HIT_rhsbls>=2; 
action=REJECT Blocked - contact postmaster@mohancheema.net for help - Multiple RHSBLs [$$HIT_rtxt]

id=REJECT_RBL_RHSBL; 
HIT_rbls>=1; HIT_rhsbls>=1; 
action=REJECT Blocked - contact postmaster@mohancheema.net for help - RHSBL and DNSBL [$$HIT_rtxt] [$$HIT_dtxt]

id=REJECT_RBL_HELO; 
HIT_rbls>=1; HIT_helo==1; 
action=REJECT Blocked - contact postmaster@mohancheema.net for help - DNSBL [$$HIT_dtxt] and suspicious HELO [$$helo_name]

id=REJECT_RBL_NODNS; 
HIT_rbls>=1; HIT_nodns==1; 
action=REJECT Blocked - contact postmaster@mohancheema.net for help - DNSBL [$$HIT_dtxt] and missing reverse DNS [$$client_address]

id=REJECT_RHSBL_HELO; 
HIT_rhsbls>=1; HIT_helo==1; 
action=REJECT Blocked - contact postmaster@mohancheema.net for help - RHSBL [$$HIT_rtxt] and suspicious HELO [$$helo_name]

id=REJECT_RHSBL_NODNS; 
HIT_rhsbls>=1; HIT_nodns==1; 
action=REJECT Blocked - contact postmaster@mohancheema.net for help - RHSBL [$$HIT_rtxt] and missing reverse DNS [$$client_address]

id=GREY_HELO; HIT_helo==1; action=check_postgrey

id=GREY_NODNS; HIT_nodns==1; action=check_postgrey

id=GREY_RBL; HIT_rbls>=1; action=check_postgrey

id=GREY_RHSBL; HIT_rhsbls>=1; action=check_postgrey

&&DNSBLS_GREY { 
rbl=dnsbl-2.uceprotect.net; 
rbl=dnsbl-3.uceprotect.net; 
};

id=GREY_DNSBL; &&DNSBLS_GREY; action=check_postgrey

Now copy the init script to /etc/init.d/:

cp postfwd-version/bin/postfwd-script.sh /etc/init.d/postfwd

Now edit the main.cf located in /etc/postfix/ and add follwing line in smtpd_recipient_restrictions section just above the permit:

check_policy_service inet:127.0.0.1:10040,

It should look like this:

smtpd_recipient_restrictions =
reject_non_fqdn_sender,
reject_non_fqdn_recipient,
reject_unknown_sender_domain,
reject_unknown_recipient_domain,
permit_mynetworks,
reject_unauth_destination,
reject_rbl_client opm.blitzed.org,
reject_rbl_client list.dsbl.org,
reject_rbl_client sbl.spamhaus.org,
reject_rbl_client cbl.abuseat.org,
reject_rbl_client dul.dnsbl.sorbs.net,
check_policy_service inet:127.0.0.1:10040,
permit

Now start the postfwd and restart the postfix as follows:

/etc/init.d/posfwd start
service postfix restart

Postgrey

Postgrey implements greylisting robustly. It has an auto-whitelist feature, which is very handy. Get the latest copy from http://postgrey.schweikert.ch/

Now run the following on command prompt:

# groupadd postgrey
# useradd -g postgrey postgrey
# mkdir /var/postgrey
# chown postgrey:postgrey /var/postgrey
# chmod 700 /var/postgrey

Just copy files like this:

$ tar xvfz postgrey-version.tar.gz
$ cd postgrey-version
# cp postgrey /usr/local/sbin/
# cp postgrey_whitelist_clients /usr/local/etc/
# cp postgrey_whitelist_recipients /usr/local/etc/
# chown postgrey:postgrey /var/postgrey -R

To speed up the database, you can create file /var/postgrey/DB_CONFIG

set_cachesize 0 16777216 1
set_flags DB_TXN_NOSYNC

All configuration options are passed to binary in init-script. Read the documentation.

Now start the postgrey

/etc/init.d/postgrey start

Now edit the main.cf and add the following line:

smtpd_restriction_classes = check_postgrey

Restart postfix:

service postfix restart

That’s it you now have your postfix running with LDAP and anti virus and anti spam checks.

Note: In order to get emails delivered to user make sure you do su – username after you add them to LDAP so that home folder is created else emails will not get delivered to user.

Be the first to comment

Leave a Reply

Your email address will not be published.


*


CommentLuv badge