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 Kamic Koala 9.10


This how to will allow you step by to configure a Postfix mail server with with virtual hosting. Virtual hosting means that you can add as many mail domains as you want and sub sequentially 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.

Optional in this how to is the use of Roundcube webmail and proftpd.

The new version of Roundcube 0.3 allows a webmail user to change his / her (ldap) password, integrate an ldap address book and vacation using ldap (plugin). These features align nicely with the setup used in this how to and also provides an easy interface for the mail user.

This how to is an upgraded and enhanced version of the Ubuntu Intrepid version. Please note that the configuration of Roundcube and Proftpd can be added to a Intrepid / Jaunty setup.

Software to be used in this how to:

Postfix MTA, Dovecot IMAP / POP3, OpenLDAP, Gnarwl as autoresponder (vacation), Proftpd as ftp server, Phamm as management interface, MySQL as database backend for the webmail and Roundcube as webmail.

This worked for me, but I cannot guarantee that this set up will work for you so this how to comes without any guarantee.

Assumptions:

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

A read only account for the o=hosting,dc=example,dc=tld tree:

cn=phamm,o=hosting,dc=example,dc=tld

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

If you want for example o=maildomains or ou=domains, 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. If you want a different read only user than phamm than replace cn=phamm with cn=wat-you everywhere in this how to.

 

Step 1: Install And Configure 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 9.10 [ISPConfig 3]

Replace the following on page 4:

aptitude install postfix postfix-mysql postfix-doc mysql-client mysql-server courier-authdaemon courier-authlib-mysql courier-pop courier-pop-ssl courier-imap courier-imap-ssl libsasl2-2 libsasl2-modules libsasl2-modules-sql sasl2-bin libpam-mysql openssl getmail4 rkhunter binutils

by

aptitude install postfix postfix-ldap mysql-client mysql-server dovecot-imapd dovecot-pop3d libsasl2-2 libsasl2-modules libsasl2-modules-sql sasl2-bin libpam-mysql openssl getmail4 rkhunter binutils

and skip the configuration of postfix. 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.
The directory names for the downloaded and extracted packages need to be changed to ver version number of the respective packages downloaded eg: phamm-0.5.17 to phamm-0.5.xx

So let’s get started with the rest.

Download some packages and openldap schema’s we will need:

cd /usr/src

Get the latest version of phamm:

wget http://open.rhx.it/phamm/phamm-0.5.17.tar.gz

Unpack the archive:

tar xvzf phamm-0.5.17.tar.gz

 

Step2: Install and configure openldap

The configuration of OpenLDAP got a bit (more) complicated. cn=config is still used, but when installing the packages from the repositories only a skeleton configuration of openldap is installed.

You’re not asked anymore to provide a password when the package is installed and issuing the “dpkg-reconfigure slapd” only resest openldap to the skeleton configuration. You will have to setup the openldap database, root dn and acl’s your self using the root account (or sudo) in order to configure openldap.

Install openldap and ldap-utils:

aptitude install slapd ldap-utils

Change into the /etc/ldap directory:

cd /etc/ldap

Copy the phamm.schema and perversia.net.schema from the phamm package to the schema directory:

cp /usr/src/phamm-0.5.17/schema/phamm.schema /etc/ldap/schema.
cp /usr/src/phamm-0.5.17/schema/contrib/perversia.net.schema /etc/ldap/schema.

Get some more schema’s we need.

cd schema
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/pureftpd.schema
cd ../

Now we need to convert the schema’s to ldif format.

Create a file called convert and paste the text below in to it.

vi convert

Contents of convert:

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         /etc/ldap/schema/phamm.schema
include         /etc/ldap/schema/ISPEnv2.schema
include         /etc/ldap/schema/amavis.schema
include         /etc/ldap/schema/pureftpd.schema
include         /etc/ldap/schema/perversia.net.schema

Now we will convert the shemas:

mkdir ldif
slaptest -f convert -F ldif

Now we change in to the directory that contains the converted schemas:

cd ldif/cn\=config/cn\=schema

The directory should contain the following files:

cn={0}core.ldif    cn={3}inetorgperson.ldif  cn={6}amavis.ldif
cn={1}cosine.ldif  cn={4}phamm.ldif          cn={7}pureftpd.ldif
cn={2}nis.ldif     cn={5}ISPEnv2.ldif        cn={8}perversia.ldif

