Qmail, Vpopmail, Webmail and Spam Scanning setup

This is under construction but I put up the plain text file to get started, as I get time I will start converting this to html format and tidying it up so it is a little more readable and has links back to the various sources, patches and sites that I got the software used in this setup.

If you find this helpful or would like to add comments to it then please feel free to drop me an e-mail at steve at focb dot co dot nz

qmail setup for somehost.co.nz

Most of the qmail files used for this installation can be found at
http://www.qmail.org

The following was done on a RedHat 9.0 box

first as root, run the following script to create the
qmail directory and userid's/group id's

-- script start --
#!/bin/bash
#
# script to create qmail ID's and groups

mkdir /var/qmail

groupadd nofiles
useradd -g nofiles -d /var/qmail/alias alias
useradd -g nofiles -d /var/qmail qmaild
useradd -g nofiles -d /var/qmail qmaill
useradd -g nofiles -d /var/qmail qmailp
groupadd qmail
useradd -g qmail -d /var/qmail qmailq
useradd -g qmail -d /var/qmail qmailr
useradd -g qmail -d /var/qmail qmails

-- end script --

untar the qmail sources (tar -zxvf qmail-1.03.tar.gz) and then change into the qmail directory

cd qmail-1.03

apply various patches to the qmail sources.

for this installation we applied

big-concurrency.patch  (patch -p1 < ../patches/big-concurrency.patch)
big-todo.103.patch  (patch -p1 < ../patches/big-todo.103.patch)
qmailqueue-patch  (patch -p1 < ../patches/qmailqueue-patch)
date-localtime  (patch -p1 < ../patches/qmail-date-localtime.patch)
smtp auth and ttls  (patch -p1 < ../patches/qmail-1.03-starttls-smtp-auth.patch)
null envelope sender  (patch -p1 < ../patches/nullenvsender-recipcount.patch)

--  NOTE : Hunk 1 failed, this will require manual patching as follows
vi qmail-smtpd.c

Search for the lines
 void err_bmf() { out("553 sorry, your envelope sender is in my badmailfrom list (#5.7.1)\r\n"); }
 void err_nogateway() { out("553 sorry, that domain isn't in my list of allowed rcpthosts (#5.7.1)\r\n"); }

and add the line

 void err_badbounce() { out("550 sorry, bounce messages should have a single envelope recipient (#5.7.1)\r\n"); }

Save and exit

tarpitting patch  (qmail-1.03]# patch -p0 < ../patches/tarpit.patch)

Note: Three hunks fail on this patch - manual patching is required as follows
edit  qmail-smtp.c

vi qmail-smtp.c

Search for 

 int flagbarf; /* defined if seenmail */
 stralloc mailfrom = {0};
 stralloc rcptto = {0};

and then add 

 int rcptcount;

after these lines, then search for

 if (!stralloc_copys(&rcptto,"")) die_nomem();
 if (!stralloc_copys(&mailfrom,addr.s)) die_nomem();
 if (!stralloc_0(&mailfrom)) die_nomem();

and then add

 rcptcount = 0;

after these lines, then search for

 if (!stralloc_cats(&rcptto,"T")) die_nomem();
 if (!stralloc_cats(&rcptto,addr.s)) die_nomem();
 if (!stralloc_0(&rcptto)) die_nomem();

and add 

 if (tarpitcount && ++rcptcount >= tarpitcount) while (sleep(tarpitdelay));

after it

Oversized DNS packets patch  (patch -p1 < ../patches/qmail-103-oversizedDNS.txt)
mfpatch  (patch -p1 < ../patches/qmail-1.03-mfcheck.3.patch)

Here we have to edit three files

vi Makefile

search for the line

 timeoutwrite.o ip.o ipme.o ipalloc.o control.o constmap.o received.o \
 date822fmt.o now.o qmail.o cdb.a fd.a wait.a datetime.a getln.a \
 open.a sig.a case.a env.a stralloc.a alloc.a substdio.a error.a str.a \

and change the line that is below this to read

 fs.a auto_qmail.o base64.o socket.lib dns.o dns.lib

