Cheap VPS & Xen Server

Residential Proxy Network - Hourly & Monthly Packages

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.

Step 3: Install And Configure phamm

Since we downloaded and extracted the phamm archive before, we can directly begin with the installation and configuration of the phamm interface.

Note: I hacked into the phamm configuration and .php script files to accomplish the following:

  • Maildrop to to postmaster@example.tld rather than postmaster wich is a Unix account
  • Maildrop for abuse to postmaster@example.tld rather than postmaster
  • %domain% for the welcome message to reflect postmaster@domain.tld rather than postmaster
  • cc for the welcome message to postmaster@example.tld to have an idea of the number of mailboxes created by the virtual mail domain admins. ==> default maps to postmaster so your Unix account will get the mails or rather root.

The other hacks are just to define other defaults:
Setting smtp auth to default
Setting the quota number for mail
Setting the default home directory for ftp
Setting the default quota for ftp

In any case I believe that these changes are an improvement rather than customization so I will list them here before we go into the actual installation and configuration of phamm. Those who do not care about these features can skip the following section until the actual phamm configuration and installation.

But first we need to get the phamm scripts to their proper location:

cd /usr/src/phamm-install
mv phamm-0.5.15 /var/www/

My hacks:

The hacks are done on the source, not the actual (see later installation).

First we will do the welcome message part.

cd /var/www/phamm
vi config.inc.php

Change (starting line 147 at the time of writing this how to):

// Welcome message
define (‘SEND_WELCOME’,0);
$welcome_msg = ‘../welcome_message.txt’;
$welcome_subject = ‘Welcome!’;
$welcome_sender = ‘postmaster@localhost’;
$welcome_bcc = ‘postmaster@localhost’;

to

// Welcome message
define (‘SEND_WELCOME’,1);
$welcome_msg = ‘../welcome_message.txt’;
$welcome_subject = ‘Welcome!’;
$welcome_sender = ‘postmaster@%domain%’;
$welcome_bcc = ‘postmaster@example.tld’;

This will send the welcome email as from postmaster@domain.tld (domain.tld being the mail domain (virtual)) and send a bcc to postmaster@example.tld where example.tld represents the technical domain.

Next we will set the defaults for email and domain creation:

vi www-data/main.php

Change (line 311):

$entry[“maildrop”] = “postmaster”;

to

$entry[“mail”] = “postmaster@”.$domain_new;

And also (line 330) from:

$entry_abuse[“maildrop”] = “postmaster”;

to

$entry_abuse[“maildrop”] = “postmaster@”.$domain_new;

Change the quota in mail.xml plugin to support Dovecot quota format:

vi plugins/mail.xml

Change (line 121):

<suffix>S</suffix>

to

<suffix></suffix>

OK these were my custom hacks, now let’s go to the configuration of phamm.

chown -R www-data:www-data /var/www/phamm
cd /var/www/phamm
rm -R examples
rm -R doc
rm -R DTD
rm -R schema

This in order to remove files that are not needed in the www directory.

Now we will configure phamm for actual use.

vi config.inc.php

Change the ldap connection parameters to fit your actual configuration.

// *============================*
// *=== LDAP Server Settings ===*
// *============================*

// The server address (IP or FQDN)
define (‘LDAP_HOST_NAME’,’127.0.0.1′);

// The protocol version [2,3]
define (‘LDAP_PROTOCOL_VERSION’,’3′);

// The server port
define (‘LDAP_PORT’,’389′);

// The container
define (‘SUFFIX’,’dc=example,dc=tld’);

// The admin bind dn (could be rootdn)
define (‘BINDDN’,’cn=admin,dc=example,dc=tld’);

// The Phamm container
define (‘LDAP_BASE’,’o=hosting,dc=example,dc=tld’);

Enable the fpt plugin (line 113) by removing the //

Enable the person plugin (line 118) by removing the //

And on line 170 change CRYPT to MD5. Most other software that uses LDAP use MD5 hashing, so it is therefore a good thing to have phamm use MD5.

Since the transport maildrop: is hardcoded in phamm we need to change this in order to enable Dovecot delivery.

vi plugins/mail.xml

Replace each entry with maildrop: with dovecot: (do no forget the colon). In ordinary situations, the commands in Postfix’s main.cf would do (that we added before), but ldap transport as used and implemented by phamm overrides this and implements maildrop.

