Installation and configuration - CentOS 7.5

Overview

This is a pure Activesync implementation example, no Openchange.

Samba Active Directory integrated with Pam via Winbind makes system aware of Active directory users,

instead of configuring LDAP within Dovecot and Sendmail.

Autodiscover via PHP and SSL via Certbot.

Outlook 2013/2016 clients connect natively on desktop devices.

Apple and Android clients connect natively on mobile devices.

Notes

New CentOS installation with package selection "Compute Node" option.

Internet Domain : example.com

Internet DNS records required for mail.example.com and autodiscover.example.com to

point to the systems public IP address and firewall to allow TCP 80/443.

Active Directory Domain : example.local

Samba username must match email address username.

In production this config is successfully deployed to serve 40 desktop Clients and 40 mobile clients

with 8G memory and x1 CPU.

Howto

Yum Repositories

  1. Configure Sogo Repo.
    echo "[sogo]
    name=Inverse SOGo Repository
    baseurl=https://packages.inverse.ca/SOGo/nightly/4/rhel/7/x86_64" > /etc/yum.repos.d/sogo.repo
  2. Configure EPEL Repo.
    rpm -Uvh https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
  3. Prevent rebuilt Samba from being replaced.
    sed -i "/\[base\]/ a\exclude=samba*" /etc/yum.repos.d/CentOS-Base.repo

