VollstÀndige Synchronisierung gemeinsamer Ordner, Kontakte und Kalender zwischen verteilten Kerio Connect-Servern

Guten Tag, Habr!

Aufgabe

In meiner Organisation verwenden wir einen E-Mail-Server auf der Kerio Connect-Plattform. In verschiedenen StĂ€dten sind E-Mail-Server installiert, die ihre eigenen Benutzer bedienen. Eine verteilte Struktur gab es ursprĂŒnglich nicht, da die Domains auf der dritten Ebene mit dem Stadtnamen der Plattform gekennzeichnet sind. Alles funktionierte und alle waren zufrieden. Eines Tages stellte das Management die Aufgabe, einen gemeinsamen Kalender fĂŒr alle Standorte einzurichten!

Vorgeschichte

UrsprĂŒnglich war die Idee, eine verteilte Kerio-E-Mail-Domain einzurichten, die alles selbst erledigt. Gesagt, getan, die verteilte Domain wurde eingerichtet, aber das war nicht alles. Der Server war bereit, Kalender, Ordner und Kontakte zwischen Domains zu synchronisieren, die sich auf demselben Server befinden, wollte jedoch die Daten zwischen mehreren Servern nicht synchronisieren.

So eine Wendung habe ich natĂŒrlich nicht erwartet und konnte lange nicht glauben, dass mir die benötigte FunktionalitĂ€t fehlt. SpĂ€ter fand ich dokumentarische BestĂ€tigungen fĂŒr diese Tatsache, was mich sehr beunruhigte und enttĂ€uschte.

Die Aufgabe verwandelte sich allmÀhlich in ein Problem.

Welche Optionen gab es?

  • Zwei Clients auf unterschiedlichen Servern zu erstellen, die mit irgendeiner Drittanbieter-Software die notwendigen Daten austauschten. Ich musste diese Drittanbieter-Software finden, die diese FunktionalitĂ€t umsetzen konnte – ich mag solche HĂŒrden nicht, aber es schien, als wĂ€re es die einzige schnelle Lösung.
  • Mein eigenes Synchronisationsskript zwischen Servern zu schreiben. Das Problem ist, dass Kerio jedes Objekt als separate Datei speichert. Daher war es notwendig, ein Skript zur Arbeit mit Dateien zu entwickeln. Aufgrund der ausreichenden Anzahl an Quellen schien die Aufgabe etwas kompliziert, besonders da ich mehrere ÜberprĂŒfungen der DatenintegritĂ€t durchfĂŒhren musste: Was wĂ€re, wenn jemand zur gleichen Zeit eine Aufgabe erstellt usw.

Um es vorwegzunehmen, Kerio speichert zwar Objekte als separate Dateien, es ist jedoch nicht so dumm, bei jedem Zugriff auf ein Objekt zu fragen – wie steht's um das Dateisystem?

Nachdem ich viel Zeit mit Nachdenken verbracht und eine Menge Papier mit PlÀnen zur "Eroberung des feindlichen Gebiets" vollgeschrieben hatte, traf ich um 6 Uhr zwei richtige Entscheidungen:

  • Die erste Lösung ist, selbst zu machen und nichts Fremdes zu suchen.
  • Die zweite Lösung ist, ins Bett zu gehen.

Am Morgen wachte ich mit einem einzigen und sicheren Gedanken auf, der auf wenige Buchstaben schrumpfte – DFS

Lösung

Die Lösung sah folgendermaßen aus

  • alle Server, die an der Synchronisierung teilnehmen, auf das Betriebssystem Windows zu bringen. (Ein Teil war auf Linux. Eine Migration der E-Mail-Daten auf ein anderes Betriebssystem war erforderlich.)
  • Sich ĂŒber die Verzeichnisstruktur zu einigen, die an der Synchronisierung teilnehmen wird – sie mĂŒssen identisch sein.
  • Alle Mailserver unter einer Domain mit einem einheitlichen DFS-Speicherplatz zu definieren.
  • Den oben genannten verteilten Kerio-Domain zu erstellen, da in meinem Fall eine Datensynchronisierung nicht nur zwischen Servern, sondern auch zwischen Domains erforderlich ist, was der Kerio-Server selbst ĂŒbernehmen kann. (im Gegensatz zum ersten)
  • Die zu synchronisierenden Verzeichnisse auf den DFS-Speicherplatz zu lenken.
  • Irgendeinen Trick zu erfinden (denn ohne Trick geht es nicht)

