E-mail server section: Difference between revisions

From SaruWiki
Jump to navigation Jump to search
(Added first mysql config file)
m (→‎MySQL configuration: added data addition)
Line 45: Line 45:
* ''dovecot-imapd'' is a daemon that will provide your users with IMAP access to their mail;
* ''dovecot-imapd'' is a daemon that will provide your users with IMAP access to their mail;
* ''dovecot-pop3d'' is another daemon, but for the POP3 protocol.
* ''dovecot-pop3d'' is another daemon, but for the POP3 protocol.
==Virtual Mailman creation==
When we're done, we'll need a "system user", a sort of virtual mailman that is the owner of all mailboxes that we're serving. We suggest the name "vmail" for this user. Note: this user does not get his own mailbox (i.e. there's no mailbox at vmail@saruman.biz).
To create this user, and his home directory, we can run the following commands:
groupadd -g 120 vmail
useradd -g vmail -u 120 vmail -d /data/vmail -m -s /bin/false
As you see, we've chosen a group ID and user ID of 120 (after confirming that this ID was not taken by another group or user, by checking ''/etc/passwd'' and ''/etc/group''. Furthermore, we've decided to keep the ''vmail'' user's home directory not under ''/home/vmail'', but in a special place where we're going to expect server data to reside - in our server, the ''/data'' directory (which is a RAID-5 array mounted under root). By adding ''-m'', we've actually created the home directory, and adding ''-s /bin/false'' makes totally sure that the user ''vmail'' can never ever log in - even if we've not created a password for this user, so ''vmail'' shouldn't be able to log in anyway. Better safe than sorry.
To tell Postfix that this ''vmail'' user is someone special, we run
postconf -e virtual_uid_maps=static:120
postconf -e virtual_gid_maps=static:120
That makes postfix understand that all mail for the virtual mail domains must be written to disk with these specified user and group ID's.


==MySQL configuration==
==MySQL configuration==
Line 51: Line 64:
(This of course assumes you have ''create.vmail.sql'' in your current working directory; if not you can include the path to the file.) Simply give the MySQL root user password, and the script creates the database, the user, and the necessary tables.
(This of course assumes you have ''create.vmail.sql'' in your current working directory; if not you can include the path to the file.) Simply give the MySQL root user password, and the script creates the database, the user, and the necessary tables.


We're not going to fill the database tables just yet, but we ''are'' going to tell Postfix to use the ''vmail'' database, and also ''how'' to read the database. To this end, we're going to create three configuration files in directory ''/etc/postfix''. We'll start off with one configuration file, with which Postfix can determine if a domain name is among the domain(s) that it's actually hosting mailboxes for.
Next up, we fill the database with the first sets of values. We'll start off with the virtual domains that we're hosting, by running the mysql client and feeding it information like this:
mysql -u root -p vmail
mysql> INSERT INTO virtual_domains (id, vdomain) VALUES (1, 'saruman.biz');
mysql> INSERT INTO virtual_domains (vdomain) VALUES ('wiki.saruman.biz');
mysql> INSERT INTO virtual_domains (vdomain) VALUES ('shop.saruman.biz');
mysql> exit
This has the effect of creating three entries. Now Postfix will be able to recognise that you have three virtual mail domains (namely the three domains in the VALUES section) for which it hosts virtual mailboxes.
 
Note: only the first entry needs an ''id'' value, because in MySQL we've defined that field as AUTO_INCREMENT. After creating your first virtual domain in the table, you never have to use a statement like the first INSERT again, only statements like the other two.
 
Whle still within the mysql client, we can now create users:
mysql> INSERT INTO virtual_users (id, domain_id, user, passwd) VALUES (1, 1, 'jan', MD5('JanSecret'));
mysql> INSERT INTO virtual_users (domain_id, user, passwd) VALUES (1, 'mike', MD5('MikeSecret'));
mysql> INSERT INTO virtual_users (domain_id, user, passwd) VALUES (3, 'shopkeeper', MD5('ShopSecret'));
This has the effect of creating three users "jan" (in domain saruman.biz), "mike" (in domain saruman.biz) and "shopkeeper" (in domain shop.saruman.biz). Again, the ''id'' value is only ever needed in the first statement, because from now on every user addition will auto-increment ''id''.
 
