Sincronización completa de carpetas compartidas, contactos y calendarios entre servidores Kerio Connect distribuidos

¡Buenas tardes Habr!

Tarea

Mi organización utiliza un servidor de correo en la plataforma Kerio Connect, los servidores de correo están instalados en diferentes ciudades para atender a sus usuarios. Inicialmente no existía una estructura distribuida, ya que los dominios se diferencian en el tercer nivel, indicando la ciudad del sitio. Todo funcionó y todos estaban felices. Un buen día, la dirección se propuso una tarea, ¡un calendario común de actividades entre todos los sitios!

Prehistoria

Inicialmente, la idea era crear el dominio de correo distribuido Kerio y lo haría todo por sí mismo. Dicho y hecho, se creó un dominio distribuido, pero ese no fue el caso, el servidor estaba listo para sincronizar calendarios, carpetas, contactos, entre dominios ubicados en el mismo servidor, pero no iba a sincronizar datos entre varios. servidores.

Por supuesto, no esperaba semejante problema y durante mucho tiempo no podía creer que faltara la funcionalidad que necesitaba. Posteriormente encontré evidencia documental de este hecho. Esto me dejó muy perplejo y decepcionado.

La tarea se convirtió sin problemas en un problema.

¿Cuáles eran las opciones?

  • Cree dos clientes en diferentes servidores que intercambien los datos necesarios con algún software de terceros. Era necesario encontrar un software de terceros que implementara esta funcionalidad; no me gusta ese rastrillo, pero parecía que era la única solución rápida.
  • Escriba su propio script para la sincronización de datos entre servidores. El caso es que Kerio almacena cada objeto como un archivo separado, por lo que fue necesario desarrollar un script para trabajar con archivos, pero en vista de la cantidad suficiente de fuentes, la tarea parecía algo complicada, sobre todo porque era necesario realizar múltiples comprueba la exactitud de los datos, en caso de que alguien cree una tarea en el mismo período de tiempo, etc., etc.

De cara al futuro, diré que aunque Kerio almacena un objeto como un archivo separado, no es tan estúpido como para preguntar cómo funciona el sistema de archivos cada vez que accede a un objeto.

Después de haber pasado mucho tiempo pensando, redactando un montón de hojas de papel con planes para "apoderarse del territorio enemigo", a las 6 en punto tomé dos decisiones correctas:

  • La primera decisión es hacer lo suyo y no buscar nada de fuera.
  • La segunda solución es irse a dormir.

Ya por la mañana me desperté con un único y verdadero pensamiento, que se redujo a unas pocas letras: DFS

Solución

La solución en sí se veía así.

  • lleve todos los servidores que participarán en la sincronización al sistema operativo Windows. (Parte de esto estaba en Linux. Se requirió la migración de datos de correo a otro sistema operativo)
  • Determine la estructura de los directorios que participarán en la sincronización; deben ser idénticos.
  • Defina todos los servidores de correo bajo un dominio con un único espacio DFS.
  • Cree el dominio Kerio distribuido antes mencionado, ya que en mi caso se requiere sincronización de datos, no solo entre servidores sino también entre dominios; el segundo lo puede manejar el servidor Kerio de forma independiente. (a diferencia del primero)
  • Establezca directorios sincronizados en el espacio DFS.
  • Inventa algún tipo de muleta (después de todo, no puedes vivir sin una muleta)

implementación

Ejemplo en dos servidores de correo (quizás más)

1. Dominio distribuido Kerio

Sincronización completa de carpetas compartidas, contactos y calendarios entre servidores Kerio Connect distribuidos

El Maestro no participa en la sincronización, pero esto no es un requisito previo.

No describiré cómo crear un dominio distribuido Kerio, no tiene nada de complicado, puedes estudiar el oficial manul

Al final, deberías ver la siguiente imagen en la consola de administración:

Sincronización completa de carpetas compartidas, contactos y calendarios entre servidores Kerio Connect distribuidos