and then the line at the end of the ./load command to read

 socket.lib` dns.o `cat dns.lib` -lssl -lcrypto

then edit qmail-smtp.c

vi qmail-smtp.c

search for the line

 #include "commands.h"

and add the line

 #include "dns.h"

underneith, then search for

 #define MAXHOPS 100
 unsigned int databytes = 0;

and add

 unsigned int mfchk = 0;

under this line.

We also need to patch qmail to support the newer glibc that comes 
with later versions of redhat - this is needed if running redhat 8.0 or
newer or if you get a compile error such as follows..

substdio.a(substdo.o)(.text+0x43): In function `allwrite':
: undefined reference to `errno'
collect2: ld returned 1 exit status
make: *** [auto-str] Error 1

glibc 2.3.1 errno patch  (patch -p0 < ../patches/errno.patch)


This should conclude all the patching for qmail.

now edit  conf-spawn and set the   number in  there (default 1000) to 500

vi conf-spawn
cw 500
:wq

edit conf-cc and add

 -I/usr/kerberos/include

to the end of the first line

After this we compile the qmail software with the command

"make setup check"

This will compile all the various modules that make up a qmail installation 
and then install them into /var/qmail

next we run ./config-fast  to setup the default configuration control 
files.

now it is time to setup the daemon tools package which will act as a wrapper to
spawn the qmail smtpd processes and the pop3 server

untar the daemontools package and change into the admin/daemontools-0.76 directory

tar zxvf daemontools-0.76.tar.gz
cd admin/daemontools-0.76

edit src/error.h
change the line that states..

extern int errno;

to 

#include 

save and exit then type

package/install

this will compile and install the daemontools package
now we will compile and install the ucspi-tcp package

un tar the package, change to the directory created and compile.

tar -zxvf ucspi-tcp-0.88.tar.gz 
as above, edit error.h and change the line

extern int errno;

to 

#include 

save and exit then type

make
make setup check

Next we download and install the Mysql 4.0.x rpms from http://www.mysql.com
save these in their own directory

first, download the following rpm's
 
MySQL-server-4.0.14-0.i386.rpm 
MySQL-devel-4.0.14-0.i386.rpm 
MySQL-client-4.0.14-0.i386.rpm 
MySQL-shared-compat-4.0.14-0.i386.rpm

then install with rpm -ivh *

set a mysql root password as advised.

Setup and install Apache+PHP

For this we use apache 1.3.28, but 2.0.x could be used as well.
PHP is not required for standard operation but we'll install it incase at
a later point we want to write our own "webmail chooser" or management frontend
- we also install mod_ssl

get apache from http://www.apache.org
get php from http://www.php.net
get mod_ssl from http://www.modssl.org

save these into their own directory

untar tar apache, php and mod_ssl

tar -zxvf apache_1.3.28.tar.gz 
tar -zxvf mod_ssl-2.8.15-1.3.28.tar.gz
tar -zxvf php-4.3.2.tar.gz

change to the mod_ssl directory

./configure --with-apache=../apache_1.3.28

now change to the apache directory

./configure \
  --with-layout=RedHat \
  --enable-module=most \
  --enable-module=ssl

now change to the PHP directory

(you will have to have the imap and imap-devel packages installed from the
 redhat 9.0 distribution cd's and the mcrypt libraries from 
 http://rpmfind.net/linux/RPM/freshrpms/ayo/redhat/9/i386/RPMS.freshrpms/libmcrypt-devel-2.4.22-fr3.i386.html
 and
 http://rpmfind.net/linux/RPM/freshrpms/ayo/redhat/9/i386/RPMS.freshrpms/libmcrypt-2.4.22-fr3.i386.html )

./configure \
  --with-apache=../apache_1.3.28 \
  --prefix=/usr \
  --with-config-file-path=/etc/httpd/conf \
  --with-zlib \
  --enable-bcmath \
  --enable-calendar \
  --with-dom \
  --with-mcrypt \
  --enable-ftp \
  --with-kerberos \
  --with-imap-ssl \
  --with-imap \
  --with-mysql=/usr

now compile php and install the module.

make
make install

change to the apache directory and compile apache with the php and mod_ssl modules

CFLAGS="-I/usr/kerberos/include" \
./configure \
  --with-layout=RedHat \
  --enable-module=most \
  --activate-module=src/modules/php4/libphp4.a \
  --enable-module=ssl

make

next we need to make an SSL certificate - at this point we will just make up a dummy
certificate - at a later point we can get a real one if required.

make certificate TYPE=test

The following are the settings to use

Algorithm = RSA
Country = NZ
State = Albany
Locality = Auckland
Organisation = somehost.co.nz
Unit = Mail Server
FQDN = mail.somehost.co.nz
E-Mail = webmaster@somehost.co.nz
Validity = 365
Version = 3
Do not encrypt the private key

make install

edit /etc/httpd/conf/httpd.conf

we need to add the PHP support to the config file - we will do
this in the same place that cgi support is enabled.

We will also add index.php to the list of files to use as an index

search for the string DirectoryIndex and add "index.php" to the end of this line

Next search for the string AddHandler cgi-script .cgi , delete the # at the start
of this line and underneith it add the following lines..

AddType application/x-httpd-php .php
AddType application/x-httpd-php-source .phps

copy the php.ini-dist file from the php source directory to /etc/httpd/conf

now install vpopmail

untar the vpopmail source and change into that directory

add a user called "vpopmail" which will be used for talking to the mail
database

mysql -u root -p
mysql> GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP,INDEX,ALTER ON vpopmail.* TO vpopmail@localhost IDENTIFIED BY 'password';
mysqladmin -u root -p flush-privileges

edit vmysql.h

put the information associated with the vpopmail mysql account just created into
the defines at the top of this file.

add the vpopmail user and group

groupadd -g 89 vchkpw
useradd -g vchkpw -u 89 -d /var/spool/vpopmail vpopmail

now  run configure with options

./configure \
  --enable-valias=y \
  --enable-clear-passwd=y \
  --enable-mysql=y \
  --enable-qmail-ext=y \
  --enable-domainquotas=y \
  --enable-ip-alias-domains=y \
  --enable-vpopuser=vpopmail \
  --enable-vpopgroup=vchkpw \
  --enable-roaming-users=y \
  --enable-relay-clear-minutes=180 \
  --enable-learn-passwords=y

The following is an SQL script that will create the necessary tables in 
the vpopmail database

-- cut SQL script --
create table dir_control ( 
  domain varchar(255) not null, 
  cur_users int, 
  level_cur int, 
  level_max int, 
  level_start0 int, 
  level_start1 int, 
  level_start2 int, 
  level_end0 int, 
  level_end1 int, 
  level_end2 int, 
  level_mod0 int, 
  level_mod1 int, 
  level_mod2 int, 
  level_index0 int, 
  level_index1 int, 
  level_index2 int, 
  the_dir varchar(255), 
  primary key (domain) 
);


/* for small site with clear passwords */
create table vpopmail (
  pw_name char(32) not null, 
  pw_domain varchar(223) not null, 
  pw_passwd varchar(255) not null, 
  pw_uid int, 
  pw_gid int, 
  pw_gecos varchar(255), 
  pw_dir varchar(255), 
  pw_clear_passwd varchar(255), 
  pw_shell varchar(255), 
  primary key(pw_name, pw_domain)
);
  
create table relay (
  ip_addr char(18) not null, 
  timestamp int(32), 
  primary key(ip_addr)
);

create table ip_alias_map (
  ip_addr char(18) not null, 
  domain varchar(255),  
  primary key(ip_addr) 
);

create table last_auth (
  pw_user char(32) NOT NULL, 
  pw_domain varchar(223) NOT NULL,
  remote_ip char(18) not null,
  timestamp int(32) DEFAULT 0 NOT NULL,
  primary key (pw_user, pw_domain)
);
-- end SQL script --

save this as vpopmail.sql
we now create the tables

mysql -uroot -p vpopmail < vpopmail.sql

now create and install the vpopmail binaries

make
make install-strip

now setup a default access file

echo "10.1.1.:allow,RELAYCLIENT=\"\"" >> ~vpopmail/etc/tcp.smtp

add the following to cron

crontab -e
40 * * * * /var/spool/vpopmail/bin/clearopensmtp 2>&1 > /dev/null

Setup the service entries

in the /service directory, create the following directories

mkdir /service/qmail-pop3d
mkdir /service/qmail-smtpd
mkdir /service/qmail-send

then log directories under these

mkdir /service/qmail-pop3d/log
mkdir /service/qmail-smtpd/log
mkdir /service/qmail-send/log

then under each directory create the following files

-- pop3d --
vi /service/qmail-pop3d/run

#!/bin/sh
env - PATH="/var/qmail/bin:/usr/local/bin" \
      tcpserver -c 400 -H -R 0 pop-3 \
      /var/qmail/bin/qmail-popup mail.somehost.co.nz \
      /var/spool/vpopmail/bin/vchkpw /var/qmail/bin/qmail-pop3d Maildir 

vi /service/qmail-pop3d/log/run

#!/bin/bash

exec /var/qmail/bin/splogger pop3d 2

-- smtpd --
vi /service/qmail-smtpd/run

#!/bin/sh
QMAILDUID=`id -u qmaild`
NOFILESGID=`id -g qmaild`
MAXSMTPD=`cat /var/qmail/control/concurrencyincoming`
QMAILQUEUE="/var/qmail/bin/qmail-scanner-queue.pl"
export QMAILQUEUE

exec /usr/local/bin/softlimit -m 20000000 \
     /usr/local/bin/tcpserver -v -R -l 0 -x ~vpopmail/etc/tcp.smtp.cdb -c "$MAXSMTPD" \
     -u "$QMAILDUID" -g "$NOFILESGID" 0 smtp \
     /usr/local/bin/rblsmtpd -t 10 \
     -b -r relays.osirusoft.com \
     /var/qmail/bin/qmail-smtpd \
     2>&1 | /var/qmail/bin/splogger smtpd 2 

vi /service/qmail-smtpd/log/run

#!/bin/bash

exec /var/qmail/bin/splogger smtpd 2

-- send --
vi /service/qmail-send/run

#!/bin/sh
QMAILQUEUE="/var/qmail/bin/qmail-scanner-queue.pl"
export QMAILQUEUE

exec /var/qmail/rc

vi /service/qmail-send/log/run

#!/bin/bash

exec /var/qmail/bin/splogger send 2

-- end --

next change the mode of these run files so they are executable

find /service -name 'run' -exec chmod 755 {} \;

make the qmail logs directory

mkdir /var/log/qmail
chown -R qmaill:nofiles /var/log/qmail

edit /var/qmail/rc

#!/bin/sh

# Using stdout for logging
# Using control/defaultdelivery from qmail-local to deliver messages by default

exec env - PATH="/var/qmail/bin:$PATH" \
qmail-start "`cat /var/qmail/control/defaultdelivery`"

save this and make it executable.

chmod 755 /var/qmail/rc

edit /var/qmail/control/defaultdelivery

it should contain a single line

./Maildir

at this point we should have a working qmail installation - however, we 
need to add the qmail-scanner program

-- no point in adding qmail scanner unless we are actually going to use 
it for something - so lets at least get it doing spam scanning.

Add spamassassin support

Before starting we should set out default language to standard C - if we dont all
sorts of compile problems start happening.

edit /etc/profile

scroll to the end of thte file and add the following two lines.

LANG=C
export LANG

save and exit then reload this file by typing

. /etc/profile

now, download and install the redhat 9.0 perl-HTML-Parser-3.26-17.i386.rpm
RPM - this has problems compiling under RedHat 9.0 - this is supplied on the RedHat 
distribution CD's (you will also need perl-HTML-Tagset and the suid perl package)

for this we will use the perl CPAN installation. CPAN setup will vary depending on
location but these settings should work for most people.

start the CPAN shell

perl -MCPAN -e shell

now configure cpan for first time use.

Are you ready for manual configuration? [yes] 
CPAN build and cache directory? [/root/.cpan] 
Cache size for build directory (in MB)? [10] 
Perform cache scanning (atstart or never)? [atstart] 
Cache metadata (yes/no)? [yes] 
Your terminal expects ISO-8859-1 (yes/no)? [yes] 
Policy on building prerequisites (follow, ask or ignore)? [ask] follow 
Where is your gzip program? [/bin/gzip] 
Where is your tar program? [/bin/tar] 
Where is your unzip program? [/usr/bin/unzip] 
Where is your make program? [/usr/bin/make] 
Warning: links not found in PATH
Where is your links program? [] 
Where is your wget program? [/usr/bin/wget] 
Warning: ncftpget not found in PATH
Where is your ncftpget program? [] 
Warning: ncftp not found in PATH
Where is your ncftp program? [] 
Where is your ftp program? [/usr/bin/ftp] 
What is your favorite pager program? [/usr/bin/less] 
What is your favorite shell? [/bin/bash] 
Your choice:  [] 
Your choice:  [] 
Your choice:  [] UNINST=1 
Timeout for inactivity during Makefile.PL? [0] 
Your ftp_proxy?  
Your http_proxy?  
Your no_proxy?  

CPAN will now fetch a list of mirror sites to use

being in New Zealand we choose options 5 and 6

Select your continent (or several nearby continents) [] 5 6 

then North America, Australia, New Zealand

Select your country (or several nearby countries) []  3 4 5 

put them on one line, separated by blanks [] 1 2 3 4 5

then

   [wait://ls6-www.informatik.uni-dortmund.de:1404] 

now we install the SpamAssassin modules

cpan> install Mail::SpamAssassin

This should download and install all dependancies and compile SpamAssassin, 
any questions asked during the install just press 

now intall Time::HiRes

cpan> install Time::HiRes

install DB_File

cpan> install DB_File

now we download maildrop

download maildrop from

http://flow.dl.sourceforge.net/sourceforge/sourceforge/sourceforge/courier/maildrop-1.5.3.tar.bz2

unzip this and then compile it with default options

./configure
make
make install-strip

and the tnef unpacker, again, use the default options

(download from http://flow.dl.sourceforge.net/sourceforge/tnef/tnef-1.2.1.tar.gz )

./configure
make
make install

Add spamd to the system startup file (better way to do this would be to write an
init script but its late :-) )

vi /etc/rc.d/rc.local

add to end of file

# Start the spam assassin daemon

/usr/bin/spamd -d -L -x -u spamc


Add the spamc user

useradd spamc

Start spamd by running the above command.

/usr/bin/spamd -d -L -x -u spamc

now unpack the qmail-scanner sources and change into the directory

./configure \
--notify "none" \
--install

This should have setup qmail-scanner under /var/qmail/bin and put the log
files for this under /var/spool/qmailscan


still to do

courier-imap
web cgi tools
(vqadmin, qmailadmin)
webmail
init scripts for httpd, qmail, courier, mysql

Now that we have the base system setup we download an IMAP server
and will use this for our webmail system.

We are going to use Binc-IMAP due to its nice intergration with the
daemon tools system which makes life quite easy when it comes to figuring
out how the various daemons are setup.

You can download binc-imap from http://www.bincimap.andreas.hanssen.name/

Binc IMAP

./configure \
--prefix=/usr/local/bincimap \
--sysconfdir=/etc/bincimap

make
make install

--

Now for a web client or two - we will install a couple.

IS Mail from inside systems
http://www.insidesystems.net/projects/project.php?projectid=4

This has support for multiple domains - yet has a downfall in that it
requires a user to select their domain from a list of possible ones and hence
allows one to know what domains are kept on the box.

The advantage is that it is very simple to use and has a nice looking interface.

Squirrel Mail
http://www.squirrelmail.org

One of the more popular webmail clients - this is feature rich but can sometimes
confuse users with the wealth of features it offers.


The Binc IMAP server acts as a cross between a UW Imap server and a courier Server
The main mailbox is INBOX and sub folders are created off this, the delimiter is
a / instead of a . however.


SquirrelMail

ISMail


download qmailadmin, autorespond and ezmlm

wget http://www.inter7.com/devel/qmailadmin-1.0.24.tar.gz
wget http://www.inter7.com/devel/autorespond-2.0.3.tar.gz
wget http://cr.yp.to/software/ezmlm-0.53.tar.gz

unpack the auto-responder
compile and install

make
cp autorespond /usr/local/bin

unpack the ezmlm list software
edit the config and install

vi conf-man

set man path to /usr/share/man

vi conf-bin

set binary paths to /usr/local/bin

make
make man
make setup

change into the qmail admin directory

./configure \
--enable-cgibindir=/var/www/cgi-bin \
--enable-vpopuser=vpopmail \
--enable-vpopgroup=vchkpw \
--enable-ezmlmdir=/usr/local/bin \
--enable-domain-autofill=Y \
--enable-modify-quota=y

now compile and install

make
make install-strip

-- notes --
6. If you want to set per domain limits on the number of:

        a) pop accounts  
        b) aliases
        c) forwards
        d) mailing lists 
        e) autoresponders

 Then create a .qmailadmin-limits file in the virtual domain directory
 for the domain you wish to limit. The syntax of the .qmailadmin-limits
 file is as follows:

maxpopaccounts          X
maxaliases              X
maxforwards             X
maxmailinglists         X
maxautoresponders       X

Where X is the maximum number you wish. Be sure the vpopmail user
has read permissions to this file. The default is unlimited.
   
If you set any of the above values to 0 it will effectually disable
that part of the menu and that feature.
-- end notes --

vqadmin

download vqadmin from http://www.inter7.com/devel/vqadmin-2.3.5.tar.gz

untar this and change to the vqadmin directory

./configure --enable-cgibindir=/var/www/cgi-bin

make
make install-strip

edit the apache config  file

vi /etc/httpd/conf/httpd.conf

look for the section that describes the cgi-bin directory permissions
and then add the following lines, save, exit and restart apache

    
        deny from all
        Options ExecCGI
        AllowOverride AuthConfig
        Order deny,allow
    

apachectl stop
apachectl startssl

Now edit /var/www/cgi-bin/vqadmin/.htaccess

add the following

AuthType Basic
AuthUserFile /var/www/auth/vqadmin.passwd
AuthName vQadmin
require valid-user
satisfy any

save and exit

chmod 600 /var/www/cgi-bin/vqadmin/.htaccess
chown nobody /var/www/cgi-bin/vqadmin/.htaccess
mkdir /var/www/auth
htpasswd -bc /var/www/auth/vqadmin.passwd admin

set an admin password.

now you should be able to browse to http://mail.somehost.co.nz/cgi-bin/vqadmin/vqadmin.cgi
for vpopmail administration.