/ informatica

Mailserver with OpenLDAP, Postfix, Dovecot, Horde from source on Debian Etch

During this howto i'll setup a mail server with LDAP users, Postfix virtual transport and POP/IMAP access (with SSL). I'll moreover setup Apache2 with PHP support, Horde webmail, vacation messages and user quotas.
Every program will be compiled into /usr/src and installed into /usr/local/program_name. The mailboxes (in Maildir format) will be stored into /mail/uid/

Debian Etch installation

Let's start installing Debian Etch from businesscard and unchecking all the default packages (Desktop environment and Base system). After the reboot install some basic package:

apt-get install build-essential vim openssh-server psmisc autoconf file

OpenSSH is just an optional server, but i'm working on a VMWare virtual machine and an ssh console is more comfortable than the VMWare console :)


Now download all the needed packages into /usr/src:

  • OpenSSL 0.9.8i
  • BerkeleyDB 4.6.21 (version 4.7 is unsupported from OpenLDAP)
  • OpenLDAP 2.4.11
  • Apache 2.2.9
  • IMAP 2007b
  • PHP 5.2.6
  • Postfix 2.5 Patchlevel 5
  • Dovecot 1.1.3


~$ cd /usr/src/openssl
~$ ./config --openssldir=/usr/local/openssl --prefix=/usr/local/openssl
~$ make
~# make install


~$ cd /usr/src/db/build_unix
~$ ../dist/configure --prefix=/usr/local/BerkeleyDB
~$ make
~# make install


~# ln -s /usr/local/BerkeleyDB/include/db.h /usr/include/
~$ CPPFLAGS="-I/usr/local/BerkeleyDB/include/" LDFLAGS="-L/usr/local/lib -L/usr/local/BerkeleyDB/lib -R/usr/local/BerkeleyDB/lib" LD_LIBRARY_PATH="/usr/src/db-4.6.21.NC/build_unix/.libs/" ./configure --prefix=/usr/local/openldap --enable-crypt
~$ make depend
~$ make
~$ make test
~# make install

For this howto i'll use dc=example,dc=com. Edit /usr/local/openldap/etc/openldap/slapd.conf including some schemas and setting the password for cn=Manager,dc=example,dc=com

include /usr/local/openldap/etc/openldap/schema/cosine.schema
include /usr/local/openldap/etc/openldap/schema/nis.schema
include /usr/local/openldap/etc/openldap/schema/inetorgperson.schema

Rename /usr/local/openldap/var/openldap-data/DB_CONFIG.example to /usr/local/openldap/var/openldap-data/DB_CONFIG and type:
to start the server.

Then create an ldif file (base.ldif) for the initial user:
dn: dc=example,dc=com
objectclass: dcObject
objectclass: organization
o: example
dc: example

  dn: cn=Manager,dc=example,dc=com
  objectclass: organizationalRole
  cn: Manager

and add it to the database:
/usr/local/openldap/bin/ldapadd -x -D "cn=Manager,dc=example,dc=com" -W -f base.ldif

Now let's create some users, i'll use these objects:
objectClass: inetOrgPerson
objectClass: top
objectClass: posixAccount
objectClass: shadowAccount

An example:
dn: cn=tommaso,ou=utenti,dc=example,dc=com
cn: Tommaso
gidNumber: 10001
homeDirectory: /mail/tommaso
sn: Visconti
uid: tommaso
uidNumber: 10001
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: shadowAccount
objectClass: top
loginShell: /bin/bash
givenName: Tommaso
mail: tommaso@example.com
shadowWarning: 7
shadowMax: 99999
shadowLastChange: 14121
labeledURI: pippo
employeeType: active
userPassword: {CRYPT}cfBmIgztxLBh6

If you want to set these users as system users install libnss-ldap
apt-get install libnss-ldap
and edit /etc/nsswitch.conf
passwd: compat ldap
group: compat ldap
shadow: compat ldap

and create the group:
groupadd -g 10001 users

You can verify with:
getent passwd


~$ cd /usr/src/apache2