This has to be done for line 75. This will substitute maildrop for Dovecot delivery.

That’s it for the configuration.

You can edit plugins/mail.xml to change the defaults for smtp and quota, modify them to your needs.

Please note that the multiplier used for quota is x*y representing x*1024. So if you want a quota of 1000Mb you need to set the quota to 1000.

<attribute name=”quota”>
<prettyName>Quota</prettyName>
<table>1</table>
<default>50</default> ==> 50=50Mb, 100=100Mb
<multiplier>1048576</multiplier>
<suffix></suffix>
<minAuthLevel>4</minAuthLevel>
</attribute>

You can edit plugins/ftp.xml to change the defaults for default ftp (base) directory and quota, modify them to your needs.

This concludes the phamm configuration.

Step 4: Install And Configure Postfix

Before this we need to have the vmail user and its home directory.

Create the vmail user and group:

useradd vmail

By default the group vmail is created, too.

Check /etc/passwd for the actual uid and group number.

Next create the vmail directory and set ownership to the vmail user and group.

mkdir /home/vmail
mkdir /home/vmail/domains
chown -R vmail:vmail /home/vmail

Run the following command to install Postfix and other required applications:

apt-get install postfix postfix-ldap postfix-pcre

You will be asked two questions. Answer as follows:

General type of mail configuration: <–Stand alone
System mail name: <– mail.example.tld

Now we create the certificates for TLS:

mkdir /etc/postfix/ssl
cd /etc/postfix/ssl/
openssl genrsa -des3 -rand /etc/hosts -out smtpd.key 1024

chmod 600 smtpd.key
openssl req -new -key smtpd.key -out smtpd.csr

openssl x509 -req -days 3650 -in smtpd.csr -signkey smtpd.key -out smtpd.crt

openssl rsa -in smtpd.key -out smtpd.key.unencrypted

mv -f smtpd.key.unencrypted smtpd.key
openssl req -new -x509 -extensions v3_ca -keyout cakey.pem -out cacert.pem -days 3650

Now we will configure postfix:

mv /etc/postfix/main.cf /etc/postfix/main.cf.bck

vi /etc/postfix/main.cf

And paste the following into it. Please not that this config allows the sending (relaying) of mails by authenticated users, and also the sending of local mails (like for example to root, postmaster, …) to the respective aliases if they are configured.

# See /usr/share/postfix/main.cf.dist for a commented, more complete version

# Debian specific: Specifying a file name will cause the first
# line of that file to be used as the name. The Debian default
# is /etc/mailname.

smtpd_banner = $myhostname ESMTP $mail_name
biff = no

# appending .domain is the MUA’s job.
append_dot_mydomain = no

# Uncomment the next line to generate “delayed mail” warnings
delay_warning_time = 4h

# TLS parameters
smtpd_tls_cert_file = /etc/postfix/ssl/smtpd.crt
smtpd_tls_key_file = /etc/postfix/ssl/smtpd.key
smtpd_use_tls = yes
smtpd_tls_session_cache_database = btree:${queue_directory}/smtpd_scache
smtp_tls_session_cache_database = btree:${queue_directory}/smtp_scache

# See /usr/share/doc/postfix/TLS_README.gz in the postfix-doc package for
# information on enabling SSL in the smtp client.

myhostname = mail.example.tld # ==> change this for your setup.
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
myorigin = localhost
relayhost =
mynetworks = 127.0.0.0/8
dovecot_destination_recipient_limit = 1
mailbox_command =
mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = all
inet_protocols = all
#smtp_bind_address = your ip address (optional) ==>unmark and change the ip address for your setup.
smtpd_sasl_local_domain =
smtpd_sasl_auth_enable = yes
smtpd_sasl_security_options = noanonymous
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
broken_sasl_auth_clients = yes
smtpd_tls_auth_only = no
smtp_use_tls = yes
smtp_tls_note_starttls_offer = yes
smtpd_tls_CAfile = /etc/postfix/ssl/cacert.pem
smtpd_tls_loglevel = 1
smtpd_tls_received_header = yes
smtpd_tls_session_cache_timeout = 3600s
tls_random_source = dev:/dev/urandom
home_mailbox = Maildir/