The passwords shown are encrypted with MD5, and put in the ''passwd'' field. Later on, the users will be able to access their mailboxes using this password; we won't tell Postfix anything about them, because it doesn't need the passwords.
 


Next, we're going to tell Postfix to use the ''vmail'' database, and also how to read the database (Postfix never writes the MySQL database). To this end, we're going to create three configuration files in directory ''/etc/postfix''. We'll start off with one configuration file, with which Postfix can determine if a domain name is among the domain(s) that it's actually hosting mailboxes for. Then we'll create the config file that checks the table that contains all the users that have a virtual mailbox, and finally we create the lookup for the table with all the aliases.
===Virtual mail domains lookup===
Create file ''/etc/postfix/mysql-virtual-domains.cf'' with the following content:
Create file ''/etc/postfix/mysql-virtual-domains.cf'' with the following content:
  user = vmail_admin
  user = vmail_admin
Line 63: Line 96:
  chmod o=/etc/postfix/mysql-virtual-domains.cf
  chmod o=/etc/postfix/mysql-virtual-domains.cf
  postconf -e virtual_mailbox_domains=mysql:/etc/postfix/mysql-virtual-domains.cf
  postconf -e virtual_mailbox_domains=mysql:/etc/postfix/mysql-virtual-domains.cf
Use of this configuration file in postfix has the effect of returning "yes" when checking our database for the domain part of an email address. Naturally, this configuration file has to be fitted with the actual ''vmail_admin'' password rather than our example "SuperSecret". Furthermore, we'll have to fill our database with all virtual domains that we're hosting, by running the mysql client and feeding it information like this:
Use of this configuration file in postfix has the effect of returning "yes" when checking our database for the domain part of an email address. Naturally, this configuration file has to be fitted with the actual ''vmail_admin'' password rather than our example "SuperSecret".  
mysql -u root -p vmail
mysql> INSERT INTO virtual_domains (id, vdomain) VALUES (1, 'saruman.biz');
mysql> INSERT INTO virtual_domains (vdomain) VALUES ('wiki.saruman.biz');
mysql> INSERT INTO virtual_domains (vdomain) VALUES ('shop.saruman.biz');
mysql> exit
This has the effect of creating three entries. Only the first entry needs an ''id'' value, because in MySQL we've defined that field as AUTO_INCREMENT. After creating your first virtual domain in the table, you never have to use a statement like the first INSERT again, only statements like the other two.


After creating data like this, postfix will be able to recognise that you have three virtual mail domains (namely the three domains in the VALUES section) for which it hosts virtual mailboxes. However,
=== Virtual mail user lookup===
Create the file ''/etc/postfix/mysql-virtual-mailbox-maps.cf'' with the following content:
user = vmail_admin
password = SuperSecret
hosts = 127.0.0.1
dbname = vmail
query = SELECT 1 FROM view_users WHERE email='%s'
Next, we change the attributes on this configuration file so that it is secure. Also, we tell Postfix that this mapping file is supposed to be used for the ''virtual_mailbox_maps'' mapping:
chown root:postfix /etc/postfix/mysql-virtual-mailbox-maps.cf
chmod o=/etc/postfix/mysql-virtual-mailbox-maps.cf
postconf -e virtual_mailbox_maps=mysql:/etc/postfix/mysql-virtual-mailbox-maps.cf
However, the lookup of virtual mailboxes at present will not work (yet), because we need data in the ''users'' table.

Revision as of 10:41, 1 November 2008

E-mail server setup

What we want to accomplish here is the setup of a mail server with the following properties:

  • can serve multiple mail domains
  • can relay mail for other domains to other mail servers
  • can have one or more mailboxes per domain
  • users of these mailboxes can be virtual (do not need to have a Linux user account)
  • can have multiple aliases per mailbox
  • can forward mail for certain aliases to multiple mailboxes

For this type of mail server setup, we owe a great thankyou to Christoph Haas, whose advise has helped us create flexible and reliable mail servers since 2003.

Preparation

We'll assume that the server currently has no mailserver installed, at least no other than the default exim mailserver. Furthermore, the server is already fitted with MySQL, and this database is running without problems.

