Author: Matthew J. Salerno

For Gentoo Linux: http://www.gentoo.org - but generic enough for most.

This has been in the planning for quite some time, but I just recently got the time and equipment to get it started. Here are my notes so far. I do not cover every step along this process, most of these programs come with well written README or INSTALL files that should not be overlooked. I am very new to postfix, so if anyone spots somthing that should be changed, please post it.

This is without a doubt the easiest virtual mail server I have ever setup.

postfix→MailScanner→postfix→DBMail

Minimum recommended use flags: sasl mysql pam apache2 innodb ssl postfix crypt

If you updated any of your use flags, try the following command to see what might need to be rebuild with the new libraries # emerge -N world –deep -pv

Here are the packages I am currently using:

  • mail-filter/spamassassin 3.0.2-r1
  • mail-filter/razor 2.61
  • dev-python/pyzor 0.4.0-r1
  • mail-filter/dcc 1.2.28-r1
  • app-antivirus/clamav 0.83
  • mail-mta/postfix 2.1.5-r2
  • dev-db/mysql 4.0.24

You have the option to use either just use SASL or SASL with pam_mysql. Completely your option.

If you choose just to use sasl, then you will need to emerge dev-libs/cyrus-sasl >= 2.1.20-r2

Which is currently masked. I just used:

ACCEPT_KEYWORDS=”~x86” emerge -v cyrus-sasl

If you don't want to emerge a masked package and you want to go the other route, then you will need

  • dev-libs/cyrus-sasl 2.1.20
  • sys-libs/pam_mysql 0.5

I used the MailScanner ebuild from http://bugs.gentoo.org/show_bug.cgi?id=36060 I know that there is a dbmail ebuild, but I built it from source - http://www.dbmail.org/

I configured postfix to run in the chroot'd env by executing: /usr/share/doc/postfix-2.1.5-r2/examples/chroot-setup/LINUX2

I also had to change the following line in the master.cf

smtp inet n - - - - smtpd

All I did was replace the second “n” with a ”-”. This tells postfix to run in a chroot.

I got postfix working before I made any of the following changes. Mail in and out with no problems. The postfix website http://www.postfix.org/documentation.html has lots of great documentation. If you are new to postfix, like me, I strongly recommend going through the docs.

Next, I setup MailScanner. Make sure postfix is in your use flags! I put it in my portage_overlay, and emerg'd it. Currently, it setups up 2 init scripts, MailScanner and MailScanner-mta. Due to my configuration, I don't start the MailScanner-mta service and I comment out MailScanner-mta in the /etc/init.d/MailScanner:


depend() {
       need net # MailScanner-mta
       after postfix
       use logger dns
}

In the /etc/MailScanner/MailScanner.conf, I only changed some basic settings. (setting the Queue paths is required!): There are many more options to set, but I just wanted to get things working first. Many of those options are just set so that I know that MailScanner is working. Read through the file, it is well commented.


Incoming Queue Dir = /var/spool/postfix/hold
Outgoing Queue Dir = /var/spool/postfix/incoming
Always Include SpamAssassin Report = yes
Sign Clean Messages = yes
Use SpamAssassin = yes

/etc/mail/spamassassin/local.cf:


rewrite_header Subject *****SPAM*****
bayes_sql_override_username     "global"
bayes_store_module              Mail::SpamAssassin::BayesStore::SQL
bayes_sql_dsn                   DBI:mysql:spamassassin:localhost
bayes_sql_username              bayesdb
bayes_sql_password              mypassword
use_bayes 1
use_bayes_rules 1
bayes_auto_learn 1
required_hits 5.5
report_safe 2
use_terse_report 1
dns_available yes
skip_rbl_checks 1
use_razor2 1
use_pyzor 1
use_dcc 1
ok_languages all
ok_locales all

For spamassassin, I imported my old bayes_db into my SQL database and could check connectivity by just executing: sa-learn –dump magic -D

At this point, you should be able to start postfix and mailscanner.

/etc/init.d/postfix start
/etc/init.d/MailScanner start

Send an e-mail to an external account

# echo Test | mutt me@foo.yahoo.com

When you receive the e-mail, check the headers for MailScanner entries.

In order to get SASL w/ TLS working with the chroot'd Postfix, I added the following lines to my /etc/fstab:

/var/lib/sasl2 /var/spool/postfix/var/lib/sasl2 bind bind 0 0
/var/run/mysqld /var/spool/postfix/var/run/mysqld bind bind 0 0

Of course I created the /var/spool/postfix/var/lib/sasl2 and the /var/spool/postfix/var/run/mysqld directories first

I also generated my own certs using:


 
cd /etc/ssl/misc/ 
perl CA.pl -newca 
perl CA.pl -newreq 
perl CA.pl -sign 

