Setting up a Postfix/Dovecot mail system with an LDAP/Fusiondirectory backend

This guide is about setting up a Postfix/Dovecot system using LDAP/Fusiondirectoory as a backend.

Prerequisites

  • Install an LDAP/Fusiondirectory infrastructure
  • A DNS A Record:
    mail.example.com.       300     IN      A       4.5.6.7
  • A DNS PTR Record:
    7.6.5.4.in-addr.arpa. 300 IN    PTR mail.example.com.
  • A DNS MX Record (Actually more than one):
    example.com.    300 IN  MX  5 mail.example.com.

Install FusionDirectory Plugins

  • Install the Mail plugin:

    apt -y install fusiondirectory-plugin-mail fusiondirectory-plugin-mail-schema
    fusiondirectory-insert-schema -i /etc/ldap/schema/fusiondirectory/mail-fd.schema
    fusiondirectory-insert-schema -i /etc/ldap/schema/fusiondirectory/mail-fd-conf.schema
  • Install the Alias plugin:

    apt -y install fusiondirectory-plugin-alias fusiondirectory-plugin-alias-schema
    fusiondirectory-insert-schema -i /etc/ldap/schema/fusiondirectory/alias-fd-conf.schema
    fusiondirectory-insert-schema -i /etc/ldap/schema/fusiondirectory/alias-fd.schema
  • Install the Postfix plugin:

    apt -y install fusiondirectory-plugin-postfix fusiondirectory-plugin-postfix-schema
    fusiondirectory-insert-schema -i /etc/ldap/schema/fusiondirectory/postfix-fd.schema

Setup mail services:

  • Enter the mail.example.com server configuration (Systems plugin)

  • From the ‘Services’ tab create a ‘Postfix (SMTP)’ and an ‘IMAP/POP3 generic’ service

  • Add mail capability to all normal users:

    • Click the ‘Mail’ tab of a user and then press ‘Add Mail settings’

    • Fill in the ‘Primary Address. field and select mail.example.com as the server.
  • Add All necessary distribution lists and redirections from ‘Aliases’

Setup postfix

  • Create a service account for postfix using the ‘DSA’ plugin in *FusionDirectory’. It should look like this:

    dn: cn=postfix,ou=dsa,dc=example,dc=com
    cn: postfix
    userPassword:: yeduyt2732tet87eoiewoi32t4873t4387f7gf47gf49i6=
    structuralObjectClass: organizationalRole
    entryUUID: 280427ce-9a54-1035-8e48-bf1fd814366b
    creatorsName: cn=admin,dc=example,dc=com
    createTimestamp: 20160419082627Z
    objectClass: organizationalRole
    objectClass: top
    objectClass: simpleSecurityObject
    entryCSN: 20160419082628.006263Z#000000#000#000000
    modifiersName: cn=admin,dc=example,dc=com
    modifyTimestamp: 20160419082628Z
  • Install postfix:

    apt -y install postfix postfix-pcre postfix-ldap

    When you are prompted about “General type of mail configuration:” select “No configuration”

  • Prepare the /etc/postfix/main.cf file:
smtpd_banner = $myhostname ESMTP $mail_name
biff = no
append_dot_mydomain = no
readme_directory = no
smtpd_tls_cert_file=/etc/ssl/certs/mail.example.com.crt
smtpd_tls_key_file=/etc/ssl/private/mail.example.com.key
smtpd_use_tls=yes
smtpd_tls_security_level = may
smtpd_tls_auth_only = yes
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
smtpd_tls_dh512_param_file = ${config_directory}/certs/dh_512.pem
smtpd_tls_dh1024_param_file = ${config_directory}/certs/dh_1024.pem
tls_random_source = dev:/dev/urandom
smtpd_tls_loglevel = 0
smtpd_client_new_tls_session_rate_limit = 10
smtpd_tls_exclude_ciphers =
    EXP
    EDH-RSA-DES-CBC-SHA
    ADH-DES-CBC-SHA
    DES-CBC-SHA
    SEED-SHA
    aNULL
    eNULL
    EXPORT
    DES
    RC4
    MD5
    PSK
    aECDH
    EDH-DSS-DES-CBC3-SHA
    KRB5-DES-CBC3-SHA
myhostname = mail.example.com
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
myorigin = /etc/mailname
mydestination = $myhostname, mail.example.com, localhost.localdomain, localhost
relayhost =
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 10.10.10.0/24
mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = all
inet_protocols = all
local_transport = local
postscreen_greet_action = enforce
smtpd_recipient_restrictions =
    reject
    permit_mynetworks
    permit_sasl_authenticated
    warn_if_reject reject_non_fqdn_hostname
    warn_if_reject reject_non_fqdn_sender
    reject_invalid_hostname
    reject_unknown_sender_domain
    reject_unverified_recipient
    reject_unauth_destination
    reject_non_fqdn_sender
    reject_non_fqdn_recipient
    reject_non_fqdn_helo_hostname
    check_sender_ns_access cidr:/etc/postfix/drop.cidr
    check_sender_mx_access cidr:/etc/postfix/drop.cidr
    reject_rbl_client bl.spamcop.net,
    reject_rbl_client cbl.abuseat.org
    reject
