Sincronizzazione completa di cartelle condivise, contatti, calendari tra server Kerio Connect distribuiti

Buon pomeriggio, Habr!

Compito

La mia organizzazione utilizza un server di posta sulla piattaforma Kerio Connect; i server di posta sono installati in diverse città per servire i propri utenti. Inizialmente non esisteva una struttura distribuita, poiché i domini si differenziano al terzo livello, indicando la città del sito. Tutto ha funzionato e tutti erano contenti. Un bel giorno, la direzione ha fissato un compito, un calendario di attività comune a tutti i siti!

Sfondo

Inizialmente, l'idea era di creare il dominio di posta distribuita Kerio e avrebbe fatto tutto da solo. Detto fatto, è stato creato un dominio distribuito, ma non era così, il server era pronto per sincronizzare calendari, cartelle, contatti - tra domini situati sullo stesso server, ma non sincronizzava affatto i dati tra diversi server.

Ovviamente non mi aspettavo una simile cattura e per molto tempo non potevo credere che mancasse la funzionalità di cui avevo bisogno. Più tardi ho trovato prove documentali di questo fatto. Sono rimasto molto perplesso e deluso da questo.

Il compito si trasformò senza problemi in un problema.

Quali erano le opzioni?

  • Crea due client su server diversi che scambiano i dati necessari con alcuni software di terze parti. Era necessario trovare questo software di terze parti che implementasse questa funzionalità: non mi piace questo rake, ma sembrava che questa fosse l'unica soluzione rapida.
  • Scrivi il tuo script per la sincronizzazione dei dati tra i server. Il fatto è che Kerio memorizza ogni oggetto come un file separato, quindi è stato necessario sviluppare uno script per lavorare con i file, ma in considerazione del numero sufficiente di fonti, l'attività sembrava alquanto complicata, soprattutto perché era necessario eseguire più controlla la correttezza dei dati, nel caso qualcuno crei un'attività nello stesso periodo di tempo, ecc., ecc.

Guardando al futuro, dirò che sebbene Kerio memorizzi un oggetto come un file separato, non è così stupido da chiedersi come sta il file system ogni volta che si accede all'oggetto.

Dopo aver passato molto tempo a pensare, a redigere un mucchio di pezzi di carta con piani per "conquistare il territorio nemico", alle 6 ho preso due decisioni giuste:

  • La prima decisione è fare le proprie cose e non cercare nulla dall’esterno.
  • La seconda soluzione è andare a dormire.

Già al mattino mi sono svegliato con un unico e vero pensiero, ridotto a poche lettere: DFS

Soluzione

La soluzione stessa appariva così

  • portare tutti i server che parteciperanno alla sincronizzazione sul sistema operativo Windows. (Parte era su Linux. Era necessaria la migrazione dei dati di posta su un altro sistema operativo)
  • Determina la struttura delle directory che parteciperanno alla sincronizzazione: devono essere identiche.
  • Definisci tutti i server di posta sotto un dominio con un singolo spazio DFS.
  • Creare il suddetto dominio Kerio distribuito, poiché nel mio caso è necessaria la sincronizzazione dei dati, non solo tra server ma anche tra domini; il secondo può essere gestito dal server Kerio in modo indipendente. (a differenza del primo)
  • Imposta le directory sincronizzate sullo spazio DFS.
  • Trova una specie di stampella (dopo tutto, non puoi vivere senza stampella)

implementazione

Esempio su due server di posta (forse di più)

1. Dominio distribuito Kerio

Sincronizzazione completa di cartelle condivise, contatti, calendari tra server Kerio Connect distribuiti

Il Master non partecipa alla sincronizzazione, ma questo non è un prerequisito.

Non descriverò come creare un dominio distribuito Kerio, non c'è niente di complicato in questo, puoi studiare il funzionario manul

Alla fine, dovresti vedere la seguente immagine nella console di amministrazione:

Sincronizzazione completa di cartelle condivise, contatti, calendari tra server Kerio Connect distribuiti

Sincronizzazione completa di cartelle condivise, contatti, calendari tra server Kerio Connect distribuiti