~$ ./configure --prefix=/usr/local/apache2 --enable-so --with-ssl=/usr/local/openssl/ --enable-ssl
~$ make
~# make install

Edit /usr/local/apache2/conf/apache.conf and launch with:
/usr/local/apache2/bin/apachectl -k start


The IMAP library is needed from PHP to send email from the webmail.
~$ wget ftp://ftp.cac.washington.edu/imap/imap.tar.Z
~$ cd /usr/src
~$ tar xvzf imap.tar.Z
~$ cd imap-2007b
~$ make slx SSLTYPE=none
~$ mkdir -p /usr/local/imap/lib
~$ mkdir /usr/local/imap/include
~$ cp c-client/.h /usr/local/imap/include/
~$ cp c-client/
.c /usr/local/imap/lib/
~$ cp c-client/c-client.a /usr/local/imap/lib/libc-client.a


First, download and unzip the mysql client libraries, then:
~$ apt-get install libjpeg-dev libpng-dev libxml2-dev libmcrypt-dev libmagic1
~$ cd /usr/src/php
~$ ./configure --prefix=/usr/local/php5 --with-apxs2=/usr/local/apache2/bin/apxs --with-gettext --with-~$ mcrypt --with-iconv --enable-mbstring=all --enable-mbregex --with-gd --with-png-dir=/usr/lib --with-jpeg-dir=/usr/lib --with-mime-magic=/usr/share/file/magic.mime --with-sqlite --with-ldap=/usr/local/openldap/ --with-imap=/usr/local/imap --with-mysql=/usr/src/mysql-5.0.67-linux-i686/ --with-mysqli=/usr/src/mysql-5.0.67-linux-i686/bin/mysql_config
~$ make
~$ make install

Edit apache.conf adding index.php to the default pages; if not present add this too:
<filesmatch .php$>
SetHandler application/x-httpd-php


Create /etc/ld.so.conf.d/my_libraries.conf:

and launch ldconfig!

~# ln -s /usr/local/BerkeleyDB/lib/libdb.so /usr/lib
~# addgroup --system postfix
~# adduser --system -ingroup postfix --home /mail --no-create-home --disabled-password postfix
~# addgroup --system postdrop
~# addgroup --gid 800 maildeliver
~# adduser --system --uid 800 --gid 800 --home /mail --disabled-password --no-create-home maildeliver
~$ export LD_LIBRARY_PATH="/usr/local/openldap/lib:/usr/local/BerkeleyDB/lib/"
~$ make makefiles CCARGS='-DDEF_CONFIG_DIR="/usr/local/postfix/etc" -DDEF_COMMAND_DIR="/usr/local/postfix/sbin" -DDEF_DAEMON_DIR="/usr/local/postfix/libexec" -DDEF_MANPAGE_DIR="/usr/local/postfix/man" -DDEF_SENDMAIL_PATH="/usr/local/postfix/bin/sendmail" -DDEF_MAILQ_PATH="/usr/local/postfix/bin/mailq" -DDEF_DATA_DIR="/usr/local/postfix/lib" -DHAS_DB -I/usr/local/BerkeleyDB/include -DHAS_LDAP -I/usr/local/openldap/include' AUXLIBS='-llber -L/usr/local/BerkeleyDB/include/ -ldb -lldap -L/usr/local/openldap/lib'
~$ make
~# make install
~# ln -s /usr/local/postfix/etc/aliases /etc/
~# /usr/local/postfix/sbin/postfix -c /usr/local/postfix/etc/ set-permissions
~# chown -R postfix /usr/local/postfix/lib

The gid and user 800 will be used for the virtual transport.