We will need to edit the phamm, amavis, pureftpd, ISPEnv2 and perversia schemas. For each you need to do the following (example for the phamm schema):

Change:

dn: cn={4}phamm
objectClass: olcSchemaConfig
cn: {4}phamm

to

dn: cn=phamm,cn=schema,cn=config
objectClass: olcSchemaConfig
cn: phamm

And delete:

structuralObjectClass: olcSchemaConfig
entryUUID: c27532b2-6a27-102e-88a5-e92372c94d84
creatorsName: cn=config
createTimestamp: 20091120135300Z
entryCSN: 20091120135300.238121Z#000000#000#000000
modifiersName: cn=config
modifyTimestamp: 20091120135300Z

So for each of these do repectively and make the changes like above:

vi cn\=\{4\}phamm.ldif
vi cn\=\{5\}ISPEnv2.ldif
vi cn\=\{6\}amavis.ldif
vi cn\=\{7\}pureftpd.ldif
vi cn\=\{8\}perversia.ldif

Note: the enry phamm in the example is ISPEnv2, amavis, pureftpd and pervisia in the  other ldif’s.

Now we copy the ldifs to the /etc/ldap/schema directory (this is not needed, but is handy whenever the ldif’s are needed).

cp cn\=\{4\}phamm.ldif /etc/ldap/schema/phamm.ldif
cp cn\=\{5\}ISPEnv2.ldif /etc/ldap/schema/ISPEnv2.ldif
cp cn\=\{6\}amavis.ldif /etc/ldap/schema/amavis.ldif
cp cn\=\{7\}pureftpd.ldif /etc/ldap/schema/pureftpd.ldif
cp cn\=\{8\}perversia.ldif /etc/ldap/schema/perversia.ldif

We can now delete the ldif directory since we don’t need it anymore and also to avoid any confusion and change back to the /etc/ldapdirectory.

cd /etc/ldap
rm -R ldif

Now we add the schemas to openldap.

ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/ldap/schema/cosine.ldif
ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/ldap/schema/inetorgperson.ldif
ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/ldap/schema/nis.ldif
ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/ldap/schema/phamm.ldif
ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/ldap/schema/ISPEnv2.ldif
ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/ldap/schema/amavis.ldif
ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/ldap/schema/pureftpd.ldif
ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/ldap/schema/perversia.ldif

We need load the database backend module and create the database.

Create a file called db.ldif and paste the text below in to it:

vi db.ldif

Content of the db.ldif:

# Load dynamic backend modules
dn: cn=module{0},cn=config
objectClass: olcModuleList
cn: module
olcModulepath: /usr/lib/ldap
olcModuleload: {0}back_hdb

# Create the database
dn: olcDatabase={1}hdb,cn=config
objectClass: olcDatabaseConfig
objectClass: olcHdbConfig
olcDatabase: {1}hdb
olcDbDirectory: /var/lib/ldap
olcSuffix: dc=example,dc=com
olcRootDN: cn=admin,dc=example,dc=com
olcRootPW: example
olcDbConfig: {0}set_cachesize 0 2097152 0
olcDbConfig: {1}set_lk_max_objects 1500
olcDbConfig: {2}set_lk_max_locks 1500
olcDbConfig: {3}set_lk_max_lockers 1500
olcLastMod: TRUE
olcDbCheckpoint: 512 30
olcDbIndex: cn,mail,givenname eq,subinitial
olcDbIndex: vd,delete eq,pres
olcDbIndex: accountActive,forwardActive eq,pres
olcDbIndex: smtpAuth eq,pres
olcDbIndex: sn,displayName eq,pres,sub
olcDbIndex: default sub
olcDbIndex: uid eq,pres
olcDbIndex: objectClass eq

Safe the file and issue the following command to load the module and initialize the database:

ldapadd -Y EXTERNAL -H ldapi:// -f db.ldif

Please note the olcRootPW: example which sets the RootPW to example. Replace example witch a password of your choice.

Now we create the base dn and the admin account for the openldap server as well as the o=hosting and phamm account.

Modify the text below to your needs and wants and generate a password for the admin account. The hash currently in this file sets the password to example. The crypt for the phamm account results in the password readonly.

To create crypt a password for the admin account  issue the following command:

slappasswd -h {MD5}

Type the wanted pasword twice and copy the result in to the text below.

Create the base.ldif:

vi base.ldif

Content of base.ldif.

