Vollständige Synchronisierung freigegebener Ordner, Kontakte und Kalender zwischen verteilten Kerio Connect-Servern

Guten Tag, Habr!

Aufgabe

Meine Organisation nutzt einen Mailserver auf der Kerio Connect-Plattform; Mailserver sind in verschiedenen Städten installiert, um ihre Benutzer zu bedienen. Zunächst gab es keine verteilte Struktur, da sich die Domänen auf der dritten Ebene unterscheiden und die Stadt des Standorts angeben. Alles hat funktioniert und alle waren zufrieden. Eines schönen Tages stellte das Management eine Aufgabe: einen gemeinsamen Aktivitätskalender für alle Standorte!

Vorgeschichte

Ursprünglich bestand die Idee darin, die Kerio Distributed Mail Domain einzurichten und alles selbst zu erledigen. Gesagt, getan, eine verteilte Domäne wurde erstellt, aber das war nicht der Fall, der Server war bereit, Kalender, Ordner und Kontakte zu synchronisieren – zwischen Domänen, die sich auf demselben Server befanden, aber er hatte überhaupt nicht vor, Daten zwischen mehreren zu synchronisieren Server.

Mit einem solchen Haken hatte ich natürlich nicht gerechnet und konnte lange nicht glauben, dass mir die Funktionalität fehlte, die ich brauchte. Später fand ich dokumentarische Beweise für diese Tatsache. Ich war darüber sehr verwirrt und enttäuscht.

Die Aufgabe wurde reibungslos zu einem Problem.

Welche Möglichkeiten gab es?

  • Erstellen Sie zwei Clients auf verschiedenen Servern, die die erforderlichen Daten mit Software von Drittanbietern austauschen. Es war notwendig, diese Software eines Drittanbieters zu finden, die diese Funktionalität implementieren würde – ich mag solche Rake nicht, aber es schien, dass dies die einzige schnelle Lösung war.
  • Schreiben Sie Ihr eigenes Skript für die Datensynchronisierung zwischen Servern. Tatsache ist, dass Kerio jedes Objekt als separate Datei speichert. Daher war es notwendig, ein Skript für die Arbeit mit Dateien zu entwickeln. Angesichts der ausreichenden Anzahl von Quellen schien die Aufgabe jedoch etwas kompliziert zu sein, insbesondere da mehrere ausgeführt werden mussten prüft die Richtigkeit der Daten, falls jemand im gleichen Zeitraum eine Aufgabe erstellt usw. usw.

Mit Blick auf die Zukunft möchte ich sagen, dass Kerio zwar ein Objekt als separate Datei speichert, es aber nicht so dumm ist, bei jedem Zugriff auf das Objekt zu fragen, wie es dem Dateisystem geht.

Nachdem ich viel Zeit damit verbracht hatte, einen Haufen Papiere mit Plänen zur „Eroberung feindlichen Territoriums“ zu entwerfen, traf ich um 6 Uhr zwei richtige Entscheidungen:

  • Die erste Entscheidung besteht darin, sein eigenes Ding zu machen und nicht nach etwas von außen zu suchen.
  • Die zweite Lösung besteht darin, schlafen zu gehen.

Schon am Morgen wachte ich mit einem einzigen und wahren Gedanken auf, der auf wenige Buchstaben reduziert wurde – DFS

Lösung

Die Lösung selbst sah so aus

  • Bringen Sie alle Server, die an der Synchronisierung teilnehmen, zum Betriebssystem Windows. (Ein Teil davon lief unter Linux. Eine Migration der E-Mail-Daten auf ein anderes Betriebssystem war erforderlich.)
  • Bestimmen Sie die Struktur der Verzeichnisse, die an der Synchronisierung teilnehmen sollen – sie müssen identisch sein.
  • Definieren Sie alle Mailserver unter einer Domäne mit einem einzigen DFS-Bereich.
  • Erstellen Sie die oben erwähnte verteilte Kerio-Domäne, da in meinem Fall eine Datensynchronisierung nicht nur zwischen Servern, sondern auch zwischen Domänen erforderlich ist; die zweite kann vom Kerio-Server unabhängig verwaltet werden. (im Gegensatz zum ersten)
  • Synchronisierte Verzeichnisse auf DFS-Speicherplatz festlegen.
  • Überlegen Sie sich eine Art Krücke (schließlich kann man ohne Krücke nicht leben)

Implementierung

Beispiel auf zwei Mailservern (vielleicht mehr)

1. Verteilte Kerio-Domäne

Vollständige Synchronisierung freigegebener Ordner, Kontakte und Kalender zwischen verteilten Kerio Connect-Servern

Der Master beteiligt sich nicht an der Synchronisation, dies ist jedoch keine Voraussetzung.

Ich werde nicht beschreiben, wie man eine verteilte Kerio-Domäne erstellt, es ist nichts Kompliziertes daran, Sie können den Beamten studieren manul

Letztendlich sollten Sie in der Administrationskonsole das folgende Bild sehen:

Vollständige Synchronisierung freigegebener Ordner, Kontakte und Kalender zwischen verteilten Kerio Connect-Servern

