Sincronização completa de pastas compartilhadas, contatos e calendários entre servidores Kerio Connect distribuídos

Boa tarde, Habr!

Tarefa

Minha organização usa um servidor de e-mail na plataforma Kerio Connect; servidores de e-mail são instalados em diferentes cidades para atender seus usuários. Inicialmente não havia estrutura distribuída, pois os domínios se diferenciam no terceiro nível, indicando a cidade do site. Tudo funcionou e todos ficaram felizes. Um belo dia, a direção definiu uma tarefa, um calendário comum de atividades entre todos os sites!

Pré-história

Inicialmente a ideia era criar o Kerio Distributed Mail Domain e ele faria tudo sozinho. Mal dito e feito, foi criado um domínio distribuído, mas não foi o caso, o servidor estava pronto para sincronizar calendários, pastas, contatos - entre domínios localizados no mesmo servidor, mas não iria de forma alguma sincronizar dados entre vários servidores.

É claro que eu não esperava tal pegadinha e por muito tempo não pude acreditar que faltava a funcionalidade que eu precisava. Mais tarde encontrei provas documentais deste facto. Fiquei muito intrigado e desapontado com isso.

A tarefa suavemente se transformou em um problema.

Quais foram as opções?

  • Crie dois clientes em servidores diferentes que troquem os dados necessários com algum software de terceiros. Foi necessário encontrar esse software de terceiros que implementasse essa funcionalidade - não gosto desse rake, mas parecia que essa era a única solução rápida.
  • Escreva seu próprio script para sincronização de dados entre servidores. O fato é que o Kerio armazena cada objeto como um arquivo separado, por isso foi necessário desenvolver um script para trabalhar com arquivos, mas tendo em vista o número suficiente de fontes, a tarefa parecia um tanto complicada, principalmente porque era necessário realizar vários verifica a exatidão dos dados, caso alguém crie tarefa no mesmo período de tempo, etc., etc.

Olhando para o futuro, direi que embora o Kerio armazene um objeto como um arquivo separado, não é tão estúpido a ponto de perguntar como está o sistema de arquivos toda vez que você acessa o objeto.

Depois de passar muito tempo pensando, elaborando um monte de papéis com planos de “tomada do território inimigo”, às 6 horas tomei duas decisões acertadas:

  • A primeira decisão é fazer o que você quer e não procurar nada de fora.
  • A segunda solução é dormir.

Já pela manhã acordei com um único e verdadeiro pensamento, que foi reduzido a algumas letras - DFS

Solução

A solução em si ficou assim

  • traga todos os servidores que participarão da sincronização para o sistema operacional Windows. (Parte disso estava no Linux. Foi necessária a migração dos dados de correio para outro sistema operacional)
  • Determine a estrutura dos diretórios que participarão da sincronização - eles devem ser idênticos.
  • Defina todos os servidores de correio em um domínio com um único espaço DFS.
  • Crie o domínio Kerio distribuído acima mencionado, pois no meu caso é necessária a sincronização de dados, não apenas entre servidores, mas também entre domínios; o segundo pode ser tratado pelo servidor Kerio de forma independente. (ao contrário do primeiro)
  • Defina diretórios sincronizados para o espaço DFS.
  • Invente algum tipo de muleta (afinal, você não pode viver sem muleta)

Implementação

Exemplo em dois servidores de email (talvez mais)

1. Domínio distribuído Kerio

Sincronização completa de pastas compartilhadas, contatos e calendários entre servidores Kerio Connect distribuídos

O Master não participa da sincronização, mas isso não é um pré-requisito.

Não vou descrever como criar um domínio distribuído Kerio, não há nada complicado nisso, você pode estudar o oficial manul

Por fim, você deverá ver a seguinte imagem no console de administração:

Sincronização completa de pastas compartilhadas, contatos e calendários entre servidores Kerio Connect distribuídos

Sincronização completa de pastas compartilhadas, contatos e calendários entre servidores Kerio Connect distribuídos

Em seguida eu estava interessado em pastas compartilhadas; no servidor Master você pode especificar as seguintes opções:

Sincronização completa de pastas compartilhadas, contatos e calendários entre servidores Kerio Connect distribuídos

Sincronização completa de pastas compartilhadas, contatos e calendários entre servidores Kerio Connect distribuídos

Específico para cada domínio - o servidor não sincronizará pastas públicas entre domínios

Comum a todos os domínios - todos os servidores abandonarão as pastas públicas existentes em cada domínio e criarão novas pastas únicas para todos os domínios em cada servidor de correio.

Atenção! Embora esta opção altere a política de configuração em todos os servidores, ela sincroniza separadamente de cada servidor (ou seja, sem um único espaço comum)

O administrador ainda poderá distribuir o acesso entre os usuários.
no meu caso, são todos meus e preciso de sincronização total (no seu caso, a solução pode ser diferente) em cada servidor você precisa criar conjuntos idênticos de domínios que precisam ser sincronizados.

2. Diretórios de dados Kerio

Agora você precisa criar diretórios compartilhados idênticos que precisam ser sincronizados em cada um dos servidores. Pastas, calendários, contatos.

Conselho - crie diretórios em inglês, se você criá-los em latim, o diretório terá um nome com alguma codificação incompreensível, isso é no mínimo inconveniente.

Agora você precisa encontrar os caminhos físicos das pastas de correio em cada servidor.

Comum a todos os domínios ~DataMailmail#publicСинхронизируемый каталог#msgs
Específico para cada domínio ~DataMailmail**Domain**#publicСинхронизируемый каталог#msgs

Observe que não sincronizaremos o diretório inteiro, mas apenas o contêiner com os dados #mensagens — os próprios objetos são armazenados aqui, todos os outros dados devem ser separados para cada servidor.

