The Perfect SpamSnake - Ubuntu Jaunty Jackalope - Page 2

10. Apache2

apt-get install apache2 apache2-suexec apache2-doc apache2-mpm-prefork apache2-utils libexpat1

Next we install PHP5 as an Apache module:

aptitude install libapache2-mod-php5 php5 php5-common php5-curl php5-dev php5-gd php5-idn php-pear php5-imagick php5-imap php5-mcrypt php5-memcache php5-mhash php5-ming php5-mysql php5-pspell php5-recode php5-snmp php5-sqlite php5-tidy php5-xmlrpc php5-xsl

Next we edit /etc/apache2/mods-available/dir.conf and change the DirectoryIndex line:

<IfModule mod_dir.c>

          #DirectoryIndex index.html index.cgi index.php index.xhtml index.htm
          DirectoryIndex index.html index.htm index.shtml index.cgi index.php index.php3 index.xhtml


Now we have to enable some Apache modules (rewrite, suexec, include)

a2enmod rewrite
a2enmod suexec
a2enmod include

Restart Apache:

/etc/init.d/apache2 restart

11. Postfix and MySQL

Install the packages:

apt-get install postfix postfix-mysql postfix-doc mysql-server mysql-client procmail


You will be asked to provide a password for the MySQL root user - this password is valid for the user [email protected] as well as [email protected], so we don't have to specify a MySQL root password manually later on:

New password for the MySQL "root" user: <-- yourrootsqlpassword
Repeat password for the MySQL "root" user: <-- yourrootsqlpassword


You will be asked two questions. Answer as follows:

General type of mail configuration: <-- Internet Site
System mail name: <--

We want MySQL to listen on all interfaces, not just localhost, therefore we edit /etc/mysql/my.cnf and comment out the line bind-address =

# Instead of skip-networking the default is now to listen only on
# localhost which is more compatible and is not less secure.
#bind-address           =

Then we restart MySQL:

/etc/init.d/mysql restart

Now check that networking is enabled. Run

netstat -tap | grep mysql

The output should look like this:

tcp        0      0 *:mysql                 *:*                     LISTEN      4318/mysqld

Stop Postfix:

postfix stop

We'll want to edit Postfix with the below:


We need to add two items below the pickup service type. The pickup service "picks up" local mail (local meaning "on this machine") and delivers it. This is a way to bypass content filtering for mail generated by this machine.

It should look like this when you are done:

pickup    fifo  n       -       -       60      1       pickup
         -o content_filter=
         -o receive_override_options=no_header_body_checks


postconf -e "alias_maps = hash:/etc/aliases"
postconf -e "myorigin ="
postconf -e "myhostname ="
postconf -e "mynetworks =,"
postconf -e "message_size_limit = 10485760"
postconf -e "local_transport = error:No local mail delivery"
postconf -e "mydestination = "
postconf -e "local_recipient_maps = "
postconf -e "virtual_alias_maps = hash:/etc/postfix/virtual"

Create /etc/postfix/virtual and add the following:

postmaster [email protected]
abuse [email protected]
root [email protected]


postmap /etc/postfix/virtual
postconf -e "relay_recipient_maps = hash:/etc/postfix/relay_recipients"

Create /etc/postfix/relay_recipients and add the following: OK OK


postmap /etc/postfix/relay_recipients
postconf -e "transport_maps = hash:/etc/postfix/transport"

Create /etc/postfix/transport and add the following: smtp:[192.168.0.x] smtp:[192.168.0.x]


postmap /etc/postfix/transport
postconf -e "relay_domains = hash:/etc/postfix/relay_domains"

Create /etc/postfix/relay_domains and add the following: OK OK


postmap /etc/postfix/relay_domains
postconf -e "smtpd_helo_required = yes"
postconf -e "smtpd_sender_restrictions = reject_non_fqdn_sender, reject_unknown_sender_domain, permit"
postconf -e "smtpd_recipient_restrictions = reject_non_fqdn_sender, reject_non_fqdn_recipient, reject_unknown_recipient_domain, permit_mynetworks, reject_unauth_destination, reject_unauth_pipelining, reject_rbl_client, reject_rbl_client, permit"
postconf -e "smtpd_data_restrictions = reject_unauth_pipelining"

