This tutorial exists for these OS versions
- Ubuntu 18.04 (Bionic Beaver)
- Ubuntu 14.04 LTS (Trusty Tahr)
- Ubuntu 9.10 (Karmic Koala)
- Ubuntu 8.10 (Intrepid Ibex)
- Ubuntu 8.04 (Hardy Heron)
On this page
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.