Bonjour, Habr !
Tâche
Mon organisation utilise un serveur de messagerie sur la plateforme Kerio Connect ; les serveurs de messagerie sont installés dans différentes villes pour servir leurs utilisateurs. Initialement, il n'y avait pas de structure distribuée, puisque les domaines diffèrent au troisième niveau, indiquant la ville du site. Tout a fonctionné et tout le monde était content. Un beau jour, la direction s'est fixé une tâche, un calendrier commun d'activités entre tous les sites !
Préhistoire
Au départ, l'idée était d'augmenter le domaine de messagerie distribué Kerio et il ferait tout lui-même. Aussitôt dit, aussitôt fait, un domaine distribué a été créé, mais ce n'était pas le cas, le serveur était prêt à synchroniser des calendriers, des dossiers, des contacts - entre des domaines situés sur un même serveur, mais n'allait pas du tout synchroniser les données entre plusieurs les serveurs.
Bien sûr, je ne m'attendais pas à une telle prise et pendant longtemps je n'ai pas pu croire qu'il manquait la fonctionnalité dont j'avais besoin. Plus tard, j'ai trouvé des preuves documentaires de ce fait. J'ai été très perplexe et déçu par cela.
La tâche s’est transformée en problème.
Quelles étaient les options ?
- Créez deux clients sur des serveurs différents qui échangent les données nécessaires avec des logiciels tiers. Il était nécessaire de trouver ce logiciel tiers qui implémenterait cette fonctionnalité - je n'aime pas un tel rake, mais il semblait que c'était la seule solution rapide.
- Écrivez votre propre script pour la synchronisation des données entre les serveurs. Le fait est que Kerio stocke chaque objet dans un fichier séparé, il était donc nécessaire de développer un script pour travailler avec des fichiers, mais compte tenu du nombre suffisant de sources, la tâche semblait quelque peu compliquée, d'autant plus qu'il fallait effectuer plusieurs vérifie l'exactitude des données, au cas où quelqu'un créerait une tâche dans le même laps de temps, etc., etc.
Pour l'avenir, je dirai que même si Kerio stocke un objet dans un fichier séparé, il n'est pas si stupide de se demander comment se comporte le système de fichiers à chaque fois que vous accédez à l'objet.
Après avoir passé beaucoup de temps à réfléchir, à rédiger un tas de morceaux de papier avec des plans « pour s'emparer du territoire ennemi », à 6 heures, j'ai pris deux bonnes décisions :
- La première décision est de faire ce que vous voulez et de ne rien chercher à l’extérieur.
- La deuxième solution est d'aller dormir.
Déjà le matin, je me suis réveillé avec une seule et vraie pensée, réduite à quelques lettres - DFS
décision
La solution elle-même ressemblait à ceci
- apportez tous les serveurs qui participeront à la synchronisation vers le système d'exploitation Windows. (Une partie était sous Linux. La migration des données de messagerie vers un autre système d'exploitation était nécessaire)
- Déterminez la structure des répertoires qui participeront à la synchronisation - ils doivent être identiques.
- Définissez tous les serveurs de messagerie sous un seul domaine avec un seul espace DFS.
- Créez le domaine Kerio distribué mentionné ci-dessus, car dans mon cas, la synchronisation des données est requise, non seulement entre les serveurs mais aussi entre les domaines ; la seconde peut être gérée indépendamment par le serveur Kerio. (contrairement au premier)
- Définissez les répertoires synchronisés sur l'espace DFS.
- Trouvez une sorte de béquille (après tout, vous ne pouvez pas vivre sans béquille)
exécution
Exemple sur deux serveurs de messagerie (peut-être plus)
1. Domaine distribué Kerio
Le Maître ne participe pas à la synchronisation, mais ce n'est pas un prérequis.
Je ne décrirai pas comment créer un domaine distribué Kerio, il n'y a rien de compliqué là-dedans, vous pouvez étudier le fonctionnaire
Au final, vous devriez voir l'image suivante dans la console d'administration :
Ensuite, je me suis intéressé aux dossiers partagés ; sur le serveur Maître, vous pouvez spécifier les options suivantes :
Spécifique à chaque domaine - le serveur ne synchronisera pas les dossiers publics entre domaines
Commun à tous les domaines - tous les serveurs abandonneront les dossiers publics existants dans chaque domaine et créeront de nouveaux dossiers uniques pour tous les domaines sur chaque serveur de messagerie.
Attention! Bien que cette option modifie la politique de configuration sur tous les serveurs, elle se synchronise séparément de chaque serveur (c'est-à-dire sans un seul espace commun).
L'administrateur aura toujours la possibilité de répartir l'accès entre les utilisateurs.
dans mon cas, ils sont tous à moi et j'ai besoin d'une synchronisation complète (dans votre cas, la solution peut être différente) sur chaque serveur, vous devez créer des ensembles identiques de domaines qui doivent être synchronisés.
2. Répertoires de données Kerio
Vous devez maintenant créer des répertoires partagés identiques qui doivent être synchronisés sur chacun des serveurs. Dossiers, calendriers, contacts.
Conseil - créez des répertoires en anglais, si vous les créez en latin, le répertoire aura un nom dans un encodage incompréhensible, c'est pour le moins gênant.
Vous devez maintenant trouver les chemins physiques des dossiers de messagerie sur chaque serveur.
Commun à tous les domaines ~DataMailmail#publicСинхронизируемый каталог#msgs
Spécifique à chaque domaine ~DataMailmail**Domain**#publicСинхронизируемый каталог#msgs
Veuillez noter que nous ne synchroniserons pas l'intégralité du répertoire, mais uniquement le conteneur avec les données #msgs — les objets eux-mêmes sont stockés ici, toutes les autres données doivent être séparées pour chaque serveur.
3.DFS
Je ne décrirai pas en détail comment configurer DFS, il existe suffisamment d'informations sur ce problème.
DFS est un service de rôle dans Windows Server qui offre la possibilité de combiner des dossiers partagés situés sur différents serveurs
Avant de configurer DFS, vous devez arrêter tous les serveurs de messagerie qui participeront à la synchronisation des données.
Une fois la configuration terminée, vous devriez recevoir l'image suivante pour chacun des dossiers synchronisés
Naturellement, nous n’avons pas besoin de publier des dossiers répliqués.
Une fois la réplication effectuée (et il n'y a rien de spécial à répliquer ici - les dossiers sont vides), les serveurs de messagerie peuvent être démarrés.
Ensuite, vous pouvez remplir l'un des serveurs de messagerie avec des données et vérifier que les données sont correctement répliquées.
4. Béquille
Description de la réflexion
Comme vous pouvez le voir après le début de la synchronisation des données (DFS), si vous avez créé quelque chose sur le premier serveur, rien n'apparaît sur le deuxième serveur, ou cela apparaît, mais pas toujours.
Ne désespérez pas ; bien sûr, il y apparaîtra tôt ou tard, mais mieux vaut le plus tôt possible. Parce qu'il est trop tard dans 6 à 12 heures.
Le fait est que dès que vous avez créé quelque chose sur le premier serveur, sur le deuxième serveur et les suivants, le fichier apparaîtra bien sûr immédiatement grâce au système DFS, mais dans le cas où ce répertoire de messagerie a déjà été lu par quelqu'un auparavant et est à nouveau demandé, le serveur ne relira pas le dossier #msgs mais crachera les données de son propre index, ce qui risque de ne plus correspondre à notre réalité.
Kerio dispose d'un mécanisme pour relire l'index, mais il peut fonctionner en six heures environ, et pendant ces 6 heures, la pertinence de la tâche dans le calendrier peut être quelque peu perdue.
Afin de tester la synchronisation dès maintenant, vous pouvez supprimer le fichier dans le répertoire synchronisé correspondant index.fld, après avoir ré-accédé au dossier sur le serveur de messagerie et si ce fichier est manquant, Kerio relira le répertoire et les données apparaîtra. Il semblerait que ce soit la solution, supprimez le fichier lorsque les données changent, mais cela ne fonctionne pas à chaque fois, mais seulement la première fois, alors Kerio, pour une raison quelconque, perd tout intérêt pour index.fld
Il commence également à cracher des messages incompréhensibles pour l'utilisateur - à propos d'une sorte d'index et indiquant qu'il y fait déjà quelque chose.
Il existe une autre option, créer quelque chose - au moment de créer un nouvel objet, le serveur se rend soudain compte que le nom de fichier qu'il voulait attribuer est déjà pris, mais cela fait boule de neige et c'est une option sans issue.
Comment est-ce possible?
Si nous prêtons encore une fois attention à l’image qui nous est déjà familière.
Mais sur un autre avion, vous pouvez voir un bouton très intéressant dont nous avons besoin maintenant - Réindexer les dossiers
Et en effet. Si nous cliquons sur ce bouton sur un serveur de messagerie qui ne sait pas que quelque chose a déjà changé dans les #msgs synchronisés, nous obtiendrons un résultat stable et rapide. Tout ce qui est caché deviendra clair.
Dans le journal, vous pouvez voir combien de temps prend ce processus ; dans mon cas, avec plusieurs milliers (15 3) enregistrements, cela prend environ 4 à XNUMX minutes.
Tout ce que nous avons à faire est de trouver comment appuyer sur ce bouton lorsque nous en avons besoin.
Il se trouve que Kerio Ont leur propre API
La fonction qui exécute notre tâche ressemble à ceci :
session = callMethod("Domains.checkPublicFoldersIntegrity",{}, token)
À partir de tout ce qui précède, nous devons écrire un script qui surveillerait l'état des dossiers d'intérêt et, si quelque chose a changé, exécuterait la fonction dont nous avons besoin.
Je tiens à dire que j'ai écrit plusieurs versions différentes de scripts qui effectuent différentes vérifications et que j'ai opté pour celle qui tire toutes les conclusions en fonction du nombre de fichiers.
Implémentation de scripts
Exemple de script CMD et description
Réindexer.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
Une copie du script s'exécute sur chaque serveur de messagerie (peut être utilisée comme service, les droits Adm ne sont pas requis)
Le script lit le fichier Setup%Computername%.List
Où %Computername% est le nom du serveur actuel (le répertoire peut contenir des listes de tous les serveurs à la fois.)
Le fichier %Computername%.List – contient les chemins complets des répertoires synchronisés, chaque chemin est écrit sur une nouvelle ligne et ne doit pas contenir de lignes vides.
Après le premier lancement, le script effectue la procédure d'indexation, que cela soit nécessaire ou non, et le script crée également un index du nombre de fichiers dans chaque répertoire synchronisé.
Le but du script est de compter tous les fichiers du répertoire spécifié.
A la fin du comptage de chaque répertoire, si dans au moins un répertoire la valeur actuelle des fichiers ne correspond pas à la précédente, le script supprime les fichiers du répertoire racine du répertoire de messagerie synchronisé : index.fld, indexlog.fld, search.fld
et démarre le processus d'indexation des dossiers de messagerie partagés.
Les informations sur l'exécution des tâches sont stockées dans le répertoire LOG.
Processus d'indexation
Le processus d'indexation se résume à l'exécution d'une fonction API Kerio
Session = callMethod("Domains.checkPublicFoldersIntegrity",{}, jeton)
Un exemple d’implémentation est donné dans – python
Dossierspublics.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)
Également dans le fichier, vous devez spécifier un compte avec les droits pour exécuter cette fonction (Adm - dossiers de messagerie publics) du serveur de messagerie.
J'espère que mon article sera utile aux administrateurs Kerio Connect.
Source: habr.com