Vollständige Synchronisation von gemeinsamen Ordnern, Kontakten und Kalendern zwischen verteilten Kerio Connect-Servern

Guten Tag, Habr!

Ziel

In meiner Organisation nutzen wir einen Mailserver auf der Kerio Connect-Plattform. In verschiedenen Städten sind Mailserver installiert, die ihre Benutzer betreuen. Eine verteilte Struktur gab es ursprünglich nicht, da die Domänen auf dritter Ebene mit der Angabe der Stadt des Standorts unterschiedlich waren. Alles funktionierte einwandfrei und alle waren zufrieden. An einem schönen Tag stellte die Geschäftsführung die Aufgabe: einen gemeinsamen Geschäftskalender für alle Standorte!

Hintergrund

Die ursprüngliche Idee war, eine verteilte Mail-Domäne für Kerio einzurichten und dass er die Synchronisation selbst übernimmt. Gesagt, getan – die verteilte Domäne wurde erstellt, aber damit war es nicht getan. Der Server war bereit, Kalender, Ordner, Kontakte zwischen Domänen auf demselben Server zu synchronisieren, aber war überhaupt nicht bereit, Daten zwischen mehreren Servern zu synchronisieren.

Mit einem solchen Betrug hatte ich natürlich nicht gerechnet und konnte lange nicht glauben, dass die benötigte Funktionalität fehlte. Später fand ich dokumentarische Beweise für diese Tatsache, was mich sehr verwirrte und enttäuschte.

Die Aufgabe entwickelte sich schnell zu einem Problem.

Welche Optionen gab es?

  • Zwei Kunden auf verschiedenen Servern zu erstellen, die mit einer bestimmten externen Software notwendige Daten austauschten. Ich musste diese externe Software finden, die diese Funktionalität umsetzt – ich mag solche Umwege nicht, aber es schien die einzige schnelle Lösung zu sein.
  • Ein eigenes Skript zur Daten-Synchronisation zwischen den Servern zu schreiben. Das Problem ist, dass Kerio jedes Objekt als separate Datei speichert, sodass ein Skript für die Dateibearbeitung entwickelt werden musste. Aufgrund der Vielzahl an Quellen erschien die Aufgabe jedoch komplex, zumal zahlreiche Datenvalidierungen erforderlich waren; andernfalls könnte jemand gleichzeitig eine Aufgabe erstellen und so weiter.

Um es vorweg zu nehmen: Kerio speichert zwar Objekte als separate Dateien, ist jedoch nicht so dumm, bei jedem Zugriff auf ein Objekt nachzufragen – wie steht es um die Dateisysteme.

Nachdem ich viel Zeit mit Überlegungen verbracht und zahlreiche Pläne zur "Eroberung feindlichen Territoriums" skizziert hatte, traf ich um 6 Uhr zwei richtige Entscheidungen:

  • Die erste Lösung besteht darin, selbst zu machen und nichts anderes zu suchen.
  • Die zweite Lösung ist, schlafen zu gehen.

Am Morgen bin ich mit einem einzigen und klaren Gedanken aufgewacht, der sich auf ein paar Buchstaben reduzierte – DFS.

Lösung

Die Lösung sah folgendermaßen aus:

  • Alle Server, die an der Synchronisierung teilnehmen, müssen auf Windows OS laufen. (Ein Teil war auf Linux. Eine Migration der E-Mail-Daten auf ein anderes OS war erforderlich.)
  • Die Struktur der Verzeichnisse, die an der Synchronisierung teilnehmen sollen, muss identisch sein.
  • Alle Mail-Server unter einer Domain mit einem einheitlichen DFS-Speicher festlegen.
  • Die oben erwähnte verteilte Kerio-Domäne erstellen, da in meinem Fall eine Daten-Synchronisierung nicht nur zwischen Servern, sondern auch zwischen Domains erforderlich ist, wobei der zweite Server Kerio das selbst übernehmen kann. (im Gegensatz zu dem ersten)
  • Die zu synchronisierenden Verzeichnisse auf den DFS-Speicher leiten.
  • Einen Trick ausdenken (denn ohne Trick geht es nicht).

Implementierung

Beispiel auf zwei Mail-Servern (es können auch mehr sein).

1. Kerio verteilte Domäne.

Vollständige Synchronisation von gemeinsamen Ordnern, Kontakten und Kalendern zwischen verteilten Kerio Connect-Servern

Der Master nimmt nicht an der Synchronisierung teil, aber das ist keine zwingende Voraussetzung.

Ich werde nicht im Detail erklären, wie man eine verteilte Kerio-Domain einrichtet; es ist nicht kompliziert und kann in der offiziellen Dokumentation

Am Ende sollten Sie im Administrationskonsole folgendes Bild sehen:

Vollständige Synchronisation von gemeinsamen Ordnern, Kontakten und Kalendern zwischen verteilten Kerio Connect-Servern

Vollständige Synchronisation von gemeinsamen Ordnern, Kontakten und Kalendern zwischen verteilten Kerio Connect-Servern

Als Nächstes interessierten mich die gemeinsamen Ordner. Auf dem Master-Server können Sie folgende Optionen angeben:

Vollständige Synchronisation von gemeinsamen Ordnern, Kontakten und Kalendern zwischen verteilten Kerio Connect-Servern

Vollständige Synchronisation von gemeinsamen Ordnern, Kontakten und Kalendern zwischen verteilten Kerio Connect-Servern

Besonders für jede Domain — der Server wird keine öffentlichen Ordner zwischen den Domains synchronisieren

Gemeinsame für alle Domains — alle Server werden auf vorhandene gemeinsame Ordner in jeder Domain verzichten und neue gemeinsame Ordner für alle Domains auf jedem der Mail-Server erstellen.

Achtung! Diese Option ändert zwar die Konfigurationseinstellungen auf allen Servern, führt jedoch die Synchronisation separat für jeden Server durch (d.h. ohne einen gemeinsamen Raum)

Der Administrator bleibt in der Lage, den Zugriff zwischen den Benutzern zu verteilen.
In meinem Fall — ich benötige die vollständige Synchronisation (in Ihrem Fall kann die Lösung anders sein). Auf jedem Server müssen identische Sätze von Domains erstellt werden, die synchronisiert werden sollen.

2. Kerio-Datenverzeichnisse

Jetzt müssen identische gemeinsame Verzeichnisse erstellt werden, die auf jedem der Server synchronisiert werden müssen. Ordner, Kalender, Kontakte.

Tipp – erstellen Sie die Verzeichnisse in englischer Sprache, da die Benennung in lateinischen Buchstaben sonst in einer unverständlichen Kodierung erfolgt, was mindestens unpraktisch ist.

Jetzt müssen die physischen Pfade der Postordner auf jedem Server gefunden werden.

Gemeinsame für alle Domains ~DataMailmail#publicSynchronisiertes Verzeichnis#msgs
Besonders für jede Domain ~DataMailmail**Domain**#publicSynchronisiertes Verzeichnis#msgs

Bitte beachten Sie, dass wir nicht das gesamte Verzeichnis synchronisieren, sondern nur den Container mit den Daten. #msgs — hier werden die Objekte selbst gespeichert; alle anderen Daten für jeden der Server müssen separat sein.

3. DFS

Ich werde nicht detailliert erklären, wie man DFS einrichtet, da es genügend Informationen zu diesem Thema gibt.

DFS ist ein Dienst in Windows Server, der die Möglichkeit bietet, gemeinsame Ordner, die sich auf verschiedenen Servern befinden, zu verbinden.
Link zum Dokument MS DFS

Vor der Konfiguration von DFS müssen alle Mailserver, die an der Datensynchronisierung teilnehmen, gestoppt werden.

Nach der Einrichtung sollten Sie für jeden synchronisierten Ordner folgendes Bild erhalten.

Vollständige Synchronisation von gemeinsamen Ordnern, Kontakten und Kalendern zwischen verteilten Kerio Connect-Servern

Es ist selbstverständlich nicht notwendig, replizierbare Ordner zu veröffentlichen.

Vollständige Synchronisation von gemeinsamen Ordnern, Kontakten und Kalendern zwischen verteilten Kerio Connect-Servern

Nach der Replikation (es gibt da wenig zu replizieren – die Ordner sind leer) können die Mailserver gestartet werden.

Anschließend können Sie einen der Mailserver mit Daten füllen und überprüfen, ob die Daten korrekt repliziert werden.

4. Notlösung

Beschreibung des Gedankens

Wie Sie feststellen können, nachdem die Daten mit DFS zu synchronisieren begonnen haben: Wenn Sie etwas auf dem ersten Server erstellt haben, erscheint auf dem zweiten Server entweder nichts oder nur manchmal etwas.

Es gibt keinen Grund zur Verzweiflung; es wird sicherlich irgendwann dort erscheinen, aber es ist besser, wenn es früher als später geschieht. Denn 'später' bedeutet in diesem Fall 6 bis 12 Stunden.

Das Problem ist, dass sobald Sie etwas auf dem ersten Server erstellt haben, die Datei auf dem zweiten und den nachfolgenden Servern sofort dank des DFS-Systems erscheinen wird. Allerdings, wenn das betreffende E-Mail-Verzeichnis bereits von jemandem gelesen wurde und erneut angefordert wird, wird der Server den Ordner #msgs nicht erneut lesen, sondern die Daten aus seinem eigenen Index ausgeben, der möglicherweise schon lange nicht mehr mit der Realität übereinstimmt.