Vollständige Synchronisierung freigegebener Ordner, Kontakte und Kalender zwischen verteilten Kerio Connect-Servern

Als nächstes interessierten mich freigegebene Ordner; auf dem Master-Server können Sie folgende Optionen festlegen:

Vollständige Synchronisierung freigegebener Ordner, Kontakte und Kalender zwischen verteilten Kerio Connect-Servern

Vollständige Synchronisierung freigegebener Ordner, Kontakte und Kalender zwischen verteilten Kerio Connect-Servern

Spezifisch für jede Domain - Der Server synchronisiert keine öffentlichen Ordner zwischen Domänen

Für alle Domänen gleich - Alle Server geben bestehende öffentliche Ordner in jeder Domäne auf und erstellen neue Einzelordner für alle Domänen auf jedem Mailserver.

Achtung! Obwohl diese Option die Konfigurationsrichtlinie auf allen Servern ändert, erfolgt die Synchronisierung separat von jedem Server (d. h. ohne einen einzigen gemeinsamen Bereich).

Der Administrator hat weiterhin die Möglichkeit, den Zugriff zwischen Benutzern zu verteilen.
In meinem Fall gehören sie alle mir und ich benötige eine vollständige Synchronisierung (in Ihrem Fall kann die Lösung anders sein). Auf jedem Server müssen Sie identische Domänensätze erstellen, die synchronisiert werden müssen.

2. Kerio-Datenverzeichnisse

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

Tipp: Erstellen Sie Verzeichnisse auf Englisch. Wenn Sie sie auf Latein erstellen, hat das Verzeichnis einen Namen in einer unverständlichen Kodierung, was zumindest unpraktisch ist.

Jetzt müssen Sie die physischen Pfade der E-Mail-Ordner auf jedem Server ermitteln.

Für alle Domänen gleich ~DataMailmail#publicСинхронизируемый каталог#msgs
Spezifisch für jede Domain ~DataMailmail**Domain**#publicСинхронизируемый каталог#msgs

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

3.DFS

Ich werde nicht im Detail beschreiben, wie man DFS konfiguriert, es gibt genügend Informationen zu diesem Thema.

DFS ist ein Rollendienst in Windows Server, der die Möglichkeit bietet, freigegebene Ordner auf verschiedenen Servern zu kombinieren
Link zum MS DFS-Dokument

Bevor Sie DFS einrichten, müssen Sie alle Mailserver stoppen, die an der Datensynchronisierung teilnehmen.

Nach Abschluss der Einrichtung sollten Sie für jeden der synchronisierten Ordner das folgende Bild erhalten

Vollständige Synchronisierung freigegebener Ordner, Kontakte und Kalender zwischen verteilten Kerio Connect-Servern

Natürlich müssen wir keine replizierten Ordner veröffentlichen.

Vollständige Synchronisierung freigegebener Ordner, Kontakte und Kalender zwischen verteilten Kerio Connect-Servern

Nachdem die Replikation erfolgt ist (und es gibt dort nichts Besonderes zu replizieren – die Ordner sind leer), können die Mailserver gestartet werden.

Als nächstes können Sie einen der Mailserver mit Daten füllen und prüfen, ob die Daten korrekt repliziert werden.

4. Krücke

Beschreibung der Reflexion

Wie Sie nach Beginn der Datensynchronisierung (DFS) sehen können, wird auf dem zweiten Server irgendwie nichts angezeigt, wenn Sie entweder etwas auf dem ersten Server erstellt haben, oder es wird angezeigt, aber irgendwie nicht immer.

Verzweifeln Sie nicht; natürlich wird es früher oder später dort auftauchen, aber besser früher als später. Weil es in 6 – 12 Stunden zu spät ist.

Die Sache ist, dass sobald Sie etwas auf dem ersten Server erstellt haben, auf dem zweiten und den folgenden Servern die Datei dank des DFS-Systems natürlich sofort erscheint, aber für den Fall, dass dieses Mail-Verzeichnis bereits zuvor von jemandem gelesen wurde und erneut angefordert wird, liest der Server den #msgs-Ordner nicht erneut, sondern spuckt Daten aus seinem eigenen Index aus, die möglicherweise nicht mehr unserer Realität entsprechen.

Kerio verfügt über einen Mechanismus zum erneuten Lesen des Index, der jedoch in etwa sechs Stunden funktionieren kann, und während dieser sechs Stunden kann die Relevanz der Aufgabe im Kalender etwas verloren gehen.
Um die Synchronisierung jetzt zu testen, können Sie die Datei im entsprechenden synchronisierten Verzeichnis index.fld löschen, nach erneutem Zugriff auf den Ordner auf dem Mailserver und wenn diese Datei fehlt, liest Kerio das Verzeichnis und die Daten erneut ein wird auftauchen. Es scheint, dass dies die Lösung ist: Löschen Sie die Datei, wenn sich die Daten ändern. Dies funktioniert jedoch nicht jedes Mal, sondern nur beim ersten Mal. Dann verliert Kerio aus irgendeinem Grund jegliches Interesse an index.fld
Es fängt auch an, für den Benutzer unverständliche Nachrichten auszuspucken – über eine Art Index und dass dort bereits etwas getan wird.

