Home
|
UNIX
|
Oracle
|
Code
|
Practical
|
Private
Postoffice smtp server -- mbox virtual hosts
Introduction
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 (using 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 between domain users.
Note. Postoffice now compiles fine on NetBSD/sparc64 (since 1.2.0 or 1.3.pre1).
Prepare the system
Check if mail user and group do exist,
grep ^mail: /etc/passwd
grep ^mail: /etc/group
Note. the shell for the mail user should be '/sbin/nologin'
Prepare directories and permissions,
mkdir -p /var/spool/virtual
mkdir -p /var/spool/mqueue
mkdir -p /etc/virtual
mkdir -p /usr/local/man
chown mail:mail /var/spool/virtual
chown mail:mail /var/spool/mqueue
chown mail:mail /etc/virtual
chmod 700 /var/spool/virtual
chmod 700 /var/spool/mqueue
chmod 700 /etc/virtual
Don't forget local users,
cd /var/spool
chown mail:mail mail
chmod 1777 mail
cd mail
chgrp mail *
chmod 600 *
Also make sure "/var/db" is writeable by root,
ls -ld /var/db
Note. postoffice will create the greylist database into /var/db/smtpauth.db
Postoffice installation
Check for dependencies :
- ndbm or gdbm (mandatory, on RHEL install gdbm-devel)
- tcpwrappers (optional, look for /etc/hosts.{allow,deny} files)
tar xvzf Orc-postoffice-v1.5.3-0-g9ae3a8a.tar.gz
cd Orc-postoffice-1001eaf
./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
make install
Note. add '--use-mailwrappers' for BSD systems
Note. we dislike greylisting because of the arrival delay it produces
Note. we didn't get rid of the few warnings with '--with-gcc-patch' on RHEL5, so we're omitting this option
Note. "--with-auth" enables virtual host SMTP authentication. No need for cyrus-sasl kluges & pain like other SMTP servers do, no configuration needed. To allow unix users only to connect use '--with-auth=passwd'.
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, fix the paths,
cd /usr/bin
ls -l mailq newaliases sendmail
mv mailq mailq.dist
mv newaliases newaliases.dist
mv sendmail sendmail.dist
ln -sf /usr/local/bin/mailq
ln -sf /usr/local/bin/newaliases
ln -sf /usr/local/bin/sendmail
check,
which mailq
which newaliases
which sendmail
which runq
Postoffice configuration
Edit Postoffice's configuration,
vi /etc/postoffice.cf
like,
self=mx.example.net
#audit
clients=100
escape-from=1
immediate
minfree=50m
qreturn=5h
timeout=5m
size=10m
checkhelo
paranoid
blacklist=bounce
spam=bounce
verify-from=1
Note. checkhelo refuses clients that claim to be us
Note. "immediate" to process the queue immediately.
Note. don't use "hops" or if you do, make sure it's a value above 10. "100" is the default
Note. paranoid to refuse mail from non resolvable sites
Note. qreturn=5h bounces undeliverable mail after 5 hours
Note. size=10m sets the largest message size that postoffice will accept
Note. if you do use greylisting (we don't), eventually define the delay,
delay=1m
Edit the global aliases and update the alias table,
vi /etc/aliases
#vi /etc/mail/aliases
which newaliases
newaliases
Eventually stop and unconfigure existing SMTP services,
#service sendmail stop
#chkconfig sendmail off
start the daemon,
/usr/local/sbin/smtpd -C/etc/postoffice.cf -q5
#/usr/local/lib/postoffice -C/etc/postoffice.cf -bd -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/sbin/smtpd -C/etc/postoffice.cf -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 :
#!/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";
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 {} \;
Note. if you're using Mutt or Pine you tweak the perms but for *your virtual user only* !
chmod 750 /var/spool/virtual
chmod 750 /var/spool/virtual/example.net
groupadd USERNAME
vi /etc/group # add USERNAME to group mail AND to its own group
cd /var/spool/virtual/example.net
chown -R mail:USERNAME user.imap
find user.imap -type d -exec chmod 770 {} \;
find user.imap -type f -exec chmod 660 {} \;
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 user's home directory will not 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 user's home directory will be created
cd /home/MDAUSER
vi .procmailrc
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 (depending on procmailrc LOGFILE variable) with permissions 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 will configure user's procmail to the vhost. Postoffice won't see the vhost (commented into /etc/postoffice.cf) but Dovecot will.
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 | grep smtpd | egrep -v 'restart|grep'
pkill smtpd
print ''
/usr/local/sbin/smtpd -C/etc/postoffice.cf -q5
sleep 1
ps ax | grep smtpd | egrep -v 'restart|grep'
EOF9
chmod +x restart_postoffice.ksh
Note. if you enabled greylisting at compilation time (we don't), check it's working :
- Send an email to some hosted address
- Check the greylisting database is created by postoffice,
ls -l /var/db/smtpauth.db # root / -rw-------
- After a while, check the message has been received,
tail /var/spool/virtual/example.net/username
Check the queue and force its immediate processing,
mailq
#cd /var/spool/mqueue
#ls -l
runq
Update all aliases at once,
newaliases
cd /etc/virtual
for domain in `cut -f2 -d: domains.cf`; do newaliases $domain; done
Upgrade
Follow the installation procedure to overwrite Postoffice binaries,
...
make install
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"
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. 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.
Under heavy attack, eventually reject mail from <>,
nodaemon
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
Postfix with mbox virtual hosts (untested)