Kerio verfügt über einen Mechanismus zur Neuindizierung, der jedoch erst nach etwa sechs Stunden funktioniert. In dieser Zeit kann die Relevanz der Aufgabe im Kalender etwas verloren gehen.
Um die Synchronisation sofort zu überprüfen, kann die Datei im entsprechenden synchronisierten Verzeichnis index.fld gelöscht werden. Nach erneutem Zugriff auf den Ordner auf dem Mailserver und bei Fehlen dieser Datei wird Kerio das Verzeichnis erneut lesen und die Daten erscheinen. Das scheint die Lösung zu sein: Löschen Sie die Datei, wenn sich die Daten ändern. Aber das funktioniert nicht jedes Mal, sondern nur beim ersten Mal. Danach verliert Kerio merkwürdigerweise das Interesse an index.fld.
Es beginnt damit, dass unverständliche Nachrichten für den Benutzer angezeigt werden – bezüglich eines bestimmten Index und dass dieser bereits etwas tut.

Es gibt noch eine andere Möglichkeit, etwas zu erstellen – zum Zeitpunkt der Erstellung eines neuen Objekts könnte der Server plötzlich feststellen, dass der Dateiname, den er zuweisen wollte, bereits vergeben ist. Aber das ist ein Schneeballsystem und eine Sackgasse.

Was sollen wir tun?

Wenn wir noch einmal auf das uns bereits bekannte Bild schauen.

Vollständige Synchronisation von gemeinsamen Ordnern, Kontakten und Kalendern zwischen verteilten Kerio Connect-Servern

Aber in einer anderen Dimension können wir eine sehr interessante und nützliche Schaltfläche bemerken – Ordner neu indizieren

Und das stimmt tatsächlich. Wenn man diese Schaltfläche auf einem Mailserver drückt, der nicht weiß, dass sich bereits etwas in den synchronisierten #msgs geändert hat, erhalten wir ein stabiles, schnelles Ergebnis. Alles Verborgene wird offenbar.

Im Protokoll kann man sehen, wie viel Zeit dieser Prozess in Anspruch nimmt; in meinem Fall mit mehreren Tausend (15.000) Einträgen dauert es etwa 3-4 Minuten.

Wir müssen nur noch herausfinden, wie wir tatsächlich auf diese Schaltfläche klicken können, wenn wir es brauchen.

Es stellt sich heraus, dass Kerio eine eigene API

Beschreibung
Dokumentation

Funktion hat, die unsere Aufgabe erfüllt, die so aussieht –
session = callMethod("Domains.checkPublicFoldersIntegrity",{}, token)

Basierend auf den obigen Ausführungen müssen wir ein Skript erstellen, das den Zustand der relevanten Ordner überwacht und im Falle von Änderungen die gewünschte Funktion ausführt.

Ich möchte erwähnen, dass ich mehrere verschiedene Versionen von Skripten geschrieben habe, die unterschiedliche Überprüfungen durchführen. Ich habe mich für die entschieden, die alle Ausgaben basierend auf der Anzahl der Dateien generiert.

Implementierung des Skripts

Beispiel für ein CMD-Skript und Beschreibung

Re-index.bat

@echo off
set dir=%~dp0
%dir:~0,2%
CD "%~dp0"
md "%CD%LOG"
md "%CD%Setup"

ECHO -Start- >> "%CD%LOG%Computername%.log"
ECHO Start -> %Computername% %Date% %Time% >> "%CD%LOG%Computername%.log"

SetLocal EnableDelayedExpansion
for /f "UseBackQ Delims=" %%A IN ("%CD%Setup%Computername%.List") do (
  set /a c+=1
  set "m!c!=%%A"
)

set d=%c%
Echo Folder = %c%
ECHO Folder = %c% >> "%CD%LOG%Computername%.log"
ECHO.
ECHO. >> "%CD%LOG%Computername%.log"

:start
cls
if %c% LSS 1 exit
set /a id=1
set R=0

:Find
REM PF-Start
if "%id%" gtr "%c%" if %R% == 1 Goto Reindex 
if "%id%" gtr "%c%" timeout 60 && Goto start

For /F "tokens=1-3" %%a IN ('Dir "!m%id%!#msgs" /-C/S/A:-D') Do Set 2DirSize!id!=!DS!& Set DS=%%c
if "2DirSize!id!" == "" set 1DirSize!id!=!2DirSize%id%!

echo %id%
ECHO !m%id%!
echo Count        [ !1DirSize%id%! -- !2DirSize%id%! ]

if "!1DirSize%id%!" == "!2DirSize%id%!" ECHO Synk

