Debian, Dovecot, postfix

Building Mailserver with Postfix

It’s been a week since i started playing around with Postfix. Though we are qmail lovers, a few days back one of my friend asked me to help him to build a Mail server. But he wanted to use Postfix as the MTA. I decided to integrate LDAP also, so that he can have a centralized user management. So in this blog i will be explaining on how to set up postfix to use LDAP for user lookup as well as using Dovecot SASL for SMTP auth and Dovecot’s lda for delivering the mails to the user’s Mailboxes. I’m using Debian 6.4 as the base os. I’ve also installed SLAPD, and i’ve a few test user’s in it. My LDAP setup has two OU’s, People and Groups respectively.

First we will setup Dovecot. The Debian Squeeze repository has Dovecot 1.2, so i will be installing those.

$ apt-get install dovecot-common dovecot-pop3d dovecot-imapd

Once dovecot is installed, we need to enable dovecot’s LDA and the dovecot’s SASL auth. Modify the dovecot.conf file as below. Since i’m using a virtual user vmail, i need to define the mail_uid and mail_gid as the vmail’s corresponding uid and gid. Also login_user must be postfix

In the lda section,

protocol lda {
 postmaster_address = postmaster@<domain_name>
 mail_plugin_dir = /usr/lib/dovecot/modules/lda
 deliver_log_format = msgid=%m: %$
 sendmail_path = /usr/sbin/sendmail
 rejection_subject = Rejected: %s
 auth_socket_path = /var/run/dovecot/auth-master
 log_path = /var/log/dovecot-deliver.log
 info_log_path = /var/log/dovecot-deliver.log

In the auth section,

auth default {
 mechanisms = plain

  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 = 0666
        # Default user/group is the one who started dovecot-auth (root)
        user = vmail
        group = vmail   

     client {
        path = /var/spool/postfix/private/auth
        mode = 0660
        user = postfix
        group = postfix

Below is the content of my dovecot-ldap.conf

hosts = localhost
dn =  <ldap_bind_dn>
dnpass = <ldap_bind_pwd>
sasl_bind = no
auth_bind = yes
ldap_version = 3
base = <ldap_base_dn>
auth_bind = yes
pass_attrs = uid=user
pass_filter = (&(objectClass=posixAccount)(uid=%u))
user_attrs = homeDirectory=home,mailQuotaSize=quota=dirsize:storage
user_filter = (&(objectClass=posixAccount)(|(mail=%u)(mailAlternateAddress=%u)(uid=%u)))

So now Dovecot is ready, we need to go ahead with Postfix installation. We need to install the below packages.

$ apt-get install postfix postfix-ldap

Once the packages are installed, we need to configure the main config file of postfix ie, Below is the my configuration,

myhostname = vagratn-postifx-box
smtpd_banner = <smtp_banner>
biff = no
# TLS parameters
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
myorigin = /etc/mailname
mydestination = localhost
relayhost =
mynetworks = [::ffff:]/104 [::1]/128
mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = all
home_mailbox = Maildir/
virtual_mailbox_maps = ldap:/etc/postfix/          #This ldap lookup will return user's MAilbox as the result from LDAPv
virtual_alias_maps = ldap:/etc/postfix/      #This ldap lookup will return uid from LDAP
$alias_maps = hash:/etc/aliases,ldap:/etc/postfix/
local_recipient_maps = $alias_maps
smtpd_sender_login_maps = ldap:/etc/postfix/     #This ldap lookup will return uid attribute from LDAP
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_auth_enable = yes
mailbox_transport = dovecot
dovecot_destination_recipient_limit = 1
virtual_mailbox_domains = <add virtual domains here>
virtual_transport = dovecot

We can also mention the SMTP sender and recipient restrictions in the above file,




Below are the contents of the various LDAP lookup file’s contents. We can verify this lookup’s using postmap command. ”postmap -q ldap:/

    server_host = ldap://localhost
    version = 3
    search_base = <ldap_base_dn>
    bind_dn = <ldap_bind_dn>
    bind_pw = <ldap_bind_password>
    bind = yes
    debug_level = 3
    query_filter = (&(|(mail=%s)(mailAlternateAddress=%s)))
    result_attribute = uid

    server_host = ldap://localhost
        version = 3
        search_base = <ldap_base_dn>
        bind_dn = <ldap_bind_dn>
        bind_pw = <ldap_bind_password>
        bind = yes
        debug_level = 3
    query_filter = (&(|(mail=%s)(mailAlternateAddress=%s)))
    result_attribute = uid
    result_format = %s/Maildir/

    server_host = ldap://localhost
        version = 3
        search_base = <ldap_base_dn>
        bind_dn = <ldap_bind_dn>
        bind_pw = <ldap_bind_password>
        bind = yes
        debug_level = 3
        query_filter = (&(|(mail=%s)(mailAlternateAddress=%s)))            
    result_attribute = uid

Now we need to allow dovecot for delivery, so we need to add the following entry to

dovecot   unix  -       n       n       -       -       pipe
    flags=DRhu user=vmail:vmail argv=/usr/lib/dovecot/deliver -f ${sender} -d ${recipient}

I’m using recipient email id completely as the delivery option, because, in the multi domain setup, ifthere exist two different user’s with same name say “abc”, LDAP dn is always unique, so we cannot have same user name for two different user’s, in such cases, we uses the full email id as the username for the second user, so in such scenario, we cannot use the user parameter as delivery option, because the it dovecot will remove the @domain part and takes the rest as the user, so if we use full email id, it will not deliver to the actual user.

This setup has worked perfectly with Debian Squeeze and as well as Debian Vagrant Boxes. I’m writing a puppet module which will automate LDAP,Postfix and Dovecot installation and configuration and will have a ready to use mail server. Soon i will upload it into my github account.

Debian, virtualization

Building custom Vagrant base box

Vagrant has become a common tool used by most of the sys admins who play around with computers. It has made virtualization so easy. Seriously it’s a must have tool. Vagrant supports Puppet/Chef provisioning, which makes it even more powerfull. We just need the base boxes to play around with Vagrant. In this blog i will be explaing about creating custom Vagrant Boxes. I work for DeepRootLinux, developers of the deepOfix Mail Server, a Debian based GNU/Linux distribution. I will be using our distribution for creating base box. It will help us to deploy deepOfix VM in a faster way and we it helps us to test our custom puppet modules into our operating system.

SO first we need to create a base VM in the Virtualbox. Ensure that the network controller is set to “NAT”. For port forwarding to work properly, NAT must be used. There a few point to remember, As per the Vagrant’s Documentation, Vagrant makes some assumptions,

  • The root password is ”Vagrant
  • One user account ”vagrant” with password ”vagrant”.
  • Domain is ”
  • Hostname is ”vagrant-[os-name]”, e.g. vagrant-debian-lenny

If any different values are being used, it has to be specified in the Vagrantfile. I’ve used custom domain name and hostname and i did not mentioned it in my Vagrant file. But it did not created any problem. Anyways Vagrant is using key-based authentication for SSH. So once we SSH into the system, we will login in to the system as the Main user, in our case ”vagrant” user. So we should make this ”vagrant” user as a member of the ”sudo (super user doers)” group, so that we can use “sudo su” to switch to the root user.

Normally, using sudo will always prompt for the user password, we can remove this by modifying the /etc/sudoers file. We just need to add one line into the file ”%sudo ALL=NOPASSWD: ALL”. This will prevent password prompt for the user’s who are the member’s of the sudo group. Once the file is edited, we need to do ”/etc/init.d/sudo restart” to reflect the changes.We can verify that sudo works without a password, but logging into the sudo user account, then sudo which sudo. We should get output similar to “/usr/bin/sudo”.

Now we need to setup Virtualbox Guest Additions. So, first we need to build the necessary packages.

apt-get install linux-headers-$(uname -r) build-essential    # for root user

sudo apt-get install linux-headers-$(uname -r) build-essential    # for sudo user's

We need to insert the guest additions image by using the GUI and clicking on ”Devices” followed by ”Install Guest Additions”. And we need to mount the CDROM.

mount /dev/hd0 /media/cdrom     # where /dev/hd0 is the CDROM block device in deepOfix

And finally, run the shell script which matches our system.

sh /media/cdrom/

Since Vagrant only supports key-based authentication for SSH, we must setup the SSH user to use key-based authentication. We need to copy a public key into ”~/.ssh/authorized_keys” of the ”vagrant” user. Vagrant provides an ”insecure” pair of public and private keys which are available here. Once the public key is copied, we can shut down our VM. And we can start building our base box.

vagrant package --base <box_name>

If there is any custom option to be set like, using a specific port port forwarding, or a specific SSH keys, we can create a Vagrantfile with all custom options and we can use it during the packaging.

vagrant package --base <bxo_name> --vagrantfile Vagrantfile

If everything goes fine, it will generate a base box file. We can use this base box file anywhere with the vagrant.

Debian, Dovecot

Mail Cluster With Qmail and Dovecot Proxy

This New year started with a new requirement, one of our client wanted a Mail cluster with 3 nodes, one node in US, a VPS, and the rest two in INDIA. Their primary server is one of the server in india. They have 3 category of USERS, all abroad user’s Mailboxes will be hosted in the VPS. For the rest, one set will be in one server and the rest in other. They want all the users to access directly the primary server not their respective server’s. I guess their Admins dont want to work much. Anyways, We decided to go ahead with it.

Since we are Qmail lover’s, we decided to ue the Qmail clustering by using DJB’s qmqpd protocol. In the LDAP, each user will have an attribute called ”mailHost”, whose value will be the FQDN of the server where their mailboxes are hosted. so the qmqpd will use this, mailHost attribute and transfers the mails between nodes to user’s corresponding mailboxes. We use’s Qmail with LDAP patch. In all the 3 nodes, LDAP will be synchronising all the time.Once we have the normal qmail setup running, in order to make cluster we need mainly 3 things.

1) We need to setup the qmqpd service in all the nodes.

2) We need to enable LDAP cluster. This can be done by creating a file ldapcluster in ”/var/qmail/control” folder. If the content of the file is ”1”, then it means cluster is active, ”0” cluster is deactive.

3) We need a dns server that can resolve all the 3 mailhost’s FQDN’s. We usually run DJB’s Tinydns in all our Mail server’s.