Implementierung

Beispiel auf zwei Mailservern (kann mehr sein)

1. Kerio verteilte Domain

VollstÀndige Synchronisierung gemeinsamer Ordner, Kontakte und Kalender zwischen verteilten Kerio Connect-Servern

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

Ich werde nicht erklÀren, wie man eine verteilte Kerio-Domain aufbaut, das ist nicht schwierig, man kann das Offizielle studieren. Handbuch

Am Ende sollten Sie in der Administrationskonsole das folgende Bild sehen:

VollstÀndige Synchronisierung gemeinsamer Ordner, Kontakte und Kalender zwischen verteilten Kerio Connect-Servern

VollstÀndige Synchronisierung gemeinsamer Ordner, Kontakte und Kalender zwischen verteilten Kerio Connect-Servern

Dann interessierten mich die gemeinsamen Ordner, auf dem Master-Server können die folgenden Optionen angegeben werden:

VollstÀndige Synchronisierung gemeinsamer Ordner, Kontakte und Kalender zwischen verteilten Kerio Connect-Servern

VollstÀndige Synchronisierung gemeinsamer Ordner, Kontakte und Kalender zwischen verteilten Kerio Connect-Servern

Besonderer Ordner fĂŒr jede Domain – der Server wird die öffentlichen Ordner zwischen den Domains nicht synchronisieren

Gemeinsame Ordner fĂŒr alle Domains – alle Server werden die bestehenden gemeinsamen Ordner in jeder Domain ablehnen und neue einheitliche Ordner fĂŒr alle Domains auf jedem Mailserver erstellen.

Achtung! Diese Option Ă€ndert zwar die Richtlinien fĂŒr die Einstellungen auf allen Servern, jedoch erfolgt die Synchronisierung separat von jedem Server (das heißt – ohne einen einheitlichen Speicherplatz).

Dem Administrator bleibt die Möglichkeit, die Zugriffe zwischen den Benutzern zu verteilen.
In meinem Fall – alles eigene und ich benötige eine vollstĂ€ndige Synchronisierung (In Ihrem Fall kann die Lösung anders sein), auf jedem Server mĂŒssen identische Sets von Domains erstellt werden, die synchronisiert werden sollen.

2. Datenverzeichnisse Kerio

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

Tipp – erstellen Sie Verzeichnisse in englischer Sprache. Wenn Sie sie in lateinischer Schrift erstellen, wird das Verzeichnis einen Namen in einer unverstĂ€ndlichen Kodierung haben, was mindestens unpraktisch ist.

Jetzt mĂŒssen die physischen Pfade der Mail-Verzeichnisse auf jedem Server gefunden werden.

Gemeinsame Ordner fĂŒr alle Domains ~DataMailmail#publicSynchronisierbares Verzeichnis#msgs
Besonderer Ordner fĂŒr jede Domain ~DataMailmail**Domain**#publicSynchronisierbares Verzeichnis#msgs

Bitte beachten Sie, dass wir nicht das gesamte Verzeichnis synchronisieren werden, 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

Wie man DFS einrichtet, werde ich auch nicht detailliert beschreiben, es gibt ausreichend Informationen zu diesem Thema.

DFS ist ein Serverrollen-Service in Windows Server, der die Möglichkeit bietet, gemeinsame Ordner, die sich auf verschiedenen Servern befinden, zusammenzufĂŒhren.
Link zum MS DFS-Dokument

Vor der Konfiguration von DFS mĂŒssen alle Mailserver, die an der Synchronisierung der Daten teilnehmen, gestoppt werden.

Nach Abschluss der Konfiguration sollten Sie das folgende Bild fĂŒr jedes der synchronisierten Verzeichnisse erhalten.