smtpd_data_restrictions = reject_multi_recipient_bounce
smtpd_sender_restrictions =
    reject_non_fqdn_sender
    reject_unknown_sender_domain
smtpd_helo_restrictions =
    permit_mynetworks
    check_helo_access pcre:/etc/postfix/identitycheck.pcre
    reject_invalid_helo_hostname
disable_vrfy_command = yes
smtpd_helo_required = yes
smtpd_delay_reject = no
smtpd_client_restrictions = check_client_access cidr:/etc/postfix/drop.cidr
message_size_limit = 51200000
  • Prepare the rest of the configuration files:

    • Prepare the virtual domains file:

      cat > /etc/postfix/virtual_domains << EOF
       # Domain                Anything
      
      example.com            OK
      EOF
    • Prepare the virtual recipients file:

      cat > /etc/postfix/ldap_virtual_recipients.cf << EOF
      bind = yes
      bind_dn = cn=postfix,ou=dsa,dc=example,dc=com
      bind_pw = NotTheRealPassword
      server_host = ldap://ldap.example.com:389
      search_base = ou=people,dc=example,dc=com
      domain = example.com
      query_filter = (mail=%s)
      result_attribute = mail
      start_tls = yes
      version = 3
      EOF
    • Prepare the virtual aliases file:

      cat > /etc/postfix/ldap_virtual_aliases.cf << EOF
      bind = yes
      bind_dn = cn=postfix,ou=dsa,dc=example,dc=com
      bind_pw = NotTheRealPass
      server_host = ldap://ldap.example.com:389
      search_base = ou=alias,dc=example,dc=com
      domain = example.com
      query_filter = (mail=%s)
      result_attribute = gosaMailAlternateAddress, gosaMailForwardingAddress
      start_tls = yes
      version = 3
      EOF
    • Prepare the identity check file:

      cat > /etc/postfix/identitycheck.pcre << EOF
      # Identity (RegEx)              Action
      
      /^(mail\.example\.com)$/       REJECT Hostname Abuse: $1
      /^(1\.2\.3\.4)$/                REJECT Hostname Abuse: $1
      /^(\[1\.2\.3\.4\])$/            REJECT Hostname Abuse: $1
      EOF
    • Prepare the blacklist file:

      cat > /etc/postfix/drop.cidr << EOF
      # IP/CIDR                       Action
      
      1.2.3.0/24                      REJECT Blacklisted
      EOF
  • Generate the virtual domains hashmap:

    postmap hash:/etc/postfix/virtual_domains
  • Start postfix:

    systemctl start postfix

    Verify:

    ss -lnptu | grep master
    tcp    LISTEN     0      100    *:25      *:*      users (("master",pid=15539,fd=12))
    
  • Enable support for smtps (port 465) and submission (port 587):

    Uncomment the following lines from /etc/postfix/master.cf:

    submission inet n       -       -       -       -       smtpd
    smtps     inet  n       -       -       -       -       smtpd

    Restart postfix:

    systemctl restart postfix

    Verify:

    ss -lnptu | grep master
    tcp    LISTEN     0      100    *:587     *:*      users:(("master",pid=15854,fd=16))
    tcp    LISTEN     0      100    *:465     *:*      users:(("master",pid=15854,fd=19))
    tcp    LISTEN     0      100    *:25      *:*      users:(("master",pid=15854,fd=12))
    
  • Take precautions for perfect forward secrecy:

    mkdir /etc/postfix/certs
    cd /etc/postfix/certs
    openssl dhparam -2 -out dh_512.pem 512
    openssl dhparam -2 -out dh_1024.pem 1024
    chmod 600 dh_*
  • Lookup test:

    postmap -q theo@example.com ldap:/etc/postfix/ldap_virtual_recipients.cf
    theo@example.com
    
  • Open SMTP, SMTPS ans Submission ports:

    ufw allow 25/tcp
    ufw allow 465/tcp
    ufw allow 587/tcp

