I’m using Postfix as the mail transport agent (MTA) and Dovecot as the mail delivery agent (MDA), and the mail server will serve just one domain (for now). The domain will be served as a virtual host. This means that the mail users don’t need their own login account on the server, and additional domains can be served in future with minimal changes.
Many thanks go to Raymond Mentjens for his help in fixing a few (actually, quite a few) errors, and for all his feedback while he followed this article. He has also created his own guides in Dutch – so if you read Dutch better than English, you may want to take a look at his site.
Versions
This how-to guide was updated in May 2009 for compatibility with the following package versions:
- Postfix 2.3.6-3
- Dovecot v1.2.0.beta1-2
This how-to may also work with previous versions, but may require slight changes with respect to paths – for example, previous versions of Dovecot installed dovecot.conf to /opt/etc/dovecot.conf, but the latest version installs it to /opt/etc/dovecot/dovecot.conf.
Install Postfix
Issue the command:
ipkg install postfix
The Postfix installation automatically creates a new group called maildrop; check maildrop is created:
more /etc/group
If the group is not there, you will have to create it yourself. Also note that it might suddenly disappear, requiring you to add it manually. For both eventualities, see the notes below.
Now we’ll need to start editing the configuration files to customise Postfix to our needs.
vi /opt/etc/postfix/master.cf
Add -v to the end of the line that specifies the smtp daemon so it reads smtpd -v (the line you need to modify is the first in the table, just beneath several lines of comments). This enables verbose output to the log file, which you should monitor in a separate PuTTY window using the following command:
tail -f /var/log/messages
This will help give you an idea of when and why problems occur. Note that tail sometimes hangs, and if you don’t see log output when you think you should then it may be time to abort tail (with CTRL+C) and restart it.
Let’s edit the main Postfix configuration file:
vi /opt/etc/postfix/main.cf
And provide our own values for the following parameters:
myhostname = <your slug’s host name – eg. mail.yourdomain.com>
inet_interfaces = all
proxy_interfaces = <your external ip address>
mynetworks_style = subnet
Before Postfix can be started, it needs to know where to deliver mail that is addressed to users such as root, postmaster, and other pseudo-accounts. The file that contains this mapping is /opt/etc/postfix/aliases. Edit the file:
vi /opt/etc/postfix/aliases
Uncomment the root alias, and provide the address where mail to root should be delivered (using your own address is a wise choice):
# Person who should get root’s mail. Don’t receive mail as root!
root: <your email address>
Now the file should be copied to /opt/etc/aliases, and turned into a hash file that postfix can read, using the newaliases tool. The output file is /opt/etc/aliases.db:
cp /opt/etc/postfix/aliases /opt/etc/aliases
newaliases
Now start Postfix, keeping an eye on your second PuTTY window for any messages Postfix might emit.
/opt/etc/init.d/S69postfix
At various points you’ll need to change Postfix configuration, and Postfix will need to reload those changes. You can do this with:
/opt/etc/init.d/S69postfix restart
Or, if you don’t like to keep stopping and starting it, you can simply issue:
postfix reload
Testing Postfix
Use telnet to connect to your slug’s smtp port:
telnet <slug’s host name or IP address> smtp
Make sure you can send mail, by having the following conversation with Postfix:
220 mail.yourdomain.com ESMTP Postfix
mail from:some_user
250 2.1.0 Ok
rcpt to:<an external email address you can check>
250 2.1.5 Ok
data
354 End data with <CR><LF>.<CR><LF>
Subject:Test Mail 1
This is a test message.
.
250 2.0.0 Ok: queued as EF7E4208003
When you check the email address to which you sent your test mail, you’ll see it comes from some_user@mail.localdomain (or something similar, according to what you put in your postfix configuration file), and is generally badly formed. Don’t worry, a proper email client will provide the necessary data, whereas we only provided the bare minimum. Note that some mail servers may reject this test mail because the sender’s address is malformed (i.e. the domain doesn’t exist). In this case, you will need to use a valid-looking email address (such as some_user@test.com) or even your own address.
If you don’t receive the test email, you can check the postfix queue to see whether an error occured:
postqueue -p
And also delete any failed/stuck messages:
postsuper -d <queue_id>
On a side note, it’s a good demonstration of how easy it is to send untraceable spam. The IP address in the email header is the only indication of where the email originated; but this can be faked quite easily.
Finalise Postfix Configuration
There’s already a convenient user and group (both called mail) configured by the system which Postfix can use to manage the mail store, so all we need to do it find out the uid and gid.
grep mail /etc/passwd
The 3rd and 4th elements of the output are the uid and gid respectively. Write them down; we’ll need them in a minute.
We need a disk location for storing users’ mail; I chose /var/spool/vmail, which seems as good as any. The following script creates the initial directory structure, along with the additional directories for user@yourdomain.com mail storage. The /var/spool directory didn’t exists on my system, so rather than checking to see if there was a more logical/suitable storage location elsewhere, I simply created it with brute force.
mkdir /var/spool
cd /var/spool
mkdir vmail
cd vmail
mkdir yourdomain.com
cd yourdomain.com
mkdir user
cd user
mkdir new cur tmp
Now the new directories need the right owners and permissions: root owns /var/spool (and gives full permission to everyone), whereas the vmail directory (and everything within it) is owned by mail, and only mail (and members of the mail group) have permissions.
chmod ugo=rwx /var/spool
chown -R mail:mail /var/spool/vmail
chmod -R ug=rwx,o= /var/spool/vmail
You can double-check this afterwards:
ls -l -R /var/spool/vmail | more
In order to use Dovecot’s SMTP AUTH mechanism, Postfix needs to know where Dovecot’s daemon socket is located. Currently it isn’t located anywhere, so that needs to be fixed:
cp /opt/var/spool/postfix/private/anvil /opt/var/spool/postfix/private/auth
chmod go=rw /opt/var/spool/postfix/private/auth
chown mail:mail /opt/var/spool/postfix/private/auth
Time to edit the postfix config again.
vi /opt/etc/postfix/main.cf
The config file isn’t set up with default values for virtual hosts, so these need to be added. We also tell Postfix that we’re using Dovecot for SMTP AUTH, and point it to the socket location we just created (relative to the queue directory). Note that as soon as we tell Postfix about the socket, it will grumble and complain (and fail to run) because Dovecot hasn’t created the socket yet. We’ll do that shortly.
# LOCAL CONFIG
local_recipient_maps = $virtual_mailbox_maps
# SMTP AUTH
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
# VIRTUAL HOSTS
# Config for virtual domains that are hosted by this server.
virtual_mailbox_domains = /opt/etc/postfix/virtual-hosts
virtual_mailbox_base = /var/spool/vmail
virtual_mailbox_maps = hash:/opt/etc/postfix/virtual-maps
virtual_uid_maps = static:<mail uid>
virtual_gid_maps = static:<mail gid>
virtual_minimum_uid = <mail uid>
Replace <mail uid> and <mail gid> with the uid and gid you noted earlier on.
Now we are left with two files to create. The file /opt/etc/postfix/virtual-hosts should contain a list of all the domains you are hosting, one on each line. The file /opt/etc/postfix/virtual-maps defines the storage location for your mail users.
virtual-hosts:
yourdomain.com
virtual-maps:
you@yourdomain.com yourdomain.com/you/
me@yourdomain.com yourdomain.com/me/
The second column is the storage path, relative to $virtual_mailbox_base. So mail for you@yourdomain.com will be stored in /var/spool/vmail/yourdomain.com/you. The trailing slash in the file is important, and specifies that the Maildir format of mail storage is to be used, as opposed than mbox. Maildir stores each mail as a separate file, which makes more sense to me than mbox, which stores all mail in one file.
We now turn /opt/etc/postfix/virtual-maps into a hash file, and give Postfix read permission:
postmap /opt/etc/postfix/virtual-maps
chmod o+r /opt/etc/postfix/virtual-maps.db
You can now restart the server so your changes take effect, but bear in mind that the smptd process will crash if you try to connect to it – because the Dovecot socket doesn’t exist yet.
/opt/etc/init.d/S69postfix restart
Install Dovecot
ipkg install dovecot
First, a warning: Dovecot caused more trouble than anything I’ve done with the Slug so far. It’s easier to configure than Postfix, but easier to mess up, too!
For starters, you will definitely want to edit the Dovecot config to turn logging on:
vi /opt/etc/dovecot/dovecot.conf
At the start of the file insert the following parameters (we’ll be removing them again later):
log_path = /var/log/dovecot
info_log_path = /var/log/dovecot
auth_debug = yes
auth_verbose = yes
Let’s tell Dovecot where mail can be found. Edit the mail_location parameter as follows. This tells Dovecot that mail for you@yourdomain.com can be found at /var/spool/vmail/yourdomain.com/you. Note that in older versions of Dovecot this setting was default_mail_env.
mail_location = maildir:/var/spool/vmail/%d/%n
Now we want to tell Dovecot about the STMP AUTH socket it needs to create. Find the auth default configuration block (about 80% of the way through the file) and add/edit the following configuration block inside the auth default block.
socket listen {
client {
path = /opt/var/spool/postfix/private/auth
mode = 0660
user = mail
group = mail
}
}
This tells Dovecot what we’ve already told Postfix – now Dovecot knows to create the auth socket, and put it in the right location. We now need to tell Dovecot which users are allowed to use our SMTP server and where it can find their passwords. The relevant sections, passdb and userdb, already exist in the auth default block, and should be edited as follows.
passdb passwd-file {
args = /etc/passwd-mail
}
userdb static {
args = uid=<mail uid> gid=<mail gid>
}
The passdb section tells Dovecot to use a passwd-like file located at /etc/passwd-mail to check users’ passwords. The userdb section is usually used in a similar way to look up valid email users – but since we don’t need another look up, we can use the ‘static’ mechanism, in which case Dovecot will rely on the passdb section for both valid users AND passwords.
Don’t forget to replace <mail uid> and <mail gid> with the uid and gid of your mail user and group. If your uid is less than 500 (which, if you used the built-in mail account, it is) you will need to change the first_valid_uid value in the config file to something less than or equal to the uid you are using.
The last thing involving the configuration file is to tell Dovecot which protocol we want clients to be able to use. By default, Dovecot supports only IMAP – but I prefer POP3.
#protocols = imap imaps
protocols = pop3
IMAP has some significant advantages over POP3, providing an Exchange-like environment for email, but it also has its disadvantages. If you’re happy to store all your email locally, you’re only going to connect from a single client, and prefer ISP-like email, the more common POP3 should be just fine.
Now we need to create the passwd-like lookup file.
vi /etc/passwd-mail
It’s content will be of the format <username>:{encryption_scheme}password, for example:
you@yourdomain.com:{plain}yourpassword
The {plain} directive denotes that the password is in plain text; this overrides whatever encryption Dovecot might be expecting – DES in this case (the same as you’d find in /etc/passwd). If you DES-encrypt your password before putting it in /etc/passwd-mail you do not need an {encryption_scheme} directive.
By default, the dovecot-auth process runs as user admin, which is a member of the group administrators. You can change this by editing dovecot.conf, but it is not necessary. The admin user needs read privileges on the mail password file, so give this permission to the group to which user admin belongs:
chown root:administrators /etc/passwd-mail
chmod g=r /etc/passwd-mail
Now you’re ready to start Dovecot. You may like to open a separate session on your Slug and run tail -f /var/log/dovecot to monitor what’s going on:
/opt/etc/init.d/S90dovecot start
If this produces errors, double-check the edits you made to /opt/etc/dovecot/dovecot.conf – a common problem is the mismatching of curly braces { and }.
Testing Dovecot
Now use telnet to connect to Dovecot on your slug:
telnet <slug’s host name or IP address> pop3
You can have the following conversation with it:
+OK Dovecot ready.
user you@yourdomain.com
+OK
pass wrongpassword
-ERR Authentication failed.
user you@yourdomain.com
+OK
pass yourpassword
+OK Logged in.
Great. You now have a working email server which offers SMTP without being an open relay, and provides POP3 to the user(s) you specified.
If Dovecot crashes when you authenticate, and logs “Panic: POP3(you@yourdomain.com): Trying to allocate 0 bytes“, you have found a kown bug with the Dovecot 1.2 beta 1 release (the latest release that is available through ipkg). Although this doesn’t prevent you from using Dovecot, most email clients will complain that the connection to the POP3 server was prematurely terminated. A patch to address this is available, but I have not had a chance to try it.
Finally
Don’t forget to turn off verbose logging for Postfix and Dovecot. For Postfix, remove the ‘-v’ smtpd parameter from /opt/etc/postfix/master.cf, and for Dovecot remove the first four lines of /opt/etc/dovecot/dovecot.conf (log_path, info_path, auth_debug and auth_verbose).
Limitations
The one big limitation with this set up is that the administration of mail users involves a lot of work. Every time you add a user you must create the relevant entry in virtual-maps, create the user’s mail delivery directory structure, and set permissions. The mitigation against this drawback is that you (probably) won’t be using your Slug as a mail server for more than a handful of email addresses – any heavier use would probably require a more significant investment, and hence more powerful tools.
Notes
Group ‘maildrop’ disappears
It seems that, at some point, the maildrop group ‘disappears’ from /etc/group. It may be something to do with the fact that /etc/group is a symbolic link to /share/flash/conf/group, and thus may be more closely-managed by the Slug than it appears. Regardless, it causes SMTP clients to be unable to connect (because Postfix fails to start), and Postfix emits an appropriate message to /var/log/message.
This can be resolved by manually recreating the appropriate entry in /etc/group for maildrop:
maildrop:x:69:
Fortunately, it seems that this is only required once.
Using your ISP’s SMTP server
Some ISPs may require that any email you send is relayed through their SMTP server; in this case you will likely need to add the relayhost parameter to your main.cf as well (although this wasn’t necessary in my case). Documentation for this parameter can be found on the Postfix website. Explicit authentication with your ISP’s SMTP server is usually not required as long as you are connected to the Internet via that ISP’s connection (either dial-up or always-on).
Encryption of stored passwords
When installing and configuring Dovecot, I store email users’ passwords in plain text. If you want to store passwords in an encrypted format, the Dovecot wiki has an explanation.
Next Steps
Firewall
If you have a firewall or NAT between your Slug and the outside world (which is highly recommended) and you want to access your email from anywhere, you will need to configure your firewall or NAT to forward ports 25 (smtp) and 110 (pop3) to your Slug.
Of course, if you open up your email server to the rest of the world, you may want to make sure it can’t be abused. Go to Abuse.net, provide your external IP address, and let it test your email server for being an open relay.
Date/Time
It’s a good idea to keep your Slug’s time accurate so that the mail server can timestamp email correctly. This can be done by running an NTP client, which will synchronise the Slug’s time with reliable time servers around the world, or by running an NTP server, which will synchronise the Slug’s time AND allow you to synchronise your network computers’ time with the Slug.
Due to a glitch in the Slug, this isn’t as straight-forward as it could be – but it’s not beyond anyone with enough patience to work with vi.
Detailed instructions are here.
SSL/TLS
These instructions give you a working email server, but all authentication is performed using plain text. That means that anyone using a network sniffer in the right place at the right time could steal your usernames and passwords as you transmit them to the server.
Rather than configure authentication mechanisms that prevent this (and which, to be honest, look difficult to configure), we can encrypt the whole of the communication between client and server using SSL and TLS.
Detailed instructions are here.
Useful Links
http://www.postfix.org/
http://www.dovecot.org/
http://www.nslu2-linux.org/
http://www.howtoforge.com/linux_postfix_virtual_hosting
http://www.howtoforge.com/linux_postfix_virtual_hosting_2
If this information was useful, please leave a comment to let me know!
References
- http://www.mentjens.nl
- http://en.wikipedia.org/wiki/IMAP#Advantages_over_POP3
- http://en.wikipedia.org/wiki/IMAP#Disadvantages_of_IMAP
- http://hg.dovecot.org/dovecot-1.2/rev/22d70947597c
- http://www.postfix.org/postconf.5.html#relayhost
- http://wiki.dovecot.org/Authentication/PasswordSchemes
- http://www.abuse.net/relay.html
- http://www.postfix.org/
- http://www.dovecot.org/
- http://www.nslu2-linux.org/
- http://www.howtoforge.com/linux_postfix_virtual_hosting
- http://www.howtoforge.com/linux_postfix_virtual_hosting_2
hey Nik.
I’m trying to install postfix + dovecot following your howto.
However I get stuck after the part: “We now turn /opt/etc/postfix/virtual-maps into a hash file,……. ”
What should I be doing there. I have no idea what “turning into a hashfile means” and I can’t seem to find any command.
Greetings Raymond
[Reply]
Hi Raymond,
I’m afraid you’ve found a typo in the instructions – the command you need to run is actually:
postmap /opt/etc/postfix/virtual-maps
The postmap tool is part of the Postfix distribution, and turns the file you specify into a database file that Postfix can read – in this case, it turns virtual-maps into virtual-maps.db.
I reformatted this article a few months ago, and I think that’s when the typo appeared. Thanks for spotting it, and sorry for any confusion it caused!
Regards,
Nik.
[Reply]
Thanx mate.
found two more typo’s
after: Now restart the server so our changes take effect.
you write:
opt/etc/init.d/S69postfix restart
should be
/opt/etc/init.d/S69postfix restart
And
vi /opt/etc/dovecot.conf
should be
vi /opt/etc/dovecot/dovecot.conf
I am replacing my postfix + cyrus configuration for a postfix + dovecot config.
Ill let you hear my progress
[Reply]
and in /etc/group it should say
maildrop:x:69:maildrop
in stead of
maildrop:x:69:
I would like to thank you for this howto. It is very comprehensive. I am not yet in the fase of testing so I dont know if it will work yet, but compared to most howto’s your explainaitions are very good.
Thanx again
Raymond
[Reply]
I’ve updated the article to bring it in line with the latest available Dovecot package (v1.2 beta 1 at time of writing) and there are some significant changes, such as Dovecot now installing to /opt/etc/dovecot instead of /opt/etc.
There were also a few missing bits of information, and a couple of typos that could mislead; these have been corrected, and I’ve tested the entire article successfully.
Oh, I have left the maildrop entry in /etc/group as maildrop:x:69: since that was how it was when I found it – although adding user maildrop as a member of the maildrop group won’t do any harm.
[Reply]
Hey Nik
Still working on it. I get stuck at the following part:
after: /opt/etc/init.d/S90dovecot start
my /var/log/dovecot says:
dovecot: May 14 21:55:53 Info: Dovecot v1.2.beta1 starting up (core dumps disabled)
dovecot: May 14 21:55:53 Error: child 5831 (auth) returned error 89 (Fatal failure)
dovecot: May 14 21:55:53 Error: auth(default): passwd-file /etc/passwd-mail: Can’t open file: Permission denied
dovecot: May 14 21:55:53 Fatal: Auth process died too early – shutting down
I checked my permissions for the mentioned file they are:
-rw—-r– 1 root administ 35 May 14 21:52 passwd-mail
is it maybe because it writes administ in stead of administrator (as stated in the chown command) or maybe something with the uid or gid ( 8 and 12 )
Cheers Raymond
[Reply]
Hi Raymond,
I think I’ve spotted the problem – your passwd-mail file needs to have read permission for ‘group’ (g=r), but my instructions tell you to give it to ‘others’ (o=r) instead. Although o=r gives read permission to all other users, the u= and g= permissions take priority, and so all permissions are denied to the administrators group.
You should be able to fix it with:
chmod g=r,o= /etc/passwd-mail
I will change the instructions accordingly.
[Reply]
Nik
I hope you dont mind me posting these problems here. I hope you see it as an extra test to your howto.
When I get this to work I will try to setup SSL/TLS. Your other howto.
greetz Raymond
[Reply]
Getting very close now.
I CAN telnet to my smtp server
I can NOT telnet to my popserver (now)
however just for fun I tried to login to the dovecot server with imap protocol and this works. I have no intention to use imap at this point. but the fact that i CAN login to dovecot with imap is very promising.
Any ideas why pop is not working? some config? or some port?
kind regards
Raymond
[Reply]
oh btw I changed /etc/services I uncommented the “#pop3″ line to “pop3″ and rebooted.
no joy
[Reply]
I found yet another omission from the article – specifying the protocols (POP3/IMAP/whatever) in the config file.
Add (or edit) the following line in your dovecot.conf file:
protocols = pop3
That should be the last stage, and you should be able to telnet into your POP3 server now!
[Reply]
Hey Nik
It looks like it works now. However I cant login with telnet because i get the “Panic: POP3(you@yourdomain.com): Trying to allocate 0 bytes etcetera bug.
However thunderbird seems to cope with it.
this weekend I will try the patch and next week I hope to do the TLS/SSL howto
Thanx mate for your swift responses
[Reply]
Thanks Nik! Works like a charm even nowadays!
In case someone still has a slug, when using virtual-maps the /opt/etc/aliases is useless and all aliases must be listed on the virtual-maps file.
cheers,
Luiz
[Reply]
Hi Luiz, I’m glad these articles are still useful
Thanks for the virtual-maps pointer as well!
[Reply]