dn: dc=example,dc=tld
objectClass: dcObject
objectclass: organization
o: example.tld
dc: example
description: My LDAP Root

dn: cn=admin,dc=example,dc=tld
objectClass: simpleSecurityObject
objectClass: organizationalRole
cn: admin
userPassword: {MD5}Gnmk1g3mcY6OWzJuM4rlMw==
description: LDAP administrator

dn: o=hosting,dc=example,dc=tld
objectClass: organizationalUnit
objectClass: top
ou: domains
description: Hosting Organization

# Read only account
dn: cn=phamm,o=hosting,dc=example,dc=tld
objectClass: simpleSecurityObject
objectClass: organizationalRole
cn: phamm
userPassword: {MD5}M267sheb6qc0Ck8WIPOvQA==
description: Read only account

Load the base dn into the database with the following command:

ldapadd -Y EXTERNAL -H ldapi:// -f base.ldif

We modify the system acl’s.

There are some acl’s set in the openldap setup that prevent phpldapadmin to interface with the directory, so we will remove them now and set openldap to the default cn=admin,cn=config. From this moment on the openldap can be configured and manipulated as before, but no longer by issuing commands like ldapadd -Y EXTERNAL -H ldapi:// -f file but rather ldapadd -x -Y EXTERNAL -H ldapi:// -D cn=admin,cn=config -W -f file.

Create a file called config.ldif and paste the text below in to it. However do not forget to replace the olcRootPW hash with the hash you created above.

vi config.ldif

Content of config.ldif:

dn: cn=config
changetype: modify
delete: olcAuthzRegexp

dn: olcDatabase={-1}frontend,cn=config
changetype: modify
delete: olcAccess

dn: olcDatabase={0}config,cn=config
changetype: modify
delete: olcRootDN

dn: olcDatabase={0}config,cn=config
changetype: modify
add: olcRootDN
olcRootDN: cn=admin,cn=config

dn: olcDatabase={0}config,cn=config
changetype: modify
add: olcRootPW
olcRootPW: {MD5}Gnmk1g3mcY6OWzJuM4rlMw==

dn: olcDatabase={0}config,cn=config
changetype: modify
delete: olcAccess

Load the config.ldif into the openldap server:

ldapadd -Y EXTERNAL -H ldapi:// -f config.ldif

Set the ldap acl’s for phamm.

Create a file called acl.ldif and paste the text below into it:

vi acl.ldif

Content of acl.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,uid,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 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

Now load the acl into the openldap server:

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

Now we have openldap configured and we can go to the next step.

Step 3: 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:

aptitude install postfix postfix-ldap libsasl2-2 libsasl2-modules libsasl2-modules-sql sasl2-bin

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 = /usr/lib/deliver
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=phamm,o=hosting,dc=example,dc=tld #==> Change this to the readonly user you created if not the default
ldap_bind_pw = the phamm user 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 = ldap:virtualforward, ldap:aliases, ldap:accountsmap
 
# virtual accounts for delivery
virtual_mailbox_base = /home/vmail
virtual_mailbox_maps = ldap:accounts
virtual_minimum_uid = 1000  #==> Change this and below to the actual uid / gid number of the vmail user.
virtual_uid_maps = static:1000
virtual_gid_maps = static:1000
 
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 4: Install And Configure Dovecot

aptitude 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 imap {
        mail_plugins = quota imap_quota
        imap_client_workarounds = outlook-idle

}
protocol pop3 {
        mail_plugins = quota
        pop3_no_flag_updates = yes
        pop3_reuse_xuidl = no
        pop3_lock_session = no
        pop3_client_workarounds = outlook-no-nuls oe-ns-eoh
}
protocol lda {
  mail_plugins = quota
  postmaster_address = postmaster@example.tld
  auth_socket_path = /var/run/dovecot/auth-master
  }
plugin {
        quota = maildir
        quota_rule = Trash:storage=10%%
        quota_rule2 = Spam:storage=10%%
        quota_warning = storage=95%%/home/vmail/bin/quota-warning.sh 95
        quota_warning2 = storage=80%% /home/vmail/bin/quota-warning.sh 80
}
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 #==> Change this and below to the neame you want
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=phamm,o=hosting,dc=example,dc=tls #The readonly user
dnpass = the readonly 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
user_attrs = quota=quota=maildir:storage=%$B

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 with a script file that issues the quota warnings.

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 -c /etc/dovecot/dovecot-nowarning.conf
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