smtpd_recipient_restrictions =
permit_mynetworks
permit_sasl_authenticated
reject_invalid_hostname
reject_non_fqdn_hostname
reject_non_fqdn_sender
reject_non_fqdn_recipient
reject_unauth_destination
reject_unauth_pipelining
reject_invalid_hostname
reject_unknown_sender_domain
reject_rbl_client zen.spamhaus.org
reject_rbl_client list.dsbl.org
reject_rbl_client cbl.abuseat.org
reject_rbl_client sbl.spamhaus.org
reject_rbl_client pbl.spamhaus.org
reject_rhsbl_sender dsn.fc-ignorant.org
smtpd_data_restrictions = reject_unauth_pipelining, reject_multi_recipient_bounce, permit
smtpd_helo_required = yes

ldap_bind_dn = cn=admin,dc=example,dc=tld
ldap_bind_pw = your openldap password
ldap_search_base = o=hosting,dc=example,dc=tld
ldap_domain = dc=example,dc=tld
ldap_server_host = localhost
ldap_server_port = 389
ldap_version = 3

# transports
transport_server_host = $ldap_server_host
transport_search_base = $ldap_search_base
transport_query_filter = (&(&(vd=%s)(objectClass=VirtualDomain))(accountActive=TRUE)(delete=FALSE))
transport_result_attribute = postfixTransport
transport_cache = no
transport_bind = yes
transport_scope = one
transport_bind_dn = $ldap_bind_dn
transport_bind_pw = $ldap_bind_pw
transport_version = $ldap_version

# aliases
aliases_server_host = $ldap_server_host
aliases_search_base = $ldap_search_base
aliases_query_filter = (&(&(objectClass=VirtualMailAlias)(mail=%s))(accountActive=TRUE))
aliases_result_attribute = maildrop
aliases_bind = yes
aliases_cache = no
aliases_bind_dn = $ldap_bind_dn
aliases_bind_pw = $ldap_bind_pw
aliases_version = $ldap_version

# VirtualForward
virtualforward_server_host = $ldap_server_host
virtualforward_search_base = $ldap_search_base
virtualforward_query_filter = (&(&(objectClass=VirtualMailAccount)(mail=%s))(vacationActive=FALSE)(forwardActive=TRUE)(accountActive=TRUE)(delete=FALSE))
virtualforward_result_attribute = maildrop
virtualforward_bind = yes
virtualforward_cache = no
virtualforward_bind_dn = $ldap_bind_dn
virtualforward_bind_pw = $ldap_bind_pw
virtualforward_version = $ldap_version

# Accounts
accounts_server_host = $ldap_server_host
accounts_search_base = $ldap_search_base
accounts_query_filter = (&(&(objectClass=VirtualMailAccount)(mail=%s))(forwardActive=FALSE)(accountActive=TRUE)(delete=FALSE))
accounts_result_attribute = mailbox
accounts_cache = no
accounts_bind = yes
accounts_bind_dn = $ldap_bind_dn
accounts_bind_pw = $ldap_bind_pw
accounts_version = $ldap_version

accountsmap_server_host = $ldap_server_host
accountsmap_search_base = $ldap_search_base
accountsmap_query_filter = (&(&(objectClass=VirtualMailAccount)(mail=%s))(forwardActive=FALSE)(accountActive=TRUE)(delete=FALSE))
accountsmap_result_attribute = mail
accountsmap_cache = no
accountsmap_bind = yes
accountsmap_bind_dn = $ldap_bind_dn
accountsmap_bind_pw = $ldap_bind_pw
accountsmap_version = $ldap_version

# virtual quota
quota_server_host = $ldap_server_host
quota_search_base = $ldap_search_base
quota_query_filter = (&(&(objectClass=VirtualMailAccount)(mail=%s))(accountActive=TRUE)(delete=FALSE))
quota_result_attribute = quota
quota_cache = no
quota_bind = yes
quota_bind_dn = $ldap_bind_dn
quota_bind_pw = $ldap_bind_pw
quota_version = $ldap_version

