Postfix as Relay - Step by Step instructions

This documentation is a long version showing all the steps needed to configure DSPAM as a relay. I mean, DSPAM server will be in DMZ accepting connections from outside, it will validate or not and pass them to the main mail server.

This documentation is inspired a lot from the documentation I found on this subject. I wrote it because documentations found were too short for me to understand all the concept or a bit to old.

References:

Before the tempest

You need

A fresh new unix based computer (I used FC2 and FC3 for this doc); to know reading!

There is a lot text editing in this document. If I didn't say nothing then text should be added if it is a search and replace i do something like:

- search-this-thing
+ replace-by-this-one

Needed packages installation

# apt-get install wget gcc tar gzip vim-enhanced gcc-c++ make db4-devel pcre-devel zlib-devel openssl-devel

Path setup to make things easier

# vim ~/.bash_profile
- PATH=$PATH:$HOME/bin
+ PATH=$PATH:$HOME/bin:/usr/local/bin/:/usr/local/apache2/bin
# . ~/.bash_profile

Users and group creation

# groupadd -g 2000 postfix
# groupadd -g 2001 mysql
# groupadd -g 2002 dspam
# groupadd -g 2003 apache
# groupadd -g 3000 postdrop
# useradd -u 2000 -g 2000 -d /var/empty -c "Postfix Server" -s /sbin/nologin postfix
# useradd -u 2001 -g 2001 -d /var/empty -c "MySQL Server" -s /sbin/nologin mysql
# useradd -u 2002 -g 2002 -d /var/empty -c "DSPAM Server" -s /sbin/nologin -G postdrop dspam
# useradd -u 2003 -g 2003 -d /var/empty -c "Apache Server" -s /sbin/nologin -G postdrop apache

Working directory creation

# mkdir -p /var/work/source
# mkdir -p /var/work/compile/configure

Downloading, compiling and starting MySQL-4.1.9

# cd /var/work/source
# wget http://mysql.secsup.org/Downloads/MySQL-4.1/mysql-4.1.9.tar.gz
# cd ../compile
# tar -zxf ../source/mysql-4.1.9.tar.gz
# cd mysql-4.1.9/
# vi ../configure/mysql
 #!/bin/sh
 ./configure --localstatedir=/var/mysql
# chmod 755 ../configure/mysql
# ../configure/mysql
# make && make install
# mkdir /var/mysql
# cp /usr/local/share/mysql/my-large.cnf /etc/my.cnf
# vim /etc/my.cnf
- log-bin
+ #log-bin
# mysql_install_db
# chown -R mysql:mysql /var/mysql/
# cp /usr/local/share/mysql/mysql.server /usr/local/bin
# mysql.server start

Checking that mysql is lanched:

# ps axf

So it is! We can now defined the root password:

# mysqladmin -u root password 'ROOTPASS'

In order not to have to type /'mysql -u root -p'/ each times we wants to logged in mysql; here is the tip:

# vi ~/.my.cnf
  [client]
  password=ROOTPASS
# chmod 400 ~/.my.cnf

You can validate this by executing /'mysql'/; if it aske you for a passord, they sould be a problem! We do this to start mysql at boot time:

# vi /etc/rc.local
  # start mysql
  /usr/local/bin/mysql.server start

Needed to be able to compile postfix:

# vi /etc/ld.so.conf
 /usr/local/lib/mysql
# ldconfig

Downloading, compiling and starting Postfix-2.2.2

# cd /var/work/source
# wget http://archive.mgm51.com/mirrors/postfix-source/official/postfix-2.2.2.tar.gz
# cd ../compile
# tar -zxf ../source/postfix-2.2.2.tar.gz
# cd postfix-2.2.2
# vim ../configure/postfix
  #!/bin/sh
  make -f Makefile.init makefiles \
       "CCARGS=-DHAS_MYSQL -I/usr/local/include/mysql" \
       "AUXLIBS=-L/usr/local/lib/mysql -lmysqlclient -lz -lm"
# chmod 755 ../configure/postfix
# ../configure/postfix
# make && make install
( answer default settings to all prompts )
# postfix start
( see that postfix starts )
# ps axf

We do this to start postfix at boot time:

# vi /etc/rc.local
  # start postfix
  /usr/sbin/postfix start

Downloading, compiling DSPAM-3.4.2

