Open-Xchange integration into MS Active Directory and MS Exchange

Overview

Mail-schema.jpg

Mail Relay

The mail relay receives all mail for users with an ox account directly from the MS Exchange Servers. Before it sends these mails to Server A (the cluster) and Server B (the standalone machine), the mail is send to amavis to filter out junk mail and viruses.


Installed packages

The following packages must be installed using yum:

Postfix configuration

Mail, that reaches postfix on port 25 will be directly submitted to amavis, which is listening on port 10024 on localhost. The corresponding configuration entry can be found in /etc/postfix/master.cf:

smtp inet n - n - - smtpd
     -o content_filter=smtp-amavis:[127.0.0.1]:10024
     -o receive_override_options=no_address_mappings

The option receive_override_options=no_address_mappings disables virtual map expansion, which is done after mail has been scanned by amavis (spamassassion / clamav).


When amavis is done, it sends mail back to postfix on port 10025. The corresponding configuration entries can be found in /etc/postfix/master.cf:

smtp-amavis unix - - n - 2 smtp
  -o smtp_data_done_timeout=1200
  -o smtp_send_xforward_command=yes
  -o disable_dns_lookups=yes
  -o max_use=20

127.0.0.1:10025 inet n - n - - smtpd
  -o local_recipient_maps=
  -o relay_recipient_maps=
  -o smtpd_restriction_classes=
  -o smtpd_delay_reject=no
  -o smtpd_client_restrictions=permit_mynetworks,reject
  -o smtpd_helo_restrictions=
  -o smtpd_sender_restrictions=
  -o smtpd_recipient_restrictions=permit_mynetworks,reject
  -o mynetworks_style=host
  -o mynetworks=127.0.0.0/8

Postfix then sends every mail to port 10025 of server A and server B.

The following options have been changed compared to the postfix default configuration:


Option Meaning
inet_interfaces = all Listen on all network interfaces
mydestination = A relay does not deliver any mail locally, therefor it is no destination for any mail
myhostname = oxmail.example.com Hostname as set in MS Exchange
relayhost = [192.168.109.113]:10025 Relay all mail to port 10025 of server A
mynetworks = 127.0.0.0/8 192.168.109.0/24 172.18.0.0/16 Networks, that may relay mail through postfix (must be extended, if necessary)
transport_maps = hash:/etc/postfix/transport Contains the transport to server B
recipient_bcc_maps = pcre:/etc/postfix/duplicate_mail Generate a BCC for every mail and send it to server B

To send a copy of every mail to a specific recipient to the second server B, the recipient_bcc_maps feature is used. This feature enables to send a BCC (engl. = Blind Carbon Copy) of every mail to a different address on a per recipient base.

