Integration/Active.Directory.iRedMail
From iRedMail
Contents
|
Summary
NOTE: We just tested this tutorial on Windows 2000, 2003, 2008 R2 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 disabled in iRedMail.
Since AD uses different LDAP schema, you will lose some iRedMail special features. e.g.
- Per-user, per-domain service control with LDAP (e.g. enable/disable POP3/IMAP/SMTP services). You should use hash file instead.
- [TO BE CONTINUED]
Requirements
To integrate Microsoft Active Directory with iRedMail, you should have:
- A working Linux/BSD server with iRedMail+OpenLDAP installed.
- A working Microsoft Windows (2000/2003) server, with Active Directory installed and working properly, listen on port 389 (ldap://) or 636 (ldaps://), and allow LDAP connections from iRedMail server.
Install iRedMail
Please install iRedMail on Linux/BSD with OpenLDAP backend first, we will achieve this AD integration by simply modify some configure files.
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 of this AD server if you want.
- 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 and mail list 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.
- Storage directory is /var/vmail/vmail1, same as default in iRedMail.
- Mailbox of user "support@example.com" will be /var/vmail/vmail1/example.com/support/Maildir/, maildir format.
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 vmail in AD, with complex password.
NOTE:
Test AD query with ldap command line tool on iRedMail server
We should make sure this newly created user is able to connect to AD server, so please verify it with below command on iRedMail server:
| Terminal: |
# ldapsearch -x -h ad.example.com -D 'vmail' -W -b 'cn=users,dc=example,dc=com' Enter password: password_of_vmail |
If it prints all users stored in AD server, then it's working as expected.
Enable LDAP query with AD in Postfix
We will execute some commands to modify Postfix settings to:
- Disable unused iRedMail special settings.
- Authenticate against AD server instead of local OpenLDAP server.
Note: we will create three AD query files later:
- /etc/postfix/ad_virtual_mailbox_maps.cf
- /etc/postfix/ad_virtual_group_maps.cf
- /etc/postfix/ad_sender_login_maps.cf
- Disable unused iRedMail special settings:
| Terminal: |
# postconf -e virtual_alias_maps='' # postconf -e sender_bcc_maps='' # postconf -e recipient_bcc_maps='' # postconf -e relay_domains='' # postconf -e relay_recipient_maps='' |
- Add your mail domain in "smtpd_sasl_local_domain" and "virtual_mailbox_domains":
| Terminal: |
# postconf -e smtpd_sasl_local_domain='example.com' # postconf -e virtual_mailbox_domains='example.com' |
- Change transport maps setting:
| Terminal: |
# postconf -e transport_maps='hash:/etc/postfix/transport' |
- Enable AD query. Note: We will create these 3 files later.
- Verify SMTP senders
| Terminal: |
# postconf -e smtpd_sender_login_maps='proxy:ldap:/etc/postfix/ad_sender_login_maps.cf' |
- Used to verify local mail users
| Terminal: |
# postconf -e virtual_mailbox_maps='proxy:ldap:/etc/postfix/ad_virtual_mailbox_maps.cf' |
- Used to verify local mail lists/groups.
| Terminal: |
# postconf -e virtual_alias_maps='proxy:ldap:/etc/postfix/ad_virtual_group_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: /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:1.2.840.113556.1.4.803:=2))) result_attribute= userPrincipalName debuglevel = 0 |
- 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 |
Note: Here, we define users' mailboxes to be "example.com/username/Maildir/" in "result_format" setting.
Maildir of the first example user created during iRedMail installation, www@example.com, is 'example.com/w/w/w/www-[TIMESTAMP]/Maildir/', and this maildir path is stored in OpenLDAP (attribute "mailMessageStore"). But we don't store maildir path in Active Directory, so we hard-code maildir path here.
- 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 |
Note:
- If your user have email address in both "mail" and "userPrincipalName", you will get duplicate result. Comment 'leaf_result_attribute' can fix it.
- If your group account doesn't contains attribute 'mail' and 'userPrincipalName', please try 'query_filter = (&(objectClass=group)(sAMAccountName=%u))' instead.
Also, we need to remove iRedAPD related settings in Postfix:
- Open /etc/postfix/main.cf
- Remove this setting: check_policy_service inet:127.0.0.1:7777.
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/user/Maildir/ |
- DEBUG*: If you got blank link instead of output like above example, it means LDAP query doesn't get expected result.
Try to set "debuglevel = 1" in file "ad_sender_login_maps.cf", then query again, it now will print more debug message, If you're not familiar with this kind of output message, please create a new forum topic and paste them in your post.
- 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. Steps:
- Create a group in AD, e.g. testgroup@example.com.
- Assign at least one member to this group.
- Execute below command on iRedMail server to verify it can get members.
| Terminal: |
# postmap -q testgroup@example.com ldap:/etc/postfix/ad_virtual_group_maps.cf member01@example.com member02@example.com |
postmap will return nothing if 1) mail group doesn't exist; 2) group doesn't have any members.
Enable LDAP query with AD in Dovecot
We need to modify /etc/dovecot-ldap.conf (RHEL/CentOS) or /etc/dovecot/dovecot-ldap.conf (Debian/Ubuntu), let dovecot query 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:1.2.840.113556.1.4.803:=2))) pass_filter = (&(userPrincipalName=%u)(objectClass=person)(!(userAccountControl:1.2.840.113556.1.4.803:=2))) pass_attrs = userPassword=password default_pass_scheme = CRYPT user_attrs = =home=/var/vmail/vmail1/%Ld/%Ln/Maildir/,=mail=maildir:/var/vmail/vmail1/%Ld/%Ln/Maildir/ |
Now restart dovecot service to make it work immediately.
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
}
|
Verify LDAP query with AD in Dovecot
We can use command telnet to verify AD query in Dovecot.
Note: Please do restart dovecot before testing.
| Terminal: |
# telnet localhost 143 # <- Type this
* OK [...] Dovecot ready.
. login user@example.com password_of_user # <- Type this
. OK [...] Logged in
# <- Quit telnet with "Ctrl+]", then type 'quit'.
|
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']["example.com"] = 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:1.2.840.113556.1.4.803:=2)))",
'filter' => "(mail=*@*)",
'fuzzy_search' => true
);
|
Additions
- If your mail domain name is different than Windows Active Directory domain: http://www.iredmail.org/forum/topic3165-integration-with-windows-domain.html
ChangeLog
- 2011-10-22: Use 'postconf -e' to set Postfix settings instead of edit main.cf directly.
- 2011-07-15: Replace 'userAccountControl=514' with 'userAccountControl:1.2.840.113556.1.4.803:=2'. This will still work if the user has additional attributes like password expired or never changes. Thanks Rick Culler <rculler@caresouth>.