# cd /var/work/source
# wget http://www.nuclearelephant.com/projects/dspam/sources/dspam-3.4.2.tar.gz
# cd ../compile
# tar -zxf ../source/dspam-3.4.2.tar.gz
# cd dspam-3.4.2/
# vi ../configure/dspam
  #!/bin/sh
  ./configure \
        --with-dspam-home=/var/dspam \
        --with-dspam-home-mode=770 \
        --with-dspam-home-owner=dspam \
        --with-dspam-home-group=postdrop \
        --with-dspam-mode=2510 \
        --with-dspam-owner=dspam \
        --with-dspam-group=postfix \
        --with-delivery-agent=/usr/sbin/sendmail \
        --with-storage-driver=mysql_drv \
        --with-mysql-includes=/usr/local/include/mysql \
        --with-mysql-libraries=/usr/local/lib/mysql \
        --enable-preferences-extension \
        --enable-virtual-users \
        --enable-daemon \
        --enable-debug
# chmod 755 ../configure/dspam
# ../configure/dspam
# make && make install
# mkdir -p /usr/local/share/dspam/

Downloading, compiling Apache-2.0.53

# cd /var/work/source
# wget http://gulus.usherbrooke.ca/pub/appl/apache/httpd/httpd-2.0.53.tar.gz
# cd ../compile
# tar -zxf ../source/httpd-2.0.53.tar.gz
# cd httpd-2.0.53/
# vi ../configure/apache
  #!/bin/sh
  ./configure \
    --enable-rewrite \
    --enable-cgi \
    --disable-userdir \
    --enable-suexec \
    --with-suexec-caller=apache \
    --with-suexec-docroot=/var/www \
    --with-suexec-uidmin=1000 \
    --with-suexec-gidmin=1000 \
    --enable-ssl
# chmod 755 ../configure/apache
# ../configure/apache
# make && make install

Closer

We have now installed the main tools; we will now start configuration!

Mysql DSPAM user and database creation.

# cd /var/work/compile/dspam-3.4.2/src/tools.mysql_drv/
# mysql -e "create database dspam"
# mysql -e "grant all on dspam.* to dspam@localhost identified by 'DSPAMSQLPASS'"
# mysql dspam < mysql_objects-4.1.sql
# mysql dspam < virtual_user_aliases.sql
# cp purge-4.1.sql /usr/local/share/dspam/

(To keep your database nice and clean you will want to run this command nightly)

# crontab -e
   0 0 * * * /usr/local/bin/mysql -udspam -pDSPAMSQLPASS dspam < /usr/local/share/dspam/purge-4.1.sql

Postfix configuration

The following configuration steps will make your postfix act as a relay (not opened), uses DSPAM for users validation and forward mails to your real inside server.

# cd /etc/postfix/
# vi master.cf
( Add/Remove what is needed )
 smtp      inet  n       -       n       -       -       smtpd
    -o content_filter=dspam:
 dspam     unix  -       n       n       -       10      pipe
    flags=Rhqu user=dspam argv=/usr/local/bin/dspam --deliver=innocent --user ${recipient} -i -f ${sender} -- ${recipient}

