Differences between revisions 71 and 72
Revision 71 as of 2020-09-23 05:07:42
Size: 30909
Editor: john.cameron
Comment:
Revision 72 as of 2020-12-09 07:25:36
Size: 31029
Editor: john.cameron
Comment:
Deletions are marked like this. Additions are marked like this.
Line 814: Line 814:
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 = 128M" /etc/my.cnf.d/server.cnf
sed -i "/\[mysqld\]/ a\max_connections = 256" /etc/my.cnf.d/server.cnf
sed -i "/\[mysqld\]/ a\collation-server = utf8mb4_unicode_ci" /etc/my.cnf.d/mysql-server.cnf
sed -i "/\[mysqld\]/ a\character-set-server = utf8mb4" /etc/my.cnf.d/mysql-server.cnf
sed -i "/\[mysqld\]/ a\character-set-client-handshake = FALSE" /etc/my.cnf.d/mysql-server.cnf
sed -i "/\[mysqld\]/ a\max_allowed_packet = 128M" /etc/my.cnf.d/mysql-server.cnf
sed -i "/\[mysqld\]/ a\max_connections = 256" /etc/my.cnf.d/mysql-server.cnf
sed -i "/\[mysqld\]/ a\binlog_expire_logs_seconds=604800" /etc/my.cnf.d/mysql-server.cnf

Installation and configuration - CentOS 8.2

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/2019 clients connect natively on desktop devices.

Apple and Android clients connect natively on mobile devices.

Notes

New CentOS 8.2 installation with package selection "Minimal Install".

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