# Mail to reply for gnarwl and mail to forward during vacation
recipient_bcc_maps = ldap:vfm
vfm_server_host = $ldap_server_host
vfm_search_base = $ldap_search_base
vfm_query_filter = (&(&(objectClass=VirtualMailAccount)(mail=%s))(vacationActive=TRUE)(forwardActive=FALSE)(accountActive=TRUE)(delete=FALSE))
vfm_result_attribute = mailAutoreply
vfm_cache = no
vfm_bind = yes
vfm_bind_dn = $ldap_bind_dn
vfm_bind_pw = $ldap_bind_pw
vfm_version = $ldap_version

# transport_maps
maildrop_destination_concurrency_limit = 2
maildrop_destination_recipient_limit = 1
gnarwl_destination_concurrency_limit = 1
gnarwl_destination_recipient_limit = 1
transport_maps = hash:/etc/postfix/transport, ldap:transport
mydestination = $transport_maps, localhost, localhost.localdomain, $myhostname, localhost.$mydomain, $mydomain
#virtual_alias_maps = hash:/etc/postfix/virtual, ldap:virtualforward, ldap:aliases, ldap:accountsmap
virtual_alias_maps = ldap:virtualforward, ldap:aliases, ldap:accountsmap

# virtual accounts for delivery
virtual_mailbox_base = /home/vmail
virtual_mailbox_maps = ldap:accounts
virtual_minimum_uid = 1000
virtual_uid_maps = static:1000
virtual_gid_maps = static:1000

$virtual_mailbox_maps
local_recipient_maps = $alias_maps

vi /etc/postfix/master.cf

And paste the following into it (add the end):

dovecot unix – n n – – pipe
flags=DRhu user=vmail:vmail argv=/usr/lib/dovecot/deliver -f ${sender} -d ${recipient)
gnarwl unix – n n – – pipe
flags=F user=vmail argv=/usr/bin/gnarwl -a ${user}@${nexthop} -s ${sender}

This concludes the Postfix configuration.

Step 5: Install And Configure Dovecot

apt-get install dovecot-imapd dovecot-pop3d

This will install dovecot and all necessary files and also create the standard ssl certificates for IMAPs and POP3s.

Now we back up the original configuration file for safe keeping.

mv /etc/dovecot/dovecot.conf /etc/dovecot/dovecot.conf.bck
mv /etc/dovecot/dovecot-ldap.conf /etc/dovecot/dovecot-ldap.conf.bck

Next you can create new configuration files with the examples provided below.

vi /etc/dovecot/dovecot.conf

auth_verbose = yes
mail_debug = no

base_dir = /var/run/dovecot/
protocols = imap imaps pop3 pop3s
protocol lda {
mail_plugins = quota
postmaster_address = postmaster@example.tld
auth_socket_path = /var/run/dovecot/auth-master
}
listen = *
shutdown_clients = yes
log_timestamp = “%b %d %H:%M:%S ”
syslog_facility = mail
disable_plaintext_auth = no
ssl_disable = no
ssl_cert_file = /etc/ssl/certs/mail.example.tld.pem
ssl_key_file = /etc/ssl/certs/mail.example.tld.pem
login_chroot = yes
login_user = postfix
login_process_per_connection = yes
login_processes_count = 2
login_max_processes_count = 128
login_max_connections = 256
login_greeting = Welcome to Dovecot eMail Server.
login_log_format_elements = user=<%u> method=%m rip=%r lip=%l %c
login_log_format = %$: %s
#default_mail_env = maildir:/home/vmail/%d/%u
mail_location = maildir:/home/vmail/%d/%u
first_valid_uid = 108 # REMEBER THIS MUST BE CHANGED TO YOUR UID FOR “postfix” FROM /etc/passwd
mail_uid = 1000
mail_gid = 1000
pop3_uidl_format = %08Xu%08Xv
auth default {
mechanisms = PLAIN LOGIN
passdb ldap {
args = /etc/dovecot/dovecot-ldap.conf
}
userdb ldap {
args = /etc/dovecot/dovecot-ldap.conf
}
socket listen {
master {
path = /var/run/dovecot/auth-master
mode = 0600
user = vmail
group = vmail
}
client {
path = /var/spool/postfix/private/auth
mode = 0660
user = postfix
group = postfix
}
}
user = vmail
}

vi /etc/dovecot/dovecot-ldap.conf