Custom Packages

  1. Newer packages to be rebuilt from src rpm's as they are required for Samba rebuild.
    yum -y group install "Development Tools"
    yum -y install createrepo
    yum -y remove gnutls
    
    rm -rf /root/rpmbuild
  2. Rebuild Nettle and add to custom Repo.
    rpmbuild --rebuild https://download.fedoraproject.org/pub/fedora/linux/releases/27/Everything/source/tree/Packages/n/nettle-3.3-5.fc27.src.rpm
    
    mkdir -p /tmp/repo
    cp /root/rpmbuild/RPMS/x86_64/* /tmp/repo
    cd /tmp/repo
    createrepo ./
    
    echo "[custom]
    name=CentOS Custom
    baseurl=file:/tmp/repo/
    enabled=1
    gpgckeck=0" > /etc/yum.repos.d/CentOS-Custom.repo
    
    rm -rf /root/rpmbuild
    yum clean all
  3. Rebuild GnuTLS and add to custom Repo.
    yum -y install texinfo autogen-libopts-devel trousers-devel gperf softhsm datefudge unbound-devel guile-devel\
        p11-kit-devel readline-devel libtasn1-devel nettle-devel libidn-devel
    
    rpm -Uvh http://archives.fedoraproject.org/pub/archive/fedora/linux/updates/24/SRPMS/g/gnutls-3.4.17-2.fc24.src.rpm
    
    cd /root/rpmbuild/SPECS
    sed -i "s/Recommends: trousers/Requires: trousers/g" gnutls.spec
    rpmbuild -bb gnutls.spec
    
    cp /root/rpmbuild/RPMS/x86_64/* /tmp/repo
    cd /tmp/repo
    wget https://copr-be.cloud.fedoraproject.org/results/humaton/nodejs4/epel-7-x86_64/00125398-crypto-policies/crypto-policies-20151005-1.gitc8452f8.el7.centos.noarch.rpm
    createrepo ./
    
    rm -rf /root/rpmbuild
    yum clean all
  4. Rebuild GNUStep Base and add to custom Repo.
    yum -y install gcc-objc libffi-devel gnutls-devel libxml2-devel libxslt-devel gnustep-make\
        avahi-compat-libdns_sd-devel texi2html texinfo-tex libicu-devel
    
    rpmbuild --rebuild https://download.fedoraproject.org/pub/fedora/linux/releases/27/Everything/source/tree/Packages/g/gnustep-base-1.25.0-4.fc27.src.rpm
    
    cp /root/rpmbuild/RPMS/x86_64/* /tmp/repo
    cp /root/rpmbuild/RPMS/noarch/* /tmp/repo
    cd /tmp/repo/
    createrepo ./
    
    rm -rf /root/rpmbuild
    yum clean all
    
    cd /usr/lib64
    ln -s libgnutls.so.30.7.0 libgnutls.so.28
    ln -s libgnustep-base.so.1.25.0 libgnustep-base.so.1.24
  5. Rebuild Samba to include Active Directory and add to custom Repo.
    yum -y install cups-devel openldap-devel python-tevent glusterfs-devel e2fsprogs-devel \
        libattr-devel pam-devel libcap-devel python2-devel pytalloc-devel gnutls-devel \
        popt-devel avahi-devel dbus-devel quota-devel libuuid-devel gnutls-devel pyldb-devel \
        libtdb-devel python-tdb libacl-devel libaio-devel docbook-style-xsl libarchive-devel \
        libcmocka-devel ncurses-devel python-dns python2-iso8601 readline-devel xfsprogs-devel \
        glusterfs-api-devel perl-Parse-Yapp krb5-server systemd-devel python2-crypto\
        perl-Test-Simple perl-ExtUtils-MakeMaker bind
    
    rpm -Uvh http://vault.centos.org/7.5.1804/updates/Source/SPackages/samba-4.7.1-9.el7_5.src.rpm
    
    cd /root/rpmbuild/SPECS
    
    sed -i "s/%define main_release 9/%define main_release 90/g" samba.spec
    
    sed -i "s/%global with_mitkrb5 1/%global with_mitkrb5 0/g" samba.spec
    sed -i "s/%global with_dc 0/%global with_dc 1/g" samba.spec
    
    sed -i "/\krb5\/plugins\/kdb\/samba.so/d" samba.spec
    sed -i "/\/var\/lib\/samba\/bind-dns/d" samba.spec
    
    sed -i "s/Requires: python2-%{name} = %{samba_depver}/Requires: %{name}-python = %{samba_depver}/" samba.spec
    
    sed -i "/%{_libdir}\/samba\/libutil-tdb-samba4.so/ a\%{_libdir}\/samba\/libHDB-SAMBA4-samba4.so" samba.spec
    sed -i "/%{_libdir}\/samba\/libutil-tdb-samba4.so/ a\%{_libdir}\/samba\/libasn1-samba4.so.8" samba.spec
    sed -i "/%{_libdir}\/samba\/libutil-tdb-samba4.so/ a\%{_libdir}\/samba\/libasn1-samba4.so.8.0.0" samba.spec
    sed -i "/%{_libdir}\/samba\/libutil-tdb-samba4.so/ a\%{_libdir}\/samba\/libcom_err-samba4.so.0" samba.spec
    sed -i "/%{_libdir}\/samba\/libutil-tdb-samba4.so/ a\%{_libdir}\/samba\/libcom_err-samba4.so.0.25" samba.spec
    sed -i "/%{_libdir}\/samba\/libutil-tdb-samba4.so/ a\%{_libdir}\/samba\/libgssapi-samba4.so.2" samba.spec
    sed -i "/%{_libdir}\/samba\/libutil-tdb-samba4.so/ a\%{_libdir}\/samba\/libgssapi-samba4.so.2.0.0" samba.spec
    sed -i "/%{_libdir}\/samba\/libutil-tdb-samba4.so/ a\%{_libdir}\/samba\/libhcrypto-samba4.so.5" samba.spec
    sed -i "/%{_libdir}\/samba\/libutil-tdb-samba4.so/ a\%{_libdir}\/samba\/libhcrypto-samba4.so.5.0.1" samba.spec
    sed -i "/%{_libdir}\/samba\/libutil-tdb-samba4.so/ a\%{_libdir}\/samba\/libhdb-samba4.so.11" samba.spec
    sed -i "/%{_libdir}\/samba\/libutil-tdb-samba4.so/ a\%{_libdir}\/samba\/libhdb-samba4.so.11.0.2" samba.spec
    sed -i "/%{_libdir}\/samba\/libutil-tdb-samba4.so/ a\%{_libdir}\/samba\/libheimbase-samba4.so.1" samba.spec
    sed -i "/%{_libdir}\/samba\/libutil-tdb-samba4.so/ a\%{_libdir}\/samba\/libheimbase-samba4.so.1.0.0" samba.spec
    sed -i "/%{_libdir}\/samba\/libutil-tdb-samba4.so/ a\%{_libdir}\/samba\/libheimntlm-samba4.so.1" samba.spec
    sed -i "/%{_libdir}\/samba\/libutil-tdb-samba4.so/ a\%{_libdir}\/samba\/libheimntlm-samba4.so.1.0.1" samba.spec
    sed -i "/%{_libdir}\/samba\/libutil-tdb-samba4.so/ a\%{_libdir}\/samba\/libhx509-samba4.so.5" samba.spec
    sed -i "/%{_libdir}\/samba\/libutil-tdb-samba4.so/ a\%{_libdir}\/samba\/libhx509-samba4.so.5.0.0" samba.spec
    sed -i "/%{_libdir}\/samba\/libutil-tdb-samba4.so/ a\%{_libdir}\/samba\/libkdc-samba4.so.2" samba.spec
    sed -i "/%{_libdir}\/samba\/libutil-tdb-samba4.so/ a\%{_libdir}\/samba\/libkdc-samba4.so.2.0.0" samba.spec
    sed -i "/%{_libdir}\/samba\/libutil-tdb-samba4.so/ a\%{_libdir}\/samba\/libkrb5-samba4.so.26" samba.spec
    sed -i "/%{_libdir}\/samba\/libutil-tdb-samba4.so/ a\%{_libdir}\/samba\/libkrb5-samba4.so.26.0.0" samba.spec
    sed -i "/%{_libdir}\/samba\/libutil-tdb-samba4.so/ a\%{_libdir}\/samba\/libroken-samba4.so.19" samba.spec
    sed -i "/%{_libdir}\/samba\/libutil-tdb-samba4.so/ a\%{_libdir}\/samba\/libroken-samba4.so.19.0.1" samba.spec
    sed -i "/%{_libdir}\/samba\/libutil-tdb-samba4.so/ a\%{_libdir}\/samba\/libwind-samba4.so.0" samba.spec
    sed -i "/%{_libdir}\/samba\/libutil-tdb-samba4.so/ a\%{_libdir}\/samba\/libwind-samba4.so.0.0.0" samba.spec
    
    rpmbuild -bb samba.spec
    
    cp /root/rpmbuild/RPMS/x86_64/* /tmp/repo
    cp /root/rpmbuild/RPMS/noarch/* /tmp/repo
    cd /tmp/repo/
    createrepo ./
    
    rm -rf /root/rpmbuild
    yum clean all

Samba Active Directory

  1. Install Samba.
    yum -y install samba-dc samba-python-dc tdb-tools samba-winbind-clients cups bind bind-utils samba-dc-bind-dlz
    yum -y remove bind-chroot
  2. Ensure no stale config.
    rm -rf /etc/samba/smb.conf
    rm -rf /var/lib/samba/private/*
    rm -rf /var/lib/samba/sysvol
  3. Hostname must be as in Active Directory before provision.
    hostname dc.example.local
  4. Samba Kerberos doesn't know of this setting. ( future yum update could put this setting back and cause bind dlz to fail )

    sed -i "s/includedir/#includedir/" /etc/krb5.conf
  5. Provision Active Directory.
    samba-tool domain provision --function-level=2008_R2 --realm=example.local --domain=EXAMPLE --adminpass='Password1' --server-role='dc' --dns-backend=BIND9_DLZ --option="interfaces=lo eth0" --option="bind interfaces only=yes"
  6. Enable RDP auth for PC's joined to domain.
    sed -i '/workgroup =/ a\\tntlm auth = ntlmv1-permitted' /etc/samba/smb.conf
  7. Dynamic DNS updates for PC's joined to domain.
    sed -i '/ntlm auth = ntlmv1-permitted/ a\\tdsdb:schema update allowed = true' /etc/samba/smb.conf
  8. Sogo by default uses LDAP not LDAPS.
    sed -i '/ntlm auth = ntlmv1-permitted/ a\\tldap server require strong auth = no' /etc/samba/smb.conf
  9. Fix Bind Ownership. ( these rights will have to be re applied after yum update of bind )

    chown named /var/lib/samba/private
    chgrp named /var/lib/samba/private/dns.keytab
    chmod g+r /var/lib/samba/private/dns.keytab
  10. Configure Bind.
    sed -i "/listen-on port 53/s/127.0.0.1/any/" /etc/named.conf
    sed -i "/allow-query/s/localhost/any/" /etc/named.conf
    sed -i '/allow-query/ a\\ttkey-gssapi-keytab "/var/lib/samba/private/dns.keytab";' /etc/named.conf
    
    sed -i '/tkey-gssapi-keytab/ a\\tforwarders { 8.8.8.8; };' /etc/named.conf
    sed -i '/forwarders/ a\\tforward first;' /etc/named.conf
    
    sed -i '/include "\/etc\/named.rfc1912.zones";/d' /etc/named.conf
    sed -i '/include "\/etc\/named.root.key";/d' /etc/named.conf
    
    sed -i "\$ainclude \"\/var\/lib\/samba\/private\/named.conf\";" /etc/named.conf
    
    sed -i '/zone "." IN {/,+4d' /etc/named.conf
  11. Configure system DNS lookup via local Bind.
    echo "search example.local
    nameserver 127.0.0.1" > /etc/resolv.conf
  12. Enable and start services.
    systemctl enable named
    systemctl start named
    
    systemctl enable cups
    systemctl start cups
    
    systemctl enable samba
    systemctl start samba
  13. Configure Active Directory.
    samba-tool domain passwordsettings set --complexity=off
    
    samba-tool domain passwordsettings set --min-pwd-length=1
    
    samba-tool user setexpiry administrator --noexpiry
  14. Verify Config.
    ping example.local
    
    wbinfo -g
    
    wbinfo -u
    
    yum -y install samba-client
    
    smbclient -L localhost -UAdministrator
    
    smbclient //localhost/netlogon -UAdministrator -c 'ls'

Users

  1. Configure Kerberos.
    sed -i "/\[libdefaults\]/ a\ default_realm = EXAMPLE.LOCAL" /etc/krb5.conf
    sed -i '/\[realms\]/ a\ EXAMPLE.LOCAL = {\n  kdc = dc.example.local\n  admin_server = dc.example.local\n}' /etc/krb5.conf
    sed -i '/\[domain_realm\]/ a\ .example.local = EXAMPLE.LOCAL\n example.local = EXAMPLE.LOCAL' /etc/krb5.conf
  2. Configure PAM.
    sed -i "/^passwd/s/$/ winbind/" /etc/nsswitch.conf
    sed -i "/^group/s/$/ winbind/" /etc/nsswitch.conf
    
    sed -i "/auth        required      pam_env.so/ a\auth        sufficient    pam_winbind.so try_first_pass" /etc/pam.d/system-auth-ac
    sed -i "/account     sufficient    pam_succeed_if.so/ a\account     \[default=bad success=ok user_unknown=ignore\] pam_winbind.so" /etc/pam.d/system-auth-ac
    sed -i "/password    sufficient    pam_unix.so/ a\password    sufficient    pam_winbind.so use_authtok" /etc/pam.d/system-auth-ac
    sed -i "/session     required      pam_unix.so/ a\session     optional      pam_winbind.so" /etc/pam.d/system-auth-ac
    
    sed -i "/auth        required      pam_env.so/ a\auth        sufficient    pam_winbind.so try_first_pass" /etc/pam.d/password-auth-ac
    sed -i "/account     sufficient    pam_succeed_if.so/ a\account     \[default=bad success=ok user_unknown=ignore\] pam_winbind.so" /etc/pam.d/password-auth-ac
    sed -i "/password    sufficient    pam_unix.so/ a\password    sufficient    pam_winbind.so use_authtok" /etc/pam.d/password-auth-ac
    sed -i "/session     required      pam_unix.so/ a\session     optional      pam_winbind.so" /etc/pam.d/password-auth-ac
  3. Verify Config.
    getent passwd administrator
  4. Configure mailbox home folders. (default hidden setting in smb.conf : template homedir = /home/%D/%U)

    mkdir /home/EXAMPLE
    chown dovecot /home/EXAMPLE
    chgrp "Domain Users" /home/EXAMPLE
    chmod 770 /home/EXAMPLE
  5. Enable SSH login for Active Directory users, e.g. roundcube mail ssh vacation plugin.
    yum -y install oddjob-mkhomedir
    
    authconfig --enablemkhomedir --update
    
    systemctl enable oddjobd
    systemctl start oddjobd
    
    sed -i '/dsdb:schema update allowed = true/ a\\ttemplate shell = /bin/bash' /etc/samba/smb.conf
  6. Active Directory user home folder, for Pc's joined to domain.
    echo "
    [users]
       comment = User Homes
       path = /data/users
       browseable = yes
       read only = no
       public = yes" >> /etc/samba/smb.conf
    
    mkdir /data
    cd /data
    mkdir users
    chmod 710 users
    chgrp "Domain Users" users
    
    systemctl restart samba
  7. Creating users.
    samba-tool user create john.doe 'Password1'
    samba-tool user setexpiry john.doe --noexpiry
    mkdir /data/users/john.doe
    chmod 700 /data/users/john.doe
    chown john.doe /data/users/john.doe
  8. Updating users. ( mail field required for auth via email and Global Address List lookups )
    yum -y install openldap-clients
    
    echo "dn: cn=john.doe,cn=Users,dc=example,dc=local
    changetype: modify
    add: mail
    mail: john.doe@example.com
    -
    add: givenName
    givenName: John
    -
    add: sn
    sn: Doe
    -
    add: displayName
    displayName: John Doe
    -
    add: HomeDirectory
    HomeDirectory: \\\\dc\\users\\john.doe
    -
    add: HomeDrive
    HomeDrive: Z:" > newuser.ldif
    
    ldapadd -f newuser.ldif -x -w "Password1" -D cn=Administrator,cn=Users,dc=example,dc=local
  9. Delete User
    samba-tool user delete john.doe
    rm -rf /home/EXAMPLE/john.doe
    rm -rf /data/users/john.doe
    sogo-tool remove john.doe

Sendmail MTA

  1. Install.
    yum -y remove postfix
    yum -y install sendmail sendmail-cf
  2. Set Internet Hostname.
    hostname mail.example.com
    echo mail.example.com > /etc/hostname
    sed -i "/^127.0.0.1/s/ localhost / mail.example.com mail localhost /g" /etc/hosts
  3. Accept connections on port 25 and locaclly deliver for internet domain : example.com
    sed -i "s/^DAEMON_OPTIONS(\`Port=smtp,Addr=127.0.0.1.*$/DAEMON_OPTIONS(\`Port=smtp, Name=MTA\')dnl/" /etc/mail/sendmail.mc
    echo example.com >> /etc/mail/local-host-names
  4. If you use a relay server to deliver outgoing email, eg. smtp.example.com
    sed -i '/SMART_HOST/s/dnl define/define/g' /etc/mail/sendmail.mc
    sed -i "s/^define(\`SMART_HOST.*$/define(\`SMART_HOST\', \`smtp.example.com\')dnl/" /etc/mail/sendmail.mc
  5. Config Maildir instead of Mailbox, improved I/O, etc ..
    echo "DEFAULT=\"\$HOME/mail/\"
    MAILDIR=\"\$HOME/mail/\"
    ORGMAIL=\"\$HOME/mail/\"
    #LOGFILE=\"/var/log/procmail.log\"" > /etc/procmailrc
    sed -i "s/^MAIL_DIR.*$/MAIL_DIR\tmail/" /etc/login.defs
    sed -i 's/MAIL="\/var\/spool\/mail\/$USER"/MAIL="$HOME\/mail"/' /etc/profile
    sed -i "s/^CREATE_MAIL_SPOOL=.*$/CREATE_MAIL_SPOOL=no/" /etc/default/useradd
  6. Enable and start Services.
    systemctl enable sendmail
    systemctl start sendmail

Dovecot

  1. Install.
    yum -y install dovecot
  2. Basic config.
    sed -i "s/^#listen =.*$/listen = \*/" /etc/dovecot/dovecot.conf
    sed -i "s/^#mail_plugins =.*$/mail_plugins = mail_log notify/" /etc/dovecot/conf.d/10-mail.conf
    sed -i "s/^#mail_privileged_group =.*$/mail_privileged_group = mail/" /etc/dovecot/conf.d/10-mail.conf
    sed -i "s/^#disable_plaintext_auth =.*$/disable_plaintext_auth = no/" /etc/dovecot/conf.d/10-auth.conf
    sed -i "s/^ssl =.*$/ssl = yes/" /etc/dovecot/conf.d/10-ssl.conf
  3. Maildir Delivery
    sed -i "s/^#mail_location =.*$/mail_location = maildir:~\/mail/" /etc/dovecot/conf.d/10-mail.conf
  4. Auth via email account.
    sed -i "s/^#auth_username_format =.*$/auth_username_format = %n/" /etc/dovecot/conf.d/10-auth.conf
  5. Auto Folder Creation
    sed -i "s/mailbox Junk/mailbox \"Junk E-Mail\"/" /etc/dovecot/conf.d/15-mailboxes.conf
    sed -i "s/mailbox Trash/mailbox \"Deleted Items\"/" /etc/dovecot/conf.d/15-mailboxes.conf
    sed -i "s/mailbox \"Sent Messages\"/mailbox \"Sent Items\"/" /etc/dovecot/conf.d/15-mailboxes.conf
    sed -i "/mailbox Drafts/ a\    auto = subscribe" /etc/dovecot/conf.d/15-mailboxes.conf
    sed -i "/mailbox \"Junk E-Mail\"/ a\    auto = subscribe" /etc/dovecot/conf.d/15-mailboxes.conf
    sed -i "/mailbox \"Deleted Items\"/ a\    auto = subscribe" /etc/dovecot/conf.d/15-mailboxes.conf
    sed -i "/mailbox \"Sent Items\"/ a\    auto = subscribe" /etc/dovecot/conf.d/15-mailboxes.conf
  6. Using Maildir, Mailbox's are almost always bigger than 2G, need to make Outlook sync.
    sed -i "s/#imap_max_line_length = 64k/imap_max_line_length = 4M/" /etc/dovecot/conf.d/20-imap.conf
  7. Enable and start Services.
    systemctl enable dovecot
    systemctl start dovecot