Install and configure dovecot

  • Create the user that will handle mail delivery:
  • Create a service account for dovecot using the ‘DSA’ plugin in *FusionDirectory’. It should look like this:

    dn: cn=dovecot,ou=dsa,dc=example,dc=com
    cn: dovecot
    userPassword:: ljsdewd98dej932j98dxjud8x3jx9843xj8943j438439e3=
    structuralObjectClass: organizationalRole
    entryUUID: 4d0d7174-9a54-1035-8e49-bf1fd814366b
    creatorsName: cn=admin,dc=example,dc=com
    createTimestamp: 20160419082730Z
    objectClass: organizationalRole
    objectClass: top
    objectClass: simpleSecurityObject
    entryCSN: 20160419082730.138012Z#000000#000#000000
    modifiersName: cn=admin,dc=example,dc=com
    modifyTimestamp: 20160419082730Z
  • Install dovecot:

    apt -y install dovecot-core dovecot-imapd dovecot-pop3d dovecot-lmtpd dovecot-ldap
  • Make the following changes in /etc/dovecot/conf.d/10-ssl.conf:

    ssl = required
    ssl_cert = </etc/ssl/certs/mail.example.com.crt
    ssl_key = </etc/ssl/private/mail.example.com.key
  • Make the following changes in /etc/dovecot/conf.d/10-auth.conf:

    disable_plaintext_auth = yes
    auth_mechanisms = plain login
    !include auth-ldap.conf.ext
  • Make the following changes in /etc/dovecot/dovecot-ldap.conf.ext:

    uris = ldap://ldap.example.com
    dn = cn=dovecot,ou=dsa,dc=example,dc=com
    dnpass = SomePass33
    tls = yes
    tls_ca_cert_file = /etc/ssl/certs/ca-certificates.crt
    tls_require_cert = demand
    ldap_version = 3
    base = ou=people,dc=example,dc=com
    user_attrs = =mail=maildir:/srv/vmail/%{ldap:mail}/Maildir
    user_filter = (&(objectClass=gosaMailAccount)(uid=%n))
    pass_attrs = uid=user,userPassword=password
    pass_filter = (&(objectClass=gosaMailAccount)(uid=%n))
    default_pass_scheme = SSHA
  • Make the following changes in /etc/dovecot/conf.d/10-logging.conf:

    log_path = syslog
    syslog_facility = mail
    auth_verbose = yes
    auth_verbose_passwords = no
    auth_debug = no
    auth_debug_passwords = no
    mail_debug = no
    verbose_ssl = no
  • Make the following changes in /etc/dovecot/conf.d/10-mail.conf:

    mail_uid = 5000
    mail_gid = 5000
  • Make the following changes in /etc/dovecot/conf.d/10-master.conf:
service imap-login {
  inet_listener imap {
    port = 143
  }
  inet_listener imaps {
    port = 993
    ssl = yes
  }
}

service pop3-login { inet_listener pop3 { port = 110 } inet_listener pop3s { port = 995 ssl = yes } }
service auth { unix_listener auth-userdb { mode = 0777 user = dovecot group = dovecot } }
  • Add the vmail user in the system:

    addgroup --system --gid 5000 vmail
    adduser --system --home /srv/vmail --uid 5000 --gid 5000 --disabled-password --disabled-login vmail
  • Restart dovecot:

    systemctl restart dovecot

    Verify:

    netstat -lnptu | grep dovecot
    tcp        0      0 0.0.0.0:993             0.0.0.0:*               LISTEN      20894/dovecot   
    tcp        0      0 0.0.0.0:995             0.0.0.0:*               LISTEN      20894/dovecot   
    tcp        0      0 0.0.0.0:110             0.0.0.0:*               LISTEN      20894/dovecot   
    tcp        0      0 0.0.0.0:143             0.0.0.0:*               LISTEN      20894/dovecot   
    tcp6       0      0 :::993                  :::*                    LISTEN      20894/dovecot   
    tcp6       0      0 :::995                  :::*                    LISTEN      20894/dovecot   
    tcp6       0      0 :::110                  :::*                    LISTEN      20894/dovecot   
    tcp6       0      0 :::143                  :::*                    LISTEN      20894/dovecot  
    
  • Check if you can login:

    openssl s_client -connect localhost:993
    <output ommitted...>
    * OK [CAPABILITY IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE IDLE AUTH=PLAIN AUTH=LOGIN] Dovecot ready.
    a1 LOGIN theo MyNotSoSecretPass
    a1 OK [CAPABILITY IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE IDLE SORT SORT=DISPLAY THREAD=REFERENCES THREAD=REFS THREAD=ORDEREDSUBJECT MULTIAPPEND URL-PARTIAL CATENATE UNSELECT CHILDREN NAMESPACE UIDPLUS LIST-EXTENDED I18NLEVEL=1 CONDSTORE QRESYNC ESEARCH ESORT SEARCHRES WITHIN CONTEXT=SEARCH LIST-STATUS SPECIAL-USE BINARY MOVE] Logged in
    a3 LOGOUT
    * BYE Logging out
    a2 OK Logout completed.
    closed
  • Enable IMAP, IMAPS, POP3 and POP3S ports:

    ufw allow 110/tcp
    ufw allow 143/tcp
    ufw allow 993/tcp
    ufw allow 995/tcp
  • Tell postfix to deliver mail using dovecot:

    • Add the following lines at the end of /etc/postfix/master.cf:

      dovecot   unix  -       n       n       -       -       pipe
        flags=ODRhu user=vmail:vmail argv=/usr/lib/dovecot/deliver -e -f ${sender} -d ${recipient}
      
    • Add these attributes in /etc/postfix/main.cf:

      virtual_transport = dovecot
      dovecot_destination_recipient_limit = 1
  • Restart postfix and dovecot:

    systemctl restart postfix dovecot