The dovecot-nowarning.conf is a copy from your dovecot.conf file from which the % warning lines are removed.

So we copy the dovecot.conf file:

cp /etc/dovecot/dovecto.conf /etc/dovecto/dovecot-nowarning.conf

We edit this files and remove the lines below.

nano /etc/dovecto/dovecot-nowarning.conf

quota_warning = storage=95%%/home/vmail/bin/quota-warning.sh 95
quota_warning2 = storage=80%% /home/vmail/bin/quota-warning.sh 80

The lines below specify the amount of space (from the quota) that is assigned to the Trash and Spam folder.

quota_rule = Trash:storage=10%%
quota_rule2 = Spam:storage=10%%

This configuration uses 10 of the total quota for the mailbox respectively for the Trash and Spam folder. So with a quota of 100Mbyte a user is limited to 80Mbyte for emails, 10Mbyte for the Trash folder and 10Mbyte for the Spam folder.

This concludes the Dovecot configuration.

Step 5: 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:

  • Change the email address from postmaster@example.tld to dummy@example.tld. You can’t deliver mail to an alias since it is not a mailbox, but a forward.
  • Maildrop to to postmaster@example.tld rather than postmaster wich is a Unix account
  • Maildrop for abuse to postmaster@example.tld rather than postmaster

The other hacks are just to define other defaults:

  • Setting the right mailbox location
  • 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/
mv phamm-0.5.17 /var/www/
cd /var/www/phamm

My hacks:

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

Set the defaults for email and domain creation:

vi www-data/main.php

Change (line 308):

$entry["maildrop"] = "postmaster";

To

$entry["mail"] = "dummy@".$domain_new;

And also (line  328) 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 143)

<default>=php.Value(%domain%,/,+account_new+/)</default>

To:

<default>=php.Value(%domain%,/,+account_new+,@,%domain%/)</default>

Now we set the permissions on the directory:

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 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');

and change

// Welcome message
define ('SEND_WELCOME',1);
$welcome_msg = '../welcome_message.txt';
$welcome_subject = 'Welcome!';
# $welcome_sender = 'postmaster@localhost';
$welcome_bcc = 'postmaster@example.tld';

This will send a welcome message and a bcc to your postmaster account.

Enable the fpt and person plugin by removeing the // in the plugins section. If wanted you can also enable the davical and or jabber plugins, the schema needed for these plugins is installed.

And on line 174 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.

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>S</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.

Do not forget to create the aliases and or mailboxes for postmaster, webmaster since these are used by official’s and ISP’s to send mail to in case of … Not having these addresses could result in being blacklisted.

This concludes the phamm configuration.

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=phamm,o=hosting,dc=example,dc=tld #==>Change this and below if needed
password readonly
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/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 ‘admin’ 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.

Next steps are the optional Roundcube and proftpd configuration.

Step 8: Install and configure Roundcube webmail

First we create a database called roundcube:

mysqladmin -u root -p create roundcube

Next, we go to the MySQL shell:

mysql -u root -p

On the MySQL shell, we create the user roundcube with the password roundcube_password (replace it with a password of your choice) who has SELECT,INSERT,UPDATE,DELETE privileges on the roundcube database. This user will be used by Postfix and Courier to connect to the roundcube database:

GRANT SELECT, INSERT, UPDATE, DELETE ON roundcube.* TO ’roundcube’@’localhost’ IDENTIFIED BY ’roundcube_password’;
GRANT SELECT, INSERT, UPDATE, DELETE ON roundcube.* TO ’roundcube’@’localhost.localdomain’ IDENTIFIED BY ’roundcube_password’;
FLUSH PRIVILEGES;

Now we download and install Roundcube:

cd/usr/src
wget http://downloads.sourceforge.net/project/roundcubemail/roundcubemail/0.3.1/roundcubemail-.3.1.tar.gz?use_mirror=surfnet
tar xvzf roundcubemail-0.3.1.tar.gz
mv roundcubemail-0.3.1 /var/www
cd /var/www/roundcube

Always check for the lastest version of Roundcube and download that one and modify the commands above to the version of Roundcube you downloaded.

Now we load the sql tables in to the database we created before:

mysql -u roundcube -p roundcube <  SQL/mysql.initial.sql

Now we edit the Roundcube configuration:

cp config /db.inc.php.dist config/db.inc.php
cp config/main.inc.php.dist config/main.inc.php