REM DEL index.fld
if "!1DirSize%id%!" NEQ "!2DirSize%id%!" del /f /q !m%id%!index.fld && del /f /q !m%id%!indexlog.fld && del /f /q !m%id%!search.fld && set R=1 && ECHO RE-index Count && ECHO RE-index Count %Date% %Time% - Delete !m%id%! >> "%CD%LOG%Computername%.log"

set 1DirSize!id!=!2DirSize%id%!

ECHO.
ECHO.

set /a id+=1
goto Find

:Reindex
ECHO. >> "%CD%LOG%Computername%.log"
ECHO --- RE-INDEX - Start - %Date% %Time% --- >> "%CD%LOG%Computername%.log"
ECHO. >> ----------------------------------- >> "%CD%LOG%Computername%.log"
call PublicFolders.py
timeout 60
goto start

exit

Eine Kopie des Skripts wird auf jedem Mailserver ausgeführt (kann als Dienst betrieben werden, Administratorrechte sind nicht erforderlich)

Das Skript liest die Datei Setup%Computername%.List

Wo %Computername% — der Name des aktuellen Servers (Das Verzeichnis kann eine Liste aller Server enthalten.)

Die Datei %Computername%.List enthält die vollständigen Pfade der synchronisierten Verzeichnisse, jeder Pfad steht in einer neuen Zeile und es dürfen keine leeren Zeilen vorhanden sein.

Nach dem ersten Start führt das Skript eine Indizierungsprozedur aus, unabhängig davon, ob sie notwendig ist oder nicht. Das Skript erstellt außerdem ein Index mit der Anzahl der Dateien in jedem der synchronisierten Verzeichnisse.

Die Aufgabe des Skripts besteht darin, alle Dateien im angegebenen Verzeichnis zu zählen.

Nach dem Zählen jedes Verzeichnisses, wenn in mindestens einem Verzeichnis die aktuelle Anzahl der Dateien nicht mit der vorherigen übereinstimmt, löscht das Skript Dateien aus dem Stammverzeichnis des synchronisierten Mailverzeichnisses: index.fld, indexlog.fld, search.fld und startet den Indizierungsprozess — aller gemeinsamen Mailordner.

Im Verzeichnis LOG wird die Information über die Ausführung der Aufgaben gespeichert.

Indizierungsprozess
Der Indizierungsprozess besteht darin, die API-Funktion von Kerio auszuführen.
Session = callMethod("Domains.checkPublicFoldersIntegrity", {}, token)

Ein Beispiel für die Ausführung ist auf – python
PublicFolders.py

import json
import urllib.request
import http.cookiejar
""" Cookie-Speicherung ist erforderlich für die Sitzungsverwaltung """
jar = http.cookiejar.CookieJar()
opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(jar))
urllib.request.install_opener(opener)
""" Hostname oder IP-Adresse Ihrer Kerio Control-Instanz mit Protokoll, Port und Anmeldedaten """

server = "http://127.0.0.1:4040"
username = "user"
password = "password"

def callMethod(method, params, token = None):
    """
    Ruft die angegebene Methode mit den gegebenen Parametern remote auf.
    :param: method string mit dem vollqualifizierten Methodennamen
    :param: params dict mit den Parametern der remote aufgerufenen Methode
    :param: token CSRF-Token wird immer benötigt, außer bei der Anmeldemethode. Verwenden Sie die Methode "Session.login", um diesen Token zu erhalten.
    """
    data = {"method": method ,"id":1, "jsonrpc":"2.0", "params": params}

    req = urllib.request.Request(url = server + '/admin/api/jsonrpc/')
    req.add_header('Content-Type', 'application/json')
    if (token is not None):
        req.add_header('X-Token', token)    

    httpResponse = urllib.request.urlopen(req, json.dumps(data).encode())

    if (httpResponse.status == 200):
        body = httpResponse.read().decode()
        return json.loads(body)

session = callMethod("Session.login", {"userName":username, "password":password, "application":{"vendor":"Kerio", "name":"Control Api-Local", "version":"Python"}})
token = session["result"]["token"]
print (session)

session = callMethod("Domains.checkPublicFoldersIntegrity",{"domainId": "test2.local"}, token)
print (session)

callMethod("Session.logout",{}, token)

http://127.0.0.1:4040 Kann so bleiben, allerdings sollte Python dem Kerio-Zertifikat vertrauen, wenn Sie HTTPS benötigen.

Im Datei muss auch ein Benutzer mit Berechtigungen zur Ausführung dieser Funktion angegeben werden (Admin – gemeinsame Postfächer) des Mailservers.

Ich hoffe, mein Artikel wird den Administratoren von Kerio Connect hilfreich sein.

Quelle: habr.com

Zuverlässiges Webhosting mit DDoS-Schutz, VPS- und VDS-Server kaufen 🔥 Zuverlässiges Webhosting mit DDoS-Schutz, VPS- und VDS-Server kaufen | ProHoster