Categories
Linux

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 &lt; &lt; 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 &lt; &lt; 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 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 = 
    
    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

    • https://documentation.fusiondirectory.org/en/documentation/plugin/mail_plugin
    • https://documentation.fusiondirectory.org/en/documentation/plugin/alias_plugin
    • https://documentation.fusiondirectory.org/en/documentation/plugin/dovecot_plugin</output>
    Categories
    Linux

    Setting up an LDAP directory with a Fusiondirectory frontend

    LDAP/Fusiondirectory setup

    In this guide we will be setting up LDAP (openldap) along with the FusionDirectory web management tool.

    Preparations

    • Install Debian jessie (Ubuntu 16.04 should work too) on your server or VM
    • Setup the DNS records in your DNS servers:

      ldap.example.com.           3599    IN      A       1.1.1.1
      

      NOTE: replace 1.1.1.1 with you actual internal or external IP

    • Allow ssh and web services on firewall:

      apt -y install ufw
      ufw allow 22/tcp
      ufw allow 80/tcp
      ufw allow 443/tcp
      ufw enable
      

      NOTE: It may be a good idea to change the default ssh port from 22 to something less predictable

    Setup LDAP

    • Setup ldap.example.com in /etc/hosts:
    127.0.2.1 ldap.example.com ldap
    
    • Install OpenLDAP and FusionDirectory

      apt -y install slapd
      

      Enter and verify the administrator password for slapd.

    • Create An Internal Certificate Authority for Example LTD:

      • First install gnutls-bin:
        apt -y install gnutls-bin
        
      • Create the key for the internal CA for example.com:
        certtool --generate-privkey --outfile example.com-rootCA.key
        
      • Create a certificate for our internal CA:
    certtool --generate-self-signed --load-privkey example.com-rootCA.key --outfile example.com-rootCA.crt
    Generating a self signed certificate...
    Please enter the details of the certificate's distinguished name. Just press enter to ignore a field.
    Common name: Example LTD Internal ROOT CA
    UID: 
    Organizational unit name: IT
    Organization name: Example LTD
    Locality name: Limassol
    State or province name: Limassol
    Country name (2 chars): CY
    Enter the subject's domain component (DC): 
    This field should not be used in new certificates.
    E-mail: admins@example.com
    Enter the certificate's serial number in decimal (default: 6295758616856773074): 
    The certificate will expire in (days): 7300
    
    Activation/Expiration time.
    The certificate will expire in (days): 7300
    
    Extensions.
    Does the certificate belong to an authority? (y/N): y
    Path length constraint (decimal, -1 for no constraint): -1
    Is this a TLS web client certificate? (y/N):
    Will the certificate be used for IPsec IKE operations? (y/N): 
    Is this a TLS web server certificate? (y/N): 
    Enter a dnsName of the subject of the certificate: 
    Enter a URI of the subject of the certificate: 
    Enter the IP address of the subject of the certificate: 
    Enter the e-mail of the subject of the certificate: 
    Will the certificate be used to sign other certificates? (y/N): y
    Will the certificate be used to sign CRLs? (y/N): 
    Will the certificate be used to sign code? (y/N): 
    Will the certificate be used to sign OCSP requests? (y/N): 
    Will the certificate be used for time stamping? (y/N):
    Enter the URI of the CRL distribution point: 
    X.509 Certificate Information:
            Version: 3
            Serial Number (hex): 575f071b0d5a41d2
            Validity:
                    Not Before: Mon Jun 13 19:19:27 UTC 2016
                    Not After: Sun Jun 08 19:20:00 UTC 2036
            Subject: CN=Example LTD Internal ROOT CA,OU=IT,O=Example LTD,L=Limassol,ST=Limassol,C=CY,EMAIL=admins@example.com
            Subject Public Key Algorithm: RSA
            Algorithm Security Level: Medium (2048 bits)
                    Modulus (bits 2048):
                            00:c0:75:c8:02:05:d0:0c:67:af:ac:0c:80:53:bf:cd
                            a3:80:76:cf:3e:14:19:99:5c:24:b4:fc:b0:42:8d:5a
                            03:5d:04:a5:85:c7:fe:e3:d4:30:6c:4c:26:90:76:c5
                            3e:a0:dc:a7:53:a7:eb:13:60:78:44:b3:0a:b2:77:0c
                            46:19:96:ea:d2:46:82:9c:11:2c:a5:e2:a1:57:38:f4
                            8e:4d:74:4f:f9:41:dd:11:f4:c2:f5:9f:b7:9a:93:7d
                            a7:f8:f3:dd:2e:08:6a:25:75:79:f3:63:e5:09:1f:bd
                            6a:38:45:85:f0:63:54:c0:08:68:41:15:66:a4:e3:84
                            49:7e:e5:c5:c7:6c:d3:c7:be:d5:5a:df:1a:1d:55:f8
                            35:73:bb:e3:ea:f7:66:af:d9:09:72:ca:17:5f:80:09
                            99:6a:49:e3:8b:f2:72:56:ac:f8:ba:60:49:d5:80:2a
                            07:e6:17:88:86:e4:3c:89:cd:af:2b:66:a1:af:53:f4
                            66:21:30:a3:22:af:a9:11:6e:98:e0:f7:6d:ef:8a:32
                            e9:0b:a4:82:7b:7b:db:2d:90:8e:bd:e4:54:04:a4:52
                            e8:cf:f6:2e:9b:97:46:ab:cb:38:06:23:33:db:42:0c
                            25:41:5a:d7:02:15:07:c6:e8:86:0b:a6:d7:7d:81:16
                            bd
                    Exponent (bits 24):
                            01:00:01
            Extensions:
                    Basic Constraints (critical):
                            Certificate Authority (CA): TRUE
                    Key Purpose (not critical):
                            Time stamping.
                    Key Usage (critical):
                            Certificate signing.
                    Subject Key Identifier (not critical):
                            7a596f6dea4080e89c9e78a698d7126cd63dafa7
    Other Information:
            Public Key ID:
                    7a596f6dea4080e89c9e78a698d7126cd63dafa7
            Public key's random art:
                    +--[ RSA 2048]----+
                    |                 |
                    |     . .         |
                    |    . . .        |
                    |   o .   .       |
                    | . .+.  S o      |
                    |  =o..o. + . .   |
                    | o.o= .oo . o o  |
                    | oo+.  .o  o o   |
                    |o...  E+   .o    |
                    +-----------------+
    
    Is the above information ok? (y/N): y
    
    
    Signing certificate...
    
    • Add the Example LTD Internal ROOT CA as trusted in ca-certificates:

      mkdir /usr/share/ca-certificates/extra
      cp example.com-rootCA.crt /usr/share/ca-certificates/extra
      dpkg-reconfigure ca-certificates
      

      Add the extra/example.com-rootCA.crt CA as a trusted CA.

      • Configure slapd:
      dpkg-reconfigure slapd
      
      • Omit OpenLDAP server configuration? No
      • DNS domain name: example.com
      • Organization name: Example LTD
      • Administrator password: ***************
      • Verify password: *************
      • Database backend to use: MDB
      • Do you want the database to be removed when slapd is purged? No
      • Move old database? Yes
      • Allow LDAPv2 protocol? No
    • Configure TLS on LDAP:

    • Create a key for ldap.example.com:

      certtool --generate-privkey --outfile ldap.example.com.key
      Generating a 2048 bit RSA private key...
      

    • Create a certificate for ldap.example.com:
    certtool --generate-certificate --load-privkey ldap.example.com.key --outfile ldap.example.com.crt --load-ca-certificate example.com-rootCA.crt --load-ca-privkey example.com-rootCA.key
    Generating a signed certificate...
    Please enter the details of the certificate's distinguished name. Just press enter to ignore a field.
    Common name: ldap.example.com
    UID: 
    Organizational unit name: IT
    Organization name: Example LTD
    Locality name: Limassol
    State or province name: Limassol
    Country name (2 chars): CY
    Enter the subject's domain component (DC): 
    This field should not be used in new certificates.
    E-mail: admins@example.com
    Enter the certificate's serial number in decimal (default: 6295762607454361711):
    
    Activation/Expiration time.
    The certificate will expire in (days): 3650
    
    Extensions.
    Does the certificate belong to an authority? (y/N): 
    Is this a TLS web client certificate? (y/N): 
    Will the certificate be used for IPsec IKE operations? (y/N): 
    Is this a TLS web server certificate? (y/N): 
    Enter a dnsName of the subject of the certificate: 
    Enter a URI of the subject of the certificate: 
    Enter the IP address of the subject of the certificate: 
    Enter the e-mail of the subject of the certificate: 
    Will the certificate be used for signing (required for TLS)? (Y/n): 
    Will the certificate be used for encryption (not required for TLS)? (Y/n):
    X.509 Certificate Information:
            Version: 3
            Serial Number (hex): 575f0abc2f81186f
            Validity:
                    Not Before: Mon Jun 13 19:35:45 UTC 2016
                    Not After: Thu Jun 11 19:36:29 UTC 2026
            Subject: CN=ldap.example.com,OU=IT,O=Example LTD,L=Limassol,ST=Limassol,C=CY,EMAIL=admins@example.com
            Subject Public Key Algorithm: RSA
            Algorithm Security Level: Medium (2048 bits)
                    Modulus (bits 2048):
                            00:d0:15:8e:02:90:5f:4a:9f:90:ea:1e:35:e6:4b:eb
                            a9:8c:e5:bf:68:ec:83:0e:49:5b:d1:f0:08:4b:ac:b0
                            31:d2:e0:a7:eb:18:d3:ee:b8:38:b7:c4:0a:cc:97:cc
                            b6:ac:2d:29:c8:a8:c4:7c:cc:f1:36:5a:e9:6b:52:f5
                            1e:e5:4f:90:67:34:1f:8c:a8:17:72:ee:40:87:ba:ae
                            8b:f8:4f:f8:be:51:ee:ea:d5:e4:17:63:79:22:41:c0
                            19:43:33:55:bb:46:80:5c:b8:16:18:fa:fb:17:58:c2
                            ed:d2:14:10:3b:57:5d:de:7f:29:ab:66:c2:81:87:05
                            f7:b7:27:78:a9:c0:8e:4f:1c:3f:66:6f:dd:43:26:9f
                            84:59:fb:c7:21:3c:62:4f:8d:4a:25:ab:7e:f0:5f:7e
                            df:97:f7:79:f8:c7:2d:c8:5a:7a:de:ea:5b:c7:bd:e9
                            12:17:56:d3:47:ff:eb:fa:b5:6f:d9:56:8f:c7:e8:7a
                            46:92:75:cc:ff:de:0e:88:49:7d:d7:dd:6e:8d:3f:57
                            fa:0a:7a:3b:80:ec:0e:10:dd:70:d5:9a:8d:91:ce:72
                            44:06:21:d2:9d:e9:b8:91:13:68:4c:fc:e2:bb:4d:a8
                            97:ed:e9:a4:98:5d:e7:c0:ef:3e:9d:30:28:de:bd:10
                            01
                    Exponent (bits 24):
                            01:00:01
            Extensions:
                    Basic Constraints (critical):
                            Certificate Authority (CA): FALSE
                    Key Usage (critical):
                            Digital signature.
                            Key encipherment.
                    Subject Key Identifier (not critical):
                            6d8a173de01efa11a892dda76ccd7abc609a2707
                    Authority Key Identifier (not critical):
                            7a596f6dea408aa89c9e78a698d7126cd63dafa7
    Other Information:
            Public Key ID:
                    6d8a173de01efa00a892dda67ccd7abc609a2707
            Public key's random art:
                    +--[ RSA 2048]----+
                    |                 |
                    |                 |
                    |        .        |
                    |       . +       |
                    |        A =      |
                    |       +Y= .     |
                    |      oo+kk+     |
                    |      iii==o*    |
                    |       .=B**o.   |
                    +-----------------+
    
    
    Is the above information ok? (y/N): y
    
    Signing certificate...
    
    • Enable LDAPS in /etc/default/slapd:

      SLAPD_SERVICES="ldap:/// ldapi:/// ldaps:///"
      
      • Copy the ldap.example.com certficate and apply permissions
        mkdir /etc/ldap/ssl
        cp ldap.example.com.crt /etc/ldap/ssl
        cp ldap.example.com.key /etc/ldap/ssl
        chown -R openldap:openldap /etc/ldap/ssl    /
        
      • Create an olcSSL.ldif file:
    mkdir /etc/ldap/custom_ldifs/
    cd /etc/ldap/custom_ldifs/<br />
    cat > olcSSL.ldif < < EOF
    dn: cn=config
    changetype: modify
    add: olcTLSCACertificateFile
    olcTLSCACertificateFile: /etc/ssl/certs/ca-certificates.crt
    -
    add: olcTLSCertificateKeyFile
    olcTLSCertificateKeyFile: /etc/ldap/ssl/ldap.example.com.key
    -
    add: olcTLSCertificateFile
    olcTLSCertificateFile: /etc/ldap/ssl/ldap.example.com.crt
    EOF
    
    • Import the TLS configuration:
    ldapmodify -Y EXTERNAL -H ldapi:/// -f olcSSL.ldif
    

    Verify with:

    slapcat -n0 | grep -i tls
    olcTLSCACertificateFile: /etc/ssl/certs/ca-certificates.crt
    olcTLSCertificateFile: /etc/ldap/ssl/ldap.example.com.crt
    olcTLSCertificateKeyFile: /etc/ldap/ssl/ldap.example.com.key
    
    • Restart and verify slapd:
      systemctl restart slapd
      netstat -lnptu | grep slapd
      tcp        0      0 0.0.0.0:636             0.0.0.0:*               LISTEN      27665/slapd     
      tcp        0      0 0.0.0.0:389             0.0.0.0:*               LISTEN      27665/slapd     
      tcp6       0      0 :::636                  :::*                    LISTEN      27665/slapd     
      tcp6       0      0 :::389                  :::*                    LISTEN      27665/slapd 
      

    Setup Apache

    • Install Apache with PHP:
      apt -y install apache2 libapache2-mod-php5 php5-ldap php5-mcrypt php5-intl php-pear
      

    Setup Let’s Encrypt:

    NOTE: this step is only necessary if you have a public facing ldap.example.com service

    • Setup Debian jessie backports:
    cat >> /etc/apt/sources.list < < EOF
    # jessie backports
    deb http://ftp.debian.org/debian jessie-backports main
    deb-src http://ftp.debian.org/debian jessie-backports main
    EOF
    
    • Run apt update
    • Install Let’s Encrypt utility, certbot:
      apt -y install python-certbot-apache -t jessie-backports
      
    • Generate a certificate for all the domain ldap.example.com:
      certbot run -d ldap.example.com
      

      In the TUI add the admins@example.com email and agree to the ToS. Use 000-default.conf for now.

  • Download and trust all Let’s Encrypt Root and Intermediate CA certificates:

    wget https://letsencrypt.org/certs/isrgrootx1.pem
    for i in {1..4}; do wget https://letsencrypt.org/certs/lets-encrypt-x$i-cross-signed.pem; done
    cp *.pem /usr/share/ca-certificates/extra/
    for f in *.pem; do cp -- "$f" "/usr/share/ca-certificates/extra/${f%.pem}.crt"; done
    dpkg-reconfigure ca-certificates # Select all the newlly added CA certs
    

  • Setup FusionDirectory

    • Setup Fusiondirectory Repo:
      gpg --keyserver keys.gnupg.net --recv-key 62B4981F 
      gpg --export -a "Fusiondirectory Archive Manager <contact @fusiondirectory.org>" > FD-archive-key
      apt-key add FD-archive-key
      echo '# fusiondirectory repository' > /etc/apt/sources.list.d/fusiondirectory.list
      echo 'deb http://repos.fusiondirectory.org/debian-jessie jessie main' >> /etc/apt/sources.list.d/fusiondirectory.list
      echo 'deb-src http://repos.fusiondirectory.org/debian-jessie jessie main' >> /etc/apt/sources.list.d/fusiondirectory.list
      apt update
      
    • Install FusionDirectory:
      apt -y install fusiondirectory fusiondirectory-schema
      
    • Insert core FusionDirectory schemas into *slapd
      fusiondirectory-insert-schema
      

      Verify:

      fusiondirectory-insert-schema -l
      core
      cosine
      nis
      inetorgperson
      samba
      core-fd
      core-fd-conf
      ldapns
      recovery-fd
      
    • Create a Fusiondirectory Apache vhost (/etc/apache2/sites-available/ldap.example.com.conf):
      <virtualhost *:80>
          ServerName ldap.example.com
          Redirect "/" "https://ldap.example.com/"
          ErrorLog ${APACHE_LOG_DIR}/ldap-error.log
          CustomLog ${APACHE_LOG_DIR}/ldap-access.log combined
      </virtualhost>
      <ifmodule mod_ssl.c>
          <virtualhost *:443>
                  ServerName ldap.example.com
                  ServerAdmin webmaster@example.com
                  DocumentRoot /usr/share/fusiondirectory/html
                  ErrorLog ${APACHE_LOG_DIR}/ldap-error.log
                  CustomLog ${APACHE_LOG_DIR}/ldap-access.log combined
                  SSLEngine on
                  SSLCertificateFile      /etc/letsencrypt/live/ldap.example.com/cert.pem
                  SSLCertificateKeyFile   /etc/letsencrypt/live/ldap.example.com/privkey.pem
                  <filesmatch "\.(cgi|shtml|phtml|php)$">
                                  SSLOptions +StdEnvVars
                  </filesmatch>
                  <directory /usr/lib/cgi-bin>
                                  SSLOptions +StdEnvVars
                  </directory>
                  BrowserMatch "MSIE [2-6]" \
                                  nokeepalive ssl-unclean-shutdown \
                                  downgrade-1.0 force-response-1.0
                  BrowserMatch "MSIE [17-9]" ssl-unclean-shutdown
                  <ifmodule mod_php5.c>
                  <location></location>
                      php_admin_flag engine on
                      php_admin_flag register_globals off
                      php_admin_flag allow_call_time_pass_reference off
                      php_admin_flag expose_php off
                      php_admin_flag zend.ze1_compatibility_mode off
                      php_admin_flag register_long_arrays off
                      php_admin_value upload_tmp_dir /var/spool/fusiondirectory/
                      php_admin_value session.cookie_lifetime 0
                      #Include /etc/fusiondirectory/fusiondirectory.secrets
      
                  </ifmodule>
                  <directory /usr/share/fusiondirectory/html></directory>
                      Order Allow,Deny
                      # Insert your public IPs here
                      Allow from 2.2.2.2
                      Allow from 2.2.2.3
      
          </virtualhost>
      </ifmodule>
      
    • Enable mod_ssl, ldap.example.com and disable 000-default and default-ssl:
      a2enmod ssl
      a2ensite ldap.example.com
      a2dissite default-ssl
      a2dissite 000-default
      systemctl restart apache2
      
    • Setup FusionDirectory:
      • Install optional prerequisities:
        apt -y install php-mdb2
        
      • Point your Browser to:
        https://ldap.example.com/
        
      • Create a temporary token for the setup (taken from the first setup webpage):
        echo -n r9l1srnu0rvdeca4k826nq4e05 > /var/cache/fusiondirectory/fusiondirectory.auth 
        

        Click ‘Next’

      • In the ‘Language setup’ select ‘English’ and press ‘Next’.

      • If everything is ‘OK'(Green) on the ‘Installation check’ click ‘Next’

      • On the ‘LDAP connection setup’:

        • Location name: default
        • Connection URI: ldap://ldap.example.com:389
        • TLS connection: Yes
        • Admin DN: cn=admin(,dc=example,dc=com)
        • Admin password: *************************
        • LDAP schema check:
          • Enable schema validation when logging in: Yes
      • Keep defaults in ‘Look and feel’ except ‘Timezone’:
        • Timezone: America/Los_Angeles
      • Keep all the defaults in ‘Password settings’ except this:
        • Password minimum length: 8
      • In the ‘SSL’ field use these:
        • Key path: /etc/ldap/ssl/ldap.example.com.key
        • Certificate path: /etc/ldap/ssl/ldap.example.com.crt
        • CA certificate path: /etc/ssl/certs/ca-certificates.crt

        Click ‘Next’ when done.

      • In the ‘LDAP inspection’ page:

        • Press ‘Migrate’ (twice) in the ‘Inspecting object classes in root object’ option
      • Press ‘Create’ in the ‘Checking for super administrator’ option’, fill the fields, and ‘Apply’ when done:

        • User ID: ldapadmin
        • Password: ***************
        • Password (again): ***************
      • In the ‘Checking for default ACL roles and groups’ field, press ‘Migrate’
    • From the ‘Finish – write the configuration file’, download the configuration file on your PC

    • Copy the configuration file from your PC to ldap.example.com:

      scp fusiondirectory.conf root@ldap.example.com:/etc/fusiondirectory
      

    • Apply the correct permissions to the /etc/fusiondirectory/fusiondirectory.conf file:
    fusiondirectory-setup --check-config
    Checking FusionDirectory's config file
    /etc/fusiondirectory/fusiondirectory.conf exists…
    /etc/fusiondirectory/fusiondirectory.conf is not set properly, do you want to fix it ?:  [Yes/No]?
    y
    
    • Click ‘Next’ when done.
  • Use encrypted passwords in fusiondirectory.conf:

    • Enable the headers module in Apache:
      a2enmod headers
      systemctl restart apache2
      
    • Encrypt passwords in fusiondirectory.conf:
      fusiondirectory-setup --encrypt-passwords
      
    • Uncomment the following line in /etc/apache2/sites-available/ldap.example.com.conf:
      Include /etc/fusiondirectory/fusiondirectory.secrets
      
    • Restart Apache:
      systemctl restart apache2
      
    • If everything works as expected remove /etc/fusiondirectory/fusiondirectory.conf.orig
      rm /etc/fusiondirectory/fusiondirectory.conf.orig
      
  • Allow ‘.’ (dot) in usernames:
    • After everything is set, login as ldapadmin
    • Go to ‘Configuration’
    • Press the ‘Edit’ button at the bottom of the page
    • Un-tick the ‘Strict naming policy’ option and save.
  • Installing essential FusionDirectory plugins

    • Setup LDAP related plugins:
      apt -y install fusiondirectory-plugin-ldapdump fusiondirectory-plugin-ldapmanager
      
    • Setup the DSA plugin for managing service accounts:
      apt -y install fusiondirectory-plugin-dsa fusiondirectory-plugin-dsa-schema
      fusiondirectory-insert-schema -i /etc/ldap/schema/fusiondirectory/dsa-fd-conf.schema
      
      • Allow the service accounts to read and write the password. First create the ACL definition:
    cat > /etc/ldap/custom_ldifs/service_accounts_acl.ldif < < EOF
    dn: olcDatabase={1}mdb,cn=config
    changetype: modify
    delete: olcAccess
    -
    add: olcAccess
    olcAccess: {0}to dn.subtree="dc=example,dc=com" attrs=userPassword
      by self write
      by dn.base="cn=admin,dc=example,dc=com" write
      by dn.children="ou=dsa,dc=example,dc=com" write
      by anonymous auth
      by * none
    -
    add: olcAccess
    olcAccess: {1}to dn.subtree="ou=people,dc=example,dc=com"
      by self read
      by dn.base="uid=test.user,ou=people,dc=example,dc=com" write
      by dn.base="cn=admin,dc=example,dc=com" write
      by dn.children="ou=dsa,dc=example,dc=com" read
      by anonymous auth
      by * none
    -
    add: olcAccess
    olcAccess: {2}to attrs=userPassword,shadowLastChange
      by self write
      by anonymous auth
      by dn="cn=admin,dc=example,dc=com" write
      by * none
    -
    add: olcAccess
    olcAccess: {3}to dn.subtree="dc=example,dc=com"
      by self read
      by dn.base="cn=admin,dc=example,dc=com" write
      by dn.children="ou=dsa,dc=example,dc=com" write
      by * none
    -
    add: olcAccess
    olcAccess: {4}to dn.base=""
      by * none
    EOF
    

    NOTE: Add two spaces before each ‘by‘ in the ldif above or you will spend endless hours in troubleshooting!

    • Apply the ACL
      ldapadd -c -Y EXTERNAL -H ldapi:/// -f /etc/ldap/custom_ldifs/service_accounts_acl.ldif
      
      • Setup the Systems plugin:
      apt -y install fusiondirectory-plugin-systems fusiondirectory-plugin-systems-schema
      fusiondirectory-insert-schema -i /etc/ldap/schema/fusiondirectory/service-fd.schema
      fusiondirectory-insert-schema -i /etc/ldap/schema/fusiondirectory/systems-fd-conf.schema
      fusiondirectory-insert-schema -i /etc/ldap/schema/fusiondirectory/systems-fd.schema
      
      • Setup a new server:
        • Name: ldap.example.com
        • Description: Communications Server
        • Location: My Datacenter
        • Base: /
        • IP-address: 10.134.31.94

        • MAC-address: 04:01:05:d6:63:02
      • From the ‘Services’ tab setup an LDAP service on the ldap.example.com server

    You are finished. You can now start connecting services to your LDAP setup like mail or asterisk.

    References

    • https://documentation.fusiondirectory.org/en/start</contact>