Successivamente mi interessavano le cartelle condivise; sul server Master è possibile specificare le seguenti opzioni:

Sincronizzazione completa di cartelle condivise, contatti, calendari tra server Kerio Connect distribuiti

Sincronizzazione completa di cartelle condivise, contatti, calendari tra server Kerio Connect distribuiti

Specifico per ogni dominio - il server non sincronizzerà le cartelle pubbliche tra domini

Comune a tutti i domini - tutti i server abbandoneranno le cartelle pubbliche esistenti in ciascun dominio e creeranno nuove cartelle singole per tutti i domini su ciascun server di posta.

Attenzione! Sebbene questa opzione modifichi la politica di configurazione su tutti i server, si sincronizza separatamente da ciascun server (ovvero senza un singolo spazio comune)

L'amministratore avrà comunque la possibilità di distribuire l'accesso tra gli utenti.
nel mio caso sono tutti miei e ho bisogno della sincronizzazione completa (nel tuo caso la soluzione potrebbe essere diversa) su ogni server è necessario creare insiemi identici di domini da sincronizzare.

2. Directory di dati Kerio

Ora devi creare directory condivise identiche che devono essere sincronizzate su ciascuno dei server. Cartelle, calendari, contatti.

Consiglio: crea directory in inglese, se le crei in latino, la directory avrà un nome in una codifica incomprensibile, questo è almeno scomodo.

Ora devi trovare i percorsi fisici delle cartelle di posta su ciascun server.

Comune a tutti i domini ~DataMailmail#publicСинхронизируемый каталог#msgs
Specifico per ogni dominio ~DataMailmail**Domain**#publicСинхронизируемый каталог#msgs

Tieni presente che non sincronizzeremo l'intera directory, ma solo il contenitore con i dati #msgs — gli oggetti stessi vengono archiviati qui, tutti gli altri dati devono essere separati per ciascun server.

3.DFS

Non descriverò in dettaglio come configurare DFS, ci sono abbastanza informazioni su questo problema.

DFS è un servizio ruolo in Windows Server che offre la possibilità di combinare cartelle condivise posizionate su server diversi
Collegamento al documento MS DFS

Prima di configurare DFS, è necessario arrestare tutti i server di posta che parteciperanno alla sincronizzazione dei dati.

Al termine della configurazione, dovresti ricevere la seguente immagine per ciascuna delle cartelle sincronizzate

Sincronizzazione completa di cartelle condivise, contatti, calendari tra server Kerio Connect distribuiti

Naturalmente non abbiamo bisogno di pubblicare cartelle replicate.

Sincronizzazione completa di cartelle condivise, contatti, calendari tra server Kerio Connect distribuiti