VollstÀndige Synchronisierung gemeinsamer Ordner, Kontakte und Kalender zwischen verteilten Kerio Connect-Servern

Es ist natĂŒrlich nicht erforderlich, replizierbare Ordner zu veröffentlichen.

VollstÀndige Synchronisierung gemeinsamer Ordner, Kontakte und Kalender zwischen verteilten Kerio Connect-Servern

Nachdem die Replikation stattgefunden hat (und es gibt nicht viel zu replizieren – die Ordner sind leer), können die Mailserver gestartet werden.

Danach kann einer der Mailserver mit Daten gefĂŒllt werden, um zu ĂŒberprĂŒfen, ob die Daten korrekt repliziert werden.

4. Notlösung

Beschreibung des Nachdenkens

Wie Sie sehen können, nachdem die Daten mit DFS synchronisiert wurden, wenn Sie etwas auf dem ersten Server erstellt haben – auf dem zweiten Server erscheint nichts oder erscheint manchmal nicht.

Verzweifeln Sie nicht, es wird natĂŒrlich frĂŒher oder spĂ€ter erscheinen, aber frĂŒh ist besser als spĂ€t. Denn spĂ€t ist in 6 – 12 Stunden.

Es liegt daran, dass, sobald Sie etwas auf dem ersten Server erstellt haben, die Datei natĂŒrlich sofort auf dem zweiten und nachfolgenden Server dank des DFS-Systems erscheint. Wenn jedoch das entsprechende Postverzeichnis bereits von jemandem zuvor gelesen wurde und erneut angefordert wird, wird der Server den Ordner #msgs nicht erneut lesen, sondern die Daten aus seinem eigenen Index abrufen, der möglicherweise schon lange nicht mehr unserer RealitĂ€t entspricht.

Kerio verfĂŒgt ĂŒber einen Mechanismus zur Neulese des Index, aber dieser kann erst nach etwa sechs Stunden wirken, wobei in diesen 6 Stunden die AktualitĂ€t der Aufgabe im Kalender möglicherweise etwas verloren geht.
Um die FunktionalitĂ€t der Synchronisierung jetzt sofort zu ĂŒberprĂŒfen, können Sie die Datei im entsprechenden synchronisierten Verzeichnis index.fld löschen. Nach erneutem Zugriff auf den Ordner auf dem Mailserver wird Kerio, wenn diese Datei fehlt, das Verzeichnis erneut einlesen und die Daten erscheinen. Es schien, als wĂ€re das die Lösung: Löschen Sie die Datei bei DatenĂ€nderungen, aber das funktioniert nicht jedes Mal, sondern nur beim ersten Mal. Danach verliert Kerio irgendwie das Interesse an index.fld.
Und es beginnt auch, unverstĂ€ndliche Nachrichten fĂŒr den Benutzer auszugeben – ĂŒber einen bestimmten Index und dass er dort bereits etwas tut.

Es gibt auch die Möglichkeit, etwas zu erstellen – in dem Moment, in dem ein neues Objekt erstellt wird, könnte der Server plötzlich bemerken, dass der Dateiname, den er zuweisen wollte, bereits vergeben ist, aber das fĂŒhrt zu einem Schneeballeffekt und ist eine Sackgasse.

Was soll man also tun?

Wenn wir uns noch einmal das bereits bekannte Bild ansehen.

VollstÀndige Synchronisierung gemeinsamer Ordner, Kontakte und Kalender zwischen verteilten Kerio Connect-Servern

Aber aus einer anderen Perspektive können wir einen sehr interessanten und fĂŒr uns jetzt wichtigen Knopf bemerken – Ordner neu indizieren

Und tatsĂ€chlich. Wenn Sie diesen Knopf auf dem Mailserver drĂŒcken, der nicht weiß, dass sich bereits etwas im synchronisierten #msgs geĂ€ndert hat, erhalten wir ein stabiles, schnelles Ergebnis. Alles Verborgene wird offensichtlich.

Im Protokoll kann man sehen, wie lange dieser Prozess dauert. In meinem Fall mit mehreren Tausend (15.000) EintrÀgen dauert das etwa 3-4 Minuten.

