Dobré odpoledne, Habr!
Úkol
Moje organizace používá poštovní server na platformě Kerio Connect, poštovní servery jsou instalovány v různých městech, aby mohly sloužit svým uživatelům. Zpočátku neexistovala žádná distribuovaná struktura, protože domény se na třetí úrovni liší a označují město místa. Všechno fungovalo a všichni byli spokojeni. Jednoho krásného dne vedení stanovilo úkol, společný kalendář aktivit mezi všemi lokalitami!
pravěk
Původně bylo myšlenkou zvýšit doménu Kerio Distributed Mail, která by vše dělala sama. Hned jak bylo řečeno, byla vytvořena distribuovaná doména, ale nebylo tomu tak, server byl připraven na synchronizaci kalendářů, složek, kontaktů - mezi doménami umístěnými na stejném serveru, ale vůbec se nechystal synchronizovat data mezi několika servery.
Takový úlovek jsem samozřejmě nečekal a dlouho jsem nemohl uvěřit, že funkce, kterou jsem potřeboval, chybí. Později jsem našel listinné důkazy o této skutečnosti. Byl jsem z toho velmi zmatený a zklamaný.
Úkol se plynule změnil v problém.
Jaké byly možnosti?
- Vytvořte dva klienty na různých serverech, kteří si vyměňují potřebná data s nějakým softwarem třetích stran. Bylo nutné najít tento software třetí strany, který by tuto funkcionalitu implementoval - nemám rád takové rake, ale zdálo se, že to bylo jediné rychlé řešení.
- Napište si vlastní skript pro synchronizaci dat mezi servery. Faktem je, že Kerio ukládá každý objekt jako samostatný soubor, takže bylo nutné vyvinout skript pro práci se soubory, ale vzhledem k dostatečnému počtu zdrojů se úkol zdál poněkud komplikovaný, zejména proto, že bylo nutné provést více kontroluje správnost údajů, v případě, že někdo vytvoří úkol ve stejném časovém období atd. atd.
Při pohledu do budoucna řeknu, že ačkoliv Kerio ukládá objekt jako samostatný soubor, není tak hloupé se při každém přístupu k objektu ptát, jak je na tom souborový systém.
Poté, co jsem strávil spoustu času přemýšlením, sestavením hromady papírků s plány „obsadit nepřátelské území“, jsem v 6 hodin učinil dvě správná rozhodnutí:
- První rozhodnutí je dělat si po svém a nehledat nic zvenčí.
- Druhým řešením je jít spát.
Už ráno jsem se probudil s jedinou a pravdivou myšlenkou, která byla zredukována na pár písmen - DFS
rozhodnutí
Samotné řešení vypadalo takto
- přenést všechny servery, které se budou podílet na synchronizaci, do OS Windows. (Část to bylo na Linuxu. Byla vyžadována migrace dat pošty do jiného OS)
- Určete strukturu adresářů, které se budou podílet na synchronizaci – musí být totožné.
- Definujte všechny poštovní servery pod jednou doménou s jediným prostorem DFS.
- Vytvořte výše zmíněnou distribuovanou doménu Kerio, protože v mém případě je nutná synchronizace dat nejen mezi servery, ale i mezi doménami, tu druhou zvládne Kerio server samostatně. (na rozdíl od prvního)
- Nastavte synchronizované adresáře na prostor DFS.
- Vymyslete nějakou berličku (koneckonců, bez berliček nemůžete žít)
uskutečnění
Příklad na dvou poštovních serverech (možná více)
1. Distribuovaná doména Kerio
Master se neúčastní synchronizace, ale není to podmínkou.
Nebudu popisovat, jak získat distribuovanou doménu Kerio, není na tom nic složitého, můžete si prostudovat oficiální
Nakonec byste v administrační konzoli měli vidět následující obrázek:
Dále mě zajímaly sdílené složky, na Master serveru můžete zadat následující možnosti:
Specifické pro každou doménu - server nebude synchronizovat veřejné složky mezi doménami
Společné pro všechny domény - všechny servery opustí stávající veřejné složky v každé doméně a vytvoří nové samostatné složky pro všechny domény na každém poštovním serveru.
Varování! Přestože tato možnost mění zásady konfigurace na všech serverech, synchronizuje se odděleně od každého serveru (tj. bez jediného společného prostoru)
Správce bude mít stále možnost distribuovat přístup mezi uživatele.
v mém případě jsou všechny moje a potřebuji plnou synchronizaci (ve vašem případě může být řešení jiné) na každém serveru je potřeba vytvořit identické sady domén, které je třeba synchronizovat.
2. Datové adresáře Kerio
Nyní musíte vytvořit identické sdílené adresáře, které je třeba synchronizovat na každém ze serverů. Složky, kalendáře, kontakty.
Rada - vytvářejte adresáře v angličtině, pokud je vytvoříte v latině, adresář bude mít název v nějakém nesrozumitelném kódování, to je přinejmenším nepohodlné.
Nyní musíte najít fyzické cesty k poštovním složkám na každém serveru.
Společné pro všechny domény ~DataMailmail#publicСинхронизируемый каталог#msgs
Specifické pro každou doménu ~DataMailmail**Domain**#publicСинхронизируемый каталог#msgs
Upozorňujeme, že nebudeme synchronizovat celý adresář, ale pouze kontejner s daty #msgs — zde jsou uloženy samotné objekty, všechna ostatní data musí být pro každý server samostatná.
3.DFS
Nebudu podrobně popisovat, jak nakonfigurovat DFS, o tomto problému je dostatek informací.
DFS je služba role v systému Windows Server, která poskytuje možnost kombinovat sdílené složky umístěné na různých serverech
Před nastavením DFS musíte zastavit všechny poštovní servery, které se budou podílet na synchronizaci dat.
Po dokončení nastavení byste měli obdržet následující obrázek pro každou ze synchronizovaných složek
Samozřejmě nemusíme publikovat replikované složky.
Po provedení replikace (a není tam nic zvláštního, co by se tam replikovalo - složky jsou prázdné), lze spustit poštovní servery.
Dále můžete naplnit jeden z poštovních serverů daty a zkontrolovat, zda jsou data správně replikována.
4. Berlička
Popis odrazu
Jak můžete vidět poté, co se data začnou synchronizovat (DFS), pokud jste buď něco vytvořili na prvním serveru, na druhém serveru se nějak nic neobjeví, nebo se objeví, ale nějak ne vždy.
Nezoufejte, samozřejmě, že se tam dříve nebo později objeví, ale lépe dříve než později. Protože za 6-12 hodin je pozdě.
Jde o to, že jakmile něco vytvoříte na prvním serveru, na druhém a dalších serverech se soubor samozřejmě okamžitě objeví díky systému DFS, ale v případě, že tento poštovní adresář již někdo četl a je znovu požadováno, server nebude znovu číst složku #msgs, ale vyplivne data ze svého vlastního indexu, který již nemusí odpovídat naší realitě.
Kerio má mechanismus pro opětovné načtení indexu, ale ten může fungovat zhruba za šest hodin a během těchto 6 hodin se může relevance úkolu v kalendáři poněkud ztratit.
Abyste mohli synchronizaci hned vyzkoušet, můžete smazat soubor v odpovídajícím synchronizovaném adresáři index.fld, po opětovném přístupu ke složce na poštovním serveru a pokud tento soubor chybí, Kerio znovu načte adresář a data objeví se. Zdálo by se, že toto je řešení, smažte soubor při změně dat, ale nefunguje to pokaždé, ale pouze poprvé, pak Kerio z nějakého důvodu ztratí veškerý zájem o index.fld
Taky to začne chrlit zprávy, které jsou pro uživatele nesrozumitelné - o nějakém indexu a že už to tam něco dělá.
Existuje další možnost, něco vytvořit - v okamžiku vytváření nového objektu si server najednou uvědomí, že název souboru, který chtěl přiřadit, je již obsazený, ale sněží a toto je slepá volba.
Jak je to možné?
Pokud ještě jednou věnujeme pozornost obrázku, který je nám již známý.
Ale na jiném letadle můžete vidět velmi zajímavé tlačítko, které nyní potřebujeme - Přeindexovat složky
A vskutku. Pokud na toto tlačítko klikneme na poštovním serveru, který neví, že se v synchronizovaném #msgs již něco změnilo, dostaneme stabilní, rychlý výsledek. Vše skryté bude jasné.
V logu vidíte, jak dlouho tento proces trvá, v mém případě s několika tisíci (15 tisíci) záznamy to trvá cca 3-4 minuty.
Jediné, co musíme udělat, je vymyslet, jak vlastně toto tlačítko stisknout, když ho potřebujeme.
Ukazuje se Kerio mít vlastní API
Funkce, která provádí náš úkol, vypadá takto:
session = callMethod("Domains.checkPublicFoldersIntegrity",{}, token)
Ze všeho výše uvedeného musíme napsat skript, který by sledoval stav zájmových složek a pokud by se něco změnilo, provedl funkci, kterou potřebujeme.
Chci říci, že jsem napsal několik různých verzí skriptů, které provádějí různé kontroly, a rozhodl jsem se pro tu, která vyvozuje všechny závěry na základě počtu souborů.
Implementace skriptu
Příklad a popis skriptu CMD
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
Kopie skriptu běží na každém poštovním serveru (lze použít jako službu, nejsou vyžadována práva správce)
Skript přečte soubor Setup%Computername%.List
Kde %Computername% je název aktuálního serveru (Adresář může obsahovat seznamy všech serverů najednou.)
Soubor %Computername%.List – obsahuje úplné cesty k synchronizovaným adresářům, každá cesta je zapsána na nový řádek a neměla by obsahovat prázdné řádky.
Po prvním spuštění skript provede indexaci bez ohledu na to, zda je to nutné nebo ne, a skript také vytvoří index počtu souborů v každém synchronizovaném adresáři.
Účelem skriptu je spočítat všechny soubory v zadaném adresáři.
Na konci počítání každého adresáře, pokud alespoň v jednom adresáři aktuální hodnota souborů neodpovídá předchozí, skript odstraní soubory z kořenového adresáře adresáře synchronizované pošty: index.fld, indexlog.fld, search.fld
a spustí proces indexování sdílených poštovních složek.
Informace o provedení úlohy se uloží do adresáře LOG.
Proces indexování
Proces indexování spočívá ve spuštění funkce rozhraní Kerio API
Session = callMethod("Domains.checkPublicFoldersIntegrity",{}, token)
Příklad implementace je uveden v – 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)
Také v souboru musíte zadat účet s právy k provádění této funkce (Adm - veřejné poštovní složky) poštovního serveru.
Doufám, že můj článek bude pro administrátory Kerio Connect užitečný.
Zdroj: www.habr.com