Integration/Active.Directory.iRedMail
From iRedMail
Contents
|
TO BE CONTINUED.
WARNING: NOT FINISHED YET, DO NOT APPLY BELOW STEPS.
Summary
NOTE: We just tested this tutorial on Windows 2000 and 2003 server, if you tested it on other versions and works well, please let us know. Contact us.
With AD + iRedMail integration, you can get below features:
- User authentication against Windows Active Directory. You can now manage mail domains, users, mail lists with AD.
- Mail list support with group in AD.
- Global LDAP Address Book with AD in Roundcube Webmail.
- Account status support. Disable user in Active Directory will cause this account be disabled in iRedMail.
Since AD uses different LDAP schema, you will lose some iRedMail special features. e.g.
- Per-user, per-domain bcc control with LDAP. You should use hash file instead.
- TO BE CONTINUED.
Requirements
To integrate Microsoft Active Directory with iRedMail, you should have:
- A working Microsoft Windows (2000/2003) server, with Active Directory installed and working, listen on port 389 (ldap://) or 636 (ldaps://).
- A working Linux/BSD with iRedMail+OpenLDAP installed.
- iRedMail server can access Windows AD server via port 389 or 636.
Install iRedMail
Please install iRedMail on Linux/BSD with OpenLDAP backend first, we will modify some configure files to achieve AD integration.
Here is iRedMail installaion guides.
Integrate Microsoft Active Directory
We assume:
- Hostname of your AD server is 'ad.example.com', listen on port 389.
- We will use this hostname below, you can replace it by IP address.
- If you want to force LDAP connection with LDAPS, use port 636 instead.
- Base dn in AD is "dc=example,dc=com", email addresses of all users are ends with '@example.com' (Your mail domain is 'example.com').
- All user accounts are placed under dn "cn=Users,dc=example,dc=com". Note: dn is case-insensitive.
- For ldap connection, protocol version '3' is recommended. All pupular LDAP servers support LDAP protocol version 3.
- Store all mails on Linux/BSD servers, not on AD server.
Create user account in AD, used for LDAP query
With iRedMail + OpenLDAP, we have a low-privileged account "cn=vmail,dc=xxx,dc=xxx" for query only. So we suggest you create a same account in AD.
- TODO: Steps to create account vmail + Screenshots.
- TODO: How to get dn of vmail. or just use 'vmail' instead of full dn.
Test AD query with ldap command line tool
Enable LDAP query with AD in Postfix
Modify postfix main.cf:
| File: main.cf |
# # Add your mail domain in "smtpd_sasl_local_domain" and "virtual_mailbox_domains". # smtpd_sasl_local_domain = example.com virtual_mailbox_domains = example.com # # Unused iRedMail special settings. # Set them to empty value OR comment these lines. # virtual_mailbox_domains = virtual_alias_maps = sender_bcc_maps = recipient_bcc_maps = relay_domains = relay_recipient_maps = # # Change some settings. # # Transport maps. transport_maps = hash:/etc/postfix/transport # Used to query mail users. virtual_mailbox_maps = ldap:/etc/postfix/ad_virtual_mailbox_maps.cf # Used to query mail lists/groups. virtual_alias_maps = ldap:/etc/postfix/ad_virtual_group_maps.cf # Used to verify sender. smtpd_sender_login_maps = /etc/postfix/ad_sender_login_maps.cf |
- Create/Edit file: /etc/postfix/transport:
| File: /etc/postfix/transport |
example.com dovecot |
Run 'postmap' so that postfix can read it:
| Terminal: |
# postmap hash:/etc/postfix/transport |
- Create/Edit file: ad_virtual_mailbox_maps.cf
| File: ad_virtual_mailbox_maps.cf |
server_host = ad.example.com server_port = 389 version = 3 bind = yes start_tls = no bind_dn = vmail bind_pw = passwd_of_vmail search_base = cn=users,dc=example,dc=com scope = sub query_filter = (&(objectclass=person)(userPrincipalName=%s)) result_attribute= userPrincipalName result_format = %d/%u/Maildir/ debuglevel = 0 |
- Create/Edit file: /etc/postfix/ad_sender_login_maps.cf:
| File: ad_sender_login_maps.cf |
server_host = ad.example.com server_port = 389 version = 3 bind = yes start_tls = no bind_dn = vmail bind_pw = password_of_vmail search_base = cn=users,dc=example,dc=com scope = sub query_filter = (&(userPrincipalName=%s)(objectClass=person)(!(userAccountControl=514))) result_attribute= userPrincipalName debuglevel = 0 |
- Create/Edit file: /etc/postfix/ad_virtual_group_maps.cf
| File: ad_virtual_group_maps.cf |
server_host = ad.example.com server_port = 389 version = 3 bind = yes start_tls = no bind_dn = vmail bind_pw = password_of_vmail search_base = cn=users,dc=example,dc=com scope = sub query_filter = (&(objectClass=group)(mail=%s)) special_result_attribute = member leaf_result_attribute = mail result_attribute= userPrincipalName debuglevel = 0 |
Verify LDAP query with AD in Postfix
We can use command line tool postmap to verify AD query in postfix.
- Query mail user:
| Terminal: |
# postmap -q user@example.com ldap:/etc/postfix/ad_virtual_mailbox_maps.cf example.com/vmail/Maildir/ |
- Verify sender login check:
| Terminal: |
# postmap -q user@example.com ldap:/etc/postfix/ad_sender_login_maps.cf user@example.com |
- Verify mail list/group:
| Terminal: |
# postmap -q list@example.com ldap:/etc/postfix/ad_virtual_group_maps.cf member01@example.com member02@example.com |
Enable LDAP query with AD in Dovecot
We need to modify /etc/dovecot-ldap.conf on RHEL/CentOS or /etc/dovecot/dovecot-ldap.conf on Debian/Ubuntu, let dovecot queries AD instead of local OpenLDAP server.
| File: dovecot-ldap.conf |
hosts = ad.example.com:389 ldap_version = 3 auth_bind = yes dn = vmail dnpass = passwd_of_vmail base = cn=users,dc=example,dc=com scope = subtree deref = never user_filter = (&(userPrincipalName=%u)(objectClass=person)(!(userAccountControl=514))) pass_filter = (&(userPrincipalName=%u)(objectClass=person)(!(userAccountControl=514))) pass_attrs = userPassword=password default_pass_scheme = CRYPT user_attrs = =home=/var/vmail/vmail01/%Ld/%Ln/Maildir/,=mail=maildir:/var/vmail/vmail01/%Ld/%Ln/Maildir/ |
Note: we don't have per-user quota limit here, you can set a hard-coded quota for all users in /etc/dovecot.conf (RHEL/CentOS) or /etc/dovecot/dovecot.conf (Debian/Ubuntu). Example:
| File: dovecot.conf |
plugin {
# --- SKIP OTHER SETTINGS HERE ---
# Format: integer + M/G/T.
# M -> MB, G -> GB, T -> TB.
quota_rule = *:storage=1G
}
|
- TODO: How to achieve per-user quota in AD.
Verify LDAP query with AD in Dovecot
We can use command telnet to verify AD query in Dovecot.
| Terminal: |
# telnet localhost 143 * OK [...] Dovecot ready. # ---- Type testing command below ---- . login user@example.com password_of_user . OK [...] Logged in |
Note: You just type . login user@example.com password (Do NOT miss the dot) in above testing, if it returns Logged in, then dovecot + AD works as expected.
Enable Global LDAP Address Book wih AD in Roundcube webmail
Edit roundcube config file: /var/www/roundcubemail/config/main.inc.php (RHEL/CentOS) or /usr/share/apache2/roundcubemail/config/main.inc.php (Debian/Ubuntu).
You can remove exist LDAP address book which stored in OpenLDAP, and add a new one with AD.
| File: main.inc.php |
#
# "sql" is personal address book stored in roundcube database.
# "example.com" is new LDAP address book with AD, we will create it below.
#
$rcmail_config['autocomplete_addressbooks'] = array("sql", "example.com");
#
# Global LDAP Address Book with AD.
#
$rcmail_config['ldap_public']["a.cn"] = array(
'name' => 'Global Address Book',
'hosts' => array("ad.example.com"), // <- Set AD hostname or IP address here.
'port' => 389,
'use_tls' => false, // <- Set to true if you want to use LDAPS. Change port to 636 on above line too.
// ---- Used to search accounts only in the same domain. ----
'user_specific' => false,
'base_dn' => "cn=users,dc=example,dc=com", // <- Set base dn in AD
'bind_dn' => "vmail", # <- bind dn
'bind_pass' => "password_of_vmail", // <- bind password
'writable' => false, # <- Do not allow mail user write data back to AD.
'ldap_version' => "3",
// ---- Search ----
//'search_fields' => array('displayname', 'userprincipalname', 'sn', 'givenname',), // <- fields to search in
'search_fields' => array('mail', 'cn', 'sAMAccountName', 'displayname', 'sn', 'givenName'),
//'name_field' => 'displayname',
'name_field' => 'cn',
//'email_field' => 'userprincipalname',
'email_field' => 'mail',
'surname_field' => 'sn',
//'firstname_field' => 'givenname',
'firstname_field' => 'givenName',
//'sort' => 'displayname',
'sort' => 'cn',
'scope' => 'sub',
//'filter' => "(&(objectclass=person)(!(userAccountControl=514)))",
'filter' => "(mail=*@*)",
'fuzzy_search' => true
);
|
