this is obsolete doc -- see http://doc.nethence.com/ instead

Postoffice smtp server -- mbox virtual hosts 

 

http://pbraun.nethence.com/doc/mail/postoffice.html 

http://pbraun.nethence.com/doc/mail/vm-pop3d.html 

http://pbraun.nethence.com/doc/mail/dovecot.html 

http://pbraun.nethence.com/doc/mail/spamass-milter.html 

http://pbraun.nethence.com/doc/mail/procmail.html 

 

 

Introduction 

In this guide we're configuring the Postoffice smtp server (http://www.pell.portland.or.us/~orc/Code/postoffice/) for mbox virtual hosts. You can use vm-pop3d for a simple POP3 service, or dovecot if you need POP3 and IMAP. 

 

Mbox is the traditional UNIX mailbox format. It's also the most convenient for data consistency, archiving and troubbleshooting, although it lacks multi-user access (it uses lock instead) and may cause bad performance on very large mailboxes. Combined with virtual hosts, we establish a clean cut separation between the domains and therefore its users. 

 

Note. Postoffice now compiles fine on NetBSD/sparc64 (since 1.2.0 or 1.3.pre1). 

 

 

Prepare the system for virtual and local mboxes 

Look for mail user and group, 

grep ^mail: /etc/passwd
grep ^mail: /etc/group

Note. on NetBSD, 

#groupadd -g 6 mail
#useradd -s /sbin/nologin -g 6 -u 6 mail
#pw useradd mail -s /sbin/nologin -g 6 -u 6

 

Prepare directories and fix permissions for virtual mboxes, 

ls -ld /var/spool/virtual /var/spool/mqueue /etc/virtual
mkdir -p /var/spool/virtual /var/spool/mqueue /etc/virtual
chown mail:mail /var/spool/virtual /var/spool/mqueue /etc/virtual
chmod 700 /var/spool/virtual /var/spool/mqueue /etc/virtual

 

Fix permissions for for local users. Two solutions. 

1) 

cd /var/spool/
chown mail:mail mail
chmod 1777 mail/
cd mail/
chgrp mail *
chmod 600 *

2) 

cd /var/spool/
chown mail:mail mail
chmod 775 mail/
cd mail/
chgrp mail *
chmod 660 *

Note. on NetBSD, 

#cd /var/ (instead of /var/spool/)

 

 

Postoffice installation 

Check for dependencies : 

- ndbm or gdbm (mandatory, on RHEL install gdbm-devel) 

- tcpwrappers (optional, look for /etc/hosts.{allow,deny} files) 

Note. on Redhat systems, 

rpm -qa gdbm-devel \
tcp_wrappers-devel

 

Note. Postoffice will create the greylist database into /var/db/smtpauth.db, so make sure "/var/db" is writeable by root, 

ls -ld /var/db/

 