This is main.cf:
queue_directory = /usr/local/postfix-2.5.5/spool
command_directory = /usr/local/postfix-2.5.5/sbin
daemon_directory = /usr/local/postfix-2.5.5/libexec
data_directory = /usr/local/postfix-2.5.5/lib
mail_owner = postfix
debug_peer_level = 2
debugger_command =
ddd $daemon_directory/$process_name $process_id & sleep 5
sendmail_path = /usr/local/postfix-2.5.5/sbin/sendmail
newaliases_path = /usr/local/postfix-2.5.5/bin/newaliases
mailq_path = /usr/local/postfix-2.5.5/bin/mailq
setgid_group = postdrop
html_directory = no
manpage_directory = /usr/local/postfix-2.5.5/man
readme_directory = no
smtpd_banner = Benvenuti ai puri di cuore
biff = no
append_dot_mydomain = no
myhostname = mail.example.com
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
myorigin = /etc/mailname
mydestination = localhost
relayhost =
mynetworks =
mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = all
home_mailbox = Maildir/
virtual_transport = virtual
virtual_uid_maps = static:800
virtual_gid_maps = static:800
virtual_mailbox_base = /mail
virtual_mailbox_maps = ldap:/usr/local/postfix-2.5.5/etc/ldap-accounts.cf
virtual_mailbox_domains = example.com
virtual_alias_maps = hash:/etc/aliases
relay_domains = localhost

server_host = localhost
search_base = ou=utenti,dc=example,dc=com
query_filter = mail=%s
result_attribute = uid
version = 3
bind = yes
bind_dn = cn=Manager,dc=example,dc=com
bind_pw = pippo

Remember to create an user for bindings and edit Postfix and Dovecot configurations to use it.
To verify the ldap file use postmap:
~$ postmap -q tommaso.visconti@example ldap:/usr/local/postfix/etc/ldap-aliases.cf

Start postfix with:
~# /usr/local/postfix/sbin/postfix start


~$ cd /usr/src/dovecot
~$ LDFLAGS="-L/usr/local/openldap/lib -L/usr/local/openssl/lib" CPPFLAGS="-I/usr/local/openldap/include -I/usr/local/openssl/include/" ./configure --prefix=/usr/local/dovecot --with-ldap=yes --with-ssl=openssl
~$ make
~# make install
~# adduser --system -ingroup mail --home /usr/local/dovecot/lib --no-create-home --shell /bin/false --disabled-password dovecot

This is dovecot.conf:
protocols = imap imaps pop3 pop3s
mail_uid = 800
mail_gid = 800
listen = *
disable_plaintext_auth = no
shutdown_clients = yes
log_path = /var/log/dovecot.log
info_log_path = /var/log/mail.log
log_timestamp = "%Y-%m-%d %H:%M:%S "
syslog_facility = mail
ssl_listen = *
ssl_disable = no
ssl_cert_file = /etc/ssl/certs/dovecot.pem
ssl_key_file = /etc/ssl/private/dovecot.pem
login_chroot = yes
login_greeting = Welcome to my mail server.
login_log_format_elements = user=< %u> method=%m rip=%r lip=%l %c
login_log_format = %$: %s
mail_location = maildir:/mail/%n
mail_full_filesystem_access = no
mail_debug = no
first_valid_uid = 800
last_valid_uid = 800
first_valid_gid = 800
last_valid_gid = 800
protocol imap {
protocol pop3 {
pop3_uidl_format = %08Xu%08Xv
auth_verbose = no
auth_debug = no
auth_debug_passwords = no
auth default {
mechanisms = PLAIN LOGIN
passdb ldap {
args = /usr/local/Dovecot-1.1.3/etc/dovecot-ldap.conf
userdb ldap {
# Path for LDAP configuration file, see /etc/dovecot/dovecot-ldap.conf for example
args = /usr/local/Dovecot-1.1.3/etc/dovecot-ldap.conf
user = mail_deliver
dict {
plugin {

and dovecot-ldap.conf:
hosts = localhost
dn = cn=Manager,dc=example,dc=come
dnpass = pippo
ldap_version = 3
base = ou=utenti, dc=example, dc=com
deref = never
scope = subtree
user_attrs = homeDirectory=home
user_filter = (&(employeeType=active)(mail=%u))
pass_attrs = mail=user@domain,userPassword=password
pass_filter = (&(employeeType=active)(mail=%u))
default_pass_scheme = CRYPT

Start dovecot with /usr/local/dovecot/sbin/dovecot


I suggest Horde Framework or Roundcube