Set the database configuration:

vi config/db.inc.php

Change the following line to the database configuration:

$rcmail_config['db_dsnw'] = 'mysql://roundcube:roundcube_password@localhost/roundcube';

Edit the main.inc.php and change the following entries:

vi config/main.inc.php

From:

// List of active plugins (in plugins/ directory)
$rcmail_config['plugins'] = array();

To:

// List of active plugins (in plugins/ directory)
$rcmail_config['plugins'] = array(password,vacation);

From:

chars.$rcmail_config['des_key'] = 'rcmail-!24ByteDESkey*Str';

To:

chars.$rcmail_config['des_key'] = 'your-own-24-digitkeystring';

From:

$rcmail_config['default_host'] = '';

To:

$rcmail_config['default_host'] = 'localhost';

From:

$rcmail_config['smtp_server'] = '';

To

$rcmail_config['smtp_server'] = 'localhost';

From:

// In order to enable public ldap search, configure an array like the Verisign
// example further below. if you would like to test, simply uncomment the example.
$rcmail_config['ldap_public'] = array();

//
// If you are going to use LDAP for individual address books, you will need to
// set 'user_specific' to true and use the variables to generate the appropriate DNs to access it.
//
// The recommended directory structure for LDAP is to store all the address book entries
// under the users main entry, e.g.:
//
// o=root
// ou=people
// uid=user@domain
// mail=contact@contactdomain
//
// So the base_dn would be uid=%fu,ou=people,o=root
// The bind_dn would be the same as based_dn or some super user login.
/*
* example config for Verisign directory
*
$rcmail_config['ldap_public']['Verisign'] = array(
'name' => 'Verisign.com',
'hosts' => array('directory.verisign.com'),
'port' => 389,
'use_tls' => false,
'user_specific' => false, // If true the base_dn, bind_dn and bind_pass default to the user's IMAP login.
// %fu - The full username provided, assumes the username is an email
// address, uses the username_domain value if not an email address.
// %u - The username prior to the '@'.
// %d - The domain name after the '@'.
'base_dn' => '',
'bind_dn' => '',
'bind_pass' => '',
'writable' => false, // Indicates if we can write to the LDAP directory or not.
// If writable is true then these fields need to be populated:
// LDAP_Object_Classes, required_fields, LDAP_rdn
'LDAP_Object_Classes' => array("top", "inetOrgPerson"), // To create a new contact these are the object classes to specify (or any other classes you wish to use).
'required_fields' => array("cn", "sn", "mail"), // The required fields needed to build a new contact as required by the object classes (can include additional fields not required by the object classes).
'LDAP_rdn' => 'mail', // The RDN field that is used for new entries, this field needs to be one of the search_fields, the base of base_dn is appended to the RDN to insert into the LDAP directory.
'ldap_version' => 3, // using LDAPv3
'search_fields' => array('mail', 'cn'), // fields to search in
'name_field' => 'cn', // this field represents the contact's name
'email_field' => 'mail', // this field represents the contact's e-mail
'surname_field' => 'sn', // this field represents the contact's last name
'firstname_field' => 'gn', // this field represents the contact's first name
'sort' => 'cn', // The field to sort the listing by.
'scope' => 'sub', // search mode: sub|base|list
'filter' => '', // used for basic listing (if not empty) and will be &'d with search queries. example: status=act
'fuzzy_search' => true); // server allows wildcard search
*/

// An ordered array of the ids of the addressbooks that should be searched
// when populating address autocomplete fields server-side. ex: array('sql','Verisign');
$rcmail_config['autocomplete_addressbooks'] = array('sql');

To:

$rcmail_config['ldap_public'] = array(GAL);
$rcmail_config['ldap_public']['GAL'] = array(
'name' => 'GAL',
'hosts' => array('localhost'),
'port' => 389,
'use_tls' => false,
'user_specific' => true,
'base_dn' => 'vd=%d,o=hosting,dc=example,dc=tls',
'bind_dn' => 'cn=phamm,o=hosting,dc=example,dc=tld',
'bind_pass' => 'readonly',
'writable' => false,
'LDAP_Object_Classes' => array("top", "inetOrgPerson"),
'required_fields' => array("cn", "sn", "mail"),
'LDAP_rdn' => 'mail',
'ldap_version' => 3,
'search_fields' => array('mail', 'cn'),
'name_field' => 'cn',
'email_field' => 'mail',
'surname_field' => 'sn',
'firstname_field' => 'gn',
'sort' => 'cn',
'scope' => 'sub',
'filter' => '(&(|(objectClass=VirtualMailAccount)objectClass=VirtualMailAlias))(accountActive=TRUE))',
'fuzzy_search' => true);
$rcmail_config['autocomplete_addressbooks'] = array('sql',GAL');

This will only allow users defined on the email server (localhost) to login and be created as email user.

The configuration for the password plugin:

cp plugins/password/config.inc.php.dist plugins/password/config.inc.php

Edit the configuration:

vi plugins/password/config.inc.php

Change the following entries

From:

$rcmail_config['password_driver'] = 'sql';

To:

$rcmail_config['password_driver'] = 'ldap';

From:

// LDAP Driver options
// -------------------
// LDAP server name to connect to.
// You can provide one or several hosts in an array in which case the hosts are tried from left to right.
// Exemple: array('ldap1.exemple.com', 'ldap2.exemple.com');
// Default: 'localhost'
$rcmail_config['password_ldap_host'] = 'localhost';

// LDAP server port to connect to
// Default: '389'
$rcmail_config['password_ldap_port'] = '389';

// TLS is started after connecting
// Using TLS for password modification is recommanded.
// Default: false
$rcmail_config['password_ldap_starttls'] = false;

// LDAP version
// Default: '3'
$rcmail_config['password_ldap_version'] = '3';

// LDAP base name (root directory)
// Exemple: 'dc=exemple,dc=com'
$rcmail_config['password_ldap_basedn'] = 'dc=exemple,dc=com';

// LDAP connection method
// There is two connection method for changing a user's LDAP password.
// 'user': use user credential (recommanded, require password_confirm_current=true)
// 'admin': use admin credential (this mode require password_ldap_adminDN and password_ldap_adminPW)
// Default: 'user'
$rcmail_config['password_ldap_method'] = 'user';

// LDAP Admin DN
// Used only in admin connection mode
// Default: null
$rcmail_config['password_ldap_adminDN'] = null;

// LDAP Admin Password
// Used only in admin connection mode
// Default: null
$rcmail_config['password_ldap_adminPW'] = null;

// LDAP user DN mask
// The user's DN is mandatory and as we only have his login,
// we need to re-create his DN using a mask
// '%login' will be replaced by the current roundcube user's login
// '%name' will be replaced by the current roundcube user's name part
// '%domain' will be replaced by the current roundcube user's domain part
// Exemple: 'uid=%login,ou=people,dc=exemple,dc=com'
$rcmail_config['password_ldap_userDN_mask'] = 'uid=%login,ou=people,dc=exemple,dc=com';

// LDAP password hash type
// Standard LDAP encryption type which must be one of: crypt,
// ext_des, md5crypt, blowfish, md5, sha, smd5, ssha, or clear.
// Please note that most encodage types require external libraries
// to be included in your PHP installation, see function hashPassword in drivers/ldap.php for more info.
// Default: 'crypt'
$rcmail_config['password_ldap_encodage'] = 'crypt';

// LDAP password attribute
// Name of the ldap's attribute used for storing user password
// Default: 'userPassword'
$rcmail_config['password_ldap_pwattr'] = 'userPassword';

// LDAP password force replace
// Force LDAP replace in cases where ACL allows only replace not read
// See http://pear.php.net/package/Net_LDAP2/docs/latest/Net_LDAP2/Net_LDAP2_Entry.html#methodreplace
// Default: true
$rcmail_config['password_ldap_force_replace'] = true;

To:

$rcmail_config['password_ldap_host'] = 'localhost';
$rcmail_config['password_ldap_port'] = '389';
$rcmail_config['password_ldap_starttls'] = false;
$rcmail_config['password_ldap_version'] = '3';
$rcmail_config['password_ldap_basedn'] = 'o=hosting,dc=example,dc=tld';

$rcmail_config['password_ldap_method'] = 'user';
$rcmail_config['password_ldap_adminDN'] = null;
$rcmail_config['password_ldap_adminPW'] = null;

$rcmail_config['password_ldap_userDN_mask'] = 'mail=%login,vd=%domain,o=hosting,dc=example,dc=tld';

$rcmail_config['password_ldap_encodage'] = 'md5';
$rcmail_config['password_ldap_pwattr'] = 'userPassword';

$rcmail_config['password_ldap_force_replace'] = true;

Now we’re going to download and install the vacation plugin:

cd /usr/src
wget http://blog.hbis.fr/wp-content/uploads/2009/10/plugin-vacation-0.3-20091008.tar.gz
tar xvzf plugin-vacation-0.3-20091008.tar.gz
mv vacation /var/www/roundcube/plugins/vacation
cd /var/www/roundcube

Now we edit the configuration and change:

vi plugins/vacation/config.inc.php

From:

$rcmail_config['vacation_gui_vacationsubject'] = TRUE;

To:

$rcmail_config['vacation_gui_vacationsubject'] = FALSE;

From:

$rcmail_config['vacation_driver'] = 'sql';

To:

$rcmail_config['vacation_driver'] = 'ldap';

From:

// Base DN
$rcmail_config['vacation_ldap_base'] = 'dc=ldap,dc=my,dc=domain';

// Bind DN
$rcmail_config['vacation_ldap_binddn'] =
'cn=user,dc=ldap,dc=my,dc=domain';

// Bind password
$rcmail_config['vacation_ldap_bindpw'] = 'pa$$w0rd';

To:

// Base DN
$rcmail_config['vacation_ldap_base'] = 'o=hosting,dc=example,dc=tld';

// Bind DN
$rcmail_config['vacation_ldap_binddn'] = 'cn=admin,dc=example,dc=tld';

// Bind password
$rcmail_config['vacation_ldap_bindpw'] = 'yourpassword';

From:

// Search filter to read data
$rcmail_config['vacation_ldap_search_filter'] = '(objectClass=mailAccount)';

// Search attributes to read data
$rcmail_config['vacation_ldap_search_attrs'] = array ('vacationActive', 'vacationInfo');

// array of DN to use for modify operations required to write data.
$rcmail_config['vacation_ldap_modify_dns'] = array (
'cn=%email_local,ou=Mailboxes,dc=%email_domain,ou=MailServer,dc=ldap,dc=my,dc=domain'
);

To:

// Search base to read data
$rcmail_config['vacation_ldap_search_base'] =
'mail=%username,vd=%email_domain,o=hosting,dc=example,dc=tld';

// Search filter to read data
$rcmail_config['vacation_ldap_search_filter'] = '(objectClass=VirtualMailAccount)';

// Search attributes to read data
$rcmail_config['vacation_ldap_search_attrs'] = array ('vacationActive', 'vacationInfo');

// array of DN to use for modify operations required to write data.
$rcmail_config['vacation_ldap_modify_dns'] = array (
'mail=%username,vd=%email_domain,o=hosting,dc=example,dc=tld'
);

This concludes the configuration for Roundcube.

You can now go to http://yourdomain.tld/roundcube and login with your email username and password. Under preferences you can now change your password and vacation settings.

Step 9: Install and configure proftpd

First we will install proftpd and its requirements:

aptitude install proftpd proftpd-mod-ldap

Depending on your load you can decide between stand alone and inet.d.

Edit /etc/proftpd/proftpd.conf:

vi /etc/proftpd/proftpd.conf

And change from:

# Use this to jail all users in their homes
# DefaultRoot ~

To:

# Use this to jail all users in their homes
DefaultRoot ~

Now edit /etc/proftpd/modules.conf:

vi /etc/proftpd/modules.conf

And change from:

# Install proftpd-mod-ldap to use this
#LoadModule mod_ldap.c

To:

# Install proftpd-mod-ldap to use this
LoadModule mod_ldap.c

And from:

# Install proftpd-mod-ldap to use this
# LoadModule mod_quotatab_ldap.c

To:

# Install proftpd-mod-ldap to use this
LoadModule mod_quotatab_ldap.c

No edit /etc/proftpd/ldap.conf and set the following:

<IfModule mod_ldap.c>

AuthOrder mod_ldap.c
AuthPAM off
LDAPUseTLS off
PersistentPasswd off
LDAPServer 127.0.0.1
LDAPDNInfo cn=abook,dc=webhabitat,dc=be readonly
LDAPDoAuth on “dc=webhabitat,dc=be” # (&(uid=%u)(objectclass=posixAccount))

</IfModule>

Now restart postfix and your domain postmasters created in phamm can login to their home directories. Note not the email accounts.

/etc/init.d/proftpd restart

This concludes the complete how to.

Comments

comments