View previous topic :: View next topic |
Author |
Message |
avenj Retired Dev
Joined: 11 Oct 2002 Posts: 495 Location: New Hampshire
|
Posted: Thu Mar 25, 2010 7:49 pm Post subject: HOWTO: A simple approach to virtual mail hosting (Postfix) |
|
|
Not very Gentoo-specific, I threw this together after putting together some simple Debian hosts for friends.
This is in no way intended to be the 'best' way to put together a virtual mailhost with SASL/POP3(s)/IMAP(s)/SpamAss, it's not especially secure (static uid for all mailboxes), but it should work for people with very simple needs. Also, I hate courier-imap and cyrus-sasl.
Banged this out just now off the top of my head without coffee, I probably missed something.
Interested in critique.
Link: http://eris.oppresses.us/misc/unix.misc/HOWTO_vmail_postfix_dovecot.txt
Code: |
# $Id: HOWTO_vmail_postfix_dovecot.txt,v 1.1 2010/03/25 19:38:52 avenj Exp avenj $
## Jon Portnoy avenj@oppresses.us
## free to redistribute, but please change the attribution above if you modify.
## rcs:
# $Revision: 1.1 $
# $Date: 2010/03/25 19:38:52 $
# $Author: avenj $
##
Simple Virtual Mail Hosting
This is a very basic HOWTO on deploying a simple, full-featured virtual mail host.
We'll be setting up authenticated SMTP/IMAP(s)/POP3(s) and effective spam-killing.
This is definitely not a guide to the "best mail hosting solution" or any such thing.
The focus is on simplicity.
This guide assumes a working knowledge of Unix administration and how mail works in general.
The focus here is on quickly configuring mail.
There is not a lot of elaboration on what, exactly, you are doing.
Do yourself a favor, do not deploy mail before you've read your software's documentation.
We use the following software:
- postfix-2.6 (SMTP -- using maildir delivery)
- dovecot-1.2 (POP3(s), IMAP(s), dovecot-auth)
- spamassassin-3.3
I'll be using a config based on the existing tarvalon.netlandtowers.com system as examples.
POSTFIX CONFIGURATION
We'll be killing two birds with one stone here: SASL auth, and the virtual mail system.
SASL will hook into dovecot to handle authentication, so user auth credentials are
consistent between IMAP/POP3 and SMTP.
* Ensure that your $mydestination setting does not include your virtually hosted domains.
You can optionally set it to localhost and host _all_ mail including Unix mail via virtual mailboxes.
Alternately you can keep your Unix mailboxes separate from your virtual mailboxes.
My hosts use the latter option.
## /etc/postfix/main.cf: Unix mail destination for @tarvalon.netlandtowers.com ##
myhostname = tarvalon.netlandtowers.com
mydestination = tarvalon.netlandtowers.com, localhost
####
You'll need this to authenticate SASL against your dovecot users later:
## /etc/postfix/main.cf: SASL via dovecot-auth ##
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_auth_enable = yes
# stupid hack for old ms clients:
broken_sasl_auth_clients = yes
smtpd_sasl_security_options = noanonymous
smtpd_recipient_restrictions = permit_sasl_authenticated, permit_mynetworks, reject_unauth_destination
####
You'll probably want SSL/TLS.
You can create a self-signed /etc/postfix/ssl/smtpd.pem thusly:
-sh$ mkdir /etc/postfix/ssl && cd /etc/postfix/ssl
-sh$ openssl req -new -x509 -nodes -out smtpd.pem -keyout smtpd.pem -days 3650
## /etc/postfix/main.cf: TLS & SpamAssassin ##
smtpd_tls_key_file = /etc/postfix/ssl/smtpd.pem
smtpd_tls_cert_file = /etc/postfix/ssl/smtpd.pem
smtpd_tls_CAfile = /etc/postfix/ssl/smtpd.pem
smtpd_use_tls=yes
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
spamassassin_destination_recipient_limit = 1
# IMPORTANT: You might also have to uncomment the 'smtps' directive in /etc/postfix/master.cf
####
Finally, the important stuff: virtual mailboxes.
## /etc/postfix/main.cf: Virtual mailboxes ##
virtual_mailbox_domains = /etc/postfix/vmail-hosts
virtual_mailbox_base = /var/spool/vmail
virtual_mailbox_maps = hash:/etc/postfix/vmail-maps
virtual_alias_maps = hash:/etc/postfix/vmail-alias
virtual_uid_maps = static:1008
virtual_gid_maps = static:1008
####
This breaks down as follows:
virtual_mailbox_domains = /etc/postfix/vmail-hosts:
This is a simple list of hosted destination domains, one per line.
For example:
netlandtowers.com
netlandwhitetower.com
virtual_mailbox_base = /var/spool/vmail:
This directory contains the actual mailboxes.
The actual layout will look like:
/var/spool/vmail/<domain>/<user>
We'll set this up later.
virtual_mailbox_maps = hash:/etc/postfix/vmail-maps
This file lists the actual mailbox mappings.
Each user with a virtual mail account needs an entry in this file, thusly:
portnoy@netlandtowers.com netlandtowers.com/portnoy/
This is easily managed with some simple scripting.
The trailing slash is important; this implies we are using maildir mailboxes.
NOTE: After editing hash: files, you MUST run `postmap` on the file.
virtual_alias_maps = hash:/etc/postfix/vmail-alias
The "virtual" equivalent of /etc/aliases.
Format is simple:
root@netlandtowers.com avenj@oppresses.us
Like above, this file must be fed to postmap.
virtual_uid_maps/virtual_gid_maps:
This is important. We'll be using one user to manage virtual mailboxes.
This could be considered a security risk.
Use your best judgement. We're going for simplicity here.
Create a user named 'vmail' with a unique UID/GID and specify 'static:<id>' for both of these.
(If you don't know how to do this on your own, don't run a mailserver.)
OPTIONAL SPAM-KILLING CONFIGURATION
Now, for this host we also want to push mail through SpamAssassin.
This assumes you have SpamAssassin configured and spamd is running.
(That part is your problem. It's easy, but varies from one distribution to another. Google it.)
This is called 'after-queue' inspection. After queue mail is pushed to a filter script.
The filter script feeds SpamAssassin, then decides what to do with the mail.
We want to do filtering as an unprivileged user.
-sh$ useradd -s /bin/false mailfilter
Now we need our filter script.
Here's an example that sends messages flagged as spam by SpamAssassin to a spam dump address.
You can tweak as-needed to just trash spam, do something more complex like filter into user .Junk
maildirs, whatever -- it's pretty easy to understand (of course, a severely complex script
will negatively impact mail performance quite noticably...)
#### /etc/postfix/filter.sh ####
#!/bin/sh
# must be chmod +x
# also see http://wiki.apache.org/spamassassin/IntegratedSpamdInPostfix
SPAMTRAP='spamtrap@my.domain.example' ## !!! EDIT THIS !!!
SENDMAIL="/usr/sbin/sendmail -i"
SPAMASSASSIN="/usr/bin/spamc -u mailfilter"
# Exit codes from <sysexits.h>
EX_TEMPFAIL=75
EX_UNAVAILABLE=69
umask 077
OUTPUT="`mktemp -p /tmp mailfilter.XXXXXXXXXX`"
if [ "$?" != 0 ]; then
/usr/bin/logger -s -p mail.warning -t filter \
"Unable to create temporary file."
exit $EX_TEMPFAIL
fi
# Clean up when done or when aborting.
trap "rm -f $OUTPUT" EXIT TERM
# toss it at spamtrap if flagged, throw it back to post queue on error
# otherwise pass it
$SPAMASSASSIN -x -E > $OUTPUT
return="$?"
if [ "$return" = 1 ] # spam
then
/usr/bin/logger -s -p mail.info -t filter \
"Redirected SPAM to spamtrap."
$SENDMAIL $SPAMTRAP < $OUTPUT
elif [ "$return" != 0 ]; then # borked
/usr/bin/logger -s -p mail.warning -t filter \
"Temporary SpamAssassin failure (spamc returned $return)"
exit $EX_TEMPFAIL
else # we're cool, not spam, feed it back to postfix
$SENDMAIL "$@" < $OUTPUT
fi
exit $?
#### EOF ####
Okay, so we've got a workable filter script.
Let's tell Postfix to push incoming mail through it.
Edit /etc/postfix/master.cf and find the 'smtp' directive.
Add '-o content_filter=spamass' as follows:
## /etc/postfix/master.cf ##
smtp inet n - - - - smtpd
-o content_filter=spamass
####
Now browse towards the end of the file, where external interfaces are defined.
Add a new interface as follows:
## /etc/postfix/master.cf ##
spamass unix - n n - - pipe
flags=Rq user=mailfilter argv=/etc/postfix/filter.sh -oi -f ${sender} ${recipient}
####
That should be all you need.
DOVECOT CONFIGURATION
dovecot is great; simple, lightweight, and can handle authentication for us.
We already set up Postfix to hook SASL authentication into dovecot-auth.
Now we need something to auth against.
The following is a fairly complete dovecot.conf.
## /etc/dovecot/dovecot.conf ##
protocols = imap pop3 imaps pop3s
disable_plaintext_auth = no
ssl = yes
# generate these w/ openssl:
ssl_cert_file = /etc/dovecot/ssl/cert/dovecot.pem
ssl_key_file = /etc/dovecot/ssl/key/dovecot.pem
ssl_verify_client_cert = no
log_path = /var/log/dovecot
info_log_path = /var/log/dovecot.info
login_chroot = yes
login_user = dovecot
login_greeting = dovecot ready
valid_chroot_dirs = /var/spool/vmail
# maildir in /domain/name
mail_location = maildir:/var/spool/vmail/%d/%n
protocol imap {
login_executable = /usr/lib/dovecot/imap-login
mail_executable = /usr/lib/dovecot/imap
}
protocol pop3 {
login_executable = /usr/lib/dovecot/pop3-login
mail_executable = /usr/lib/dovecot/pop3
# outlook sucks hard:
pop3_client_workarounds = outlook-no-nuls oe-ns-eoh
}
# dovecot-auth for SASL:
auth default {
mechanisms = plain digest-md5 login
passdb passwd-file {
args = /etc/dovecot/users
}
userdb passwd-file {
args = username_format=%n /etc/dovecot/users
}
# needed for postfix to hook into dovecot-auth:
socket listen {
client {
path = /var/spool/postfix/private/auth
mode = 0660
user = postfix
group = postfix
}
}
}
####
The passdb/userdb directives above tell dovecot that auth will be handled by
a simple '/etc/passwd'-style flatfile.
The format of /etc/dovecot/users is as follows:
joe@netlandtowers.com:{plain}j0ema1l:1008:1008::/var/spool/vmail/netlandtowers.com/:/bin/false::
bob@netlandtowers.com:{plain}b0bmail:1008:1008::/var/spool/vmail/netlandtowers.com/:/bin/false::
Fairly self-explanatory format.
First field is the username (including the domain in login names cuts down confusion)
Second field is the password ({plain} specifies plaintext method -- you should probably at least use crypt...).
Use the ID for your 'vmail' user created during Postfix configuration in place of '1008'
The directory field should be the path to the domain this user is on.
IMPORTANT: You definitely do not want anyone reading /etc/dovecot/users:
-sh$ chgrp dovecot /etc/dovecot/users && chmod o-rwx /etc/dovecot/users
Now we have virtual mail. Create the spool directory for your domains:
-sh$ mkdir -p /var/spool/vmail/netlandtowers.com
-sh$ mkdir -p /var/spool/vmail/netlandwhitetower.com
We want the vmail user we created earlier to own this:
-sh$ chown -R vmail:vmail /var/spool/vmail
Check permissions on /etc/dovecot/users -- definitely make sure it isn't world-readable...
Add a user or two using the script below or similar.
Verify that everything looks correct after adding, then fire up postfix and dovecot.
If you're looking for simple and reasonably good webmail, try the Roundcube project.
MANAGING THE SYSTEM
Adding users manually sucks.
Here's an example script that handles adding a new user.
Read, understand, modify as appropriate:
## /etc/postfix/new_mailbox.sh ##
#!/bin/bash
# quick ugly hack for adding virtual mailboxes
vmail_uid=1008
vmail_gid=1008
postfix_vdomains="/etc/postfix/vmail-hosts"
postfix_vmaps="/etc/postfix/vmail-maps"
spool_dir="/var/spool/vmail"
vmail_usr="vmail"
user_db="/etc/dovecot/users"
if [[ `id -u` != 0 ]]
then
echo "Need to be superuser, sorry!"
exit
fi
echo "**** Available domains:"
cat ${postfix_vdomains}
echo -n "** New mailbox domain: "
read domain
echo -n "** User name: "
read username
echo -n "** Passwd: "
read passwd
echo "*** Adding ${username}@${domain} to ${postfix_vmaps}"
echo "${username}@${domain} ${domain}/${username}/" >> ${postfix_vmaps}
postmap ${postfix_vmaps}
echo "*** Creating mailboxes on disk in ${spool_dir}/${domain}/${username}"
mkdir -p ${spool_dir}/${domain}/${username}/{new,cur,tmp} || echo "mkdir failed"
mkdir -p ${spool_dir}/${domain}/${username}/.Trash/{new,cur,tmp}
mkdir -p ${spool_dir}/${domain}/${username}/.Junk/{new,cur,tmp}
mkdir -p ${spool_dir}/${domain}/${username}/.Sent/{new,cur,tmp}
mkdir -p ${spool_dir}/${domain}/${username}/.Drafts/{new,cur,tmp}
echo -e "Trash\nJunk\nSent\nDrafts" >> ${spool_dir}/${domain}/${username}/subscriptions
chown -R ${vmail_usr}:${vmail_usr} ${spool_dir}/${domain}/${username}
chmod -R 700 ${spool_dir}/${domain}/${username}
echo "*** Adding user to ${user_db}"
echo "${username}@${domain}:{plain}${passwd}:${vmail_uid}:${vmail_gid}::${spool_dir}/${domain}/:/bin/false::" >> ${user_db}
echo "*** Reloading mail servers"
/etc/init.d/postfix reload
/etc/init.d/dovecot reload
# EOF
####
Deletion is as easy as removing from postfix/vmail-maps (+ run postmap) and dovecot/users.
(...and archival/deletion of the appropriate mailbox in /var/spool/vmail)
|
|
|
Back to top |
|
|
likewhoa l33t
Joined: 04 Oct 2006 Posts: 778 Location: Brooklyn, New York
|
Posted: Tue Aug 17, 2010 2:10 pm Post subject: |
|
|
thanks for this script. |
|
Back to top |
|
|
comprookie2000 Retired Dev
Joined: 25 Jul 2004 Posts: 925 Location: Sun City Center, Florida
|
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|