And then copying them to /etc/postfix/ssl/

These lines will allow postfix to access the mysql and sasl sockets from the chroot.

For my master.cf, I added the below line under the line for smtp:

dbmail-lmtp unix - - n - - lmtp

This is to tell postfix to hand the mail over to dbmail.

Current main.cf


 
queue_directory = /var/spool/postfix
command_directory = /usr/sbin
daemon_directory = /usr/lib/postfix
mail_owner = postfix

sendmail_path = /usr/sbin/sendmail
newaliases_path = /usr/bin/newaliases
mailq_path = /usr/bin/mailq
setgid_group = postdrop
html_directory = no
manpage_directory = /usr/share/man
sample_directory = /etc/postfix
readme_directory = /usr/share/doc/postfix-2.1.5-r2/readme

debug_peer_level = 2
debug_peer_list = 127.0.0.1
debugger_command =
        PATH=/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin
        xxgdb $daemon_directory/$process_name $process_id & sleep 5

# SASL
smtpd_sasl_auth_enable = yes
smtpd_sasl_security_options = noanonymous
smtpd_sasl_local_domain =
broken_sasl_auth_clients = yes

# TLS
smtpd_tls_auth_only = yes
smtp_use_tls = yes
smtpd_use_tls = yes
smtp_tls_note_starttls_offer = yes
smtpd_tls_key_file = /etc/postfix/ssl/ozone.key
smtpd_tls_cert_file = /etc/postfix/ssl/ozone.crt
smtpd_tls_CAfile = /etc/postfix/ssl/ozone.pem
smtpd_tls_loglevel = 1
smtpd_tls_received_header = yes
smtpd_tls_session_cache_timeout = 3600s
tls_random_source = dev:/dev/urandom

mynetworks_style = subnet
mynetworks = 127.0.0.0/8

alias_database = hash:/etc/mail/aliases
alias_maps = hash:/etc/mail/aliases

# Server
header_checks = regexp:/etc/postfix/header_checks

myhostname = foo.bar
mydomain = foo.bar
myorigin = $mydomain
mydestination = localhost, foo.bar

unknown_local_recipient_reject_code = 550


virtual_transport = dbmail-lmtp:localhost:24
virtual_mailbox_domains = mysql:/etc/postfix/virtual-domains.cf
virtual_mailbox_maps = mysql:/etc/postfix/virtual_aliases.cf mysql:/etc/postfix/valiasdom.cf

smtpd_recipient_restrictions =  reject_invalid_hostname, reject_non_fqdn_recipient, reject_non_fqdn_sender, reject_unauth_pipelining, reject_unknown_recipient_domain, reject_unknown_sender_domain, permit_mx_backup, permit_mynetworks, permit_sasl_authenticated, check_relay_domains, permit

/etc/postfix/header_checks:


/^Received:/ HOLD

/etc/postfix/virtual-domains.cf:


user = dbmail
password = password
dbname = dbmail
table = dbmail_vdomains
select_field = domain
where_field = domain

/etc/postfix/virtual_aliases.cf:


user = dbmail
password = password
hosts = localhost
dbname = dbmail
table = dbmail_aliases
select_field = alias
where_field = alias

/etc/postfix/valiasdom.cf:


user = dbmail
password = password
dbname = dbmail
table = dbmail_vdomains
select_field = concat( '@', pridomain )
where_field = concat( '@', domain )
additional_conditions = and pridomain is not NULL

Table structure for table 'dbmail_vdomains'

Field Type Null Key Default Extra
id int(7) PRI NULL auto_increment
domain varchar(40) UNI
comment varchar(40) YES NULL
pridomain varchar(40) YES NULL

id      domain                 comment                       pridomain 
1       foo.com                Primary domain                NULL 
2       bar.com                Another domain                foo.com 

SQL to create table 'dbmail_vdomains':


DROP TABLE IF EXISTS `dbmail_vdomains`; 
CREATE TABLE IF NOT EXISTS `dbmail_vdomains` ( 
  `id` int(7) NOT NULL auto_increment, 
  `domain` varchar(40) NOT NULL default '', 
  `comment` varchar(40) default NULL, 
  `pridomain` varchar(40) default NULL, 
  PRIMARY KEY  (`id`), 
  UNIQUE KEY `domain` (`domain`), 
) TYPE=InnoDB AUTO_INCREMENT=1 ; 

Then you can populate the table with:

For Primary domain:

INSERT INTO `dbmail_vdomains` (`domain`, `comment`, `pridomain`) VALUES(“pridom.com”, “Primary Domain”, NULL);

For Secondary domain:

INSERT INTO `dbmail_vdomains` (`domain`, `comment`, `pridomain`) VALUES(“secdom.com”, “Primary Domain”, “pridom.com);

Download the DBMail source and unpack it. Read through the README and INSTALL and the INSTALL.postfix for better instructions. You will need to copy the given dbmail.conf to /etc/ and make some changes. The only changes I made were for the database connection.

/etc/dbmail.conf:


[DBMAIL] 
host=localhost 
sqlport=3306 
sqlsocket=/var/run/mysqld/mysqld.sock 
user=dbmail 
pass=mypassword 
db=dbmail 
POSTMASTER=postmaster@foo.com 
TRACE_LEVEL=1 

[SMTP] 
SENDMAIL=/usr/sbin/sendmail 
AUTO_NOTIFY=no 
AUTO_REPLY=no 
TRACE_LEVEL=1 

[LMTP] 
EFFECTIVE_USER=nobody 
EFFECTIVE_GROUP=nogroup 
BINDIP=127.0.0.1 
                          
PORT=24 
NCHILDREN=20 
MAXCHILDREN=15 
MINSPARECHILDREN=2 
MAXSPARECHILDREN=4 
MAXCONNECTS=10000 
TIMEOUT=300 
RESOLVE_IP=yes 
TRACE_LEVEL=1 
MAX_ERRORS=500 

[POP] 
EFFECTIVE_USER=nobody 
EFFECTIVE_GROUP=nogroup 
BINDIP=* 
PORT=110 
NCHILDREN=30 
MAXCHILDREN=200 
MINSPARECHILDREN=2 
MAXSPARECHILDREN=4 
MAXCONNECTS=10000 
TIMEOUT=300 
RESOLVE_IP=yes 
POP_BEFORE_SMTP=no 
TRACE_LEVEL=1 

[IMAP] 
EFFECTIVE_USER=nobody 
EFFECTIVE_GROUP=nogroup 
BINDIP=* 
PORT=143 
NCHILDREN=5 
MAXCHILDREN=100 
MINSPARECHILDREN=2 
MAXSPARECHILDREN=4 
MAXCONNECTS=10000 
TIMEOUT=4000 
RESOLVE_IP=yes 
IMAP_BEFORE_SMTP=no 
TRACE_LEVEL=1 

I got the init scripts from the ebuild

/etc/conf.d/saslauthd:


SASLAUTHD_OPTS="" 
SASLAUTHD_OPTS="${SASLAUTH_MECH} -a pam -r" 

<Just SASL> If you plan on using just SASL: This will allow you to authenticate your through your SMTP server using: crypt, plaintext, md5 /etc/sasl2/smtpd.conf:


pwcheck_method: auxprop 
auxprop_plugin: sql 
allowanonymouslogin: no 
allowplaintext: yes 
mech_list: PLAIN LOGIN 
srp_mda: md5 
srvtab: /dev/null 
opiekeys: /dev/null 
password_format: crypt 
sql_user: dbmail 
sql_passwd: mypassword 
sql_hostnames: localhost 
sql_database: dbmail 
sql_select: SELECT passwd FROM dbmail_users WHERE userid = '%u@%r' 
log_level: 10 
sql_verbose: yes 

</Just SASL>

<SASL with pam_mysql> If you plan on using SASL with pam_mysql: /etc/pam.d/smtp: This will allow you to authenticate your through your SMTP server using: crypt, plaintext, md5 Watch out for the line wrap. When you create the smtp file, there should only be 2 lines.


auth    sufficient      pam_mysql.so user=dbmail passwd=password host=127.0.0.1 db=dbmail table=dbmail_users usercolumn=userid passwdcolumn=passwd crypt=1 

account required        pam_mysql.so user=dbmail passwd=password host=127.0.0.1 db=dbmail table=sbmail_users usercolumn=userid passwdcolumn=passwd crypt=1 

/etc/sasl2/smtpd.conf:


pwcheck_method:saslauthd 
mech_list: plain login 

</SASL with pam_mysql>

/etc/init.d/dbmail-lmtpd:


#!/sbin/runscript
#
# chkconfig: - 91 35
# description: Starts and stops the dbmail-lmtpd daemon
#

PROGRAM=dbmail-lmtpd 
BIN_DIR=/usr/local/sbin 

PID_DIR=/var/run 
PID=pid 

# Where is the dbmail.conf file located? 
CONFIG=/etc/dbmail.conf 

# opts="${opts} reload" 

depend() { 
        need net 
        # This won't cause a hard failure if neither is installed, however. 
        use mysql 
        after mysql mta 
} 

initService() { 
    # Avoid using root's TMPDIR 
    unset TMPDIR 

    # Check that config file exists. 
    [ -f $CONFIG ] || exit 0 

    RETVAL=0 
} 