hosts = localhost
auth_bind = yes
auth_bind_userdn = mail=%u,vd=%d,o=hosting,dc=example,dc=tld
ldap_version = 3
base = o=hosting,dc=example,dc=tld
dn = cn=admin,dc=example,dc=tls
dnpass = your openldap password
deref = never
scope = subtree
user_attrs = quota=quota=maildir:storage
user_filter = (&(objectClass=VirtualMailAccount)(accountActive=TRUE)(mail=%u))
pass_attrs = mail,userPassword
pass_filter = (&(objectClass=VirtualMailAccount)(accountActive=TRUE)(mail=%u))
default_pass_scheme = MD5

Note: Remember to change example.tld to your own domain.tld (see assumptions).

Quota support is enabled, but no quota warnings are issued. This can be done by adding the following to your dovecot.conf:

plugin {
quota_warning = storage=95%% /usr/local/bin/quota-warning.sh 95
quota_warning2 = storage=80%% /usr/local/bin/quota-warning.sh 80
}

Now we need to create the quota-warning.sh:

vi /usr/local/bin/quota-warning.sh

And paste the following into it:

#!/bin/bash
PERCENT=$1
cat << EOF | /usr/local/libexec/dovecot/deliver -d $USER
From: postmaster@domain.com
Subject: quota warning

Your mailbox is now $PERCENT% full.
EOF

Now me make the script executable:

chmod +x /usr/local/bin/quota-warning.sh

This concludes the Dovecot coonfiguration.

Step 6: Install And Configure gnarwl

Let’s install gnarwl:

apt-get install gnarwl

Now let’s configure gnarwl.

First we’re going to back up the original configuration file and replace it with a new one.

mv /etc/gnarwl.conf /etc/gnarwl.conf.bck

Now we create the new conf file:

vi /etc/gnarwl.conf

And insert the following:

map_sender $sender
map_receiver $recepient
map_subject $subject
map_field $begin vacationStart
map_field $end vacationEnd
map_field $fullname cn
map_field $deputy vacationForward
map_field $reply mail
server localhost
port 389
scope sub
login cn=admin,dc=example,dc=tld
password secret
protocol 0
base dc=example,dc=tld
queryfilter (&(mailAutoreply=$recepient)(vacationActive=TRUE))
result vacationInfo
blockfiles /var/lib/gnarwl/block/
umask 0644
blockexpire 48
mta /usr/sbin/sendmail -F $recepient -t $sender
maxreceivers 64
maxheader 512
charset ISO8859-1
badheaders /var/lib/gnarwl/badheaders.db
blacklist /var/lib/gnarwl/blacklist.db
forceheader /var/lib/gnarwl/header.txt
forcefooter /var/lib/gnarwl/footer.txt
recvheader To Cc
loglevel 3

Change the default to your actual configuration.

Last but not least execute the following command to make gnarwl work:

chown -R vmail:vmail /var/lib/gnarwl/

This concludes the gnarwl configuration.
Step 7: Bringing It All Together And Making It Work

The following command will put into effect the configurations we made before:

/etc/init.d/apache2 stop
/etc/init.d/apache2 start
/etc/init.d/postfix/stop
/etc/init.d/dovecot stop

First we restart postfix:

/etc/init.d/postfix start

We need to do this in order to have the following directory created:

/var/run/dovecot/login

Now we need to make new ssl certificates for Dovecot:

dpkg-reconfigure dovecot-common

If the directory /var/run/dovecot and /var/run/dovecot/login don’t exist the reconfigure command above will produce errors complaining that the directories do not exist. In that case just create them. And re-run the command above.

Now we can start Dovecot:

/etc/init.d/dovecot start

You can now browse to http://example.tld/phamm

Log in with the user admin and your OpenLDAP password.

You should now be able to create domains and users.

One more thing: since phamm doesn’t actually delete users and / or domains, we need to enable the cleaner.sh that comes with phamm.

cp /var/www/tools/cleaner.sh /home/vmail/.

Edit the file to your settings, but set the BINDDN to BINDDN=”cn=admin,dc=example,dc=tld” for the script to work correctly.

Now we add a crontab to run the script periodically:

crontab -e

And insert the following:

30 * * * * /home/vmail/cleaner.sh

Well everything should be up and running now.

 

Comments

comments