Es bleibt nur zu ĂŒberlegen, wie man tatsĂ€chlich auf diesen Knopf drĂŒcken kann, wann immer wir es brauchen.

Es stellt sich heraus, dass Kerio eine eigene API

Beschreibung
Dokumentation

Funktion hat, die unsere Aufgabe erfĂŒllt, sieht folgendermaßen aus –
session = callMethod("Domains.checkPublicFoldersIntegrity",{}, token)

Aus allem Vorstehenden mĂŒssen wir ein Skript schreiben, das den Zustand der interessierenden Ordner ĂŒberwacht und, falls sich etwas Ă€ndert, die gewĂŒnschte Funktion fĂŒr uns ausfĂŒhrt.

Ich möchte sagen, dass ich mehrere verschiedene Versionen von Skripten geschrieben habe, die unterschiedliche ÜberprĂŒfungen durchfĂŒhren. Ich habe mich fĂŒr das Skript entschieden, das alle Ausgaben basierend auf der Anzahl der Dateien erstellt.

Implementierung des Skripts

Beispielskript CMD und Beschreibung

Re-index.bat

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

ECHO -Start- >> "%LOG%Computername%.log"
ECHO Start -> %Computername% te% %Time% >> "%LOG%Computername%.log"

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

set d=%c%
Echo Folder = %c%
ECHO Folder = %c% >> "%LOG%Computername%.log"
ECHO.
ECHO. >> "%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 te% %Time% - Delete !m%id%! >> "%LOG%Computername%.log"

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

ECHO.
ECHO.

set /a id+=1
goto Find

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

exit

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

Das Skript liest die Datei Setup%Computername%.List

Wo %Computername% der Name des aktuellen Servers ist (das Verzeichnis kann Listen aller Server enthalten).

Die Datei %Computername%.List enthĂ€lt die vollstĂ€ndigen Pfade der zu synchronisierenden Verzeichnisse, jeder Pfad wird in einer neuen Zeile aufgefĂŒhrt, leere Zeilen sollten nicht enthalten sein.

Nach dem ersten Start fĂŒhrt das Skript den Indizierungsvorgang aus, unabhĂ€ngig davon, ob dieser erforderlich ist oder nicht, und erstellt auch einen Index der Anzahl der Dateien in jedem der synchronisierten Verzeichnisse.

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

Am Ende der ZĂ€hlung jedes Verzeichnisses, wenn sich der aktuelle Wert der Dateien in mindestens einem Verzeichnis von dem vorherigen unterscheidet, löscht das Skript die Dateien aus dem Stammverzeichnis des synchronisierten Postfachverzeichnisses: index.fld, indexlog.fld, search.fld und initiiert den Indexierungsprozess – gemeinsamer PostfĂ€cher.

Im Verzeichnis LOG wird Informationen zu den ausgefĂŒhrten Aufgaben abgelegt.

Indexierungsprozess
Der Indexierungsprozess besteht darin, die Kerio API-Funktion auszufĂŒhren
Session = callMethod("Domains.checkPublicFoldersIntegrity",{}, token)

Ein Beispiel fĂŒr die AusfĂŒhrung wird auf – python bereitgestellt
PublicFolders.py

import json
import urllib.request
import http.cookiejar
""" Cookie-Speicher ist erforderlich fĂŒr das Sitzungsmanagement """
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 angegebenen Parametern aus der Ferne auf.
    :param: method String mit dem vollstÀndig qualifizierten Methodennamen
    :param: params dict mit Parametern der remote aufgerufenen Methode
    :param: token CSRF-Token ist immer erforderlich, außer bei der Anmeldemethode. Verwenden Sie die Methode "Session.login", um dieses 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, jedoch, wenn Sie HTTPS benötigen – python muss dem Zertifikat von Kerio vertrauen.

Im Datei muss auch ein Konto mit Rechten zur AusfĂŒhrung dieser Funktion angegeben werden (Admin – gemeinsame PostfĂ€cher) des Mailservers.

Ich hoffe, mein Artikel wird den Administratoren von Kerio Connect nĂŒtzlich sein.

Quelle: habr.com

60GB SSD 8Gb DDR4