Install SASL for SMTP AUTH

  • Create a service account for saslauthd using the ‘DSA’ plugin in *FusionDirectory’. It should look like this:

    dn: cn=saslauthd,ou=dsa,dc=example,dc=com
    cn: saslauthd
    userPassword:: ejdoedoifj9ewufd9843e9ejfd98je938jcr9843843=
    structuralObjectClass: organizationalRole
    entryUUID: 61143234-9a54-1035-8e4a-bf1fd814366b
    creatorsName: cn=admin,dc=example,dc=com
    createTimestamp: 20160419082803Z
    objectClass: organizationalRole
    objectClass: top
    objectClass: simpleSecurityObject
    entryCSN: 20160419082803.738357Z#000000#000#000000
    modifiersName: cn=admin,dc=example,dc=com
    modifyTimestamp: 20160419082803Z
  • Install SASL:

    apt -y install libsasl2-2 sasl2-bin
  • Create the /etc/postfix/sasl/smtpd.conf file:

    cat > /etc/postfix/sasl/smtpd.conf << EOF
    log_level: 3
    pwcheck_method: saslauthd
    mech_list: PLAIN LOGIN
    EOF
  • Make the following changes in /etc/default/saslauthd:

    START=yes
    MECHANISMS="ldap"
    OPTIONS="-c -m /var/spool/postfix/var/run/saslauthd"
  • Create the /etc/saslauthd.conf file:

    cat > /etc/saslauthd.conf << EOF
    ldap_servers: ldap://ldap.example.com/
    ldap_bind_dn: cn=saslauthd,ou=dsa,dc=example,dc=com
    ldap_bind_pw: MySecretPass
    ldap_timeout: 10
    ldap_time_limit: 10
    ldap_scope: sub
    ldap_search_base: ou=people,dc=example,dc=com
    ldap_auth_method: bind
    ldap_filter: (&(uid=%u)(mail=*))
    ldap_debug: 0
    ldap_verbose: off
    ldap_ssl: yes
    ldap_starttls: no
    ldap_referrals: yes
    EOF
  • Add the postfix user in the sasl group:

    usermod -aG sasl postfix
  • Add these attributes in /etc/postfix/main.cf:

    smtpd_sasl_auth_enable = yes
    broken_sasl_auth_clients = yes
  • Restart saslauthd and postfix:

    systemctl restart saslauthd postfix
  • Test message delivery using SMTP AUTH:

    First you need to install swaks:

    apt -y install swaks

    Then use swaks to test message delivery:

    swaks --from noreply@example.com --to theo@example.com --server 127.0.0.1:25 --tls --auth plain --auth-user=theo
  • Test if the message has been delivered to inbox:

    First you need to install mutt:

    apt -y install mutt

    Then use mutt to test if the message has been delivered to inbox:

    mutt -f /srv/vmail/theo@example.com/Maildir/

    NOTE: When you are asked to create a ‘mail’ folder just say ‘no’.

References

8 comments

  1. Hi Theo,

    After following this tutorial. I keep ending up with a temporary lookup failure on postfix when using swaks to send the test mail.

  2. hi, I’ve been follow your posts and successfuly install the fusiondirectory and mail server. now I am not able to use the password recovery utility from fusiondirectory. mail server is working properly. I setup mail box for admin but is not sendin mail on pasword recovery request. probably is missing some settings. please can you help with some guidance. thank you.

  3. Hi,

    thank you for pointing out FusionDirectory. Till this time i”ve ever ignored this software, I don’t no why >< My first question is:

    What do you meen with the sentence: “Create a service account for postfix using the ‘DSA’ plugin in *FusionDirectory’. It should look like this:”

    I can create a “Simple security object” named postfix but It looks like this:

    ldapsearch -xLLL -b cn=postfix,ou=dsa,dc=zzeroo,dc=org

    dn: cn=postfix,ou=dsa,dc=zzeroo,dc=org objectClass: organizationalRole objectClass: top objectClass: simpleSecurityObject cn: postfix

Leave a Reply

Your email address will not be published. Required fields are marked *