Dopo che è avvenuta la replica (e non c'è niente di speciale da replicare lì - le cartelle sono vuote), è possibile avviare i server di posta.

Successivamente, puoi riempire uno dei server di posta con i dati e verificare che i dati vengano replicati correttamente.

4. Stampella

Descrizione della riflessione

Come puoi vedere dopo l'avvio della sincronizzazione dei dati (DFS), se hai creato qualcosa sul primo server, in qualche modo non appare nulla sul secondo server, oppure appare ma in qualche modo non sempre.

Non disperare; ovviamente prima o poi apparirà lì, ma meglio prima che poi. Perché tra 6 – 12 ore è troppo tardi.

Il fatto è che non appena hai creato qualcosa sul primo server, sul secondo e sui server successivi il file apparirà ovviamente immediatamente grazie al sistema DFS, ma nel caso in cui questa directory di posta sia già stata letta da qualcuno prima e viene nuovamente richiesto, il server non rileggerà la cartella #msgs ma sputerà dati dal proprio indice, che potrebbero non corrispondere più alla nostra realtà.

Kerio ha un meccanismo per rileggere l'indice, ma può funzionare in circa sei ore e durante queste 6 ore la pertinenza dell'attività nel calendario potrebbe essere leggermente persa.
Per testare subito la sincronizzazione, puoi eliminare il file nella directory sincronizzata corrispondente index.fld, dopo aver riacceso alla cartella sul server di posta e se questo file manca, Kerio rileggerà la directory e i dati apparirà. Sembrerebbe che questa sia la soluzione, elimina il file quando i dati cambiano, ma questo non funziona ogni volta, ma solo la prima volta, quindi Kerio per qualche motivo perde ogni interesse per index.fld
Inizia anche a sputare messaggi incomprensibili per l'utente - su una sorta di indice e sul fatto che sta già facendo qualcosa lì.

C'è un'altra opzione, per creare qualcosa: al momento della creazione di un nuovo oggetto, il server si rende conto improvvisamente che il nome del file che voleva assegnare è già occupato, ma la situazione aumenta a dismisura e questa è un'opzione senza uscita.

Come può essere?

Se prestiamo ancora una volta attenzione all'immagine che ci è già familiare.

Sincronizzazione completa di cartelle condivise, contatti, calendari tra server Kerio Connect distribuiti

Ma su un altro aereo puoi vedere un pulsante molto interessante di cui abbiamo bisogno ora: Reindicizzare le cartelle

E senza dubbio. Se clicchiamo su questo pulsante su un server di posta che non sa che qualcosa è già cambiato nei #msg sincronizzati, otterremo un risultato stabile e veloce. Tutto ciò che è nascosto diventerà chiaro.

Nel log puoi vedere quanto tempo impiega questo processo; nel mio caso con diverse migliaia (15mila) record ci vogliono circa 3-4 minuti.

Tutto quello che dobbiamo fare è capire come premere effettivamente questo pulsante quando ne abbiamo bisogno.

Si scopre Kerio hanno il loro API

descrizione
Documentazione

La funzione che esegue il nostro compito è simile alla seguente:
session = callMethod("Domains.checkPublicFoldersIntegrity",{}, token)

Da tutto quanto sopra, dobbiamo scrivere uno script che monitori lo stato delle cartelle di interesse e, se qualcosa è cambiato, svolga la funzione di cui abbiamo bisogno.

Voglio dire che ho scritto diverse versioni di script che eseguono controlli diversi e ho optato per quello che trae tutte le conclusioni in base al numero di file.

Implementazione dello script

Esempio e descrizione dello script CMD

Reindicizzare.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

Una copia dello script viene eseguita su ciascun server di posta (può essere utilizzata come servizio, i diritti di amministratore non sono richiesti)

Lo script legge il file Setup%Computername%.List

Dove %Nomecomputer% è il nome del server corrente (la directory può contenere elenchi di tutti i server contemporaneamente.)

Il file %NomeComputer%.Elenco – contiene i percorsi completi delle directory sincronizzate, ogni percorso viene scritto su una nuova riga e non deve contenere righe vuote.

Dopo il primo avvio, lo script esegue la procedura di indicizzazione, indipendentemente dal fatto che sia necessaria o meno, e crea anche un indice del numero di file in ciascuna directory sincronizzata.

Lo scopo dello script è contare tutti i file nella directory specificata.

Al termine del conteggio di ciascuna directory, se in almeno una directory il valore corrente dei file non corrisponde a quello precedente, lo script elimina i file dalla directory root della directory di posta sincronizzata: index.fld, indexlog.fld, search.fld e avvia il processo di indicizzazione delle cartelle di posta condivise.

Le informazioni sull'esecuzione dell'attività vengono scaricate nella directory LOG.

Processo di indicizzazione
Il processo di indicizzazione si riduce all'esecuzione di una funzione API Kerio
Sessione = callMethod("Domains.checkPublicFoldersIntegrity",{}, token)

Un esempio di implementazione è fornito 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 puoi lasciarlo così com'è, ma se richiedi HTTPS, Python deve fidarsi del certificato Kerio.

Inoltre nel file è necessario specificare un account con diritti per eseguire questa funzione (Adm - cartelle di posta pubbliche) del server di posta.

Spero che il mio articolo possa essere utile agli amministratori di Kerio Connect.

Fonte: habr.com

Aggiungi un commento