Let's take a final look at the Postfix configuration:

less /etc/postfix/

Check the contents of the file for errors and repair if needed. Fire up Postfix:

postfix start

Check that Postfix responds:

telnet 25

You should see:

220 [yourFQDNhere] ESMTP Postfix (Ubuntu)

12. MailScanner Razor Pyzor DCC Clamav Installation

apt-get install mailscanner razor pyzor clamav-daemon

Let's start with MailScanner. The MailScanner that was just installed from the repositories is a very old version so we will now remove it and install the MailScanner package from source. The above is done to install the dependencies only.

apt-get remove mailscanner

Download into /usr/src/mailscanner/ and run:

tar xvfz MailScanner-install-4.75.11-1.tar.gz
cd MailScanner-install-4.75.11

Disable the default MailScanner:

mv /etc/MailScanner /etc/MailScanner.dist

Share this page:

Suggested articles

2 Comment(s)

Add comment



Update for Ubuntu / Debian:

The default debian system does not have a /var/lock/susbsys, and in a normal chroot - it needs to be created before the MailWasher Daemon starts:

I have amended the required change => /etc/rc2.d/S20mailscanner

16.2 Fix to Disable Permission Checks on MailScanner Directories

Edit /etc/rc2.d/S20mailscanner to look like:

check_dir /var/spool/MailScanner       ${user:-postfix} ${group:-postfix}
check_dir /var/lib/MailScanner         ${user:-postfix} ${group:-postfix}
check_dir /var/run/MailScanner         ${user:-postfix} ${group:-postfix}
check_dir /var/lock/subsys             ${user:-root}    ${group:-root}
check_dir /var/lock/subsys/MailScanner ${user:-postfix} ${group:-postfix}
In the file /etc/default/mailscanner, make sure this parameter is at 1:
The logic of the above is made apparent when you see the rest of the /etc/rc2.d/S20mailscanner file contents:

    if [ ! -d $1 ]; then
        mkdir -p "$1" || \
            fail "directory $1: does not exist and cannot be created"
    actual="$(stat -c %U $1)"
    if [ "$actual" != "$2" ]; then
        chown -R "$2" "$1" || \
            fail "directory $1: wrong owner (expected $2 but is $actual)"
    actual="$(stat -c %G $1)"
    if [ "$actual" != "$3" ]; then
        chgrp -R "$3" "$1" || \
            fail "directory $1: wrong group (expected $3 but is $actual)"
user=$(echo $(awk -F= '/^Run As User/ {print $2; exit}' $CONFFILE))
group=$(echo $(awk -F= '/^Run As Group/ {print $2; exit}' $CONFFILE))
check_dir /var/spool/MailScanner       ${user:-postfix} ${group:-postfix}
check_dir /var/lib/MailScanner         ${user:-postfix} ${group:-postfix}
check_dir /var/run/MailScanner         ${user:-postfix} ${group:-postfix}
check_dir /var/lock/subsys             ${user:-root}    ${group:-root}  ## required to CREATE folder!
check_dir /var/lock/subsys/MailScanner ${user:-postfix} ${group:-postfix}

The above change avoids the need to dynamically add these directories through the slower use of /etc/rc.local (as I have seen Ubuntu / Debian MailScanner use as a 'solution' when they discovered that the MailScanner ( /var/xxx folders ) were lost after a reboot.

A lot of debian / ubuntu users use enhanced protection to the /var/xxx folder areas, and then it is normal to have to create 'real' chroot access across reboots.”

Spamsnake's author mentions the need to install clamav-module; this is an older perl module that is superseded by Ubuntu's clamav-daemon. The author is actually using this new daemon for mailwasher - evident by the
MailWasher.conf file with:

Virus Scanners = clamd                     ## clamav daemon use

So it not required to chase the older perl clamav-module; just get the latest Ubuntu clamav-daemon

aptitude install clamav-daemon

Notes: The clamav-daemon is faster than the previous perl
clamav-module! MailSanners own wiki states this change and recommended use.

Peter Bowey

By: Anonymous

I got this error after I do postmap /etc/postfix virtual:

postmap: fatal: /etc/postfix/, line 43: missing '=' after attribute name:  "postconf -e alias_maps = hash:etc/aliases"