The hostname of the server must be set correctly, so that hostname -f returns a valid DNS name, like lighthouse.saruman.biz.. It might also be an internal name like lighthouse.saruman.lan. but that will require us to give extra attention to the name under which Postfix will contact its collegues on the Internet. Also, the server can correctly [Networking_section#DNS_resolution_under_Debian | resolve DNS names] like www.debian.org, preferably by running it's own caching DNS server.

The server is kept on the correct date and time using NTP, TCP port 25 is open on the server, the ISP will allow connections from Internet to this port, and if there's a firewall running on this server, then it has port 25 open so as to not block incoming e-mail.

Software installation

As a first step, we use apt or aptitude to make sure that our server is up-to-date. Then we can install the necessary software packages. Under Debian 5.0 "Lenny", the (single) packages is:

  • postfix, the mail server itself - this includes the "virtual package" postfix-tls, that we want to use to secure connections to Postfix with the TLS protocol

At the same time we can - and must - purge the following packages:

  • exim4
  • exim4-base
  • exim4-daemon-light
  • exim4-config

In aptitude, only press "go" when you've marked all four of these packages "purge", or you cannot install postfix.

When installing the postfix package, the Debian installer script will ask you several questions, which you can answer like this:

  • General type of mail configuration: Internet site
  • System mail name: the FQDN of the mail server that you've verified in the previous section. Note that the script will try to guess the DNS name, but that might yield a DNS name with a trailing dot. That is technically correct, but the installation script will barf. Remove the trailing dot before hitting <enter>!
  • Postmaster mail address: the address that all mail should go to that is addressed to "root" and "postmaster".
  • Domain list: give the list of all domains that the machine can consider itself the FINAL destination for. This should at a minimum include an empty value, "localhost" and the FQDN of the machine itself (no trailing dots!); however, if you're running your own mail domain, you can also add that (e.g. "saruman.biz"). Thus, the list could look like this:
saruman.biz, lighthouse.saruman.lan, localhost.saruman.lan, , localhost
  • Force synchronous updates? We think that's not necessary, but please read the question and decide for yourself
  • Local networks: something like 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 192.168.67.0/24 (the default, augmented with your local IP range)
  • Mailbox size limits: you can give postfix a limit in bytes, but we're going to use one single big mailbox for all users, so we cannot let Postfix guard it. Leave it at 0 (zero) so we don't have a size limit.
  • Character for local address extension: we leave it at +
  • Internet protocols to use: currently we don't have IPv6 support, so there's no sense in letting Postfix try to serve IPv6. We choose ipv4 only.

With the above data, the Debian install script for Postfix can do its job and configure Postfix with some basic settings.

Now that Postfix is installed, we can install some dependent packages (we could install them in the same run, but if anything goes amiss with the postfix installation, then these packages are going to remain unconfigured as well):

  • postfix-doc, the accompanying documentation;
  • postfix-mysql, necessary to have Postfix talk to our MySQL server;
  • postfix-pcre to be able to parse regular expressions, which which we can combat spam;
  • dovecot-imapd is a daemon that will provide your users with IMAP access to their mail;
  • dovecot-pop3d is another daemon, but for the POP3 protocol.

Virtual Mailman creation

When we're done, we'll need a "system user", a sort of virtual mailman that is the owner of all mailboxes that we're serving. We suggest the name "vmail" for this user. Note: this user does not get his own mailbox (i.e. there's no mailbox at vmail@saruman.biz).

To create this user, and his home directory, we can run the following commands:

groupadd -g 120 vmail
useradd -g vmail -u 120 vmail -d /data/vmail -m -s /bin/false

As you see, we've chosen a group ID and user ID of 120 (after confirming that this ID was not taken by another group or user, by checking /etc/passwd and /etc/group. Furthermore, we've decided to keep the vmail user's home directory not under /home/vmail, but in a special place where we're going to expect server data to reside - in our server, the /data directory (which is a RAID-5 array mounted under root). By adding -m, we've actually created the home directory, and adding -s /bin/false makes totally sure that the user vmail can never ever log in - even if we've not created a password for this user, so vmail shouldn't be able to log in anyway. Better safe than sorry.

To tell Postfix that this vmail user is someone special, we run

postconf -e virtual_uid_maps=static:120
postconf -e virtual_gid_maps=static:120

That makes postfix understand that all mail for the virtual mail domains must be written to disk with these specified user and group ID's.

MySQL configuration

