Buongiorno, Habr!
Compito
Nella mia organizzazione utilizziamo un server di posta sulla piattaforma Kerio Connect, con server di posta installati in diverse città che servono i propri utenti. Non c'era una struttura distribuita all'inizio, poiché i domini differiscono a livello di terzo livello indicando la città della sede. Tutto funzionava e tutti erano soddisfatti. Un bel giorno, la dirigenza ha posto la sfida di un calendario comune per tutti i siti!
Antefatti
Inizialmente l'idea era di attivare un dominio di posta distribuito Kerio che avrebbe fatto tutto da solo. Detto, fatto: il dominio distribuito è stato creato, ma non è andata così, il server era pronto a sincronizzare calendari, folder, contatti tra domini situati sullo stesso server, ma non era affatto disposto a sincronizzare i dati tra più server.
Un colpo del genere, naturalmente, non me l'aspettavo e per molto tempo non potevo credere all'assenza della funzionalità di cui avevo bisogno. Più tardi ho trovato documentazione a conferma di questo fatto, il che mi ha molto sorpreso e deluso.
La sfida è gradualmente diventata un problema.
Quali erano le opzioni?
- Creare due client su server diversi, che scambiassero i dati necessari tramite un software di terze parti. Dovevo trovare proprio questo software di terze parti che implementasse questa funzionalità: non amo queste complicazioni, ma sembrava che fosse l'unica soluzione rapida.
- Scrivere il mio script di sincronizzazione dati tra server. Il fatto è che Kerio memorizza ogni oggetto come file separato, quindi era necessario sviluppare uno script per lavorare con i file, ma vista l'abbondanza di fonti, il compito sembrava piuttosto complesso, soprattutto perché era necessario effettuare molteplici controlli di correttezza dei dati, nel caso in cui qualcuno creasse un'attività nello stesso intervallo di tempo, e così via.
Anticipando gli eventi, posso dire che Kerio, anche se memorizza l'oggetto come file separato, non è così stupido da chiedere ogni volta che si accede all'oggetto: come sta il file system.
Dopo aver trascorso molto tempo a riflettere, riempiendo un mucchio di fogli con piani 'per la conquista del territorio nemico', alle sei ho preso due decisioni corrette:
- La prima decisione – fare il mio e non cercare nulla di esterno.
- La seconda decisione – andare a dormire.
Già al mattino mi sono svegliato con un solo pensiero chiaro e fermo, ridotto a poche lettere – DFS
Soluzione
La soluzione stessa si presentava nel seguente modo
- portare tutti i server che parteciperanno alla sincronizzazione a OS Windows. (Parte era su Linux. era necessaria una migrazione dei dati postali su un'altra OS)
- Stabilire la struttura delle directory che parteciperanno alla sincronizzazione – devono essere identiche.
- Definire tutti i server di posta sotto un unico dominio con uno spazio DFS unificato.
- Creare il dominio distribuito Kerio sopra menzionato, poiché nel mio caso è necessaria la sincronizzazione dei dati non solo tra server ma anche tra domini, quest'ultimo potrà essere gestito autonomamente dal server Kerio. (a differenza del primo)
- Collegare le directory sincronizzate allo spazio DFS.
- Inventare qualche escamotage (perché senza escamotage non si può fare)
Implementazione
Esempio su due server di posta (potrebbero essercene di più)
1. Dominio distribuito Kerio

Il Master non partecipa alla sincronizzazione, ma non è una condizione obbligatoria.
Non tratterò di come impostare un dominio distribuito Kerio, non è così complicato, si può studiare il manuale ufficiale
Alla fine, nella console di amministrazione dovresti vedere la seguente immagine:
![]()

Successivamente ero interessato alle cartelle condivise, sul server Master è possibile specificare le seguenti opzioni:
![]()

Speciale per ogni dominio – il server non sincronizzerà le cartelle pubbliche tra i domini
Comune a tutti i domini – tutti i server rinunceranno alle cartelle pubbliche esistenti in ogni dominio e creeranno nuove cartelle unificate per tutti i domini su ciascun server di posta.
Attenzione! Questa opzione, sebbene cambi la politica di configurazione su tutti i server, esegue la sincronizzazione separatamente da ciascun server (cioè – senza uno spazio comune)
All'amministratore rimarrà la possibilità di distribuire gli accessi tra gli utenti.
nel mio caso – tutti i miei e ho bisogno di una sincronizzazione completa (Nel vostro caso la soluzione potrebbe essere diversa) su ogni server bisogna creare set di domini identici che devono essere sincronizzati.
2. Directory dei dati Kerio
Ora è necessario creare cartelle condivise identiche che devono essere sincronizzate su ciascuno dei server. Cartelle, Calendari, Contatti.
Consiglio: crea cataloghi in lingua inglese, altrimenti se li crei in latino, la directory avrà un nome in qualche codifica incomprensibile, il che è scomodo almeno.
Ora è necessario trovare i percorsi fisici delle cassette postali su ciascun server.
Comune a tutti i domini ~DataMailmail#publicCatalogo sincronizzato#msgs
Speciale per ogni dominio ~DataMailmail**Dominio**#publicCatalogo sincronizzato#msgs
Fai attenzione che sincronizzeremo non l'intero catalogo, ma solo il contenitore con i dati. #msgs — qui sono memorizzati gli oggetti stessi, tutti gli altri dati per ciascun server devono essere specifici.
3. DFS
Non entrerò nei dettagli su come configurare DFS, ci sono informazioni a sufficienza su questo argomento.
DFS è un servizio di ruolo in Windows Server che consente di unire cartelle condivise su server diversi.
Prima di configurare DFS, è necessario fermare tutti i server di posta che parteciperanno alla sincronizzazione dei dati.
Al termine della configurazione, dovresti ottenere la seguente vista per ciascuna delle cartelle sincronizzate.

Non è necessario pubblicare le cartelle replicate.

Dopo che la replicazione avrà avuto luogo (e non c'è molto da replicare — le cartelle sono vuote), i server di posta possono essere avviati.
Dopo di che, puoi riempire uno dei server di posta con i dati e verificare che i dati vengano replicati correttamente.
4. Soluzione alternativa
Descrizione della riflessione
Come puoi vedere, dopo che i dati hanno iniziato a sincronizzarsi (DFS), se hai creato qualcosa sul primo server, sul secondo server nulla appare, oppure appare ma non sempre.
Non disperare, ovviamente comparirà, prima o poi, ma è meglio prima che dopo. Perché dopo significa tra 6 e 12 ore.
Il fatto è che non appena crei qualcosa sul primo server, sul secondo e successivi file appariranno immediatamente grazie al sistema DFS, tuttavia se questa cartella di posta è già stata letta da qualcuno in precedenza e viene richiesta nuovamente, il server non rileggerà la cartella #msgs ma restituirà i dati dal suo indice, che potrebbe non corrispondere più alla nostra realtà.
Kerio ha un meccanismo per la lettura dell'indice, ma potrebbe attivarsi dopo circa sei ore, durante le quali la rilevanza del compito nel calendario potrebbe essere un po' persa.
Per controllare il funzionamento della sincronizzazione in questo momento, è possibile eliminare il file nella cartella sincronizzata index.fld; dopo aver riaperto la cartella sul server di posta e in assenza di questo file, Kerio rileggerà la cartella e i dati appariranno. Sembra una soluzione, eliminare il file quando i dati cambiano, ma questo funziona solo la prima volta, dopo di che Kerio sembra perdere interesse per index.fld.
Inoltre, inizia a sputare messaggi incomprensibili per l'utente — riguardo a qualche indice e che sta già facendo qualcosa.
C'è anche un'alternativa, creare qualcosa — nel momento in cui si crea un nuovo oggetto, il server potrebbe inspiegabilmente rendersi conto che il nome del file che voleva assegnare è già occupato, ma qui è una palla di neve e questo è un vicolo cieco.
Cosa fare allora?
Se prestiamo ancora una volta attenzione all'immagine che già conosciamo.

Ma in un altro contesto, possiamo notare un pulsante molto interessante e utile per noi adesso — Reindicizza le cartelle
E in effetti. Se premiamo questo pulsante sul server di posta, che non sa che qualcosa è già cambiato in #msgs sincronizzato, otterremo un risultato stabile e veloce. Tutto ciò che è nascosto diventerà visibile.
Nel registro si può vedere quanto tempo richiede questo processo, nel mio caso con diverse migliaia (15 mila) di record circa 3-4 minuti.
Resta solo da trovare un modo per premere questo pulsante quando ne abbiamo bisogno.
Si scopre che Kerio ha una propria API
funzione che esegue il nostro compito, si presenta così —
session = callMethod("Domains.checkPublicFoldersIntegrity",{}, token)
Da tutto quanto sopra, dobbiamo scrivere uno script che monitori lo stato delle cartelle di interesse e, nel caso in cui qualcosa cambi, esegua per noi la funzione necessaria.
Voglio dire che ho scritto diverse versioni di script che eseguono controlli diversi, ma mi sono fermato a quello che costruisce tutte le uscite in base al numero di file.
Implementazione dello script
Esempio di script CMD e descrizione
Re-index.bat
@echo off
set dir=%~dp0
%dir:~0,2%
CD "%~dp0"
md "%LOG"
md "%Setup"
ECHO -Inizio- >> "%LOG%Computername%.log"
ECHO Inizio -> %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 Cartella = %c%
ECHO Cartella = %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-Inizio
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 Conteggio [ !1DirSize%id%! -- !2DirSize%id%! ]
if "!1DirSize%id%!" == "!2DirSize%id%!" ECHO Sincronizzato
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 Riconteggio && ECHO Riconteggio te% %Time% - Elimina !m%id%! >> "%LOG%Computername%.log"
set 1DirSize!id!=!2DirSize%id%!
ECHO.
ECHO.
set /a id+=1
goto Find
:Reindex
ECHO. >> "%LOG%Computername%.log"
ECHO --- RICONTEGGIO - Inizio - te% %Time% --- >> "%LOG%Computername%.log"
ECHO. >> ----------------------------------- >> "%LOG%Computername%.log"
call PublicFolders.py
timeout 60
goto start
exit
Una copia dello script viene eseguita su ogni server di posta (può essere come servizio, non sono necessari diritti di amministratore)
Lo script legge il file Setup%Computername%.List
Dove %Computername% è il nome del server attuale (la directory può contenere direttamente elenchi di tutti i server.)
Il file %Computername%.List contiene i percorsi completi delle directory sincronizzate, ogni percorso è registrato in una nuova riga, non deve contenere righe vuote.
Dopo il primo avvio, lo script esegue la procedura di indicizzazione, indipendentemente dal fatto che sia necessaria o meno; lo script crea anche un indice del numero di file in ciascuna delle directory sincronizzate.
L'obiettivo dello script è contare tutti i file nella directory specificata.
Al termine del conteggio di ogni directory, se in almeno una directory il valore corrente dei file non coincide con il precedente, lo script elimina i file dalla directory radice del catalogo di posta sincronizzato: index.fld, indexlog.fld, search.fld e avvia il processo di indicizzazione delle cartelle pubbliche.
Nella directory LOG vengono accumulate informazioni sull'esecuzione dei compiti.
Il processo di indicizzazione
Il processo di indicizzazione consiste nell'eseguire la funzione API Kerio
Session = callMethod("Domains.checkPublicFoldersIntegrity",{}, token)
Esempio di esecuzione fornito su – python
PublicFolders.py
import json
import urllib.request
import http.cookiejar
""" La memorizzazione dei cookie è necessaria per la gestione delle sessioni """
jar = http.cookiejar.CookieJar()
opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(jar))
urllib.request.install_opener(opener)
""" Nome host o indirizzo IP della tua istanza Kerio Control con protocollo, porta e credenziali """
server = "http://127.0.0.1:4040"
username = "user"
password = "password"
def callMethod(method, params, token = None):
"""
Chiama remotamente il metodo dato con i parametri forniti.
:param: method string con il nome completo del metodo
:param: params dict con i parametri del metodo chiamato remotamente
:param: token Il token CSRF è sempre richiesto tranne nel metodo di login. Usa il metodo "Session.login" per ottenere questo 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)
puoi lasciarlo così com'è, tuttavia se hai bisogno di HTTPS — python deve fidarsi del certificato Kerio.
Inoltre, nel file è necessario specificare un'account con diritti per eseguire questa funzione (Admin – cartelle pubbliche condivise) del server di posta.
Spero che il mio articolo sarà utile agli amministratori di Kerio Connect.
Fonte: habr.com