Now replace the content of your main.cf by this one; and modifie the 4 lines (you'll see where) with your data

# vi main.cf
    queue_directory = /var/spool/postfix
    command_directory = /usr/sbin
    daemon_directory = /usr/libexec/postfix
    mail_owner = postfix
    unknown_local_recipient_reject_code = 550
    debug_peer_level = 2
    debugger_command =
             PATH=/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin
             xxgdb $daemon_directory/$process_name $process_id & sleep 5
    sendmail_path = /usr/sbin/sendmail
    newaliases_path = /usr/bin/newaliases
    mailq_path = /usr/bin/mailq
    setgid_group = postdrop
    html_directory = no
    manpage_directory = /usr/local/man
    sample_directory = /etc/postfix
    readme_directory = no
    # Modify to your need thoses 4 lignes
    mynetworks = 127.0.0.0/8 12.34.56.0/24
    myorigin = dspam.lab.infoglobe.ca
    mydomain = lab.infoglobe.ca
    virtual_mailbox_domains = dspam.lab.infoglobe.ca
    virtual_transport = lmtp:unix:/tmp/dspam.sock
    virtual_mailbox_maps = mysql:/etc/postfix/vmailbox.cf
    dspam_destination_recipient_limit = 1
    mydestination =
    local_recipient_maps =
    local_transport = error:local mail delivery is disabled
    unknown_local_recipient_reject_code = 550
    parent_domain_matches_subdomains =
        debug_peer_list smtpd_access_maps
    smtpd_recipient_restrictions =
        permit_mynetworks reject_unauth_destination
    relay_recipient_maps = hash:/etc/postfix/relay_recipients
    transport_maps = hash:/etc/postfix/transport
    alias_maps = hash:/etc/aliases
    relay_domains = $transport_maps
    smtpd_helo_required = yes
    disable_vrfy_command = yes
    biff = no
    empty_address_recipient = MAILER-DAEMON
    queue_minfree = 40000000
    message_size_limit = 20000000
    mailbox_size_limit = 100000000
    smtpd_banner = $myhostname ESMTP Postfix
    local_transport = local
# vi vmailbox.cf
  user = dspam
  password = DSPAMSQLPASS
  dbname = dspam
  query = SELECT username FROM dspam_virtual_uids WHERE username='%s'
  table = dspam_virtual_uids
  host = 127.0.0.1
  select_field = username
  where_field = username
  additiona_conditions =

Put every domain you want to relay mail for in the transport table, and what server to relay each one to. This will route mail for "domain.com" to the inside gateway machine. The [] forces Postfix to do no MX lookup.

# vi transport
   domain.com  smtp:[inside-gateway.domain.com]

Now we enter every valid e-mail address in the relay_recipient table. Any not found will get rejected right here. If you want to allow any e-mail address for a domain, leave off the user name. The right-hand "dummy" value must be present. It is ignored, but the file must be in name/value pairs.

# vi relay_recipients
   # domain1.com, three valid addresses
   foo@domain1.com dummy
   foo2@domain1.com dummy
   foo3@domain1.com dummy
   # domain2.com, one valid address
   foo@domain2.com dummy
   # domain3.com, allow any address
   @domain3.com dummy

Do not forget to use this each times you modifie one of theses files:

# postmap transport
# postmap relay_recipients

You need to setup an address that root mail goes to (not here!):

# vi aliases
   root: you@domain.com
# postalias aliases
# postfix reload
# tail /var/log/maillog

Verify you logs (# tail /var/log/maillog) that postfix started correctly.

Apache configuration

Add/modify the following to your apache configuration:

# vi /usr/local/apache2/conf/httpd.conf
   User apache
   Group apache
   AddHandler cgi-script .cgi
   # Modifie /dspam.example.com/ to your needs
   <VirtualHost *:443>
        DocumentRoot "/var/www/htdocs/dspam.example.com"
        ServerName dspam.example.com
        ServerAdmin webmaster@example.com
        ErrorLog /usr/local/apache2/logs/dspam.example.com-error_log
        TransferLog /usr/local/apache2/logs/dspam.example.com-access_log
        SSLEngine on
        SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL
        SSLCertificateFile /usr/local/apache2/conf/ssl.crt/dspam.crt
        SSLCertificateKeyFile /usr/local/apache2/conf/ssl.key/dspam.key
        RewriteEngine on
        RewriteRule ^/$ /dspam.cgi [R]
        SuexecUserGroup dspam dspam
        <Directory "/var/www/htdocs/dspam.example.com">
            Options FollowSymLinks ExecCGI
            AllowOverride None
            Order deny,allow
            Deny from all
            SSLRequireSSL
            AuthType Basic
            AuthName "DSPAM Control Center"
            AuthUserFile /var/www/etc/htpasswd
            Require valid-user
            Satisfy Any
        </Directory>
    </VirtualHost>

Here is the ssl certificate generation in order to be able to use https:

# openssl genrsa 1024 > /usr/local/apache2/conf/ssl.key/dspam.key
# chmod 400 /usr/local/apache2/conf/ssl.key/dspam.key
# openssl req -new -x509 -nodes -sha1 -days 365 \
        -key /usr/local/apache2/conf/ssl.key/dspam.key \
        > /usr/local/apache2/conf/ssl.crt/dspam.crt

Checking that apache starts correctly:

# apachectl startssl
# ps axf

Setting up the DSPAM web interface

# mkdir -p /var/www/etc/
# chown apache.dspam /var/www/etc/
Setup the password file for logging into the web interface:
# htpasswd -c /var/www/etc/htpasswd user@domain.com
# htpasswd /var/www/etc/htpasswd user2@domain.com

Create an administrative account (you'll be able in a few lines to edit a file containing the list of user with have access to admin interface; file is called /admins/):

# htpasswd /var/www/etc/htpasswd root

Replace /dspam.exemple.com/ by the path defined in your apache configuration:

# mkdir -p /var/www/htdocs/dspam.exemple.com
# chmod 555 /var/www/htdocs/dspam.exemple.com
# chown dspam.dspam /var/www/htdocs/dspam.example.com
# cd /var/www/htdocs/dspam.example.com
# cp -r /var/work/compile/dspam-3.4.2/cgi/* .
# rm -f Makefile*
# chown -R dspam.dspam *
# chmod 444 *.*
# chmod 554 *.cgi
# chmod 555 templates
# chmod 444 templates/*

You need to modifie 2 littles things:

# vi configure.pl
   $CONFIG{'LOCAL_DOMAIN'} = "YourDomain.com";
   $CONFIG{'DSPAM_HOME'}   = "/var/dspam";

And you need (for the configuration we choses (authentication with the domain name) to remove the domain:

# vi templates/nav_performance.html
- <strong>spam-$REMOTE_USER$@yourdomain.com</strong>
+ <strong>spam-$REMOTE_USER$</strong>

You should now be able to test the web interface! BUT graphics generation is not ready!...

Downloading, compiling and installing GD & Co.

# apt-get install libpng-devel libjpeg-devel
# cd /var/work/source
# wget http://www.boutell.com/gd/http/gd-2.0.33.tar.gz
# mkdir CPAN; cd CPAN
# wget http://www.perl.com/CPAN/modules/by-module/GD/GDGraph-1.43.tar.gz
# wget http://www.perl.com/CPAN/modules/by-module/GD/GDTextUtil-0.86.tar.gz
# wget http://www.perl.com/CPAN/modules/by-module/GD/GD-Graph3d-0.63.tar.gz
# wget http://www.perl.com/CPAN/modules/by-module/GD/GD-2.23.tar.gz
# cd ../../compile/
# tar xzf ../source/gd-2.0.33.tar.gz
# cd gd-2.0.33/
# vi ../configure/gd
  #!/bin/sh
  ./configure
# chmod 755 ../configure/gd
# ../configure/gd
# make
# make install
# cd ..
# mkdir CPAN; cd CPAN
# tar xzf ../../source/CPAN/GDGraph-1.43.tar.gz
# tar xzf ../../source/CPAN/GDTextUtil-0.86.tar.gz
# tar xzf ../../source/CPAN/GD-Graph3d-0.63.tar.gz
# tar xzf ../../source/CPAN/GD-2.23.tar.gz
# cd GD-2.23
# perl Makefile.PL
# make && make test
# make install
# cd ../GDTextUtil-0.86/
# perl Makefile.PL
# make && make test
# make install
# cd ../GDGraph-1.43/
# perl Makefile.PL
# make && make test
# make install
# cd ../GD-Graph3d-0.63/
# perl Makefile.PL
# make && make test
# make install

If you followed thoses steps graphics should be printed now!

The real thing

Edition of you DSPAM configuration file

"But why have you make me wait so long?!" Just to increase pleasure ;)

# vi /usr/l
811
ocal/etc/dspam.conf
+ Trust dspam
+ Trust apache
+ Trust postfix
+ AllowOverride localStore
 MySQLServer     /tmp/mysql.sock
 MySQLPort       3306
 MySQLUser               dspam
 MySQLPass               DSPAMSQLPASS
 MySQLDb                 dspam
 MySQLCompress           true

This prevents Postfix from needing to use any aliases for retraining. When users email spam-name@domain.com, DSPAM will automatically realize that it needs to retrain the message.

 ParseToHeaders on
 ChangeModeOnParse on
 ChangeUserOnParse off
 ServerQueueSize         32
 ServerPID               /var/run/dspam.pid
 ServerMode              standard
 ServerParameters        "--deliver=innocent"
 ServerIdent             "localhost.localdomain"
 ServerDomainSocketPath  /tmp/dspam.sock

Misc

Database cleanning

# crontab -e
0 0 * * * /usr/local/bin/mysql -u dspam -p'DSPAMPASS' dspam < /usr/local/share/dspam/purge-4.1.sql | mail root

last edited 2006-01-07 02:11:50 by FrankLuithle