3.DFS

Não descreverei em detalhes como configurar o DFS; há informações suficientes sobre esse assunto.

DFS é um serviço de função no Windows Server que oferece a capacidade de combinar pastas compartilhadas localizadas em servidores diferentes
Link para o documento MS DFS

Antes de configurar o DFS, você deve parar todos os servidores de email que participarão da sincronização de dados.

Após a conclusão da configuração, você deverá receber a seguinte imagem para cada uma das pastas sincronizadas

Sincronização completa de pastas compartilhadas, contatos e calendários entre servidores Kerio Connect distribuídos

Naturalmente, não precisamos publicar pastas replicadas.

Sincronização completa de pastas compartilhadas, contatos e calendários entre servidores Kerio Connect distribuídos

Após a replicação (e não há nada especial para replicar lá - as pastas estão vazias), os servidores de e-mail podem ser iniciados.

Em seguida, você pode preencher um dos servidores de e-mail com dados e verificar se os dados foram replicados corretamente.

4. Muleta

Descrição da reflexão

Como você pode ver depois que os dados começam a ser sincronizados (DFS), se você criou algo no primeiro servidor, de alguma forma nada aparece no segundo servidor, ou aparece, mas de alguma forma nem sempre.

Não se desespere; claro, ele aparecerá lá mais cedo ou mais tarde, mas é melhor mais cedo ou mais tarde. Porque é tarde demais em 6 a 12 horas.

O fato é que assim que você criar algo no primeiro servidor, no segundo e nos servidores subsequentes o arquivo aparecerá imediatamente graças ao sistema DFS, mas no caso de este diretório de e-mail já ter sido lido por alguém antes e for solicitado novamente, o servidor não irá reler a pasta #msgs mas irá cuspir dados do seu próprio índice, o que pode não corresponder mais à nossa realidade.

O Kerio possui um mecanismo de releitura do índice, mas pode funcionar em cerca de seis horas, e durante essas 6 horas a relevância da tarefa no calendário pode se perder um pouco.
Para testar a sincronização agora mesmo, você pode deletar o arquivo no diretório sincronizado correspondente index.fld, após acessar novamente a pasta no servidor de e-mail e se este arquivo estiver faltando, o Kerio irá reler o diretório e os dados vai aparecer. Parece que esta é a solução, exclua o arquivo quando os dados mudarem, mas isso não funciona sempre, mas apenas na primeira vez, então o Kerio por algum motivo perde todo o interesse em index.fld
Ele também começa a cuspir mensagens incompreensíveis para o usuário - sobre algum tipo de índice e que já está fazendo algo lá.

Existe outra opção, para criar algo - no momento de criar um novo objeto, o servidor de repente percebe que o nome do arquivo que ele queria atribuir já está em uso, mas é uma bola de neve e esta é uma opção sem saída.

Como pode ser isso?

Se prestarmos atenção mais uma vez ao quadro que já nos é familiar.

Sincronização completa de pastas compartilhadas, contatos e calendários entre servidores Kerio Connect distribuídos

Mas em outro plano você pode ver um botão muito interessante que precisamos agora - Reindexar pastas

E realmente. Se clicarmos neste botão em um servidor de e-mail que não sabe que algo já mudou nas #msgs sincronizadas, obteremos um resultado estável e rápido. Tudo o que está oculto ficará claro.

No log você pode ver quanto tempo leva esse processo; no meu caso, com vários milhares (15 mil) registros leva cerca de 3-4 minutos.

Tudo o que precisamos fazer é descobrir como pressionar esse botão quando precisarmos dele.

Acontece que Kerio tem o seu próprio API

descrição
Documentação

A função que executa nossa tarefa é semelhante a esta:
session = callMethod("Domains.checkPublicFoldersIntegrity",{}, token)

De tudo isso, precisamos escrever um script que monitore o estado das pastas de interesse e, se algo mudar, execute a função que precisamos.

Quero dizer que escrevi várias versões diferentes de scripts que realizam verificações diferentes e optei por aquela que tira todas as conclusões com base no número de arquivos.

Implementação de script

Exemplo e descrição de script CMD

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

Uma cópia do script é executada em cada servidor de e-mail (pode ser usado como um serviço, não são necessários direitos de administrador)

O script lê o arquivo Setup%Computername%.List

Onde %Computername% é o nome do servidor atual (o diretório pode conter listas de todos os servidores de uma só vez).

O arquivo %Computername%.List – contém os caminhos completos dos diretórios sincronizados, cada caminho é escrito em uma nova linha e não deve conter linhas vazias.

Após o primeiro lançamento, o script realiza o procedimento de indexação, independente de ser necessário ou não, e o script também cria um índice da quantidade de arquivos em cada diretório sincronizado.

O objetivo do script é contar todos os arquivos no diretório especificado.

Ao final da contagem de cada diretório, se em pelo menos um diretório o valor atual dos arquivos não corresponder ao anterior, o script exclui os arquivos do diretório raiz do diretório de correio sincronizado: index.fld, indexlog.fld, search.fld e inicia o processo de indexação de pastas de correio compartilhadas.

As informações sobre a execução da tarefa são despejadas no diretório LOG.

Processo de indexação
O processo de indexação se resume à execução de uma função Kerio API
Sessão = callMethod("Domains.checkPublicFoldersIntegrity",{}, token)

Um exemplo de implementação é fornecido em – python
Pastas 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 você pode deixar como está, mas se precisar de HTTPS, o python deverá confiar no certificado Kerio.

Também no arquivo você deve especificar uma conta com direitos para executar esta função (Adm - pastas de correio públicas) do servidor de correio.

Espero que meu artigo seja útil para administradores do Kerio Connect.

Fonte: habr.com

Adicionar um comentário