Apache Web Server

  1. Install
    yum -y install httpd mod_ssl php
  2. Basic Config.
    echo "<VirtualHost _default_:80>
        DocumentRoot /var/www/html
    </VirtualHost>" > /etc/httpd/conf.d/00-default.conf
  3. Redirect default Apache home to HTTPS Sogo.
    echo '<?php
    $Hostname = gethostname();
    header("Location: https://$Hostname/SOGo");
    ?>' > /var/www/html/index.php
  4. Create Auto Discover folder.
    mkdir -p /var/www/autodiscover/autodiscover
  5. Create Auto Discover PHP file /var/www/autodiscover/autodiscover/autodiscover.php

    <?php
    /*
     Open Source Autodiscover implementation in PHP.
     
     Version: 1.0
     
     Allows auto configuration of ActiveSync and Outlook (or any other MUA that has
     autodiscover support).
     
    */
    
    $Hostname = gethostname();
     
    /*** Begin Configuration ***/
    // ActiveSync URL.
    $_CONFIG['MobileSync']['Url'] = "https://$Hostname/Microsoft-Server-ActiveSync";
     
    // For other supported protocols and more protocol settings, see:
    //  http://technet.microsoft.com/en-us/library/cc511507.aspx
     
    // Get contents of request made to Autodiscover.
    $request = file_get_contents("php://input");
     
    // XML document heading.
    header("Content-Type: text/xml");
    echo "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
    
    // Get the schema from the request.
    preg_match("/\<AcceptableResponseSchema\>(.*?)\<\/AcceptableResponseSchema\>/", $request, $schema);
    // Determine the type of device requesting Autodiscover.
    if (preg_match("/\/mobilesync\//", $schema[1]))
    {
            // Mobile device.
            preg_match("/\<EMailAddress\>(.*?)\<\/EMailAddress\>/", $request, $email_address);
    ?>
                    <Autodiscover xmlns="http://schemas.microsoft.com/exchange/autodiscover/responseschema/2006">
                            <Response xmlns="<?php echo $schema[1]; ?>">
                                    <Culture>en:en</Culture>
                                    <User>
                                            <DisplayName><?php echo $email_address[1]; ?></DisplayName>
                                            <EMailAddress><?php echo $email_address[1]; ?></EMailAddress>
                                    </User>
                                    <Action>
                                            <Settings>
                                                    <Server>
                                                            <Type>MobileSync</Type>
                                                            <Url><?php echo $_CONFIG['MobileSync']['Url']; ?></Url>
                                                            <Name><?php echo $_CONFIG['MobileSync']['Url']; ?></Name>
                                                    </Server>
                                            </Settings>
                                    </Action>
                            </Response>
                    </Autodiscover>
            <?php
    }
    else if (preg_match("/\/outlook\//", $schema[1]))
    {
            // MUA (mail client).
            ?>
                    <Autodiscover xmlns="http://schemas.microsoft.com/exchange/autodiscover/responseschema/2006">
                            <Response xmlns="<?php echo $schema[1]; ?>">
                                    <Account>
                                            <AccountType>email</AccountType>
                                            <Action>settings</Action>
                                    <?php
                                            // Loop through each configured protocol.
                                            while(list($protocol, $settings) = each($_CONFIG))
                                            {
                                                    // Skip ActiveSync protocol.
                                                    //if ($protocol == "MobileSync") continue;
                                            ?>
                                                    <Protocol>
                                                            <Type><?php echo $protocol; ?></Type>
                                            <?php
                                                    // Loop through each setting for this protocol.
                                                    while(list($setting, $value) = each($settings))
                                                    {
                                                            echo "\t\t\t\t\t\t\t<$setting>$value</$setting>\n";
                                                    }
                                            ?>
                                                    </Protocol>
                                            <?php
                                            }
                                    ?>
                                    </Account>
                            </Response>
                    </Autodiscover>
            <?php
    }
    else
    {
            // Unknown.
            list($usec, $sec) = explode(' ', microtime());
            ?>
                    <Autodiscover xmlns="http://schemas.microsoft.com/exchange/autodiscover/responseschema/2006">
                            <Response>
                                    <Error Time="<?php echo date('H:i:s', $sec) . substr($usec, 0, strlen($usec) - 2); ?>" Id="2477272013">
                                            <ErrorCode>600</ErrorCode>
                                            <Message>Invalid Request</Message>
                                            <DebugData />
                                    </Error>
                            </Response>
                    </Autodiscover>
            <?php
    }
    ?>
  6. Virtual Host.
    echo "Alias /autodiscover/autodiscover.xml /var/www/autodiscover/autodiscover/autodiscover.php
    <Directory /var/www/autodiscover>
        Options Indexes FollowSymLinks
        AllowOverride None
        Require all granted
    </Directory>
    <VirtualHost *:443>
        SSLEngine on
        SSLCertificateFile /etc/pki/tls/certs/mail.example.com.crt
        SSLCertificateKeyFile /etc/pki/tls/private/mail.example.com.key
        DocumentRoot /var/www/autodiscover
        ServerName autodiscover.example.com
    
        RewriteEngine On
        RewriteMap lc int:tolower
        RewriteCond %{REQUEST_URI} [A-Z]
        RewriteRule (.*) \${lc:\$1} [R=301,L]
    
        ErrorLog logs/autodiscover_error_log
        CustomLog logs/autodiscover_access_log common
    </VirtualHost>" > /etc/httpd/conf.d/autodiscover.conf
  7. Certbot for SSL.
    yum -y install certbot mod_ssl
  8. Create Certificate, Ensure Ports 80 and 443 are reachable on this host from the Internet on the DNS hostnames.
    systemctl stop httpd
    
    certbot certonly --standalone -d mail.example.com -d autodiscover.example.com
  9. Link Certificate to Apache.
    ln -s /etc/letsencrypt/live/mail.example.com/cert.pem /etc/pki/tls/certs/mail.example.com.crt
    ln -s /etc/letsencrypt/live/mail.example.com/privkey.pem /etc/pki/tls/private/mail.example.com.key
    
    sed -i "s/localhost/mail.example.com/g" /etc/httpd/conf.d/ssl.conf
  10. Schedule Auto Renewal as Letsencrypt is only valid for 3 months.
    echo "# Letsencrypt automatic SSL certicate renewal
    SHELL=/bin/bash
    PATH=/sbin:/bin:/usr/sbin:/usr/bin
    MAILTO=
    HOME=/
    @daily root systemctl stop httpd;certbot renew --quiet;systemctl start httpd" > /etc/cron.d/letsencrypt
  11. Enable and start services.
    systemctl enable httpd
    systemctl start httpd