Once all the above 3 steps are done, we have a working Qmail Cluster. Mails will be delivered to each user according to the mailHost attribute mentioned in the LDAP.

Next Major thing is IMAP/POP3 services. Since all user’s will be be using the primary server as their incoming server in their MUA like outook,thunderbird, and even webmail user’s will also access the primary server, we decided to use the Dovecot’s Proxy feature, which can proxy the request’s based on the ”mailHost” attribute. When ever a user’s login request comes, Dovecot will check for the user’s ”mailHost” attribute from the LDAP. The dovecot will then proxy pass the request to the corresponding server.

Enabling Proxy in Dovecot is very simple. We need to add the host as well as the proxy variable in the dovecot-ldap userdb and passdb config file. Below is the content of our dovecot-ldap.conf.

hosts = localhost
dn =  uid=dummyuser,ou=People,dc=example,dc=com
dnpass = dummy_password
sasl_bind = no
auth_bind = yes
ldap_version = 3
base = dc=example,dc=com
auth_bind = yes
pass_attrs = uid=user,`mailHost`=host,qmailUID=proxy_maybe
pass_filter = (&(objectClass=posixAccount)(uid=%u))
user_attrs = homeDirectory=home,uidNumber=uid,gidNumber=gid,mailQuotaSize=quota=dirsize:storage,`mailHost`=host,qmailUID=proxy_maybe

This proxy is working perfectly in dovecot2.0 onwards. But in dovecot1.2, the proxy fails, when the mailHost attributes has a FQDN value. But if we mention ip instead of the FQDN, proxy seems to we working. But some times qmqpd will not work properly. That is because the dovecot is expecting values as ip, but we are supplying a FQDN. But in dovecot2.0 onwards, they have added a dnslookup function. But there is patch. We haven’t tested this patch, as we are using dovecot2.0