There is a new version of this tutorial available for Ubuntu 18.04 (Bionic Beaver).

Postfix Virtual Hosting With LDAP Backend And With Dovecot As IMAP/POP3 Server On Ubuntu Intrepid Ibex Server 8.10

This how to will allow you to configure a Postfix mail server with with virtual hosting. Virtual hosting means that you can add as many maildomains as you want and subsequentially as many mailboxes for these domains as you want. Here we we use an LDAP backend for both the MTA (Postfix) and POP3/IMAP server (Dovecot), and a web based management interface.

This how to is an upgraded version of the Ubuntu Hardy Heron version.

Software to be used in this how to:

Postfix MTA, Dovecot IMAP / POP3, OpenLDAP, and Gnarwl as autoresponder (vacation) and Phamm as management interface.

Assumtions:

This how to assumes the following configurations, if your installation differs from this, then replace the entries below with your actual configuration.

Mail delivery (mailboxes) path:

/home/vmail/domains

User vmail:

UID:1000, GID:1000

User postfix:

UID: 108, GID:108

OpenLDAP base dn:

dc=example,dc=tld

OpenLDAP admin account:

cn=admin,dc=example,dc=tld

Phamm search dn:

o=hosting,dc=example,dc=tld

You're using root as the user during this guide. 

If you want for example o=maildomains or o=whatever, please make sure to replace o=hosting with what you  want, especially in the acl.ldif. This acl file is strict, phamm will not work correctly if it is not exactly as it should be.

 

Step 1: Install And Configure An Ubuntu Server

I recommend following the guide below for this (I do not need to rewrite or reinvent what others did better than me) :

The Perfect Server - Ubuntu Intrepid Ibex (Ubuntu 8.10)

Don't install the following items (in the how to):

apt-get install postfix libsasl2-2 sasl2-bin libsasl2-modules procmail
apt-get install courier-authdaemon courier-base courier-imap courier-imap-ssl courier-pop courier-pop-ssl courier-ssl gamin libgamin0 libglib2.0-0

on page 5. We will install and configure Postfix and Dovecot further on in this guide.

Note: all of the URLs and package names are valid at the time of writing of this how to. Best practice is to check if there are new versions available.

So let's get started:

 

Step 2: Installing And Configuring OpenLDAP

Run the following to install OpenLDAP on your server and enter a password for the admin user when prompted:

apt-get install slapd ldap-utils

Now we're going to download additional schemas that are used and needed and also the phamm package since it contains a schema that we need:

mkdir /usr/src/phamm-inst
cd /usr/src/phamm-inst
wget http://open.rhx.it/phamm/phamm-0.5.15.tar.gz
wget http://open.rhx.it/phamm/schema/ISPEnv2.schema
wget http://open.rhx.it/phamm/schema/amavis.schema
wget http://open.rhx.it/phamm/schema/samba.schema
wget http://open.rhx.it/phamm/schema/pureftpd.schema

Now we're going to unpack  the phamm package to get the needed schema.

tar xvzf phamm-0.5.15.tar.gz

OpenLDAP in Intrepid is no longer configured using a slapd.conf file, but by using ldif files stored in /etc/ldap/slapd.d so we need to convert the schema files to ldif files first.

Make a temporary directory for the converted schema files:

cd ..
mkdir ldif_out

Copy the phamm.schema for convenience:

 cp phamm-0.5.15/schema/phamm.schema .

Create a schema.convert file:

vi schema.convert

Paste the following into the file:

include         /etc/ldap/schema/core.schema
include         /etc/ldap/schema/cosine.schema
include         /etc/ldap/schema/nis.schema
include         /etc/ldap/schema/inetorgperson.schema
include         phamm.schema
include         ISPEnv2.schema
include         amavis.schema
include         pureftpd.schema

The additional schemas are needed for the conversion to succeed since from these schema's certain objects are used by the other shema's.

Now we're going to convert the schema files to ldif files:

slaptest -f schema.convert -F ldif_out

This will convert the schemas to ldif, but we have to edit them before we can import them into the OpenLDAP server.

vi ldif_out/cn\=config/cn\=schema/cn\=\{4\}phamm.ldif

