For small email systems, it's often more than adequate to have each mail account
'attached' to a real user (e.g., bob@example.com is for a user called bob who
has an entry in
/etc/passwd).
However, this solution limits you when you want to have lots of users with just
email accounts and nothing else, like if you wanted to give your friends webmail
accounts.
If you start hosting email for other domains, or have lots of users, the
limitation of having every user in
/etc/passwd
quickly becomes an major issue. The solution for this is virtual users, which
are accounts that the mail system knows about but which do not exist in
/etc/passwd.
However, account information still has to be stored somewhere. Normally, this
data is stored in a relational database. This gives a mail administrator several
advantages and more flexibility over his or her accounts. One advantage is that
it becomes easy to build a web interface to allow users to administer their own
accounts in an easy fashion.
One database that can be used for this task is [http://www.postgresql.org
PostgreSQL]. However, postfix does not know to talk to PostgreSQL in a default
installation. The rest of this article will cover enabling PostgreSQL support in
Postfix and setting up the database.
If you are running Debian, simply running the command:
# apt-get install postfix-pgsql
as the root user will install PostgreSQL support for Postfix.
If you are running the Ubuntu, running the command:
$ sudo apt-get install postfix-pgsql
as any user will install PostgreSQL support for Postfix. You need to use our
provided
sources.list
file, or add the
universe
repository manually.
Other distributions may include PostgreSQL support for Postfix. If they do, add
a section like the ones above describing how to install it, or noting that it is
enabled out-of-the-box. To check, run the command:
postconf -m
If the output lists:
pgsql
Then support for PostgreSQL is available. Failing that, you'll have to build
Postfix from source.
NB:
These are the official guide for enabling PostgreSQL support with Postfix and
installing Postfix from source code. The instructions here are adapted from the
above and intended as a guideline only. These instructions assume you have
familiarity with compiling software from source code. You should also read the
above documents to be sure you understand any other steps you need to take care
on your system to make Postfix properly work.
$ tar -xzf postfix-2.1.5.tar.gz
Note that Postfix 2.1.5 was the release when I wrote this. If the file you
download is different, substitute it's name in place of
postfix-2.1.5.tar.gz.
5. $ make tidy
6. $ make -f Makefile.init makefiles \
7. >'CCARGS=-DHAS_PGSQL -I<path to PostgreSQL includes>' \
>'AUXLIBS=-L<path to PostgreSQL libraries> -lpq'
Note that this will include only PostgreSQL support. If you need additional
options, you should read the installation guide linked above. By default, the
PostgreSQL headers are at
/usr/local/include/pgsql
and the libraries at
/usr/local/lib.
$ make
10. # groupadd postfix
11. # useradd -g postfix -d /nonexistent -s /bin/false postfix
# groupadd postdrop
# make install
$ createuser -U postgres -ADP postfix
It will prompt you for a password for this user. Remember it, as it must be
supplied later. For the rest of this article, we'll assume the password is
postfix.
Also, if your PostgreSQL administrator account isn't
postgres
(the default), replace it in the above command. If the administrator account has
a password, you will be prompted for it.
$ createdb -U postgres -O postfix mail
If your PostgreSQL administrator account isn't
postgres
(the default), replace it in the above command. If the administrator account has
a password, you will be prompted for it.
Three tables need to be created in the database:
The transport table has the following layout:
|
Column
|
Type
|
Modifiers
|
|
pkey
|
serial
|
|
|
domain
|
text
|
NOT NULL |
|
transport
|
varchar(128)
|
|
|
Primary Key:
pkey |
||
The
various columns are:
The user table has the following layout:
|
Column
|
Type
|
Modifiers
|
|
pkey
|
serial
|
|
|
id |
text
|
NOT NULL |
|
address
|
text
|
|
|
crypt
|
varchar(128)
|
|
|
uid
|
serial
|
|
|
gid
|
integer
|
NOT NULL |
|
home
|
varchar(256)
|
NOT NULL DEFAULT '/' |
|
domain
|
text
|
|
|
maildir
|
varchar(256)
|
NOT NULL |
|
absolute_maildir
|
text
|
|
|
Primary Key:
pkey |
||
The various columns are:
The virtual table has the following layout:
|
Column
|
Type
|
Modifiers
|
|
pkey
|
serial
|
|
|
address
|
text
|
NOT NULL |
|
goto
|
text
|
NOT NULL |
|
Primary Key:
pkey |
||
The
various columns are:
The following steps will create the tables:
$ psql -U postfix mail
If you are prompted for the postfix account password, enter it.
3. CREATE TABLE transport (
4. pkey serial,
5. domain text NOT NULL,
6. transport varchar(128),
7. PRIMARY KEY ( pkey )
);
9. CREATE TABLE users (
10. pkey serial,
11. id text NOT NULL,
12. address text,
13. crypt varchar(128),
14. uid serial NOT NULL,
15. gid integer NOT NULL,
16. home varchar(256) NOT NULL DEFAULT '/',
17. domain text,
18. maildir varchar(256) NOT NULL,
19. absolute_maildir text,
20. PRIMARY KEY ( pkey )
);
22. CREATE TABLE virtual (
23. pkey serial,
24. address text NOT NULL,
25. goto text NOT NULL,
26. PRIMARY KEY ( pkey )
);
The next
step is to configure Postfix to access the data stored in the PostgreSQL
database. This is done by creating several text files. These text files should
go into /etc/postfix,
or wherever your Postfix configuration is kept. All of the files follow more or
less the same format.
This file
sets up the mailbox maps and should look like:
# The database username
user=postfix
# The database password
password=postfix
# The database name
dbname=mail
# The table containing the user data
table=users
#the field containing the users maildir location
select_field=maildir
#the field containing the users email address. It's used in the query
# SELECT * FROM [table] WHERE [this field] = <email address>
where_field=address
# The database host. You can have more than one host here, which is
# useful if you want to have a backup database.
hosts=127.0.0.1
Change
the parameters as necessary to match your configuration.
This file
sets up the transport maps and should look like:
user=postfix
password=postfix
dbname=mail
table=transport
select_field=transport
where_field=domain
hosts=127.0.0.1
Change
the parameters as necessary to match your configuration.
This file
sets up the virtual maps and should look like:
user=postfix
password=postfix
dbname=mail
table=virtual
select_field=goto
where_field=address
hosts=127.0.0.1
This file
sets up the uid maps and should look like:
user=postfix
password=postfix
dbname=mail
table=users
select_field=uid
where_field=address
hosts=127.0.0.1
This file
sets up the gid maps and should look like:
user=postfix
password=postfix
dbname=mail
table=users
select_field=gid
where_field=address
hosts=127.0.0.1
In
main.cf
add or edit the following lines as appropriate.
transport_maps=pgsql:/etc/postfix/transport.cf
virtual_mailbox_maps=pgsql:/etc/postfix/pgsql_virt.cf
virtual_uid_maps=pgsql:/etc/postfix/uids.cf
virtual_gid_maps=pgsql:/etc/postfix/gids.cf
virtual_mailbox_base=/var/spool/postfix/virtual/
mydestination = $mydomain, $myhostname, $transport_maps
virtual_maps =pgsql:/etc/postfix/virtual.cf
relay_domains = $mydestination
Postfix
is now setup to gather its data from the database. However, data has to be put
into the database in order for it to actually be useful. The first thing that
has to be created is a domain entry. To do this:
$ psql -U postfix mail
If you are
prompted for the postfix account password, enter it.
mail=# INSERT INTO transport (domain, transport) VALUES ('example.com', 'virtual');
This creates
an entry for domain
example.com;
replace example.com
in the above with whatever domain you want to create.
5. # mkdir /var/spool/postfix/virtual/example
6. # chown postfix:<gid> /var/spool/postfix/virtual/example
# chmod 775 /var/spool/postfix/virtual/example
Replace
gid in the above with GID you chose in the previous step.
Now,
users entries in the newly created domain have to be added:
$ psql -U postfix mail
If you are
prompted for the postfix account password, enter it.
3. INSERT INTO users (id, domain, address, crypt, gid, maildir, absolute_maildir)
4. VALUES (
5. 'bob@example.com',
6. 'example.com',
7. 'bob@example.com',
8. 'T/c7XRT543rW2', -- The user's encrypted password
9. <gid>, -- The GID from the domain creation
10. '/example/bob/',
'/var/spool/postfix/virtual/example/bob/');
To generate the user's password, run the following command:
$ perl -e "print crypt ('<password>', '<salt>');"
where
password is the user's desired password and salt is any two
alphanumeric characters. The encrypted password will be printed to standard out.
In order
for virtual users to be able to access their mail, Courier must be configured to
lookup the data in the database as well. Fortunately, this is much easier than
the Postfix configuration. Create a file called
authpgsqlrc
in the Courier configuration directory (normally
/etc/courier
or /usr/lib/courier/etc
for custom installs). It should have the following contents:
PGSQL_HOST 127.0.0.1
PGSQL_PORT 5432
PGSQL_USERNAME postfix
PGSQL_PASSWORD postfix
PGSQL_DATABASE mail
PGSQL_USER_TABLE users
PGSQL_CRYPT_PWFIELD crypt
PGSQL_UID_FIELD uid
PGSQL_GID_FIELD gid
PGSQL_LOGIN_FIELD id
PGSQL_HOME_FIELD home
PGSQL_MAILDIR_FIELD absolute_maildir
Finally,
make sure authpgsql
is included on the
authmodulelist
line in the
authdaemonrc
file. If it is not, add it and then restart the Courier authdaemon.