This is done using a envelope rewrite based on a PCRE (= Perl Compatible Regular Expressions, see http://www.pcre.org/) expression. /etc/postfix/duplicate_mail contains the following expression:

/^(.*?)@.*$/ ${1}@serverb.example.com

On the left side the expression matches the localpart of an email address and captures it in ${1}, which is then used to rewrite the envelope to localpart@serverb.example.com.

The file /etc/postfix/transport contains a transport definition on how to send mail to serverb.example.com:

serverb.example.com smtpcopy:[192.168.109.104]:10025

Instead of using the transport definition smtp, it uses a transport called smtpcopy. This is defined in /etc/postfix/master.cf:

smtpcopy unix - - n - - smtp
  -o myhostname=archive.example.com

It's just the standard smtp transport with the exception that it does not use the hostname as configured in main.cf. This has to be done because every mail server relay, server a and server b have the same hostname. This will result in a rejection of messages with an error message like “server is greeting me with my own hostname”.

In /etc/aliases an alias is set, that sends all mail destined to the root user to oxadmin@example.com.

Amavis configuration

The complete configuration of amavis can be found in /etc/amavisd/amavisd.conf. The following table contains some important configuration options.


Option Meaning
$max_servers = 2; The number of amavis prozesses, that are started when amavis is started. This could be changed to a higher value if scanning becomes to slow later in production.
$mydomain = 'example.com';@local_domains_maps = ( [".$mydomain"] ); The domain name(s). Might be necessary later to add further domain names in local_domains_maps. Syntax: ( [“.$mydomain”], [“.example.org”], [“...”], ... );
$inet_socket_port = 10024; On what port amavis is listening on
$sa_tag_level_deflt = 2.0; The level above which amavis starts adding spamassassin headers, even if not spam
$sa_tag2_level_deflt = 6.31;$sa_kill_level_deflt = 6.31; The level where mail is marked as spam
$sa_mail_body_size_limit = 1024*1024; The maximum size of mail to scan for spam. This should not be set too high, because scanning for spam consumes a lot of memory and spam mail is not very big, anyway. This value does NOT apply for virus scanning.
$sa_local_tests_only = 1; Do only tests which do not require an internet connection (e.g. querying RBL or DUL lists).
$virus_admin = "oxadmin\@example.com";$mailfrom_notify_admin = "oxadmin\@example.com";$mailfrom_notify_recip = "oxadmin\@example.com";$mailfrom_notify_spamadmin = "oxadmin\@example.com"; The email address where amavis should send to and the sender address of amavis generated mail.
$notify_method = 'smtp: [127.0.0.1]:10025';$forward_method = 'smtp: [127.0.0.1]:10025'; Where to send mail back.
$final_spam_destiny = D_PASS; When mail is marked as spam, PASS it through instead of quarantining it to local disc, which is the default.
$bad_header_quarantine_to = undef; Do not quarantine mail with non RFC compliant headers.
# @bypass_virus_checks_maps = (1);# @bypass_spam_checks_maps = (1); If either spam or virus scanning should be turned of temporary, remove the hash sign.

How to configure virus scanners into amavis

The numerous virus scanners amavis supports can be found preconfigured in /etc/amavisd/amavisd.conf below the line starting with @av_scanners. A lot of them are already activated.

In the current setup, Clamav is used and already installed. It's configuration file is /etc/clamd.d/amavisd.conf.


Clamav configuration

The following values have been changed:

LogSyslog yes
FixStaleSocket yes


Those values did not have a valid setting in the default installation, they missed the values and therefor clamav did not work. Nothing else has been changed.

In order to activate the automatic update of the virus database, the package clamav-update must be installed. This, however requires to have internet access.


Activation of the configured services

To permanently activate the services, the following commands must be run:

chkconfig –level 345 postfix on
chkconfig –level 345 amavisd on
chkconfig –level 345 clamd.amavisd on

Server B setup

Installed packages

The following packages must be installed using yum:

To install oxldapsync, the following instructions can be found in the Open-Xchange WIKI:


The installation instructions for Open-Xchange Server 6 for RHEL5 can be found in this article:

Open-Xchange_Installation_Guide_for_RHEL5


All other software packages such as apache2 and mysql will be installed automatically due to software dependencies when following the instruction above instructions.


Postfix configuration

Postfix is listening on four ports on this system. On port 25, 465, 10026 and on port 10025. Mail, that is submitted to port 25 will be piped to procmail, where a disclaimer will be added using the altermime command.

The following options in /etc/postfix/master.cf are responsible for this setup:

smtp inet n - n - - smtpd
  -o content_filter=procmail:procmail

smtps inet n - n - - smtpd
  -o smtpd_tls_wrappermode=yes
  -o content_filter=procmail:procmail

:10026 inet n - n - - smtpd
  -o cleanup_service_name=copycleanup

:10025 inet n - n - - smtpd

copycleanup unix n - n - 0 cleanup
  -o virtual_alias_maps=ldap:/etc/postfix/adcopyfix

procmail unix - n n - 5 pipe
  flags=R user=nobody argv=/usr/bin/procmail -t -m /etc/postfix/procmailrc ${sender} ${recipient}


The following options have been changed compared to the postfix default configuration:


Option Meaning
inet_interfaces = all Listen on all network interfaces
mydestination = $myhostname, localhost.$mydomain, localhost Postfix is responsible for mail, that is generated locally and for oxmail.example.com ($myhostname)
myhostname = oxmail.example.com Hostname as set in MS Exchange
myorigin = $myhostname When only the localpart is given, append $myhostname. That's required for the lookups which query the ADS for oxmail.example.com. Do not set $mydomain here.
mailbox_transport = lmtp:unix:/var/lib/imap/socket/lmtp Transport locally delivered mail to cyrus-imapd using the LMTP protocol.
broken_sasl_auth_clients = yes Some older clients such as Outlook Express 4.0 and MS Exchange 5.0 won't work with this setting.
smtpd_sasl_auth_enable = yes Enable SASL (SMTP AUTH)
smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination Extend the default rule of clients to be able to relay mail through postfix by permit_sasl_authenticated. That means clients, that are not within the trusted networks (mynetworks) may submit mail, if they supply proper authentication credentials (against ADS).
virtual_alias_maps = pcre:/etc/postfix/copyfix ldap:/etc/postfix/adlocalrecipients ldap:/etc/postfix/exchrecipients Lookup ADS using LDAP queries to find out whether mail must be delivered locally or send to MS Exchange.
local_recipient_maps = proxy:unix:passwd.byname $alias_maps [ldap:///etc/postfix/adlocalrecipients ldap:/etc/postfix/adlocalrecipients] ldap:/etc/postfix/exchrecipients This setting must contain every mail account which exists in ADS. If not, smtpd will reject mail.
message_size_limit = 0mailbox_size_limit = 0 Set message- and mailbox size limits to 0, which means unlimited.
disable_dns_lookups = yes Disable dns lookups for the postfix smtp client. Instead of only querying dns, postfix smtp client now also looks up entries in /etc/hosts
relayhost = [172.18.254.25] Send all mail not destined to queries resolvable via ADS to the MS Exchange server.
unknown_local_recipient_reject_code = 450 Do not immediately reject a mail destined to a local user when e.g. the ADS lookups fail for whatever reason, which is the default (Code = 550).

The configuration is the same as in server A with the exception of the configuration for the mail archival. The relay sends a copy of each mail to server B with a different To-Envelope. Instead of @oxmail.example.com, it uses serverb.example.com. Before mail can be delivered, that must be reverted back to oxmail.example.com. That is done in the virtual alias map definition pcre:/etc/postfix/copyfix, which is and must be the first map in the virtual_alias_maps definition.

The file /etc/postfix/copyfix contains the following:

/^(.*?)@serverb.example.com$/ ${1}@oxmail.example.com

This will simply revert back the rewrite done by the relay.


In addition, server a is sending a copy of every sent mail to port 10026. These mails must be put into the “Sent Items” folder of the sender of the mail. To achieve that, a different cleanup service definition using a special LDAP virtual table is used.


/etc/postfix/adcopyfix


result_attribute = samaccountname
result_format = "%s+Sent Items@oxmail.example.com"
query_filter = (&(objectclass=user)(|(mail=%u@*)(proxyaddresses=smtp:%u@*)))


The filter checks, whether the sender has an email address within the mail or the proxyAddresses attributes. If that is the case, it uses the samaccountname and appends the “Sent Items” folder to the address.


To actually deliver directly in that folder, it must have a special IMAP ACL set. The “p” (post) ACL flag must be set, which means, that one can post a mail into that folder.

Because the postfix/cyrus lmtp delivery agent cannot authenticate as a specific user, the reserved user anyone must be given the mentioned “p” flag.


Example:

Imap session without the ACL set:

. getacl "inbox/Sent Items"
* ACL "inbox/Sent Items" test1001 lrswipkxtecda
. OK Completed


Imap session with the ACL set:

. getacl "inbox/Sent Items"
* ACL "inbox/Sent Items" test1001 lrswipkxtecda anyone p
. OK Completed


Unfortunately, it is not possible to automatically apply this additional ACL on automatic mailbox creation. That means, that on server b, this ACL must be set periodically on the Sent Items folders of every user.

If that will not happen, mail will not be lost, though, but just be delivered into the INBOX of that user.


This form of directly addressing sub folders within the local part of a mail address is called sub-addressing or plus-addressing (although, the technique is not limited to use the plus character).

See http://en.wikipedia.org/wiki/E-mail_address#Sub-addressing for further details.

Shellscript to add the “p” ACL

The following shell script can be used to be run by a cronjob, to fulfill that task:


#! /bin/bash
MBFILE=/var/lib/imap/mailboxdump.tmp
# uncomment the following line, if no backup should be created
BAKFILE=/var/lib/imap/mailboxdump.bak

if [ -n "$BAKFILE" ]; then
   su - cyrus -c "/usr/lib/cyrus-imapd/ctl_mboxlist -d > $BAKFILE"
fi

su - cyrus -c "/usr/lib/cyrus-imapd/ctl_mboxlist -d > $MBFILE"

perl -pi -e 's;^(user.*Sent Items(?!.*anyone).*)$;$1anyone\tp\t;' $MBFILE

su - cyrus -c "/usr/lib/cyrus-imapd/ctl_mboxlist -u < $MBFILE"

rm -f $MBFILE


The script has been installed to /opt/open-xchange/sbin/setpostacl and has also been added to the already existing /etc/cron.d/ox:

*/5 * * * * root /opt/open-xchange/sbin/setpostacl > /dev/null 2>&1


Global Mail Signature (Disclaimer)

The disclaimer is added using the altermime program (http://www.pldaniels.com/altermime/). To feed each mail into altermime, procmail is used acting as a general purpose mail filter. /etc/postfix/procmailrc contains the place where altermime is invoked.


Every mail that is sent via port 25 of server b will also be piped into procmail and a disclaimer is added.

Cyrus-Imapd configuration

The following options have been changed in /etc/imapd.conf:


Option Meaning
sasl_mech_list: PLAIN LOGIN Also allow LOGIN instead of just PLAIN. That's useful for debugging, e.g. doing IMAP queries using telnet.
allowplaintext: 1 Allow cleartext passwords.
allowplainwithouttls: 1 Allow PLAIN login mechanism even without TLS on. That's also useful for debugging.

NOTE: In production it is recommended to activate SSL/TLS.

autocreateinboxfolders: Drafts|Sent Items|Junk|Trash The list of INBOX subfolders to be automatically created.
autosubscribeinboxfolders: Drafts|Sent Items|Junk|Trash The list of INBOX subfolders to be automatically subscribed.
createonpost: 1 Automatically create user upon the first post of a mail.
autocreatequota: -1 autocreatequota must be set to a value != 0 when the autocreate feature is used. -1 means unlimited
unixhierarchysep: 1 Use “/” as separator instead of “.”, which is the default. E.g. INBOX/Junk instead of INBOX.Junk.
autocreate_sieve_script: /opt/open-xchange/etc/groupware/Open-Xchange.script Create a default filterscript with the mailbox creation.
singleinstancestore: 0 Do not use that feature. That will reduce the amount of berkeleydb backends in use.
duplicatesuppression: 0 Same as with singleinstancestore.

The file /etc/cyrus.conf contains the definition of services cyrus starts and also some periodically started maintenance tasks. The automatic deletion of mails older then a configurable amount of time is also defined there within the EVENTS section. Documentation of that feature has been added there as comments.


Deletion of old mails

The automatic deletion of mails older then 7 days except within the Sent Mail folder is done by the script /bin/purgit which is called within the cronjob /etc/cron.d/ox. The script calls the command

/usr/lib/cyrus-imapd/ipurge -d 7 -f -n -p "Sent Items"

from the package cyrus-imapd, which is patched by Open-Xchange to support the exclusion of folder patterns. The meaning of the parameters is documented in the corresponding manpage of man ipurge.

Important:

When an update of the cyrus-imapd package from Redhat will be installed, that feature will no longer work!


Cyrus tuning

To prepare cyrus for a greater amount of users using it, the underlying berkeleydb backend has been tuned. The file /var/lib/imap/db/DB_CONFIG contains the relevant parameters. To change these values, cyrus imapd must be stopped. To apply the changes, the command db_recover -h /var/lib/imap/db must be run. When that is done, cyrus can be started again. It might be necessary to delete all files within /var/lib/imap/db – with the exception of DB_CONFIG – before running the db_recover command.

set_cachesize 0 2097152 1
set_lg_regionmax 1048576


In addition, the /var/log/maillog entry in /etc/syslog.conf has been changed to reduce the amount of logging which cyrus is done per default to keep the maillog clear:

mail.*;mail.!=debug -/var/log/maillog

The change will remove the DEBUG priority. Unfortunately that's the only way to switch off debugging with cyrus-imapd.

OXLDAPSync configuration

There are two different configuration files for oxldapsync:

  1. /opt/oxldapsync/etc/ldapsync-ads.conf is responsible for synchronizing users which should use Open-Xchange with all features enabled including mail.
  2. /opt/oxldapsync/etc/ldapsync-infostore-ads.conf synchronizes users which should only have access to the infostore, contacts and send-only mail.

The following options have been set in these files (from /opt/oxldapsync/etc/ldapsync-ads.conf):


Option Meaning
ldapuri=ldap://172.18.16.21 The LDAP (ADS) server to query.
userbasedn = DC=example,DC=comgroupbasedn = DC=example,DC=com The base dn to search for users and groups
ldaptype = openldap Should be set to ads, but that does not work because of a bug in oxldapsync.

NOTE: the openldap type does not do paged result querying. The synch

userfilter =(&(objectclass=user)(mail=*)(extensionAttribute1=*)) The LDAP filter that must return all Open-Xchange users.
userignorefilter =(&(objectclass=user)(mail=*)(!(extensionAttribute1=*))) The LDAP filter that must return all Infostore users.
deleteusers = yes Delete users, that are in Open-Xchange, but not anymore in ADS.
dontModifyUids = admin959474 The name of the Open-Xchange adminuser, which should be ignored.

The only difference in /opt/oxldapsync/etc/ldapsync-infostore-ads.conf is that the filters of userfilter and userignorefilter are interchanged.


In the files /opt/oxldapsync/etc/mapping.ads.conf and /opt/oxldapsync/etc/mapping-infostore.ads.conf contain the mappings of attributes between ADS and Open-Xchange and the feature set to be enabled.


The difference between the features of both files:


mapping.ads.conf mapping-infostore.ads.conf
access-calendar = "on" access-calendar = "off"
access-contacts = "on" access-contacts = "on"
access-delegate-tasks = "on" access-delegate-tasks = "off"
access-edit-public-folder = "on" access-edit-public-folder = "off“
access-forum = "on" access-forum = "off"
access-ical = "on" access-ical = "off"
access-infostore = "on" access-infostore = "on"
access-pinboard-write = "on" access-pinboard-write = "off"
access-projects = "on" access-projects = "off"
access-read-create-shared-Folders = "on" access-read-create-shared-Folders = "off"
access-rss-bookmarks = "on" access-rss-bookmarks = "off"
access-rss-portal = "on" access-rss-portal = "off"
access-syncml = "on" access-syncml = "off"
access-tasks = "on" access-tasks = "off"
access-vcard = "on" access-vcard = "off"
access-webdav = "on" access-webdav = "on"
access-webdav-xml = "on" access-webdav-xml = "on"
access-webmail = "on" access-webmail = "on"
access-edit-group = "off" access-edit-group = "off"
access-edit-resource = "off" access-edit-resource = "off"
access-edit-password = "off" access-edit-password = "off"
Access-multiple-mail-accounts = “on”
Access-subscription = “on”
Access-publication = “on”
Uploadfilesizelimit = “-1”
Uploadfilesizelimitperfile =”1048576”

The following other changes have been made to both files:


Option Meaning
imapserver = "192.168.109.104" IP Address of IMAP Server
smtpserver = "192.168.109.104" IP Address of SMTP Server
mail_folder_spam_name = "Junk" Non standard name of SPAM Folder
gui_spam_filter_capabilities_enabled = "true" Enable SPAM buttons in WEB UI

To start each sync individually, run either

/opt/oxldapsync/sbin/oxldapsync.pl -f \
  /opt/oxldapsync/etc/ldapsync-infostore-ads.conf \
  -A oxadmin -P secret -c 1

or

/opt/oxldapsync/sbin/oxldapsync.pl -f \
  /opt/oxldapsync/etc/ldapsync-ads.conf -A oxadmin -P secret -c 1

A cronjob /etc/cron.d/ox has been prepared to run these commands regularly from with the script /opt/open-xchange/sbin/oxsync.

AD Kerberos configuration

The complete Kerberos configuration is done in the file /etc/krb5.conf:

[logging]
 default = FILE:/var/log/krb5libs.log
 kdc = FILE:/var/log/krb5kdc.log
 admin_server = FILE:/var/log/kadmind.log

[libdefaults]
 default_realm = AD.EXAMPLE.COM
 dns_lookup_realm = false
 dns_lookup_kdc = true
 ticket_lifetime = 24h
 forwardable = yes

[realms]
 AD.EXAMPLE.COM = {
  kdc = 172.18.224.27:88
  admin_server = 172.18.224.27:749
  default_domain = ad.example.com
 }

[domain_realm]
 .ad.example.com = AD.EXAMPLE.COM
 ad.example.com = AD.EXAMPLE.COM

[appdefaults]
 pam = {
   debug = false
   ticket_lifetime = 36000
   renew_lifetime = 36000
   forwardable = true
   krb4_convert = false
 }

Pam setup for Kerberos

The services are configured to use Kerberos as authentication source. Services in that matter are imap,pop, sieve and smtp. The pam files are all identical:

/etc/pam.d/smtp.postfix,/etc/pam.d/imap,/etc/pam.d/pop,/etc/pam.d/sieve
#%PAM-1.0
#auth       include     system-auth
#account    include     system-auth
auth        sufficient   pam_krb5.so no_user_check validate
account     sufficient   pam_permit.so

Apache configuration

deletion of the default welcome screen:

rm /etc/httpd/conf.d/welcome.conf

creating a configuration for the Open-Xchange service

/etc/httpd/conf.d/ox.conf

with following contend:

NameVirtualHost *
<VirtualHost *>
        ServerAdmin webmaster@localhost

        DocumentRoot /var/www/html/

        <Directory /var/www/html/>
                AllowOverride None
                Order allow,deny
                allow from all
                RedirectMatch ^/$ /ox6/
        </Directory>

        ExpiresActive On
        ExpiresByType image/gif "access plus 230 hours"
        ExpiresByType image/png "access plus 230 hours"
        ExpiresByType image/jpg "access plus 230 hours"
        ExpiresByType image/jpeg "access plus 230 hours"
        ExpiresByType text/javascript "access plus 230 hours"
        ExpiresByType text/css "access plus 230 hours"
        ExpiresByType text/html "access plus 230 hours"
        ExpiresByType application/x-javascript "access plus 230 hours"
        <Files ~ "\.(js|css|gif|jpe?g|png)$">
                Header append Cache-Control "public"
        </Files>

        DeflateFilterNote ratio
        AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css application/x-javascript application/javascript
        BrowserMatch ^Mozilla/4 gzip-only-text/html
        BrowserMatch ^Mozilla/4\.0[678] no-gzip
        BrowserMatch \bMSI[E] !no-gzip !gzip-only-text/html
        Header append Vary User-Agent env=!dont-vary
</VirtualHost></nowiki>


Creation of a ajp configuration file:

/etc/httpd/conf.d/proxy_ajp.conf

with contend:

LoadModule proxy_ajp_module modules/mod_proxy_ajp.so
<Proxy *>
 Order deny,allow
 allow from all
</Proxy>
ProxyPass /ajax ajp://127.0.0.1:8009/ajax smax=0 ttl=60 retry=5
ProxyPass /servlet ajp://127.0.0.1:8009/servlet smax=0 ttl=60 retry=5
ProxyPass /infostore ajp://127.0.0.1:8009/infostore smax=0 ttl=60 retry=5
ProxyPass /publications ajp://127.0.0.1:8009/publications smax=0 ttl=60 retry=5
ProxyPass /Microsoft-Server-ActiveSync ajp://127.0.0.1:8009 /Microsoft-Server-ActiveSync smax=0 ttl=60 retry=5

after configuration, it was needed to restart the apache web service by:

/etc/init.d/http restart

Open-Xchange Service configuration

The first step for the Open-Xchange service configuration was to create the initial configuration database:

/opt/open-xchange/sbin/initconfigdb --configdb-pass=secret --configdb-user=oxusr --configdb-port=3313 -i

Afterwards, a basic configuration was created using the script oxinstaller:

/opt/open-xchange/sbin/oxinstaller --servername=oxserver --configdb-pass=secret --master-pass=secret --ajp-bind-port='*' --configdb-readport=3313 --configdb-writeport=3313 --servermemory=8169 --adminmemory=1024 --clt-memory=50 --configdb-user=oxusr --disableauth

initial registration of the Open-Xchange internal server name:

/opt/open-xchange/sbin/registerserver -n  oxserver

registration of the user data database:

/opt/open-xchange/sbin/registerdatabase -A oxadminmaster -P secret -n oxdatabasea -p secret -m true --dbuser oxusr --hostname localhost:3313

create and register the filestore:

mkdir -p /u01/open-xchange/filestore
chown open-xchange:open-xchange /u01/open-xchange/filestore
/opt/open-xchange/sbin/registerfilestore -A oxadminmaster -P secret -t file:///u01/open-xchange/filestore -s 200000

creation of the Context:

/opt/open-xchange/sbin/createcontext -A oxadminmaster -P secret -c 1 -u oxadmin -d "Context Admin" -g Admin -s User -p secret -L defaultcontext -e oxadmin@example.com -q 200000 –access-combination-name=all

IMAP authentication bundle configuration:


Option Meaning
IMAP_SERVER=localhost IP Address of IMAP Server
IMAP_PORT=143 PORT of IMAP Server
USE_FULL_LOGIN_INFO=false only username is used for login

Configuration settings after initial config generation:


File Option
groupware/ox-scriptconf.sh NRFILES="16635"
groupware/cache.ccf jcs.auxiliary.LTCP.attributes.TcpServers=127.0.0.1:57461
jcs.auxiliary.LTCP.attributes.TcpListenerPort=57462
# Define UDP discovery here, but ensure you do not specify static TCP server via jcs.auxiliary.LTCP.attributes.TcpServers 
#jcs.auxiliary.LTCP.attributes.UdpDiscoveryAddr=224.0.0.1 
#jcs.auxiliary.LTCP.attributes.UdpDiscoveryPort=6780 
#jcs.auxiliary.LTCP.attributes.UdpDiscoveryEnabled=true 
groupware/foldercache.properties ENABLE_INTERNAL_USER_EDIT=FALSE
groupware/mailfilter.properties SIEVE_LOGIN_TYPE=user
SIEVE_CREDSRC=session
SIEVE_SERVER=localhost
SIEVE_PORT=2000
groupware/notification.properties object_link=http://node2750.example.com/#m=[module]&i=[object]&f=[folder]
groupware/participant.properties com.openexchange.participant.autoSearch=false
admindeamon/cache.ccf jcs.auxiliary.LTCP.attributes.TcpServers=127.0.0.1:57462
jcs.auxiliary.LTCP.attributes.TcpListenerPort=57461
# Define UDP discovery here, but ensure you do not specify static TCP server via jcs.auxiliary.LTCP.attributes.TcpServers 
#jcs.auxiliary.LTCP.attributes.UdpDiscoveryAddr=224.0.0.1 
#jcs.auxiliary.LTCP.attributes.UdpDiscoveryPort=6780 
#jcs.auxiliary.LTCP.attributes.UdpDiscoveryEnabled=true 

Infostore Use Case

File Option
groupware/transport.porperties com.openexchange.mail.transport.enablePublishOnExceededQuota=true
groupware/transport.porperties com.openexchange.mail.transport.publishingPublicInfostoreFolder=Email attachments
groupware/transport.porperties com.openexchange.mail.transport.publishPrimaryAccountOnly=false
groupware/transport.porperties com.openexchange.mail.transport.sendAttachmentToExternalRecipients=true
groupware/server.properties MAX_UPLOAD_SIZE=1048576

Log files

Currently, the Open-Xchange service is configured to log directly to files below /var/log/open-xchange. There are different files for the groupware and admin process. The files open-xchange.log* hold log information of user related actions and the files open-xchange-admin.log* provisioning related messages.

For later, it is recommended to activate syslog and to direct all messages to a syslog server. Detailed configuration steps are to be found here:

http://www.open-xchange.com/wiki/index.php?title=Syslog_Configuration

Activation of the configured services

To permanently activate the services, the following commands must be run:

chkconfig –level 345 postfix on
chkconfig –level 345 cyrus-imapd on
chkconfig –level 345 saslauthd on
chkconfig –level 345 httpd on
chkconfig –level 345 open-xchange-groupware on
chkconfig –level 345 open-xchange-admin on

Server A setup

Installed packages

Server A has the same packages installed like Server B.


Postfix configuration

Postfix is listening on four ports on this system. On port 25, 465, 11025 and on port 10025. Mail, that is submitted to port 25 will be piped to procmail, where a disclaimer will be added using the altermime command.

The following options in /etc/postfix/master.cf are responsible for this setup:

smtp inet n - n - - smtpd
  -o content_filter=procmail:procmail
smtps inet n - n - - smtpd
  -o smtpd_tls_wrappermode=yes
  -o content_filter=procmail:procmail

localhost:11025 inet n - n - - smtpd
  -o cleanup_service_name=archivecleanup

:10025 inet n - n - - smtpd

archivecleanup unix n - n - 0 cleanup
  -o sender_bcc_maps=pcre:/etc/postfix/archive_sentmail

procmail unix - n n - 5 pipe
  flags=R user=nobody argv=/usr/bin/procmail -t -m /etc/postfix/procmailrc ${sender} ${recipient}


The following options have been changed compared to the postfix default configuration:


Option Meaning
inet_interfaces = all Listen on all network interfaces
mydestination = $myhostname, localhost.$mydomain, localhost Postfix is responsible for mail, that is generated locally and for oxmail.example.com ($myhostname)
myhostname = oxmail.example.com Hostname as set in MS Exchange
myorigin = $myhostname When only the localpart is given, append $myhostname. That's required for the lookups which query the ADS for oxmail.example.com. Do not set $mydomain here.
mailbox_transport = lmtp:unix:/var/lib/imap/socket/lmtp Transport locally delivered mail to cyrus-imapd using the LMTP protocol.
broken_sasl_auth_clients = yes Some older clients such as Outlook Express 4.0 and MS Exchange 5.0 won't work with this setting.
smtpd_sasl_auth_enable = yes Enable SASL (SMTP AUTH)
smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination Extend the default rule of clients to be able to relay mail through postfix by permit_sasl_authenticated. That means clients, that are not within the trusted networks (mynetworks) may submit mail, if they supply proper authentication credentials (against ADS).
virtual_alias_maps = ldap:/etc/postfix/adlocalrecipients ldap:/etc/postfix/exchrecipients Lookup ADS using LDAP queries to find out whether mail must be delivered locally or send to MS Exchange.
local_recipient_maps = proxy:unix:passwd.byname $alias_maps [ldap:///etc/postfix/adlocalrecipients ldap:/etc/postfix/adlocalrecipients] ldap:/etc/postfix/exchrecipients This setting must contain every mail account which exists in ADS. If not, smtpd will reject mail.
message_size_limit = 0mailbox_size_limit = 0 Set message- and mailbox size limits to 0, which means unlimited.
disable_dns_lookups = yes Disable dns lookups for the postfix smtp client. Instead of only querying dns, postfix smtp client now also looks up entries in /etc/hosts
relayhost = [172.18.254.25] Send all mail not destined to queries resolvable via ADS to the MS Exchange server.
unknown_local_recipient_reject_code = 450 Do not immediately reject a mail destined to a local user when e.g. the ADS lookups fail for whatever reason, which is the default (Code = 550).

The LDAP query /etc/postfix/adlocalrecipients is looking for users that have an Open-Xchange account and an MS Exchange account. These users must have a forwarding contact created within MS Exchange. The LDAP Attribute mailNickname of these contacts must be set to the numeric account name as used also to login to Windows workstations and to Open-Xchange.

query_filter =
(&(objectclass=contact)(mail=*@oxmail.example.com)(proxyaddresses=smtp:%s@*))
result_attribute = mailNickname

The query looks for every contact containing oxmail.example.com in the LDAP mail attribute and containing the localpart of the recipient address in one of the LDAP proxyAddresses.

As result of the lookup, mailNickname ist used. That's just the localpart of the email address.


The LDAP query /etc/postfix/exchrecipients is looking for every user in ADS, that can receive mail. Either delivered to Open-Xchange or Exchange.

query_filter = (&(objectclass=user)(|(mail=%s)(proxyaddresses=smtp:%s)))
result_attribute = mail

The query looks for every user object within ADS, which has either set mail to the (envelope) address it is just about to accept mail for or which contains that address within one of the proxyAddresses.

As a result of that lookup, the mail address is used. The mail attribute either contains one of the configured domains like example.com, example.org or oxmail.example.com in case it should be forwarded to Open-Xchange, without having an MS Exchange Account.


Sent Items archiving

A copy of every mail originated from Open-Xchange or Outlook must be sent to the Sent Items folder of the mail archive server b.

This can be achieved using a per sender bcc map /etc/postfix/archive_sentmail:

/^(.*?)@example.com$/ ${1}@serverb.example.com
/^(.*?)@example.org$/ ${1}@serverb.example.com


Note: This file must contain a line for each sender domain.


This expression will rewrite the envelope of every mail originated from a user foo@example.com to foo on server b.


In order for server a to send mail to server b, a transport entry in /etc/postfix/transport must be created:

serverb.example.com smtp:[192.168.109.104]:10026

like already done on the mail relay. After adding this entry, the command

postmap /etc/postfix/transport

must be executed.


Now to finally use the sender_bcc_map, the file /etc/postfix/master.cf must be changed. A new entry must be added:


localhost:11025 inet n - n - - smtpd
  -o cleanup_service_name=archivecleanup

Procmail will send back mail to port 11025 after the disclaimer has been added.


Also the additional cleanup service must be defined:

archivecleanup unix n - n - 0 cleanup
  -o sender_bcc_maps=pcre:/etc/postfix/archive_sentmail

best place would be below the existing cleanup service definition, but that's just cosmetics.


Global Mail Signature (Disclaimer)

The disclaimer is added using the altermime program (http://www.pldaniels.com/altermime/). To feed each mail into altermime, procmail is used acting as a general purpose mail filter. /etc/postfix/procmailrc contains the place where altermime is invoked.


Every mail that is sent via port 25 of server a will also be piped into procmail and a disclaimer is added.

On server a, procmail will deliver mail back to port 11025 using the program ssmtp instead of using sendmail as on server b.

Cyrus-Imapd configuration

The same as on Server B.

OXLDAPSync configuration

The same as on Server B with the exception of the parameters imapserver and smtpserver in mapping-infostore.ads.conf and mapping.ads.conf which point to the external LVS address of the Cluster.


AD Kerberos configuration

The same as on Server B.

Apache configuration

The same as on Server A except the ajp configuration. Both nodes have different settings for the route, relative to the groupware ajp configuration

node8888:

LoadModule proxy_ajp_module modules/mod_proxy_ajp.so
<Proxy *>
 Order deny,allow
 allow from all
</Proxy>
ProxyPreserveHost On
ProxyPass /ajax balancer://oxcluster/ajax stickysession=JSESSIONID
ProxyPass /servlet balancer://oxcluster/servlet stickysession=JSESSIONID
ProxyPass /infostore balancer://oxcluster/infostore stickysession=JSESSIONID
ProxyPass /publications balancer://oxcluster/publications stickysession=JSESSIONID
ProxyPass /Microsoft-Server-ActiveSync balancer://oxcluster/Microsoft-Server-ActiveSync stickysession=JSESSIONID

<Proxy balancer://oxcluster>
 BalancerMember ajp://localhost:8009 smax=0 ttl=60 retry=5 loadfactor=50 route=OX-1
 BalancerMember ajp://192.168.109.115:8009 smax=0 ttl=60 retry=5 route=OX-2 status=+H
</Proxy>

node9999:

LoadModule proxy_ajp_module modules/mod_proxy_ajp.so
<Proxy *>
 Order deny,allow
 allow from all
</Proxy>
ProxyPreserveHost On
ProxyPass /ajax balancer://oxcluster/ajax stickysession=JSESSIONID
ProxyPass /servlet balancer://oxcluster/servlet stickysession=JSESSIONID
ProxyPass /infostore balancer://oxcluster/infostore stickysession=JSESSIONID
ProxyPass /publications balancer://oxcluster/publications stickysession=JSESSIONID
ProxyPass /Microsoft-Server-ActiveSync balancer://oxcluster/Microsoft-Server-ActiveSync stickysession=JSESSIONID

<Proxy balancer://oxcluster>
 BalancerMember ajp://localhost:8009 smax=0 ttl=60 retry=5 loadfactor=50 route=OX-2
 BalancerMember ajp://192.168.109.114:8009 smax=0 ttl=60 retry=5 route=OX-1 status=+H
</Proxy>

Open-Xchange Service configuration

The same as on Server B except the following and no changes to the cache.ccf files:

node8888

/opt/open-xchange/groupware/ajp.properties:


Option Meaning
AJP_JVM_ROUTE:OX-1 name for the ajp SESSIONID route
/opt/open-xchange/groupware/imapauth.properties:


Option Meaning
IMAP_SERVER=192.168.109.113 IMAP server IP
/opt/open-xchange/groupware/mailfilter.properties:


Option Meaning
SIEVE_SERVER=192.168.109.113 SIEVE server IP
/opt/open-xchange/groupware/notification.properties:


Option Meaning
object_link=http://192.168.109.117/#m=[module]&i=[object]&f=[folder] Link which will be found in server generated emails for direkt links.

node9999

/opt/open-xchange/groupware/ajp.properties:


Option Meaning
AJP_JVM_ROUTE:OX-2 name for the ajp SESSIONID route
/opt/open-xchange/groupware/imapauth.properties:


Option Meaning
IMAP_SERVER=192.168.109.113
/opt/open-xchange/groupware/mailfilter.properties:


Option Meaning
SIEVE_SERVER=192.168.109.113 SIEVE server IP
/opt/open-xchange/groupware/notification.properties:


Option Meaning
object_link=http://192.168.109.117/#m=[module]&i=[object]&f=[folder] Link which will be found in server generated emails for direkt links.

Log files

Currently, the Open-Xchange service is configured to log directly to files below /var/log/open-xchange. There are different files for the groupware and admin process. The files open-xchange.log* hold log information of user related actions and the files open-xchange-admin.log* provisioning related messages.

For later, it is recommended to activate syslog and to direct all messages to a syslog server. Detailed configuration steps are to be found here:

http://www.open-xchange.com/wiki/index.php?title=Syslog_Configuration

Activation of the configured services

To permanently activate the services, the following commands must be run:

chkconfig –level 345 httpd on

all other services are under control of the RHEL cluster and will get automatically started.

Trouble shooting

Authentication

IMAP, SMTP,SIEVE services are using Kerberos authentication for the users. Authentication can be tests using the command kinit:

kinit <SAMaccountName>

it gives back an error on failure and just a prompt if successful.

The Open-Xchange service uses IMAP as authentication source. A imap login can be tested using telnet as test programm:

telnet <imap ip> 143

after the IMAP greeting appears, type:. login <SAMaccountName> <password>This shows if the login succeeds or the service is running.

Following command shows weather the user is successfully synced to Open-Xchange:

listuser -c 1 -s <SAMaccountName> --csv

this command should give the record of that single user or nothing in case the synchronization failed.

Log files

in case of support enquries, log files and configuration will be collected and packaged by the commands:

/opt/open-xchange/sbin/oxsysreport
sosreport

System log

/var/log/messages


Synchronization log

/var/log/oxldapsync.log


Admin service log

Log files for the Open-Xchange administration daemon, the console log collects all messages from the java virutal machine (needed in case the daemon does not start):

/var/log/open-xchange/open-xchange-admin.log*

/var/log/open-xchange/open-xchange-admin-console.log


Groupware service log

Log files for the Open-Xchange groupware daemon, the console log collects all messages from the java virutal machine (needed in case the daemon does not start):

/var/log/open-xchange/open-xchange.log*

/var/log/open-xchange/open-xchange-console.log

Apache Web server log

/var/log/httpd/*

Mail Service log

/var/log/maillog

procmailrc server A

LOGFILE=/tmp/procmail.log
VERBOSE=no

SENDER=$1
SHIFT=1
:0 hbfwi
| /usr/bin/altermime --force-for-bad-html --input=- --disclaimer=/etc/postfix/disclaimer.txt --disclaimer-html=/etc/postfix/disclaimer.txt

:0
| /usr/sbin/ssmtp -i -f "$SENDER" -- "$@"

procmailrc server B

LOGFILE=/tmp/procmail.log
VERBOSE=no

SENDER=$1
SHIFT=1
:0 hbfwi
| /usr/bin/altermime --force-for-bad-html --input=- --disclaimer=/etc/postfix/disclaimer.txt --disclaimer-html=/etc/postfix/disclaimer.txt

:0
| /usr/sbin/sendmail -i -f "$SENDER" -- "$@"

Workarounds for RHEL5 Bugs

Cyrus-imapd autocreatesieve dies with SEGFAULT on x86_64.

When autocreating the default filter SIEVE script, the corresponding process imap or lmtp dies with SIG11. This is a bug in cyrus-imapd on RHEL5.

As a workaround, a script can be created, started every minute as a cron job in /etc/cron.d/ox. This script /opt/open-xchange/sbin/copyjunkfilter copies the default filter to /var/lib/imap/sieve/ of every user as soon as it has been created and as long as it does not have a filter already.