And change the needed entries to match the following:

dn: cn=phamm,cn=schema,cn=config
...
cn: phamm

And remove the following from the end of the ldif (ignore the content after: since it will vary depending on the date, time, ... of conversion):

structuralObjectClass: olcSchemaConfig
entryUUID: 08bf1a06-7a89-102d-9fa6-4bee1e86d7f6
creatorsName: cn=config
createTimestamp: 20090119152440Z
entryCSN: 20090119152440.275296Z#000000#000#000000
modifiersName: cn=config
modifyTimestamp: 20090119152440Z

And do this for the other ldif files as well.

cn={5}ISPEnv2.ldif
cn={6}amavis.ldif
cn={7}pureftpd.ldif

Now we're going to load the schema files into OpenLDAP:

ldapadd -x -D cn=admin,cn=config -W -f ldif_out/cn\=config/cn\=schema/cn\=\{4\}phamm.ldif
ldapadd -x -D cn=admin,cn=config -W -f ldif_out/cn\=config/cn\=schema/cn\=\{5\}ISPEnv2.ldif
ldapadd -x -D cn=admin,cn=config -W -f ldif_out/cn\=config/cn\=schema/cn\=\{6\}amavis.ldif
ldapadd -x -D cn=admin,cn=config -W -f ldif_out/cn\=config/cn\=schema/cn\=\{7\}pureftpd.ldif

You will be asked for the password you defined when you installed OpenLDAP.

Now we need to set the proper acl for OpenLDAP. You're in luck, that I did the conversion to ldif style so that you can use the commands below to set the acl's needed.

We will create two files: acl-del.ldif and acl-add.ldif.

vi acl-del.ldif

Paste the following into it:

dn: olcDatabase={1}hdb,cn=config
delete: olcAccess 
olcAccess: to attrs=userPassword,shadowLastChange by dn="cn=admin,dc=example,dc=tld" write by anonymous auth by self write by * none 
olcAccess: to dn.base="" by * read 
olcAccess: to * by dn="cn=admin,dc=example,dc=tld" write by * read
vi acl-add.ldif
dn: olcDatabase={1}hdb,cn=config
add: olcAccess
olcAccess: to dn.regex=".+,vd=([^,]+),o=hosting,dc=example,dc=tld$" attrs=userPassword by dn="cn=admin,dc=example,dc=tld" write by self write by anonymous auth by dn.exact,expand="cn=postmaster,vd=$1,o=hosting,dc=example,dc=tld" write by set.expand="user/vd & [$1]" write 
olcAccess: to dn.regex=".+,vd=([^,]+),o=hosting,dc=example,dc=tld$" attrs=amavisBypassVirusChecks,quota,smtpAuth,accountActive by dn="cn=admin,dc=example,dc=tld" write by self read by dn.exact="cn=phamm,o=hosting,dc=example,dc=tld" read by set.expand="user/editAccounts & [TRUE]" write by dn.exact,expand="cn=postmaster,vd=$1,o=hosting,dc=example,dc=tld" read by set.expand="user/vd & [$1]" write 
olcAccess: to dn.regex=".+,vd=([^,]+),o=hosting,dc=example,dc=tld$" attrs=cn,sn,forwardActive,vacationActive,vacationInfo,vacationStart,vacationEnd,vacationForward,amavisSpamTagLevel,amavisSpamTag2Level,amavisSpamKillLevel by dn="cn=admin,dc=example,dc=tld" write by self write by dn.exact="cn=phamm,o=hosting,dc=example,dc=tld" read by dn.exact,expand="cn=postmaster,vd=$1,o=hosting,dc=example,dc=tld" write by set.expand="user/vd & [$1]" write 
olcAccess: to dn.regex="^.*,vd=([^,]+),o=hosting,dc=example,dc=tld$" attrs=editAccounts by dn="cn=admin,dc=example,dc=tld" write by self read by set.expand="user/editAccounts & [TRUE]" write by dn.exact="cn=phamm,o=hosting,dc=example,dc=tld" read by * none 
olcAccess: to dn.regex=".+,vd=([^,]+),o=hosting,dc=example,dc=tld$" attrs=objectClass,entry by dn="cn=admin,dc=example,dc=tld" write by self write by anonymous read by dn.exact="cn=phamm,o=hosting,dc=example,dc=tld" read by set.expand="user/editAccounts & [TRUE]" write by dn.exact,expand="cn=postmaster,vd=$1,o=hosting,dc=example,dc=tld" read 
olcAccess: to dn.regex=".+,vd=([^,]+),o=hosting,dc=example,dc=tld$" attrs=amavisBypassSpamChecks,accountActive,delete by dn="cn=admin,dc=example,dc=tld" write by self read by dn.exact="cn=phamm,o=hosting,dc=example,dc=tld" read by dn.exact,expand="cn=postmaster,vd=$1,o=hosting,dc=example,dc=tld" write by set.expand="user/vd & [$1]" write 
olcAccess: to dn.regex=".+,vd=([^,]+),o=hosting,dc=example,dc=tld$" attrs=otherPath    by dn="cn=admin,dc=example,dc=tld" write by anonymous read by self read by dn.exact="cn=phamm,o=hosting,dc=example,dc=tld" read by dn.exact,expand="cn=postmaster,vd=$1,o=hosting,dc=example,dc=tld" read by set.expand="user/vd & [$1]" write 
olcAccess: to dn.regex=".+,vd=([^,]+),o=hosting,dc=example,dc=tld$" attrs=createMaildir,vdHome,mailbox,otherTransport by dn="cn=admin,dc=example,dc=tld" write by self read by dn.exact="cn=phamm,o=hosting,dc=example,dc=tld" read  by set.expand="user/vd & [$1]" read
olcAccess: to dn.regex="^(.+,)?vd=([^,]+),o=hosting,dc=example,dc=tld$" attrs=vd by dn="cn=admin,dc=example,dc=tld" write by self write by dn.exact="cn=phamm,o=hosting,dc=example,dc=tld" read by dn.exact,expand="cn=postmaster,vd=$2,o=hosting,dc=example,dc=tld" write by set.expand="user/vd & [$2]" write 
olcAccess: to dn.regex="^(.+,)?vd=([^,]+),o=hosting,dc=example,dc=tld$" by dn="cn=admin,dc=example,dc=tld" write by self write by dn.exact="cn=phamm,o=hosting,dc=example,dc=tld" read by set.expand="user/editAccounts & [FALSE]" read by dn.exact,expand="cn=postmaster,vd=$2,o=hosting,dc=example,dc=tld" write by set.expand="user/vd & [$2]" write 
olcAccess: to dn.regex=".+,o=hosting,dc=example,dc=tld$" by dn="cn=admin,dc=example,dc=tld" write by self write by dn.exact="cn=phamm,o=hosting,dc=example,dc=tld" read by anonymous auth 
olcAccess: to dn.regex=".+,dc=tld$" by dn="cn=admin,dc=example,dc=tld" write by dn.exact="cn=phamm,o=hosting,dc=example,dc=tld" read by anonymous auth 
olcAccess: to dn.regex=".+,ou=admin,dc=example,dc=tld$" attrs=userPassword by dn="cn=admin,dc=example,dc=tld" write by self write by anonymous auth 
olcAccess: to dn.regex=".+,ou=admin,dc=example,dc=tld$" attrs=vd by dn="cn=admin,dc=example,dc=tld" write by self read
olcAccess: to dn.regex="ou=admin,dc=x4w,dc=it$" by dn="cn=admin,dc=example,dc=tld" write by self read

Now we're going to set the acl's:

ldapmodify -x -D cn=admin,cn=config -W -f acl-del.ldif
ldapmodify -x -D cn=admin,cn=config -W -f acl.ldif

You will be asked for the password you defined when you installed OpenLDAP.

Now we're going to add the hosting organization to OpenLDAP:

vi phamm.ldif

And paste the following into it:

dn:o=hosting,dc=example,dc=tld
objectClass: top
objectClass: organization
o: hosting
description: mail.example.tld hosting root

Change the description to what you want.

Now we're going to import the ldif:

ldapadd -x -D cn=admin,dc=example,dc=tld -W -f phamm.ldif

This concludes the OpenLDAP configuration.

Share this page:

10 Comment(s)