Articles

How to configure PostFix and Dovecot for Virtual Users with out a Database

Author: nathacof
Published: Monday 18th of February 2008

Before we Start

Check Versions

In this tutorial we assume you have Postfix v2.3 and Dovecot v1.0 or greater installed from your OS Specific repositories. If your repos don't have a new enough RPM you will need to compile from source.

If you end up compiling this software from source you will need to add them as exclusions in the customer's yum.conf so that subsequent security updates don't trash your installation

Check Hostname

You should already have a valid hostname.

To check the hostname run the following command:

[root@vps ~]# hostname && dig +short $(hostname) && dig +short -x $(dig +short $(hostname))
vps.neranjara.org
76.12.12.17
vps.neranjara.org.

If the top and bottom domain match, you're good to go.

Ensure PostFix is Listening

PostFix should be configured to listen on a public IP on your server.

To check that PostFix is configured to accept incoming SMTP transactions ensure that the following command lists a public IP, and not simply localhost:

[root@vps ~]$ grep ^inet_interfaces /etc/postfix/main.cf
inet_interfaces = all

Virtual Users, or System Accounts?

Before you begin you must select between two configurations. Virtual Users, support multiple Domains, whereas System Users eases setup, but has more restrictions on what addresses can be used.

If you have a customer who doesn't care about hosting multiple domains you can use System users in this configuration. Bare in mind there are some severe limitations to this method. For example user accounts that are used by the system can not be used as email addresses. For example the user 'articles' is often a reserved user and should not be used in this scenario.

PostFix Configuration

Add the following lines to, /etc/postfix/main.cf


# SMTP Auth Configuration

smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_auth_enable = yes
smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination

smtpd_recipient_restrictions can be adjusted to include additional requirements on the RCPT TO: command. This can be extremely helpful if the server is overloaded with SPAM. Reference: smtpd_recipient_restrictions

Virtual User Configuration

Edit Config

If you are configuring Virtual Domains add the following to /etc/postfix/main.cf make sure to adjust virtual_mailbox_domains to include the customer's domains.:


# Virtual Domain Configuration

virtual_mailbox_domains = neranjara.org ncoffield.com
virtual_mailbox_base = /var/mail/vhosts
virtual_mailbox_maps = hash:/etc/postfix/vmailbox
virtual_minimum_uid = 100
virtual_uid_maps = static:5000
virtual_gid_maps = static:5000
virtual_alias_maps = hash:/etc/postfix/virtual

Create Directories

Now might be a good time to create our new mail directory:

[root@vps ~]$ mkdir /var/mail/vhosts
[root@vps ~]$ chown 5000:5000 /var/mail/vhosts

Add Vmail User

If using numbers for the UID, and GID, seems a bit cryptic you can add a user to the system like so:

[root@vps ~]$ adduser -s /sbin/nologin -M -u 5000 vmail

Create vmailbox file

After we add this configuration to the main.cf, and created the necessary directories, we need to setup our vmailbox file, which tells PostFix where to deliver these messages:

[root@vps ~]$ vi /etc/postfix/vmailbox
nathacof@neranjara.org neranjara.org/nathacof/
support@neranjara.org neranjara.org/support/
@neranjara.org neranjara.org/catch-all/
~
:wq

The first entry in the table is the email address in question, the second field is the location of the MailDir relative to virtual_mailbox_base.

Without the trailing slash these entries would use mbox style mailboxes, which is not a good thing (REF: MBox Limitations).

After updating this file we need to run postmap to make the settings permanent:

[root@vps ~]# postmap /etc/postfix/vmailbox
[root@vps ~]# service postfix reload
Reloading postfix:                                         [  OK  ]

System User Configuration

If you are planning on using System accounts you must set the $mydomain variable in /etc/postfix/main.cf, and we'll configure these users for MailDir style mailboxes:

$mydomain = example.com
home_mailbox = Maildir/

Be careful if the server is using system users for FTP accounts. You don't want your mail delivered to your home directory if that directory is in the DocumentRoot of your website!

Dovecot Configuration

There are some shorthand variables in the configuration file you should be aware of:

#  %u - username
#  %n - user part in user@domain, same as %u if there's no domain
#  %d - domain part in user@domain, empty if there's no domain
#  %h - home directory

Virtual User Configuration

Modify Dovecot.conf

Add the following to /etc/dovecot.conf, but make sure to comment out the old reference to auth default if it exists. You can only have one section by that name.


# Here we set the default password and user files to be relative the the domain's folder 
# (This makes it easier to allow user administration later on)

auth default {
  mechanisms = plain login CRAM-MD5
  userdb passwd-file {
    args = username_format=%n /var/mail/vhosts/%d/passwd
  }
  passdb passwd-file {
    args = username_format=%n /var/mail/vhosts/%d/shadow
  }
  # We need this to use Dovecot SASL Auth in Postfix.
  socket listen {
      client {
      path = /var/spool/postfix/private/auth
      mode = 0660
      user = postfix
      group = postfix
    }
  }
}

Also we need to modify the mail location to match our PostFix delivery location:

#
#
#  Mailbox locations and namespaces 
#
# Location for users' mailboxes. This is the same as the old default_mail_env
# setting. The default is empty, which means that Dovecot tries to find the
# mailboxes automatically. This won't work if the user doesn't have any mail
# yet, so you should explicitly tell Dovecot the full location.

# If you're using mbox, giving a path to the INBOX file (eg. /var/mail/%u)
# isn't enough. You'll also need to tell Dovecot where the other mailboxes are
# kept. This is called the "root mail directory", and it must be the first
# path given in the mail_location setting.