Download, and install Postoffice (http://www.pell.portland.or.us/~orc/Code/postoffice/), 

cd ~/
wget http://www.pell.portland.or.us/~orc/Code/postoffice/postoffice-1.5.5.tar.bz2
tar xjf postoffice-1.5.5.tar.bz2
cd postoffice-1.5.5/
./configure.sh --help
./configure.sh \
--with-tcpwrappers \
--with-queuedir=/var/spool/mqueue \
--with-auth \
--with-milter \
--with-vhost=/etc/virtual \
--with-vspool=/var/spool/virtual \
--with-vuser=mail
make clean
make
mkdir -p /usr/local/man/
make install

note. add '--use-mailwrappers' on BSD systems 

note. we dislike greylisting because of the arrival delay it produces 

note. --with-gcc-patch patch the code to stop gcc -Wall from complaining 

note. --with-auth enable smtp authentication (for AUTH LOGIN). No need for cyrus-sasl kluges & pain like other SMTP servers does: no configuration is needed. Also add '--with-auth=passwd' if you only want Unix users (no virtual users) to connect. 

 

Make sure those commands point to postoffice. On BSD systems, mail wrappers do the job (NetBSD: /etc/mailer.conf, FreeBSD : /etc/mail/mailer.conf). But on Linux and non BSD-like systems, just remove the default executables, 

cd /usr/sbin/
ls -l sendmail
mv sendmail sendmail.dist

 

cd /usr/bin/
ls -l mailq newaliases
mv mailq mailq.dist
mv newaliases newaliases.dist

now check, 

which sendmail
which mailq
which newaliases
which runq

 

 

Postoffice configuration 

Here's an example, 

cd /etc/
wget http://pbraun.nethence.com/code/mail/postoffice.cf
vi postoffice.cf

Note. change self= accordingly. 

Note. 'debug' enables the DEBUG ESMTP command (disabled) 

Note. 'immediate' to process the queue immediately (enabled) 

Note. qreturn=5h bounces undeliverable mail after 5 hours 

Note. size=30m sets the largest message size that postoffice will accept, m for Megabytes 

Note. checkhelo refuses clients that claim to be us 

Note. paranoid to refuse mail from non resolvable sites 

Note. under attack eventually use 'nodaemon' to reject mail from <> (needed to receive normal bounces) 

Note. don't use "hops" or if you do, make sure it's a value above 10. 100 is the default. 

Note. if you do use greylisting (I don't), eventually define the delay, 

delay=1m

Note. disable verify-from if (is this an obsolete note? was it a bug?): 

- you're using another smtp for outgoing messages 

- AND you're sending mail as local user (non-virtual & remote with auth) 

otherwise you might not get the delivery returns. Your outgoing smtp will try to send them as MAIL FROM local@example.net and postoffice will refuse them as non-local. 

Note. for the two milter filters, see http://pbraun.nethence.com/doc/mail/milter_spamass-milter.html and http://pbraun.nethence.com/doc/mail/milter_dnsbl-milter.html 

 

Edit the global aliases and update the alias table, 

vi /etc/aliases
#vi /etc/mail/aliases
newaliases

 

Eventually stop and unconfigure existing SMTP services, 

#service sendmail stop
#chkconfig sendmail off

start the daemon, 

/usr/local/lib/postoffice -bd -q5
#/usr/local/sbin/smtpd -q5

note. "-q5" for queue processing interval of 5 minutes 

and enable at boot time, 

cat >> /etc/rc.local <<EOF9
echo -n starting postoffice...
/usr/local/lib/postoffice -bd -q5 && echo done
EOF9

 

 

Virtual hosts 

Configure a vhost, 

mkdir -p /etc/virtual/example.net
mkdir -p /var/spool/virtual/example.net
vi /etc/virtual/domains.cf

like e.g., 

mainuser:example.net:1:comment

 

 

Virtual users management 

Create a password file for it, 

cd /etc/virtual
mkdir -p example.net
htpasswd -c example.net/passwd USERNAME

and eventually configure its virtual aliases, 

vi example.net/aliases
newaliases example.net

Note. if you don't want to use htpasswd, there are some alternatives : 

- pop_passwd.pl (http://www.reedmedia.net/software/virtualmail-pop3d/#passwords) 

#!/usr/bin/perl
# pop_passwd username password >> password file
 $name = $ARGV[0];
 @salt_chars         = ('a'..'z','A'..'Z','0'..'9');
 $salt               = $salt_chars[rand(62)] . $salt_chars[rand(62)];
 $passwd = crypt ($ARGV[1], $salt);
 print "$name:$passwd\n";

- vpasswd (http://www.pell.portland.or.us/%7Eorc/Code/post/) 

 

 

Local users management 

Simple (POP3) account no MDA 

To simply enable /var/spool/mail/%u delivery, 

useradd -s /sbin/nologin -M -g mail MAILUSER

Note. -M for user's home directory not to be created 

 

MDA capable account 

Note. MDA delivery is only possible with local UNIX accounts 

To pass user's mail through an MDA (e.g. procmail), 

useradd -s /sbin/nologin -m -g mail MDAUSER

note. -m to create user's home directory 

cd /home/MDAUSER
vi .procmailrc
... (see http://pbraun.nethence.com/doc/mail/procmail.html)
vi .forward

like, 

"|IFS=' '&&p=/usr/bin/procmail&&test -f $p&&exec $p -f-||exit 75"

fix perms, 

chown MDAUSER:mail .forward .procmailrc
chmod 400 .forward .procmailrc

note. .procmailrc.log will eventually be created (procmailrc: LOGFILE=) with perms 600 

 

MDA + IMAP account 

Same as above plus, to keep dovecot vhost configuration intact, although it's possible to force mail_location for specific users, we tell procmail to send the messages to the vhost. 

 

Dovecot will see the vhost, Postoffice won't (/etc/virtual/domains.cf). 

 

Note. you'll have to use specific permissions to let both, user's procmail AND the pop/imap daemon write to the vhost (see below). 

 

 

Permissions 

Fix permssions which where altered during the vhost configuration, 

chown -R mail:mail /etc/virtual
chown -R mail:mail /var/spool/virtual
find /etc/virtual -type d -exec chmod 700 {} \;
find /etc/virtual -type f -exec chmod 600 {} \;
find /var/spool/virtual -type d -exec chmod 700 {} \;
find /var/spool/virtual -type f -exec chmod 600 {} \;

 

For specific vhosts *only*, not all of them, the following permission changes are required if : 

- you want to access a vhost locally e.g. with Pine (or Mutt) 

- and/or you want some unix user's procmail to write to the vhost 

enable ACL (edit fstab) on the required filesystem and proceed, 

setfacl -m u:unixuser:x /var/spool/virtual
setfacl -m u:unixuser:x /var/spool/virtual/example.net
find /var/spool/virtual/example.net/user.imap -type d -exec setfacl -m u:unixuser:rwx {} \;
find /var/spool/virtual/example.net/user.imap -type d -exec setfacl -dm u:unixuser:rw {} \;
find /var/spool/virtual/example.net/user.imap -type f -exec setfacl -m u:unixuser:rw {} \;

Note. Dovecot doesn't read the symlink but user.imap's content only. So no need to fix the symlink 

 

 

MX record 

Postoffice skips /etc/hosts and system DNS resolution. It has its own resolver so you absolutely need to have the right MX or A records for the domains you're willing to host. 

 

 

Usage 

Eventually deploy this handy restart script, 

cd ~/
mkdir -p bin/
cd bin/
cat > restart_postoffice.ksh <<EOF9
#!/bin/ksh

 

        ps ax | egrep 'smtpd|postoffice' | egrep -v 'restart|grep'
        pkill postoffice
        print ''
        /usr/local/lib/postoffice -bd -q5
        sleep 1
        ps ax | grep postoffice | egrep -v 'restart_|grep'
EOF9
chmod +x restart_postoffice.ksh

 

Note. if you enabled greylisting at compilation time (I didn't), check it's working. Send an email to some hosted address and verify that the greylisting database has been created by postoffice, 

ls -l /var/db/smtpauth.db

 

Check the queue and force its immediate processing, 

#cd /var/spool/mqueue/
#ls -l
mailq
runq

 

Update all aliases at once, 

newaliases
cd /etc/virtual
for domain in `cut -f2 -d: domains.cf`; do newaliases $domain; done

 

 

Update procedure 

Follow the installation procedure to overwrite Postoffice binaries, 

/usr/local/lib/postoffice -V
wget http://www.pell.portland.or.us/~orc/Code/postoffice/postoffice-1.5.5.tar.bz2
tar xjf postoffice-1.5.5.tar.bz2
cd postoffice-1.5.5/
./configure.sh \
--with-tcpwrappers \
--with-queuedir=/var/spool/mqueue \
--with-auth \
--with-milter \
--with-vhost=/etc/virtual \
--with-vspool=/var/spool/virtual \
--with-vuser=mail
make
make install
/usr/local/lib/postoffice -V

note. add '--use-mailwrappers' on BSD systems 

and restart the daemon, 

restart_postoffice.ksh

 

 

Milters 

For milters, either a UNIX socket e.g., 

filter=/path/to/unix.socket

or a TCP socket e.g., 

filter=hostname:port

Note. DNS hosts only 

 

 

Backup MX 

On the backup MX, same configuration but simply add this to /etc/postoffice.cf, 

mxpool=1

Note. and change qreturn= to something much bigger, like 3 days 

 

 

Smart host 

To define an outgoing smtp (untested), 

relay-host=host
#forward-all

 

 

SMTP relay 

Interesting options (untested), 

#localmx
#relay
#trusted=host

 

 

MDA 

Local users are allowed to use external MDA through the ~/.forward file, 

vi ~/.forward

like, 

"|IFS=' '&&p=/usr/local/bin/procmail&&test -f $p&&exec $p -f-||exit 75"

Ref. http://mirror.ncsa.illinois.edu/procmail-faq/mini-faq.html#forward 

 

However, in your procmailrc, don't use the USER variable. Hard code the username e.g., 

ORGMAIL=/var/spool/mail/USERNAME

Note. otherwise we would get something like, 

/var/spool/mail/new/1282953512.2676_1.mx.example.net

 

 

Mail quotas 

Simply use LVM for mail quotas, one LV per imap user (inbox is symlinked), 

LV /var/spool/virtual/example.net/user.imap
symlink /var/spool/virtual/example.net/inbox -> user.imap/inbox

Note. there's also LVM for NetBSD (http://www.netbsd.org/docs/guide/en/chap-lvm.html) 

Note. use the minfree= configuration option 

Note. you may do daily script to let users know if they're reaching their maximum space usage 

 

 

Additional notes 

Looks like Postoffice works this way when receiving a valid message : 

- checks for MX or A record with its own resolver 

- looks for virtual host matching domain and virtual user 

- looks for local users 

Note. when using an IP instead of a domain name through telnet, you need to embrace the IP e.g., 

rcpt to:user@[XX.XX.XX.XX]

 

Note. add double quotes when using piped aliases, 

"|/usr/bin/msgs -s"

 

Note. edit smtpd welcome message, 

vi /etc/issue.smtp

 

Note. postoffice doesn't provide /var/log/mail.stat 

 

 

Troubbleshooting 

Check you've got the latest version, 

/usr/local/lib/postoffice -V

 

Find out what's using /var/spool/mqueue (in case it's not even a lying runq process), 

lsof | grep mqueue

 

Some other UNICES use "/var/mail/" instead of "/var/spool/mail". Adapt your MAIL or MAILPATH variable or make sure there's a symlink to one another. That's for local users. Virtual hosts are usually hosted into /var/spool/virtual. 

 

Eventually test your server remotely by telnet, 

helo check
helo check
mail from:<>
rcpt to:email@example.net
data
from:<>
to:email@example.net
subject:check

 

check
.
quit

 

 

Mail server migration 

Assuming the old MX is currently in production, and either you just configured a new one, or you have a backup MX standing by. Either way you want to migrate the service to the new MX. 

 

Update the DNS records but force the old behaviour 

- configure vhosts's DNS MX records so the new MX has a higher priority 

- do not configure the wanted vhosts on the new MX yet 

- don't change old MX's configuration (no mxpool) 

 

Migrate the data and switch MXes 

Proceed once the MX records are propagated (approx. 4 hours). 

 

On old MX : 

- empty the queue and disable the vhosts you need to migrate 

- make an archive of their configuration and mbox folders 

- rename the mbox folder to .old (no need to create a new-empty one) 

- send the archives to the new MX 

- reenable the vhost 

- fix perms 

- update postoffice to get the mxpool feature 

- start the daemon with mxpool 

 

On the new MX : 

- deploy vhost's archives 

- configure the vhost 

- apply vhost's aliases 

- fix perms 

 

Notes 

Note. this may happen : greylisting db isn't as up to date on the new MX as it is on the old one. So the new MX may refuse temporarily some messages, which will be hence sended to the backup (old) MX. The latter will keep them for the new one. 

Note. unfortunately you can't enable mxpool for one vhost and keep it disabled for another. 

Note. this will go smoothly on the client side, username and passwords don't change, hostname don't change (update the pop server DNS record), e.g. thunderbird just proceeds on the new host w/o warning nor errors. 

Note. only thing is, you might get emails twice (those who where intetionnaly kept on the server) if you don't migrate all at once. 

 

 

References 

https://www.milter.org/ 

http://www.faqs.org/rfcs/rfc2554.html 

http://www.pell.portland.or.us/%7Eorc/Code/post/ 

http://www.washington.edu/imap/documentation/formats.txt.html 

http://www.washington.edu/imap/documentation/formats.txt.html 

 

Postfix with mbox virtual hosts (untested) 

http://www.postfix.org/VIRTUAL_README.html#virtual_mailbox 

http://unixdoc.ua-i.net/articles/mail/postfix/virtual-hostsninstall.txt 

http://www.inter7.com/index.php?page=vpopmail 

http://www.steki.net/code/download/ 

http://christian.caleca.free.fr/qmail/vpopmail.htm