Dnf Repositories

  1. Configure DNF
    sed -i "s/^enabled=.*$/enabled=1/" /etc/yum.repos.d/CentOS-AppStream.repo
    sed -i "s/^enabled=.*$/enabled=1/" /etc/yum.repos.d/CentOS-Extras.repo
    sed -i "s/^enabled=.*$/enabled=1/" /etc/yum.repos.d/CentOS-PowerTools.repo
    
    sed -i "s/^gpgcheck=.*$/gpgcheck=0/" /etc/yum.conf
    sed -i "s/^gpgcheck=.*$/gpgcheck=0/" /etc/dnf/dnf.conf
  2. Configure Sogo Repo.
    echo "[sogo]
    name=Inverse SOGo Repository
    baseurl=https://packages.inverse.ca/SOGo/nightly/5/rhel/8/x86_64
    gpgcheck=0
    enabled=1" > /etc/yum.repos.d/sogo.repo
  3. Configure EPEL Repo.
    dnf -y install epel-release
  4. Configure Custom Repo.
    dnf -y install createrepo
    
    mkdir -p /tmp/repo
    cd /tmp/repo
    createrepo ./
    
    echo "[Custom]
    name=CentOS-\$releasever - Custom
    baseurl=file:/tmp/repo/
    enabled=1
    gpgckeck=0" > /etc/yum.repos.d/CentOS-Custom.repo
  5. Prevent rebuilt Samba from being replaced.
    sed -i "/\[BaseOS\]/ 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.
    dnf -y group install "Development Tools"
    
    rm -rf /root/rpmbuild
  2. Rebuild Openssl and add to custom Repo.
    dnf -y install lksctp-tools-devel perl-Module-Load-Conditional perl-Test-Simple perl-Math-BigInt perl-Test-Harness perl-Time-HiRes zlib-devel
    
    rpmbuild --rebuild https://dl.fedoraproject.org/pub/fedora/linux/development/rawhide/Everything/source/tree/Packages/o/openssl-1.1.1g-15.fc33.src.rpm
    
    cp /root/rpmbuild/RPMS/x86_64/* /tmp/repo
    cd /tmp/repo
    createrepo ./
    
    rm -rf /root/rpmbuild
    dnf clean all
  3. Rebuild E2fsprogs and add to custom Repo.
    dnf -y install fuse-devel libblkid-devel multilib-rpm-config texinfo libselinux-devel libsepol-devel
    
    rpmbuild --rebuild https://dl.fedoraproject.org/pub/fedora/linux/development/rawhide/Everything/source/tree/Packages/e/e2fsprogs-1.45.6-4.fc33.src.rpm
    
    cp /root/rpmbuild/RPMS/x86_64/* /tmp/repo
    cd /tmp/repo
    createrepo ./
    
    rm -rf /root/rpmbuild
    dnf clean all
  4. Rebuild Python-pyrad and add to custom Repo.
    dnf -y install python3-netaddr python3-nose python3-devel python3-sphinx
    rpmbuild --rebuild https://dl.fedoraproject.org/pub/fedora/linux/development/rawhide/Everything/source/tree/Packages/p/python-pyrad-2.1-7.fc33.src.rpm
    
    cp /root/rpmbuild/RPMS/noarch/* /tmp/repo
    cd /tmp/repo
    createrepo ./
    
    rm -rf /root/rpmbuild
    dnf clean all
  5. Rebuild Libtalloc and add to custom Repo.
    dnf -y install doxygen
    
    rpmbuild --rebuild https://dl.fedoraproject.org/pub/fedora/linux/development/rawhide/Everything/source/tree/Packages/l/libtalloc-2.3.1-5.fc33.src.rpm
    
    cp /root/rpmbuild/RPMS/x86_64/* /tmp/repo
    cd /tmp/repo
    createrepo ./
    
    rm -rf /root/rpmbuild
    dnf clean all
  6. Rebuild Libtdb and add to custom Repo.
    rpmbuild --rebuild https://dl.fedoraproject.org/pub/fedora/linux/development/rawhide/Everything/source/tree/Packages/l/libtdb-1.4.3-5.fc33.src.rpm
    
    cp /root/rpmbuild/RPMS/x86_64/* /tmp/repo
    cd /tmp/repo
    createrepo ./
    
    rm -rf /root/rpmbuild
    dnf clean all
  7. Rebuild Libtevent and add to custom Repo.
    dnf -y install libtalloc-devel python3-talloc-devel
    
    rpmbuild --rebuild https://dl.fedoraproject.org/pub/fedora/linux/development/rawhide/Everything/source/tree/Packages/l/libtevent-0.10.2-5.fc33.src.rpm
    
    cp /root/rpmbuild/RPMS/x86_64/* /tmp/repo
    cd /tmp/repo
    createrepo ./
    
    rm -rf /root/rpmbuild
    dnf clean all
  8. Rebuild Quota and add to custom Repo.
    dnf -y install libnl3-devel dbus-devel e2fsprogs-devel openldap-devel libtirpc-devel rpcgen
    
    rpmbuild --rebuild https://dl.fedoraproject.org/pub/fedora/linux/development/rawhide/Everything/source/tree/Packages/q/quota-4.05-16.fc34.src.rpm
    
    cp /root/rpmbuild/RPMS/x86_64/* /tmp/repo
    cd /tmp/repo
    createrepo ./
    
    rm -rf /root/rpmbuild
    dnf clean all
  9. Rebuild Krb5 and add to custom Repo.
    dnf -y install cmake dejagnu keyutils libedit-devel libss-devel lmdb-devel net-tools openssl-devel rpcbind tcl-devel \
     python3-sphinx python3-pyrad keyutils-libs-devel libverto-devel libverto-module-base pam-devel
    
    rpmbuild --rebuild https://dl.fedoraproject.org/pub/fedora/linux/updates/32/Everything/SRPMS/Packages/k/krb5-1.18.2-22.fc32.src.rpm
    
    cp /root/rpmbuild/RPMS/x86_64/* /tmp/repo
    cd /tmp/repo
    createrepo ./
    
    rm -rf /root/rpmbuild
    dnf clean all
  10. Rebuild Libldb and add to custom Repo.
    dnf -y install libtdb-devel libtevent-devel popt-devel libcmocka-devel python3-tdb python3-tevent
    
    rpmbuild --rebuild https://dl.fedoraproject.org/pub/fedora/linux/development/rawhide/Everything/source/tree/Packages/l/libldb-2.2.0-4.fc33.src.rpm
    
    cp /root/rpmbuild/RPMS/x86_64/* /tmp/repo
    cd /tmp/repo
    createrepo ./
    
    rm -rf /root/rpmbuild
    dnf clean all
  11. Rebuild Liburing and add to custom Repo.
    rpmbuild --rebuild https://dl.fedoraproject.org/pub/fedora/linux/releases/32/Everything/source/tree/Packages/l/liburing-0.5-1.fc32.src.rpm
    
    cp /root/rpmbuild/RPMS/x86_64/* /tmp/repo
    cd /tmp/repo
    createrepo ./
    
    rm -rf /root/rpmbuild
    dnf clean all
  12. Rebuild Samba to include Active Directory and add to custom Repo.
    dnf -y install avahi-devel bind cups-devel glusterfs-api-devel gpgme-devel \
     jansson-devel ldb-tools libacl-devel libuuid-devel lmdb ncurses-devel \
     pam-devel perl-Parse-Yapp tdb-tools xfsprogs-devel readline-devel \
     systemd-devel libarchive-devel libldb-devel libnsl2-devel libtasn1-tools perl-Archive-Tar \
     perl-ExtUtils-MakeMaker python3-devel python3-iso8601 python3-markdown rpcsvc-proto-devel krb5-devel \
     krb5-server python3-ldb-devel quota-devel libaio-devel libcap-devel libicu-devel
    
    rpm -Uvh https://dl.fedoraproject.org/pub/fedora/linux/updates/32/Everything/SRPMS/Packages/s/samba-4.12.6-0.fc32.src.rpm
    
    cd /root/rpmbuild/SPECS
    
    sed -i "s/%global with_dc 0/%global with_dc 1/g" samba.spec
    sed -i "s/%global with_winexe 1/%global with_winexe 0/g" 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
    dnf clean all

Samba Active Directory

  1. Install Samba.
    dnf -y install samba-dc tdb-tools samba-winbind-clients cups bind bind-utils samba-dc-bind-dlz
    dnf -y remove bind-chroot
  2. Ensure no stale config.
    rm -rf /etc/samba/smb.conf
    rm -rf /etc/krb5.conf
    rm -rf /var/lib/samba/private/*
    rm -rf /var/lib/samba/sysvol/*
    rm -rf /var/lib/samba/bind-dns/*
  3. Hostname must be as in Active Directory before provision.
    hostname dc.example.local
  4. 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"
  5. Configure Kerberos.
    cp /var/lib/samba/private/krb5.conf /etc
  6. If you are migrating from an older Samba that used Heimdal Kerberos create MIT Kerberos KDC file /var/lib/samba/private/kdc.conf

    [kdcdefaults]
           kdc_ports = 88
           kdc_tcp_ports = 88
           kadmind_port = 464
    
    [realms]
           EXAMPLE.LOCAL = {
           }
    
           example.local = {
           }
    
           EXAMPLE = {
            }
    
    [dbmodules]
           db_module_dir = /usr/lib64/krb5/plugins/kdb
    
           EXAMPLE.LOCAL = {
                   db_library = samba
           }
    
           example.local = {
                   db_library = samba
           }
    
           EXAMPLE = {
                   db_library = samba
           }
    
    [logging]
           kdc = FILE:/var/log/samba/mit_kdc.log
           admin_server = FILE:/var/log/samba/mit_kadmin.log
  7. Change home folder path. (new default hidden setting in smb.conf : template homedir = /home/%D@%U)

    sed -i '/workgroup =/ a\\ttemplate homedir = /home/%D/%U' /etc/samba/smb.conf
  8. Dynamic DNS updates for PC's joined to domain.
    sed -i '/template homedir =/ a\\tdsdb:schema update allowed = true' /etc/samba/smb.conf
  9. Sogo by default uses LDAP not LDAPS.
    sed -i '/template homedir =/ a\\tldap server require strong auth = no' /etc/samba/smb.conf
  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/bind-dns/dns.keytab";' /etc/named.conf
    sed -i '/allow-query/ a\\tallow-transfer { any; };' /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\/bind-dns\/named.conf\";" /etc/named.conf
    
    sed -i '/zone "." IN {/,+4d' /etc/named.conf
  11. If you are upgrading from an older Samba that provisioned Bind DLZ in : /var/lib/samba/private
    mkdir -p /var/lib/samba/bind-dns/dns
    
    samba_upgradedns --dns-backend=BIND9_DLZ
    
    sed -i "s/samba\/private/samba\/bind-dns/g" /etc/named.conf
  12. Configure system DNS lookup via local Bind.
    echo "search example.local
    nameserver 127.0.0.1" > /etc/resolv.conf
  13. Enable and start services.
    systemctl enable named --now
    
    systemctl enable cups --now
    
    systemctl enable samba --now
  14. Configure Active Directory.
    samba-tool user setexpiry administrator --noexpiry
  15. Verify Config.
    ping example.local
    
    wbinfo -g
    
    wbinfo -u
    
    dnf -y install samba-client
    
    smbclient -L localhost -UAdministrator
    
    smbclient //localhost/netlogon -UAdministrator -c 'ls'

Users

  1. 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
    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
    sed -i "/password    sufficient    pam_unix.so/ a\password    sufficient    pam_winbind.so use_authtok" /etc/pam.d/system-auth
    sed -i "/session     required      pam_unix.so/ a\session     optional      pam_winbind.so" /etc/pam.d/system-auth
    
    sed -i "/auth        required      pam_env.so/ a\auth        sufficient    pam_winbind.so try_first_pass" /etc/pam.d/password-auth
    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
    sed -i "/password    sufficient    pam_unix.so/ a\password    sufficient    pam_winbind.so use_authtok" /etc/pam.d/password-auth
    sed -i "/session     required      pam_unix.so/ a\session     optional      pam_winbind.so" /etc/pam.d/password-auth
  2. Verify Config.
    getent passwd administrator
  3. Configure mailbox home folders.
    mkdir /home/EXAMPLE
    chown dovecot /home/EXAMPLE
    chgrp "Domain Users" /home/EXAMPLE
    chmod 770 /home/EXAMPLE
  4. Enable SSH login for Active Directory users, e.g. roundcube mail ssh vacation plugin.
    dnf -y install oddjob-mkhomedir
    
    sed -i "/-session     optional      pam_systemd.so/ a\session     optional      pam_oddjob_mkhomedir.so umask=0077" /etc/pam.d/password-auth-ac
    sed -i "/-session     optional      pam_systemd.so/ a\session     optional      pam_oddjob_mkhomedir.so umask=0077" /etc/pam.d/system-auth-ac
    
    systemctl enable oddjobd --now
    
    sed -i '/dsdb:schema update allowed = true/ a\\ttemplate shell = /bin/bash' /etc/samba/smb.conf
  5. 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
  6. 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
  7. Updating users. ( mail field required for auth via email and Global Address List lookups )
    dnf -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
  8. 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.
    dnf -y remove postfix
    dnf -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 --now

Dovecot

  1. Install.
    dnf -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
    sed -i "s/^#default_process_limit =.*$/default_process_limit = 1024/" /etc/dovecot/conf.d/10-master.conf
    sed -i "s/^#default_client_limit =.*$/default_client_limit = 5120/" /etc/dovecot/conf.d/10-master.conf
  7. Enable and start Services.
    systemctl enable dovecot --now

Apache Web Server

  1. Install
    dnf -y install httpd mod_ssl php php-fpm
  2. Basic Config.
    echo "<VirtualHost _default_:80>
        DocumentRoot /var/www/html
    </VirtualHost>" > /etc/httpd/conf.d/00-default.conf
    
    sed -i "s/^listen.acl_users = .*$/listen.acl_users = apache/" /etc/php-fpm.d/www.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.
    dnf -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 --now
    systemctl enable php-fpm --now

Sogo

  1. Install.
    dnf -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
    dnf -y install mysql-server
    
    sed -i "/\[mysqld\]/ a\collation-server = utf8mb4_unicode_ci" /etc/my.cnf.d/mysql-server.cnf
    sed -i "/\[mysqld\]/ a\character-set-server = utf8mb4" /etc/my.cnf.d/mysql-server.cnf
    sed -i "/\[mysqld\]/ a\character-set-client-handshake = FALSE" /etc/my.cnf.d/mysql-server.cnf
    sed -i "/\[mysqld\]/ a\max_allowed_packet = 128M" /etc/my.cnf.d/mysql-server.cnf
    sed -i "/\[mysqld\]/ a\max_connections = 256" /etc/my.cnf.d/mysql-server.cnf
    sed -i "/\[mysqld\]/ a\binlog_expire_logs_seconds=604800" /etc/my.cnf.d/mysql-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 mysqld --now
    
    echo 'CREATE DATABASE sogo /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;' > mysql.createdb.sql
    echo "CREATE USER 'sogo' IDENTIFIED BY 'sogo';" >> mysql.createdb.sql
    echo "GRANT ALL PRIVILEGES ON sogo.* TO 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 = imap://127.0.0.1:143;
      SOGoDraftsFolderName = "Drafts";
      SOGoSentFolderName = "Sent Items";
      SOGoTrashFolderName = "Deleted Items";
      SOGoJunkFolderName = "Junk E-Mail";
      SOGoMailingMechanism = smtp;
      SOGoSMTPServer = smtp://127.0.0.1:25;
    
      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 = 4096;
    
      SxVMemLimit = 512;
    
      NGMimeBuildMimeTempDirectory = "/var/tmp";
     
    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 = "dc.example.local";
            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 --now
    systemctl enable sogod --now
  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
    dnf -y install dovecot-pigeonhole
    
    sed -i 's/#mail_temp_dir = .*$/mail_temp_dir = \/var\/tmp/' /etc/dovecot/conf.d/10-mail.conf
    
    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.
    dnf -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 --now

Other

  1. You might want to disable SElinux.
    setenforce 0
    sed -i "s/SELINUX=enforcing/SELINUX=disabled/g" /etc/selinux/config
  2. Configure the default local firewall to allow connections or stop for fault finding.
    systemctl stop firewalld
  3. Manage Samba from Windows 10 PC joined to domain with Remote Server Administration Tools :
    Start / Settings / Apps / Optional Features / RSAT - Active Directory Domain Services
  4. Fix sysvol rights.
    samba-tool ntacl sysvolreset
  5. Upgrade Schema.
    dnf install python3-markdown patch
    
    samba-tool domain schemaupgrade
    samba-tool domain functionalprep --function-level=2012_R2
  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.
    
    
    Newer Outlook will try and find mailbox at 365 or where root website is hosted.
    Create a .reg file and import the following settings to avoid this :
    
    Windows Registry Editor Version 5.00
    
    [HKEY_CURRENT_USER\Software\Policies\Microsoft\Office\16.0\Outlook\AutoDiscover]
    "ExcludeExplicitO365Endpoint"=dword:00000001
    "ExcludeHttpsRootDomain"=dword:00000001
    [HKEY_CURRENT_USER\Software\Policies\Microsoft\Office\16.0\Outlook\setup]
    "DisableOffice365SimplifiedAccountCreation"=dword:00000001

InstallationConfigurationCentos (last edited 2020-12-09 07:25:36 by john.cameron)