# There are a few special variables you can use, eg.:
#
#   %u - username
#   %n - user part in user@domain, same as %u if there's no domain
#   %d - domain part in user@domain, empty if there's no domain
#   %h - home directory

#
#   mail_location = maildir:~/Maildir
#   mail_location = mbox:~/mail:INBOX=/var/mail/%u
#   mail_location = mbox:/var/mail/%d/%1n/%n:INDEX=/var/indexes/%d/%1n/%n

mail_location = Maildir:/var/mail/vhosts/%d/%n

Now that PostFix is letting Dovecot do the authentication we need to setup some users!

The way that I've chosen to configure this, each domain will have it's own user and password file:

  userdb passwd-file {
    args = username_format=%n /var/mail/vhosts/%d/passwd
  }
  passdb passwd-file {
    args = username_format=%n /var/mail/vhosts/%d/shadow
  }

If you get an error such as the following when testing the new account:

Oct 08 09:28:15 Info: auth(default): passwd-file(user@example.com): 
        no passwd file: username_format=user /var/mail/vhosts/example.com/shadow

Remove the text "username_format=%n" from the args line for both passdb and userdb sections.

Create passwd File

Here is the content of the passwd-file we use for our users which you will need to create:

[root@vps ~]# vi /var/mail/vhosts/neranjara.org/passwd
nathacof::5000:5000::/var/mail/vhosts/neranjara.org/nathacof
support::5000:5000::/var/mail/vhosts/neranjara.org/support
catch-all::5000:5000::/var/mail/vhosts/neranjara.org/catch-all
~
:wq

Create shadow File

We need to generate the password hashes using dovecotpw. This doesn't actually create the password file you have to manually add it to the file as you will see in a moment:

[root@vps ~]# dovecotpw
Enter new password:
Retype new password:
{HMAC-MD5}f320e8595ecdbdd468a55695dc6ca0329b341fcbb9bf0d899f4bec990a14feb4
[root@vps ~]#

And here is the contents of the shadow file which contains our encrypted passwords which you will need to create:

[root@vps ~]# vi /var/mail/vhosts/neranjara.org/shadow
nathacof:{HMAC-MD5}f320e8595ecdbdd468a55695dc6ca0329b341fcbb9bf0d899f4bec990a14feb4
support:{HMAC-MD5}f320e8595ecdbdd468a55695dc6ca0329b341fcbb9bf0d899f4bec990a14feb4
catch-all:{HMAC-MD5}f320e8595ecdbdd468a55695dc6ca0329b341fcbb9bf0d899f4bec990a14feb4
~
:wq

Both the passwd, and shadow files follow the guidelines outlined here, Dovecot: Passwd File.

Update Permissions

When you're done setting up the files, make sure to remove world permissions:

[root@vps ~]# chmod o-rwx /var/mail/vhosts/neranjara.org/*

Bash Script to add users

This is just an example of how you can script adding users, feel free to expand upon this as you see fit.

#!/bin/bash
#
# Script to add users for
# Dovecot/PostFix using Virtual Users
 
USAGE="Usage: $0 EMAIL PASSWORD [BASEDIR]";
 
if [ ! -n "$2" ]
then
  echo $USAGE;
  exit 1;
fi
 
USERNAME=$(echo "$1" | cut -f1 -d@);
DOMAIN=$(echo "$1" | cut -f2 -d@);
ADDRESS=$1;
PASSWD=$2;
 
if [ -n "$3" ]
then
  if [ ! -d "$3" ]
  then
    echo $USAGE;
    echo "BASEDIR must be a valid directory!";
    echo "I would have tried, $(postconf | grep ^virtual_mailbox_base | cut -f3 -d' ')";
    exit 2;
  else
    BASEDIR="$3";
  fi
else
  BASEDIR="$(postconf | grep ^virtual_mailbox_base | cut -f3 -d' ')";
fi
 
if [ -f /etc/postfix/vmailbox ]
then
 
  echo "Adding Postfix User Configuration..."
  echo $ADDRESS $DOMAIN/$USERNAME/ >> /etc/postfix/vmailbox
  postmap /etc/postfix/vmailbox
 
  if [ $? -eq 0 ]
  then
    echo "Adding Dovecot User Configuration..."
    echo $USERNAME::5000:5000::$BASEDIR/$DOMAIN/$USERNAME >> $BASEDIR/$DOMAIN/passwd
    echo $USERNAME":"$(dovecotpw -p $PASSWD) >> $BASEDIR/$DOMAIN/shadow
    service postfix reload
  fi
 
fi

System User Configuration

We just need to make changes to the userdb, and passdb, and the mail_location variable:


auth default {
  mechanisms = plain login CRAM-MD5
  userdb passwd {
    args = blocking=yes
  }
  passdb pam {
    args = blocking=yes
  } 

 # We need this to use Dovecot SASL Auth in Postfix.
  socket listen {
      client {
      path = /var/spool/postfix/private/auth
      mode = 0660
      user = postfix
      group = postfix
    }
  }
}
mail_location = maildir:~/Maildir

To add a user we do the following:

$ adduser -s /sbin/nologin -m newUserName

Now set the password for the new user:

$ passwd newUserName
Changing password for user newUserName.
New UNIX password:
Retype new UNIX password:
passwd: all authentication tokens updated successfully.
$

Testing

Once this has been completed you should login to the POP3/IMAP server, and use SMTP authentication through your email client to ensure that everything has been properly setup. Detailed testing instructions can be found here, http://wiki.dovecot.org/TestInstallation. Details on testing SASL in PostFix can be found here, http://www.postfix.org/SASL_README.html#server_test.

If you have any questions in regards to PostFix or Dovecot please see the following pages:

Article Search

Social Networks