Sincronización completa de carpetas compartidas, contactos y calendarios entre servidores Kerio Connect distribuidos

A continuación me interesaron las carpetas compartidas; en el servidor maestro puedes especificar las siguientes opciones:

Sincronización completa de carpetas compartidas, contactos y calendarios entre servidores Kerio Connect distribuidos

Sincronización completa de carpetas compartidas, contactos y calendarios entre servidores Kerio Connect distribuidos

Específico para cada dominio - el servidor no sincronizará carpetas públicas entre dominios

Común a todos los dominios - todos los servidores abandonarán las carpetas públicas existentes en cada dominio y crearán nuevas carpetas únicas para todos los dominios en cada servidor de correo.

¡Atención! Aunque esta opción cambia la política de configuración en todos los servidores, se sincroniza por separado de cada servidor (es decir, sin un único espacio común)

El administrador seguirá teniendo la capacidad de distribuir el acceso entre los usuarios.
en mi caso, son todos míos y necesito una sincronización completa (en su caso, la solución puede ser diferente) en cada servidor necesita crear conjuntos idénticos de dominios que deben sincronizarse.

2. Directorios de datos de Kerio

Ahora necesita crear directorios compartidos idénticos que deben sincronizarse en cada uno de los servidores. Carpetas, Calendarios, Contactos.

Consejo: cree directorios en inglés, si los crea en latín, el directorio tendrá un nombre en alguna codificación incomprensible, esto es al menos un inconveniente.

Ahora necesitas encontrar las rutas físicas de las carpetas de correo en cada servidor.

Común a todos los dominios ~DataMailmail#publicСинхронизируемый каталог#msgs
Específico para cada dominio ~DataMailmail**Domain**#publicСинхронизируемый каталог#msgs

Tenga en cuenta que no sincronizaremos todo el directorio, sino solo el contenedor con los datos. #mensajes — los objetos en sí se almacenan aquí, todos los demás datos deben estar separados para cada servidor.

3.DFS

No describiré en detalle cómo configurar DFS, hay suficiente información sobre este tema.

DFS es un servicio de rol en Windows Server que brinda la capacidad de combinar carpetas compartidas ubicadas en diferentes servidores.
Enlace al documento de MS DFS

Antes de configurar DFS, debe detener todos los servidores de correo que participarán en la sincronización de datos.

Al finalizar la configuración, debería recibir la siguiente imagen para cada una de las carpetas sincronizadas.

Sincronización completa de carpetas compartidas, contactos y calendarios entre servidores Kerio Connect distribuidos

Naturalmente, no necesitamos publicar carpetas replicadas.

Sincronización completa de carpetas compartidas, contactos y calendarios entre servidores Kerio Connect distribuidos

Una vez que se produce la replicación (y no hay nada especial que replicar allí; las carpetas están vacías), se pueden iniciar los servidores de correo.

A continuación, puede llenar uno de los servidores de correo con datos y comprobar que los datos se replican correctamente.

4. Muleta

Descripción de la reflexión

Como puede ver después de que los datos comienzan a sincronizarse (DFS), si creó algo en el primer servidor, de alguna manera no aparece nada en el segundo servidor, o aparece pero de alguna manera no siempre.

No desesperes, claro que tarde o temprano aparecerá por ahí, pero más vale cuanto antes. Porque ya es demasiado tarde entre 6 y 12 horas.

El caso es que tan pronto como haya creado algo en el primer servidor, en el segundo servidor y en los siguientes, el archivo, por supuesto, aparecerá inmediatamente gracias al sistema DFS, pero en el caso de que alguien ya haya leído este directorio de correo antes y se solicita nuevamente, el servidor no volverá a leer la carpeta #msgs sino que arrojará datos de su propio índice, que pueden no corresponder ya a nuestra realidad.