Sogo

  1. Install.
    yum -y install sogo sope49-gdl1-mysql sogo-tool sogo-activesync libwbxml memcached
  2. Configure Apache.
    sed -i "s/#ProxyPass \/Microsoft-Server-ActiveSync/ProxyPass \/Microsoft-Server-ActiveSync/" /etc/httpd/conf.d/SOGo.conf
    sed -i "s/# http:\/\/127.0.0.1:20000\/SOGo\/Microsoft-Server-ActiveSync/ http:\/\/127.0.0.1:20000\/SOGo\/Microsoft-Server-ActiveSync/" /etc/httpd/conf.d/SOGo.conf
    sed -i "s/# retry=60 connectiontimeout=5 timeout=360/ retry=60 connectiontimeout=5 timeout=3600/" /etc/httpd/conf.d/SOGo.conf
  3. Configure Sogo Daemon
    sed -i "s/# PREFORK=3/PREFORK=90/" /etc/sysconfig/sogo
  4. Prepare Database
    yum -y install mariadb-server
    
    sed -i "/\[mysqld\]/ a\innodb_large_prefix = TRUE" /etc/my.cnf.d/server.cnf
    sed -i "/\[mysqld\]/ a\innodb_file_format = barracuda" /etc/my.cnf.d/server.cnf
    sed -i "/\[mysqld\]/ a\innodb_file_per_table = TRUE" /etc/my.cnf.d/server.cnf
    sed -i "/\[mysqld\]/ a\collation-server = utf8mb4_unicode_ci" /etc/my.cnf.d/server.cnf
    sed -i "/\[mysqld\]/ a\character-set-server = utf8mb4" /etc/my.cnf.d/server.cnf
    sed -i "/\[mysqld\]/ a\character-set-client-handshake = FALSE" /etc/my.cnf.d/server.cnf
    sed -i "/\[mysqld\]/ a\max_allowed_packet=100M" /etc/my.cnf.d/server.cnf
    
    sed -i "/\[client\]/ a\default-character-set = utf8mb4" /etc/my.cnf.d/client.cnf
    
    sed -i "/\[mysql\]/ a\default-character-set = utf8mb4" /etc/my.cnf.d/mysql-clients.cnf
    
    systemctl enable mariadb
    systemctl start mariadb
    
    echo 'CREATE DATABASE sogo /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;' > mysql.createdb.sql
    echo "GRANT ALL PRIVILEGES ON sogo.* TO sogo@localhost IDENTIFIED BY 'sogo';" >> mysql.createdb.sql
    
    mysql < mysql.createdb.sql
    
    rm -rf mysql.createdb.sql
  5. Configure /etc/sogo/sogo.conf

    {
    
     MySQL4Encoding = "utf8mb4";
    
      SOGoProfileURL = "mysql://sogo:sogo@127.0.0.1:3306/sogo/sogo_user_profile";
      OCSFolderInfoURL = "mysql://sogo:sogo@127.0.0.1:3306/sogo/sogo_folder_info";
      OCSSessionsFolderURL = "mysql://sogo:sogo@127.0.0.1:3306/sogo/sogo_sessions_folder";
    
      SOGoLanguage = English;
      SOGoTimeZone = Africa/Johannesburg;
      SOGoMailDomain = example.com;
      SOGoIMAPServer = 127.0.0.1;
      SOGoDraftsFolderName = "Drafts";
      SOGoSentFolderName = "Sent Items";
      SOGoTrashFolderName = "Deleted Items";
      SOGoJunkFolderName = "Junk E-Mail";
      SOGoMailingMechanism = smtp;
      SOGoSMTPServer = 127.0.0.1;
    
      SOGoSuperUsernames = (support);
      SOGoPageTitle = SOGo;
      SOGoVacationEnabled = YES;
      SOGoForwardEnabled = YES;
      SOGoSieveScriptsEnabled = YES;
      SOGoSieveServer = sieve://127.0.0.1:4190;
    
      WOWorkersCount = 90;
      WOWatchDogRequestTimeout = 60;
      SOGoMaximumPingInterval = 3540;
      SOGoMaximumSyncInterval = 3540;
      SOGoInternalSyncInterval = 60;
    
      SOGoMaximumSyncResponseSize = 2048;
      SOGoMaximumSyncWindowSize = 32;
    
      SxVMemLimit = 512;
     
    SOGoUserSources = (
     {
            type = ldap;
            CNFieldName = displayName;
            IDFieldName = cn;
            UIDFieldName = sAMAccountName;
            baseDN = "cn=Users,dc=example,dc=local";
            bindDN = "cn=Administrator,cn=Users,dc=example,dc=local";
            bindFields = (sAMAccountName, mail);
            bindPassword = "Password1";
            canAuthenticate = YES;
            displayName = "Shared Addresses";
            hostname = "localhost";
            id = public;
            isAddressBook = YES;
            port = 389;
    }
    );
    
    }
  6. Session cleanup.
    sed -i "/expire-sessions/s/^#//" /etc/cron.d/sogo
  7. Enable and start services.
    systemctl enable memcached
    systemctl start memcached
    systemctl enable sogod
    systemctl start sogod
  8. Monitoring
    tail -f /var/log/sogo/sogo.log
    
    sogo-tool manage-eas listdevices john.doe
    
    sogo-tool manage-eas resetdevice john.doe D403113BAAB54B9B9DB34B643EC9BD76
    
    sogo-tool manage-eas listfolders john.doe D403113BAAB54B9B9DB34B643EC9BD76
    
    sogo-tool manage-eas resetfolder john.doe 139804EBDF92456789DF25B3818FC274+foldera82bec1250479155c5750000c0f2a9f1
  9. Autoreply - Out of Office
    yum -y install dovecot-pigeonhole
    
    sed -i 's/#protocols = $protocols sieve/protocols = $protocols sieve/' /etc/dovecot/conf.d/20-managesieve.conf
    
    sed -i "s/#lda_mailbox_autocreate = no/lda_mailbox_autocreate = yes/" /etc/dovecot/conf.d/15-lda.conf
    sed -i "s/#lda_mailbox_autosubscribe = no/lda_mailbox_autosubscribe = yes/" /etc/dovecot/conf.d/15-lda.conf
    
    sed -i "/^MAILER(procmail)/ i\FEATURE(\`local_procmail', \`\/usr\/libexec\/dovecot\/dovecot-lda',\`\/usr\/libexec\/dovecot\/dovecot-lda -d \$u')" /etc/mail/sendmail.mc
    sed -i "/^MAILER(procmail)/ i\MODIFY_MAILER_FLAGS(\`LOCAL', \`-f')" /etc/mail/sendmail.mc
    
    echo "define(\`confDONT_BLAME_SENDMAIL',\`forwardfileingroupwritabledirpath')" >> /etc/mail/sendmail.mc
    
    sed -i "/update-autoreply/s/^#//" /etc/cron.d/sogo
  10. Dovecot as LDA doesnt like root
    useradd -g 100 support
    echo Password1 | passwd --stdin support
    echo -e "root:\t\tsupport" >> /etc/aliases
    
    newaliases