Es gibt noch eine andere Möglichkeit, etwas zu erstellen: Im Moment der Erstellung eines neuen Objekts stellt der Server plötzlich fest, dass der Dateiname, den er zuweisen wollte, bereits vergeben ist, aber es kommt zu Schneebällen, und dies ist eine Sackgasse.

Wie kann das sein?

Wenn wir uns noch einmal dem Bild widmen, das uns bereits bekannt ist.

Vollständige Synchronisierung freigegebener Ordner, Kontakte und Kalender zwischen verteilten Kerio Connect-Servern

Aber auf einer anderen Ebene können Sie einen sehr interessanten Knopf sehen, den wir jetzt brauchen – Ordner neu indizieren

Und in der Tat. Klicken wir auf diesen Button auf einem Mailserver, der nicht weiß, dass sich in den synchronisierten #msgs bereits etwas geändert hat, erhalten wir ein stabiles, schnelles Ergebnis. Alles Verborgene wird klar.

Im Protokoll können Sie sehen, wie lange dieser Vorgang dauert; in meinem Fall dauert es bei mehreren tausend (15) Datensätzen etwa 3-4 Minuten.

Wir müssen nur herausfinden, wie wir diesen Knopf tatsächlich drücken, wenn wir ihn brauchen.

Es stellt sich heraus Kerio haben ihr eigenes API

Beschreibung
Dokumentation

Die Funktion, die unsere Aufgabe ausführt, sieht folgendermaßen aus:
session = callMethod("Domains.checkPublicFoldersIntegrity",{}, token)

Aus all dem müssen wir ein Skript schreiben, das den Status der gewünschten Ordner überwacht und, wenn sich etwas geändert hat, die von uns benötigte Funktion ausführt.

Ich möchte sagen, dass ich mehrere verschiedene Versionen von Skripten geschrieben habe, die unterschiedliche Prüfungen durchführen, und mich für die Version entschieden habe, die alle Schlussfolgerungen basierend auf der Anzahl der Dateien zieht.

Skriptimplementierung

Beispiel und Beschreibung eines CMD-Skripts

Indizieren Sie die Datei neu.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

Auf jedem Mailserver läuft eine Kopie des Skripts (kann als Dienst genutzt werden, Adm-Rechte sind nicht erforderlich)

Das Skript liest die Datei Setup%Computername%.List

Wobei %Computername% der Name des aktuellen Servers ist (Das Verzeichnis kann Listen aller Server gleichzeitig enthalten.)

Die Datei %Computername%.List – enthält die vollständigen Pfade der synchronisierten Verzeichnisse, jeder Pfad wird in eine neue Zeile geschrieben und sollte keine Leerzeilen enthalten.

Nach dem ersten Start führt das Skript den Indizierungsvorgang durch, unabhängig davon, ob er erforderlich ist oder nicht, und erstellt außerdem einen Index der Anzahl der Dateien in jedem synchronisierten Verzeichnis.

Der Zweck des Skripts besteht darin, alle Dateien im angegebenen Verzeichnis zu zählen.

Wenn am Ende der Zählung jedes Verzeichnisses in mindestens einem Verzeichnis der aktuelle Wert der Dateien nicht mit dem vorherigen übereinstimmt, löscht das Skript Dateien aus dem Stammverzeichnis des synchronisierten Mail-Verzeichnisses: index.fld, indexlog.fld, search.fld und startet den Indexierungsprozess freigegebener E-Mail-Ordner.

Informationen zur Aufgabenausführung werden im LOG-Verzeichnis gespeichert.

Indexierungsprozess
Beim Indizierungsprozess kommt es auf die Ausführung einer Kerio-API-Funktion an
Session = callMethod("Domains.checkPublicFoldersIntegrity",{}, token)

Eine Beispielimplementierung finden Sie in – Python
PublicFolders.py

import json
import urllib.request
import http.cookiejar
""" Cookie storage is necessary for session handling """
jar = http.cookiejar.CookieJar()
opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(jar))
urllib.request.install_opener(opener)
""" Hostname or ip address of your Kerio Control instance with protocol, port and credentials """

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

def callMethod(method, params, token = None):
    """
    Remotely calls given method with given params.
    :param: method string with fully qualified method name
    :param: params dict with parameters of remotely called method
    :param: token CSRF token is always required except login method. Use method "Session.login" to obtain this token.
    """
    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 Sie können es unverändert lassen, aber wenn Sie HTTPS benötigen, muss Python dem Kerio-Zertifikat vertrauen.

Außerdem müssen Sie in der Datei ein Konto mit Rechten zum Ausführen dieser Funktion (Adm – öffentliche Mailordner) des Mailservers angeben.

Ich hoffe, dass mein Artikel für Kerio Connect-Administratoren nützlich sein wird.

Source: habr.com

Kommentar hinzufügen