Kerio tiene un mecanismo para releer el índice, pero puede funcionar en unas seis horas, y durante estas 6 horas la relevancia de la tarea en el calendario puede perderse un poco.
Para probar la sincronización ahora mismo, puede eliminar el archivo en el directorio sincronizado correspondiente index.fld, después de volver a acceder a la carpeta en el servidor de correo y si falta este archivo, Kerio volverá a leer el directorio y los datos. aparecerá. Parecería que esta es la solución, eliminar el archivo cuando cambian los datos, pero esto no funciona siempre, sino solo la primera vez, entonces Kerio, por alguna razón, pierde todo interés en index.fld.
También comienza a escupir mensajes que son incomprensibles para el usuario, sobre algún tipo de índice y que ya está haciendo algo allí.

Hay otra opción, crear algo: en el momento de crear un nuevo objeto, el servidor de repente se da cuenta de que el nombre del archivo que quería asignar ya está en uso, pero se acumula y esta es una opción sin salida.

¿Cómo puede ser eso?

Si prestamos atención una vez más a la imagen que ya nos resulta familiar.

Sincronización completa de carpetas compartidas, contactos y calendarios entre servidores Kerio Connect distribuidos

Pero en otro plano, puedes ver un botón muy interesante que necesitamos ahora: Reindexar carpetas

Y de hecho. Si hacemos clic en este botón en un servidor de correo que no sabe que algo ya ha cambiado en los #msgs sincronizados, obtendremos un resultado estable y rápido. Todo lo oculto se aclarará.

En el registro puedes ver cuánto tiempo lleva este proceso; en mi caso, con varios miles (15 mil) registros, tarda entre 3 y 4 minutos.

Todo lo que tenemos que hacer es descubrir cómo presionar este botón cuando lo necesitemos.

Resulta que Kerio tener su propio API

Descripción
Документация

La función que realiza nuestra tarea se ve así:
session = callMethod("Domains.checkPublicFoldersIntegrity",{}, token)

De todo lo anterior, necesitamos escribir un script que monitoree el estado de las carpetas de interés y, si algo ha cambiado, realice la función que necesitamos.

Quiero decir que escribí varias versiones diferentes de scripts que realizan diferentes comprobaciones y me decidí por la que saca todas las conclusiones en función de la cantidad de archivos.

Implementación de script

Ejemplo y descripción del script CMD

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

Se ejecuta una copia del script en cada servidor de correo (se puede utilizar como servicio, no se requieren derechos de administrador)

El script lee el archivo. Setup%Computername%.List

Donde %Computername% es el nombre del servidor actual (el directorio puede contener listas de todos los servidores a la vez).

El archivo %Computername%.List – contiene las rutas completas de los directorios sincronizados, cada ruta está escrita en una nueva línea y no debe contener líneas vacías.

Después del primer lanzamiento, el script realiza el procedimiento de indexación, independientemente de si es necesario o no, y el script también crea un índice de la cantidad de archivos en cada directorio sincronizado.

El propósito del script es contar todos los archivos en el directorio especificado.

Al final de contar cada directorio, si en al menos un directorio el valor actual de los archivos no coincide con el anterior, el script elimina los archivos del directorio raíz del directorio de correo sincronizado: index.fld, indexlog.fld, search.fld e inicia el proceso de indexación de carpetas de correo compartidas.

La información sobre la ejecución de la tarea se descarga en el directorio LOG.

Proceso de indexación
El proceso de indexación se reduce a ejecutar una función de la API de Kerio
Sesión = callMethod("Domains.checkPublicFoldersIntegrity",{}, token)

Se proporciona un ejemplo de implementación en – Python
Carpetas públicas.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 puede dejarlo como está, pero si requiere HTTPS, Python debe confiar en el certificado Kerio.

También en el archivo debe especificar una cuenta con derechos para realizar esta función (Adm - carpetas de correo público) del servidor de correo.

Espero que mi artículo sea útil para los administradores de Kerio Connect.

Fuente: habr.com

Añadir un comentario