This is G o o g l e's cache of http://www.marlow.dk/tech/postfix.html.
G o o g l e's cache is the snapshot that we took of the page as we crawled the web.
The page may have changed since that time. Click here for the current page without highlighting.
To link to or bookmark this page, use the following url: http://www.google.com/search?q=cache:v1cE_29kOmoC:www.marlow.dk/tech/postfix.html+sqwebmail+patch+download%26amp;hl=zh-CN%26amp;ie=UTF-8
Google is not affiliated with the authors of this page nor responsible for its content.
These search terms have been highlighted: sqwebmail patch download
--------------------------------------------------------------------------------
ISP Mailserver Solution Howto
Author: Martin List-Petersen martin@list-petersen.dk
The newest version of this document can allways be found at http://www.marlow.dk/postfix/
Version: 0.04
Created: May 11th, 2002
Last updated: May 15th, 2002
Acknowledgements: There has been many efforts out there to describe how to get a mailserver to work with storing tables, users and so on in databases, but most of the stuff found out there did only describe parts of, what was needed. So what i try, is to describe the setup, the way i did it. This is maybe not the solution you want, but it'll give you pretty much insight in, how it can be done. This document describes a working solution, which is used in production on several hosting servers with multiple domains, but gives you no warranty on that it'll work for you. This document is provided as is.
Thanks to Ryan Skov for testing and the work spend on getting this setup together.
Purpose
The goals of this document:
- archive an ISP hosting solution that is dynamically and easy to manage.
- to get rid of different limitations in comparison to creating unix accounts for every mailuser.
- to archive the possibility for CRAM-MD5 encryptet password challenges on POP and IMAP instead of cleartext.
- the domains hosted should be handled independant to each other (different namespaces for every domain).
- to be able to act as SMTP for clients without knowing their ip upfront, but still not being an open relay.
- scan mails for virus and notify hostmaster, sender and receiver on virus alerts.
Related Stuff:
- Postfix (MTA): http://www.postfix.org
- MySQL (sql server): http://www.mysql.com
- Courier-IMAP, POP3, SqWebMail (courier imap/pop3 servers and webmail, supporting maildirs): http://sourceforge.net/projects/courier/
- pam-mysql (pam plugin for storing auth data in mysql): http://sourceforge.net/projects/pam-mysql/
- sasl (client/server library for smtp auth): http://asg.web.cmu.edu/sasl/
- Amavis (wrapper script for virusscan): http://www.amavis.org
Packages which can be used on Debian:
postfix-mysql, postfix-tls
mysql-server
courier-imap, courier-pop, courier-authdaemon, courier-authmysql
libpam-mysql
libsasl7, libsasl-modules-plain
-- optionally courier-imap-ssl, courier-pop-ssl
-- optionally sqwebmail
-- optionally courier-maildrop, but the version in Debian has no MySQL support, needs recompile.
-- amavis has to be compiled by hand, no module found for that, but you will need the following packages:
file, bzip2, lha (min. rev. 1.14g), unarj, unzip, gzip, unrar, zoo,
perl-5.004, libio-stringy-perl, mailtools, libmime-perl, libmailtools-perl, libmime-base64-perl, libcompress-zlib-perl,
libnet-perl, libconvert-uulib-perl, libconvert-tnef-perl, tnef, libarchive-tar-perl, libarchive-zip-perl, libunix-syslog-perl
Also you will need arc, which can be found here: http://www.gws-online.de/download/arc_5.21e-5_i386.deb
The Background Story
The reason for this setup was quite simple. I wanted a solution, that was as flexible and easy to support as possible. To keep this as short and clear as possible, i'll take this in different parts.
- the user should have an easy login, like their complete email-address.
This does not polute the passwd file with thousands of different aliases and gives you as the system administrator a good view on, what customer you are talking to. Besides a customer knows nearly allways his email-address, since he uses it all the time. The username is easily forgotten. Another thing is, that you allways know the answer, if a customer can't remember his/her username.
- the password should be stored in plain text, not encryptet.
There are two reasons why this should be done. However, it's your choice. You have the ability to store it encryptet in the database, if you like that better.
The first reason is, that you'll be able to use CRAM-MD5 encryption for the password challenge. For this you need the plaintext password on both sides, since this is a one way encryption method.
The customers i know personally (and that are many of them) can give me a call and get their password on the phone, if they should forget it or so ...
- the smtp server should be used for smtp relay for accounts related on it.
There are several methods to archive that (pop-over-smtp, domain based relay, ip based relay and so on) without getting an open relay, but most of them require, that you know your customers location or requires him to authentificate on pop3 before being able to use smtp. I wanted to the smtp-auth feature, which is supported by most clients and i wanted to use the same username and password as on the pop3/imap server. Makes it easier for the customer to remember things. Also i didn't want to store the username in two places. I did choose pam-mysql for that, because the sasl-mysql patch out there is quite buggy. I managed to apply it and compiled the sasl lib afterwards, but couldn't get it to work. Pam-mysql works nice and does exactly fit my needs. Also in mind, that i can use it for ever i want afterwards (samba, shell-login .....)
- maildir is used for faster access to mails and a better structure, which mail is stored in.
Installation
Amavis
To configure Amavis:
./configure --enable-postfix --with-logdir=/var/log/amavis
--sysconfdir=/etc/amavis
--with-warnsender=/etc/amavis/template/sender
--with-warnrecip=/etc/amavis/template/recip
--with-warnadmin=/etc/amavis/template/admin
--with-amavisuser=vscan
--with-mailto=virusalert
--with-mailfrom=postmaster
- Documentation of this issue is not finished yet -
McAfee uvscan
The following Debian packages need to be installed:
libstdc++2.8
- Documentation of this issue is not finished yet -
Database
- "alias" table:
Overview
+-------------+--------------+------+-----+---------+----------------+
│ Field │ Type │ Null │ Key │ Default │ Extra │
+-------------+--------------+------+-----+---------+----------------+
│ id │ int(11) │ │ PRI │ │ auto_increment │
│ alias │ varchar(128) │ │ │ │ │
│ destination │ varchar(128) │ │ │ │ │
+-------------+--------------+------+-----+---------+----------------+
Comment
This table is only used on local delivery. So it wont work, if you deliver "virtual". Just have that in mind, when you configure your aliases. Also this is the only table, where can execute scripts directly.
Description id This is not necessary, but I also use the id field as an unique identifier in some other places, so it's up to you, if you want to use it.
alias The alias, you wish to redirect, could be postmaster, root or other aliases.
destination This field can hold several types of destinations. I can be one or more addresses (delimited by comma), a file for delivery to file, a "pipe" to a command for executing a script handling STDIN or an include, which has several addresses, one on each line.
Manual: aliases(5)
- "relocated" table:
Overview
+-------------+--------------+------+-----+---------+----------------+
│ Field │ Type │ Null │ Key │ Default │ Extra │
+-------------+--------------+------+-----+---------+----------------+
│ id │ int(11) │ │ PRI │ │ auto_increment │
│ email │ varchar(128) │ │ │ │ │
│ destination │ varchar(128) │ │ │ │ │
+-------------+--------------+------+-----+---------+----------------+
Comment
This table is only used to tell senders, that the user, they tried to contact doesn't exist on the server anymore, but has moved to a new address. All this does is generating a mailer-daemon message, telling the sender the new address, where this recipient moved to.
Description id This is not necessary, but I also use the id field as an unique identifier in some other places, so it's up to you, if you want to use it.
email The originally email-address.
destination The email-address, where the user can be found now. Eventually you just put "unknown" here, if you don't want to refer to a new address or you don't know the users new address.
Manual: relocated(5)
- "transport" table:
Overview
+-------------+--------------+------+-----+---------+----------------+
│ Field │ Type │ Null │ Key │ Default │ Extra │
+-------------+--------------+------+-----+---------+----------------+
│ id │ int(11) │ │ PRI │ │ auto_increment │
│ domain │ varchar(128) │ │ UNI │ │ │
│ destination │ varchar(128) │ │ │ │ │
+-------------+--------------+------+-----+---------+----------------+
Description id This is not necessary, but I also use the id field as an unique identifier in some other places, so it's up to you, if you want to use it.
domain The domain field contains the domainnames, of the domains you host.
destination This field is describing the way, postfix should deliver the mail. "local:" would be for local delivery, "virtual:" for delivery to the virtual accounts, we are going to use. You can use every transport type you want in this place. "maildrop:" for mails, who have to be filtered first (see description of maildrop, later in this document) or "uucp:" for delivery to UUCP. IMPORTANT: The hosts primary hostname has to be "local:" delivery !!
Manual: transport(5)
- "users" table:
Overview
+-------------+---------------+------+-----+---------+----------------+
│ Field │ Type │ Null │ Key │ Default │ Extra │
+-------------+---------------+------+-----+---------+----------------+
│ id │ int(11) │ │ PRI │ │ auto_increment │
│ email │ varchar(128) │ │ UNI │ │ │
│ clear │ varchar(128) │ │ │ │ │
│ name │ tinytext │ │ │ │ │
│ uid │ int(11) │ │ │ 1001 │ │
│ gid │ int(11) │ │ │ 1001 │ │
│ homedir │ tinytext │ │ │ │ │
│ maildir │ tinytext │ │ │ │ │
│ quota │ tinytext │ │ │ │ │
│ postfix │ enum('y','n') │ │ │ y │ │
+-------------+---------------+------+-----+---------+----------------+
Description id This is not necessary, but I also use the id field as an unique identifier in some other places, so it's up to you, if you want to use it.
email The users eMail-address and username
clear The cleartext password used for smtp-auth, pop3 and imap
name The users name. This is only for informational purpose and totally optionally. Courier can use it, but wont need it necessarily.
uid The uid (User ID) of the vmail-user, that we are going to create. This is the only unix-user, that is needed for virtual-delivery, since there still must be some kind of ownership on the stored mails.
You can also create your local unix-users in this table, if you want to give them the possibility to use CRAM-MD5 challenging and maybe give them another password, than the one used for local access. The fun thing about Courier is, that it will check both this and the local password, so that the unix-user will be able to authentificate with both passwords, however CRAM-MD5 challenging can not be used on allready encryptet passwords.
gid The gid (Group ID) of the vmail-user.
homedir This is the path, where the path where the homedir of the user resides. It's "/home/vmail" for our virtual users and should be the same allways for the virtual user, because it'll be hardcoded in postfix configuration. This field is only used by Courier. For any local unix-user this is his/her homepath.
maildir This is the path, where the mails reside inside the homedir. Postfix-style is, that the mails reside in "/Maildir" on local unix-users. For our vmail-user this is a bit different, because all mails for all users reside in the same homedir. Personally i use the format "/domain.tld/user/", some other prefer "/domain.tld/user/Maildir/". This is totally up to you, to choose, what fits your needs best. There is one caveeat here: Remember the trailing slash or else postfix will deliver your mail to a mailspool instead of a maildir.
quota - still not documented -
- "virtual" table:
Overview
+-------------+--------------+------+-----+---------+----------------+
│ Field │ Type │ Null │ Key │ Default │ Extra │
+-------------+--------------+------+-----+---------+----------------+
│ id │ int(11) │ │ PRI │ │ auto_increment │
│ email │ varchar(128) │ │ │ │ │
│ destination │ varchar(128) │ │ │ │ │
+-------------+--------------+------+-----+---------+----------------+
Comment - IMPORTANT !!
There are some caveeats in this table and the way, i've chosen to setup my postfix. If you want to use maildrop-address (addresses, that collect all mails not going to other recipients), you'll have to make an alias for every account created in the users-table. If an user isn't found in the virtual table, but a maildrop-address is found, mails will be delivered to the maildrop-address instead. By creating a row containing the user (some@domain.tld) in the email- and destination-fields, this doesn't happen. Postfix then also checks the users table and delivers the mail correctly.
Description id This is not necessary, but I also use the id field as an unique identifier in some other places, so it's up to you, if you want to use it.
email The email-address field. Here you can specify aliases of addresses in the format user@domain.tld, create a maildrop-address, create domain-canonicals or distributers.
The formats are accepted:
"domain.tld" - destination just has to contain anything. This is used for domains that are hosted without actually having an account. If you have an entry in the transport-table allready, you should not create this type, but in every other case it's needed to tell postfix, that this domain is hosted. This type has top priority for postfix. It'll allways be the first thing for a domain, that postfix looks for.
"user@domain.tld" - an email-alias or entry as mentioned in the comment. It's also the second priority.
"@domain.tld" - a maildrop-address. This takes all mail not yet delivered and sends it all to one recipient. Read the comment earlier in this document carefully, if you plan to use this. This thing has third priority.
The priorities are a nice thing about postfix, meaning, that you don't have to care about the order you insert your aliases in the database. Postfix handles this totally by itself and doesn't care about where in the database you aliases are and what order they are in.
One additional nice feature is having "@domain.tld" in email and "@other-domain.tld" in destination. This is normally used in the canonical table, but can also be put here, which is the reason, why i left the canonical table out. So if you want to have the same accounts on two domains you can do it this way.
destination The destination address for the alias. This could be a virtual user (user@domain.tld), a local unix-users or a remote email-address. You can also specify more than one recipient delimited by comma.
Manual: virtual(5)
Configuration
Linux Users/Files
Create a unix-user named vmail or whatever you want and change the configuration accordingly to that. Maildirs are created automatically by Postfix, when the first mail to an account arrive (if you've set the correct rights to the vmail-homedir). If you however use maildrop, then you'll be forced to create the maildirs manually with the maildirmake command, since maildrop and all other Courier utilities don't create maildirs automatically.
For Virus-scan add also a user named vscan, which is the user Amavis will be running under.
Postfix
Locate the postfix configuration files. These should reside in /etc/postfix on most Linux distributions (OpenBSD uses this also) or on FreeBSD you probably can locate them in /usr/local/etc/postfix
# master.cf
We'll have to create a new delivery, called virtual. The following line should do it:
virtual unix - n n - - virtual
If you're going to install maildrop filtering, add this line:
maildrop unix - n n - - pipe
flags=R user=vmail argv=/usr/bin/maildrop -d ${recipient}
And finally the virus scanning support based on amavis needs you to change a bit more.
Find the following line:
smtp inet n - n - - smtpd
and change it to:
smtp inet n - n - - smtpd
-o content_filter=vscan:
After that add the following lines:
vscan unix - n n - 10 pipe
user=vscan argv=/usr/sbin/amavis ${sender} ${recipient}
localhost:10025 inet n - n - - smtpd
# main.cf
Here we got several changes to do. Please add the following lines (evt. changing the paths to suit your needs):
home_mailbox = Maildir/
- this tells postfix to deliver Maildir-style.
mydestination = $myhostname, $transport_maps
- this tells postfix, to accept mails to $myhostname (should be the hostname of your host) and mails send to any domain in the transport-table. Of course postfix also will look in the virtual-table, if that exists. Eventually you should specify $mydomain here also, but i do it in the transport-table instead. Remember, that default delivery is local, unless anything else is specified in the transport table.
alias_maps = mysql:/etc/postfix/mysql-aliases.cf
relocated_maps = mysql:/etc/postfix/mysql-relocated.cf
transport_maps = mysql:/etc/postfix/mysql-transport.cf
virtual_maps = mysql:/etc/postfix/mysql-virtual.cf
- here we tell postfix, where to find the tables needed for this. Every of the files mentioned has information about, how to get the needed data out of the sql database.
local_recipient_maps = $alias_maps $virtual_mailbox_maps unix:passwd.byname
- these are the methods, how postfix will deliver to local recipients
virtual_mailbox_base = /home/vmail
virtual_mailbox_maps = mysql:/etc/postfix/mysql-virtual-maps.cf
virtual_uid_maps = mysql:/etc/postfix/mysql-virtual-uid.cf
virtual_gid_maps = mysql:/etc/postfix/mysql-virtual-gid.cf
- and finally the information about the virtual users. As you can see, the homedir is hardcoded here, where it is stored in the database for use by Courier.
broken_sasl_auth_clients = yes
smtpd_sasl_auth_enable = yes
smtpd_sasl_security_options = noanonymous
- these are for activation of sasl (smtp-auth)
maps_rbl_domains = rbl.maps.vix.com,
relays.mail-abuse.org,
relays.ordb.org,
dev.null.dk,
spews.relays.osirusoft.com,
spamhaus.relays.osirusoft.com,
relays.visi.com
- if you want to check for spammers, this is an ok choice of rbl-lists to check. However it's you choice, what to use and what not
smtpd_recipient_restrictions = permit_mynetworks,
permit_sasl_authenticated,
reject_maps_rbl,
check_relay_domains,
permit
- the permit_mynetworks allows your networks access no matter what, perm_sasl_authenticated is for smtp authentification, reject_maps_rbl rejects all mail from known spamsites and open relays defined by the maps_rbl_domains and the last permit allows everyone else to deliver to your site if the domain is located at your site.
Next the defintion of the mysql-queries. Note, that multiple sql-servers can be defined. This gives you the possibility for clustering. Also be careful: "127.0.0.1" is used intentionally instead of "localhost". Postfix tries to connect via socket, if you use "localhost" and that does somehow not work. By using "127.0.0.1" postfix get forced to connect by network via localhost.
Remember also to disable the "skip-networking" option in your MySQL configuration (on Debian /etc/mysql/my.cnf). It could give you trouble, if that is enabled.
# mysql-aliases.cf
user = mysql-postfix-user
password = mysql-postfix-pass
dbname = postfix
table = alias
select_field = destination
where_field = alias
hosts = 127.0.0.1
# mysql-relocated.cf
user = mysql-postfix-user
password = mysql-postfix-pass
dbname = postfix
table = relocated
select_field = destination
where_field = email
hosts = 127.0.0.1
# mysql-transport.cf
user = mysql-postfix-user
password = mysql-postfix-pass
dbname = postfix
table = transport
select_field = destination
where_field = domain
hosts = 127.0.0.1
# mysql-virtual.cf
user = mysql-postfix-user
password = mysql-postfix-pass
dbname = postfix
table = virtual
select_field = destination
where_field = email
hosts = 127.0.0.1
Now the definitions for the virtual users, providing postfix with maildir-directory, uid and gid to deliver to.
# mysql-virtual-maps.cf
user = mysql-postfix-user
password = mysql-postfix-pass
dbname = postfix
table = users
select_field = maildir
where_field = email
additional_conditions = and postfix = 'y'
hosts = 127.0.0.1
# mysql-virtual-uid.cf
user = mysql-postfix-user
password = mysql-postfix-pass
dbname = postfix
table = users
select_field = uid
where_field = email
additional_conditions = and postfix = 'y'
hosts = 127.0.0.1
mysql-virtual-gid.cf
user = mysql-postfix-user
password = mysql-postfix-pass
dbname = postfix
table = users
select_field = gid
where_field = email
additional_conditions = and postfix = 'y'
hosts = 127.0.0.1
Courier
Couriers configuration resides under /etc/courier on Debian. We'll have to edit a few of the configuration files here. I'll only mention lines to be changed. Everything else should stay in default or be changed to suit your needs # imapd
AUTHMODULES="authdaemon"
- we want all authentification handled by the authdaemon
IMAP_CAPABILITY="IMAP4rev1 CHILDREN NAMESPACE THREAD=ORDEREDSUBJECT THREAD=REFERENCES SORT AUTH=CRAM-MD5 AUTH=CRAM-SHA1 IDLE"
- this tells the IMAP daemon about the stuff it can handle. Change it to suit your needs, however note the AUTH= parameters, which enable CRAM-MD5 and CRAM-SHA1 authentification.
IMAPDSTART=YES
- this has to be yes, if you want the IMAP daemon to start.
# pop3d
AUTHMODULES="authdaemon"
- also here we want the authdaemon to handle the authentification.
POP3AUTH="LOGIN CRAM-MD5 CRAM-SHA1"
- and also here we want to provide CRAM-MD5 and CRAM-SHA1 challenging methods.
POP3DSTART=YES
- this has to be yes, if you want the POP3 daemon to start.
# authdaemonrc
authmodulelist="authmysql authpam"
- we specify authmysql for mysql authenfication and if you want to authentificate local users also, you can, like here, specify authpam or authshadow also. All types will be checked in that order you provide them.
# authmysqlrc
MYSQL_SERVER localhost
MYSQL_USERNAME mysql-postfix-user
MYSQL_PASSWORD mysql-postfix-pass
MYSQL_PORT 0
MYSQL_OPT 0
MYSQL_DATABASE postfix
MYSQL_USER_TABLE users
MYSQL_LOGIN_FIELD email
MYSQL_CLEAR_PWFIELD clear
MYSQL_UID_FIELD uid
MYSQL_GID_FIELD gid
MYSQL_HOME_FIELD homedir
MYSQL_MAILDIR_FIELD maildir
- here we specify the access to the database for both pop3 and imap, actually even sqWebMail, if you want to use that. sqWebMail is a Webmail-Solution, which also is in the Courier Project. It works quite well and is pretty fast, since it accesses the maildirs directly and is written in C. It uses the same authdaemon and can easily be customized, since it uses templates.
Here are some other options, which might be of your interest:
MYSQL_SOCKET /var/mysql/mysql.sock
- this gives you the possibility to use a local socket instead of an ip connnection.
MYSQL_CRYPT_PWFIELD crypt
- if you rather want to store your passwords encryptet, use this. Remember to change the database and be aware of that you cannot use CRAM-MD5 encryption with allready encrypted passwords. Also keep in mind, that you have to use the crypt() function and not the password() function in mysql to encrypt passwords.
MYSQL_NAME_FIELD name
- as mentioned before this is only of informational purpose and optional. Use it, if you want.
MYSQL_QUOTA_FIELD quota
- -- needs documentation --
SASL library
yep .... you saw right, this baby also needs a bit configuration :)
The configuration file needed is /usr/local/lib/sasl/smtpd.conf or on Debian /usr/lib/sasl/smtpd.conf and contains the following:
pwcheck_method: PAM
That should cover it.
PAM-MySQL
Most Linux Distributions have this file at /etc/pam.d/smtp, however you can also use other services with pam-mysql authentification. This is only the example, how to do it for postfix with smtp-auth.
# smtp
auth optional pam_mysql.so server=localhost db=postfix user=mysql-postfix-user
passwd=mysql-postfix-pass table=users usercolumn=email passwdcolumn=clear crypt=n
account required pam_mysql.so server=localhost db=postfix user=mysql-postfix-user
passwd=mysql-postfix-pass table=users usercolumn=email passwdcolumn=clear crypt=n
As you can see, also here you'll be able to change to having the passwords encryptet. I haven't tried it, but since smtp-auth also sends encryptet passwords, i'm not sure, it'll work with encryptet passwords in this case.