start() { 
        initService 
        ebegin "Starting DBMail LMTP daemon ($PROGRAM)" 
            start-stop-daemon --start --quiet \ 
              --pidfile $PID_DIR/$PROGRAM.$PID \ 
              --exec $BIN_DIR/$PROGRAM \ 
              --name $PROGRAM \ 
              -- -f $CONFIG -p $PID_DIR/$PROGRAM.$PID 2>&1 
        eend $? 
} 

stop() { 
        initService 
        ebegin "Stopping DBMail LMTP daemon ($PROGRAM)" 
            start-stop-daemon --stop --quiet --retry 5 \ 
              --pidfile $PID_DIR/$PROGRAM.$PID 
        eend $? 
} 

/etc/init.d/dbmail-pop3d:


#!/sbin/runscript
#
# chkconfig: - 91 35
# description: Starts and stops the dbmail-pop3d daemon
#

PROGRAM=dbmail-pop3d 
BIN_DIR=/usr/local/sbin 

PID_DIR=/var/run 
PID=pid 

# Where is the dbmail.conf file located? 
CONFIG=/etc/dbmail.conf 

# opts="${opts} reload" 

depend() { 
        need net 
        # This won't cause a hard failure if neither is installed, however. 
        use mysql 
        use pgsql 
        after mta 
} 

initService() { 
    # Avoid using root's TMPDIR 
    unset TMPDIR 

    # Check that config file exists. 
    [ -f $CONFIG ] || exit 0 

    RETVAL=0 
} 

start() { 
        initService 
        ebegin "Starting DBMail POP3 daemon ($PROGRAM)" 
            start-stop-daemon --start --quiet \ 
              --pidfile $PID_DIR/$PROGRAM.$PID \ 
              --exec $BIN_DIR/$PROGRAM \ 
              --name $PROGRAM \ 
              -- -f $CONFIG -p $PID_DIR/$PROGRAM.$PID 2>&1 
        eend $? 
} 

stop() { 
        initService 
        ebegin "Stopping DBMail POP3 daemon ($PROGRAM)" 
            start-stop-daemon --stop --quiet --retry 5 \ 
              --pidfile $PID_DIR/$PROGRAM.$PID 
        eend $? 
} 

/etc/init.d/dbmail-imapd:


#!/sbin/runscript
#
# chkconfig: - 91 35
# description: Starts and stops the dbmail-imapd daemon
#

PROGRAM=dbmail-imapd 
BIN_DIR=/usr/local/sbin 

PID_DIR=/var/run 
PID=pid 

# Where is the dbmail.conf file located? 
CONFIG=/etc/dbmail.conf 

# opts="${opts} reload" 

depend() { 
        need net 
        # This won't cause a hard failure if neither is installed, however. 
        use mysql 
        use pgsql 
        after mta 
} 

initService() { 
    # Avoid using root's TMPDIR 
    unset TMPDIR 

    # Check that config file exists. 
    [ -f $CONFIG ] || exit 0 

    RETVAL=0 
} 

start() { 
        initService 
        ebegin "Starting DBMail IMAP daemon ($PROGRAM)" 
            start-stop-daemon --start --quiet \ 
              --pidfile $PID_DIR/$PROGRAM.$PID \ 
              --exec $BIN_DIR/$PROGRAM \ 
              --name $PROGRAM \ 
              -- -f $CONFIG -p $PID_DIR/$PROGRAM.$PID 2>&1 
        eend $? 
} 

stop() { 
        initService 
        ebegin "Stopping DBMail IMAP daemon ($PROGRAM)" 
            start-stop-daemon --stop --quiet --retry 5 \ 
              --pidfile $PID_DIR/$PROGRAM.$PID 
        eend $? 
} 

Currently with this setup, my mail server is working great. Now all I have to do is setup mysql to listen on an external ip address, setup another server with almost the same settings, setup sql replication and I should have some pretty reliable and redundant mail servers. Of course the switchover won't be automatic, yet…

Good luck

Readers note, perhaps this would be better served by an email to the author; but im a bit lazy tonight – kerpal2343 at domain yahoo.com – The primary and seconday domain portion I feel is a bitt off from a default setup, as its not in the database and I am a DBMA web user (more so, im setting up the system to be so for a client). I could not tell from this article how this affects the system, im left to assume that this allows one to have a postmaster@organization.com mapped to an organization.net address or silly.com address by default.. let me know if I am fool with this thought. If not.. umm please add a description up there – End –

 
gentoo/postfix_-_sasl_tls_-_mailscanner_-_dbmail.txt · Last modified: 2011/08/25 18:24 by michaelbibby
 
DBMail is developed by Paul J Stevens together with developers world-wide