We will use the MySQL database to record data on our mail system, and then give our Postfix access to this database so that it can read its configuration from there. For starters, we'll create a MySQL database named "vmail", and a MySQL user named "vmail_admin" that can read all necessary data from that "vmail" database. Then, we create the necessary tables. We do this with the MySQL client mysql. However, we're quite lazy, so we don't create this database by hand, but by use of a script create.vmail.sql. To this end, feed the create.vmail.sql script into the mysql client like this:

mysql -u root -p < create.vmail.sql

(This of course assumes you have create.vmail.sql in your current working directory; if not you can include the path to the file.) Simply give the MySQL root user password, and the script creates the database, the user, and the necessary tables.

Next up, we fill the database with the first sets of values. We'll start off with the virtual domains that we're hosting, by running the mysql client and feeding it information like this:

mysql -u root -p vmail
mysql> INSERT INTO virtual_domains (id, vdomain) VALUES (1, 'saruman.biz');
mysql> INSERT INTO virtual_domains (vdomain) VALUES ('wiki.saruman.biz');
mysql> INSERT INTO virtual_domains (vdomain) VALUES ('shop.saruman.biz');
mysql> exit

This has the effect of creating three entries. Now Postfix will be able to recognise that you have three virtual mail domains (namely the three domains in the VALUES section) for which it hosts virtual mailboxes.

Note: only the first entry needs an id value, because in MySQL we've defined that field as AUTO_INCREMENT. After creating your first virtual domain in the table, you never have to use a statement like the first INSERT again, only statements like the other two.

Whle still within the mysql client, we can now create users:

mysql> INSERT INTO virtual_users (id, domain_id, user, passwd) VALUES (1, 1, 'jan', MD5('JanSecret'));
mysql> INSERT INTO virtual_users (domain_id, user, passwd) VALUES (1, 'mike', MD5('MikeSecret'));
mysql> INSERT INTO virtual_users (domain_id, user, passwd) VALUES (3, 'shopkeeper', MD5('ShopSecret'));

This has the effect of creating three users "jan" (in domain saruman.biz), "mike" (in domain saruman.biz) and "shopkeeper" (in domain shop.saruman.biz). Again, the id value is only ever needed in the first statement, because from now on every user addition will auto-increment id.

The passwords shown are encrypted with MD5, and put in the passwd field. Later on, the users will be able to access their mailboxes using this password; we won't tell Postfix anything about them, because it doesn't need the passwords.


Next, we're going to tell Postfix to use the vmail database, and also how to read the database (Postfix never writes the MySQL database). To this end, we're going to create three configuration files in directory /etc/postfix. We'll start off with one configuration file, with which Postfix can determine if a domain name is among the domain(s) that it's actually hosting mailboxes for. Then we'll create the config file that checks the table that contains all the users that have a virtual mailbox, and finally we create the lookup for the table with all the aliases.

Virtual mail domains lookup

Create file /etc/postfix/mysql-virtual-domains.cf with the following content:

user = vmail_admin
password = SuperSecret
hosts = 127.0.0.1
dbname = vmail
query = SELECT 1 FROM virtual_domains WHERE vdomain='%s'

Next, we change the attributes on this configuration file so that it is secure. Also, we tell postfix to check this configuration file when it needs to check "virtual_mailbox_domains":

chown root:postfix /etc/postfix/mysql-virtual-domains.cf
chmod o=/etc/postfix/mysql-virtual-domains.cf
postconf -e virtual_mailbox_domains=mysql:/etc/postfix/mysql-virtual-domains.cf

Use of this configuration file in postfix has the effect of returning "yes" when checking our database for the domain part of an email address. Naturally, this configuration file has to be fitted with the actual vmail_admin password rather than our example "SuperSecret".

Virtual mail user lookup

Create the file /etc/postfix/mysql-virtual-mailbox-maps.cf with the following content:

user = vmail_admin
password = SuperSecret
hosts = 127.0.0.1
dbname = vmail
query = SELECT 1 FROM view_users WHERE email='%s'

Next, we change the attributes on this configuration file so that it is secure. Also, we tell Postfix that this mapping file is supposed to be used for the virtual_mailbox_maps mapping:

chown root:postfix /etc/postfix/mysql-virtual-mailbox-maps.cf
chmod o=/etc/postfix/mysql-virtual-mailbox-maps.cf
postconf -e virtual_mailbox_maps=mysql:/etc/postfix/mysql-virtual-mailbox-maps.cf

However, the lookup of virtual mailboxes at present will not work (yet), because we need data in the users table.