Fail2ban

  1. Install.
    yum -y install fail2ban whois
  2. Configure.
    echo '[DEFAULT]
    
    ignoreip = 127.0.0.1/8 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16
    bantime  = 172800
    findtime = 3600
    maxretry = 3
    
    [sogo-auth]
    
    enabled = true
    filter  = sogo-auth
    action  = iptables-multiport[name=sogo-auth, port="https", protocol=tcp]
    logpath = /var/log/sogo/sogo.log' > /etc/fail2ban/jail.local
  3. Enable and start services.
    systemctl enable fail2ban
    systemctl start fail2ban

Other

  1. Found the following helps if system hangs.
    sysctl -w kernel.sem="250 256000 32 1024"
    sysctl --system
    
    echo "kernel.sem = 250 256000 32 1024" > /usr/lib/sysctl.d/30-sogo.conf
  2. You might want to disable SElinux.
    setenforce 0
    sed -i "s/SELINUX=enforcing/SELINUX=disabled/g" /etc/selinux/config
  3. Configure the default local firewall to allow connections or stop for fault finding.
    systemctl stop firewalld
  4. Manage Samba from Windows PC joined to domain with Remote Server Administration Tools :

    https://www.microsoft.com/en-za/download/details.aspx?id=45520

  5. Fix sysvol rights.
    samba-tool ntacl sysvolreset
  6. Allow NT File Rights edit from MMC.
    net rpc rights grant "EXAMPLE\administrator" SeDiskOperatorPrivilege -U "EXAMPLE\administrator"
    
    net rpc rights list privileges SeDiskOperatorPrivilege -U "EXAMPLE\administrator"
  7. Outlook Autodiscover Quirks.

Outlooks Setup Wizard will not prompt for password when setting up an email account if the PC is joined to the Samba domain.

"Your Name" will be obtained from the "Display Name" field in Active directory and the "E-Mail Address" will be obtained form the "mail" field in Active Directory.

Workaround : When adding an email account, in the "Auto Account Setup" wizard, edit the "E-Mail Address" field and change a character, the password prompt will now be available for you to supply the password.

InstallationConfigurationCentos (last edited 2018-09-19 02:44:57 by john.cameron)