Pełna synchronizacja współdzielonych folderów, kontaktów, kalendarzy pomiędzy rozproszonymi serwerami Kerio Connect

Dzień dobry, Habro!

Zadanie

Moja organizacja korzysta z serwera pocztowego na platformie Kerio Connect; serwery pocztowe są zainstalowane w różnych miastach, aby służyć swoim użytkownikom. Początkowo nie było rozproszonej struktury, ponieważ domeny różnią się na trzecim poziomie, wskazując miasto witryny. Wszystko zadziałało i wszyscy byli zadowoleni. Pewnego pięknego dnia kierownictwo ustaliło zadanie, wspólny kalendarz działań dla wszystkich lokalizacji!

prehistoria

Początkowo pomysł polegał na stworzeniu domeny poczty rozproszonej Kerio, która miałaby wszystko zrobić sama. Ledwo powiedziane, zrobione, utworzono domenę rozproszoną, ale tak się nie stało, serwer był gotowy do synchronizacji kalendarzy, folderów, kontaktów - między domenami znajdującymi się na tym samym serwerze, ale w ogóle nie miał zamiaru synchronizować danych między kilkoma serwery.

Ja oczywiście nie spodziewałem się takiego haczyka i długo nie mogłem uwierzyć, że brakuje mi potrzebnej funkcjonalności. Później znalazłem dokumenty potwierdzające ten fakt. Bardzo mnie to zdziwiło i rozczarowało.

Zadanie płynnie zamieniło się w problem.

Jakie były opcje?

  • Utwórz dwóch klientów na różnych serwerach, którzy wymieniają niezbędne dane z oprogramowaniem innych firm. Należało znaleźć oprogramowanie innej firmy, które zaimplementowałoby tę funkcjonalność – nie lubię takich rake’ów, ale wydawało mi się, że to jedyne szybkie rozwiązanie.
  • Napisz własny skrypt do synchronizacji danych pomiędzy serwerami. Faktem jest, że Kerio przechowuje każdy obiekt jako osobny plik, dlatego konieczne było opracowanie skryptu do pracy z plikami, jednak przy wystarczającej liczbie źródeł zadanie wydawało się nieco skomplikowane, zwłaszcza że konieczne było wykonanie wielu sprawdza poprawność danych, w przypadku, gdy ktoś utworzy zadanie w tym samym przedziale czasu, itp., itp.

Patrząc w przyszłość, powiem, że chociaż Kerio przechowuje obiekt jako oddzielny plik, nie jest na tyle głupi, aby pytać, jak radzi sobie system plików za każdym razem, gdy uzyskujesz dostęp do obiektu.

Spędziwszy dużo czasu na rozmyślaniach, sporządzając plik kartek z planami „zajęcia terytorium wroga”, o godzinie 6:XNUMX podjąłem dwie właściwe decyzje:

  • Pierwsza decyzja to robić swoje i nie szukać niczego z zewnątrz.
  • Drugie rozwiązanie to iść spać.

Już rano obudziłam się z jedną jedyną i prawdziwą myślą, która została zredukowana do kilku liter – DFS

decyzja

Samo rozwiązanie wyglądało tak

  • sprowadź wszystkie serwery, które będą uczestniczyć w synchronizacji z systemem operacyjnym Windows. (Część była na Linuksie. Wymagana była migracja danych poczty do innego systemu operacyjnego)
  • Określ strukturę katalogów, które będą brały udział w synchronizacji - muszą być identyczne.
  • Zdefiniuj wszystkie serwery pocztowe w ramach jednej domeny z pojedynczą przestrzenią DFS.
  • Utwórz wspomnianą wyżej rozproszoną domenę Kerio, ponieważ w moim przypadku wymagana jest synchronizacja danych nie tylko między serwerami, ale także między domenami, ta druga może być obsługiwana przez serwer Kerio niezależnie. (w odróżnieniu od pierwszego)
  • Ustaw zsynchronizowane katalogi na przestrzeń DFS.
  • Wymyśl jakąś kulę (w końcu bez kuli nie da się żyć)

realizacja

Przykład na dwóch serwerach pocztowych (może więcej)

1. Domena rozproszona Kerio

Pełna synchronizacja współdzielonych folderów, kontaktów, kalendarzy pomiędzy rozproszonymi serwerami Kerio Connect

Master nie uczestniczy w synchronizacji, ale nie jest to warunek konieczny.

Nie będę opisywał jak podnieść domenę rozproszoną Kerio, nie ma w tym nic skomplikowanego, możesz przestudiować oficjalną stronę manul

Ostatecznie w konsoli administracyjnej powinieneś zobaczyć następujący obraz:

Pełna synchronizacja współdzielonych folderów, kontaktów, kalendarzy pomiędzy rozproszonymi serwerami Kerio Connect

Pełna synchronizacja współdzielonych folderów, kontaktów, kalendarzy pomiędzy rozproszonymi serwerami Kerio Connect

Następnie zainteresowały mnie foldery współdzielone, na serwerze Master możesz określić następujące opcje:

Pełna synchronizacja współdzielonych folderów, kontaktów, kalendarzy pomiędzy rozproszonymi serwerami Kerio Connect

Pełna synchronizacja współdzielonych folderów, kontaktów, kalendarzy pomiędzy rozproszonymi serwerami Kerio Connect

Specyficzne dla każdej domeny - serwer nie będzie synchronizował folderów publicznych pomiędzy domenami

Wspólne dla wszystkich domen - wszystkie serwery porzucą istniejące foldery publiczne w każdej domenie i utworzą nowe, pojedyncze foldery dla wszystkich domen na każdym serwerze pocztowym.

Ostrzeżenie! Chociaż ta opcja zmienia zasady konfiguracji na wszystkich serwerach, synchronizuje się oddzielnie z każdym serwerem (to znaczy bez jednej wspólnej przestrzeni)

Administrator nadal będzie mógł rozdzielać dostęp pomiędzy użytkownikami.
w moim przypadku wszystkie są moje i potrzebuję pełnej synchronizacji (w Twoim przypadku rozwiązanie może być inne) na każdym serwerze musisz utworzyć identyczne zestawy domen, które wymagają synchronizacji.

2. Katalogi danych Kerio

Teraz musisz utworzyć identyczne katalogi współdzielone, które należy zsynchronizować na każdym z serwerów. Foldery, kalendarze, kontakty.

Rada - twórz katalogi po angielsku, jeśli utworzysz je po łacinie, katalog będzie miał nazwę w jakimś niezrozumiałym kodowaniu, jest to co najmniej niewygodne.

Teraz musisz znaleźć fizyczne ścieżki folderów pocztowych na każdym serwerze.

Wspólne dla wszystkich domen ~DataMailmail#publicСинхронизируемый каталог#msgs
Specyficzne dla każdej domeny ~DataMailmail**Domain**#publicСинхронизируемый каталог#msgs

Pamiętaj, że nie będziemy synchronizować całego katalogu, a jedynie kontener z danymi #wiadomości — tutaj przechowywane są same obiekty, wszystkie pozostałe dane muszą być osobne dla każdego serwera.

3.DFS

Nie będę szczegółowo opisywał, jak skonfigurować DFS, jest wystarczająco dużo informacji na ten temat.

DFS to usługa roli w systemie Windows Server, która umożliwia łączenie folderów współdzielonych znajdujących się na różnych serwerach
Link do dokumentu MS DFS

Przed skonfigurowaniem systemu DFS należy zatrzymać wszystkie serwery pocztowe, które będą uczestniczyć w synchronizacji danych.

Po zakończeniu konfiguracji powinieneś otrzymać następujący obraz dla każdego zsynchronizowanych folderów

Pełna synchronizacja współdzielonych folderów, kontaktów, kalendarzy pomiędzy rozproszonymi serwerami Kerio Connect

Naturalnie nie musimy publikować zreplikowanych folderów.

Pełna synchronizacja współdzielonych folderów, kontaktów, kalendarzy pomiędzy rozproszonymi serwerami Kerio Connect

Po zakończeniu replikacji (a nie ma tam nic specjalnego do replikowania - foldery są puste) można uruchomić serwery pocztowe.

Następnie możesz wypełnić jeden z serwerów pocztowych danymi i sprawdzić, czy dane są poprawnie replikowane.

4. Kula

Opis odbicia

Jak widać po rozpoczęciu synchronizacji danych (DFS), jeśli albo utworzyłeś coś na pierwszym serwerze, w jakiś sposób nic nie pojawia się na drugim serwerze, albo pojawia się, ale jakoś nie zawsze.

Nie rozpaczaj, oczywiście prędzej czy później się tam pojawi, ale lepiej wcześniej niż później. Ponieważ za 6 – 12 godzin jest już za późno.

Rzecz w tym, że gdy tylko utworzysz coś na pierwszym serwerze, na drugim i kolejnych serwerach plik oczywiście od razu się pojawi dzięki systemowi DFS, ale w przypadku, gdy ten katalog pocztowy był już przez kogoś czytany i zostanie ponownie zażądany, serwer nie będzie już ponownie czytał folderu #msgs, ale wypluł dane z własnego indeksu, które mogą już nie odpowiadać naszej rzeczywistości.

Kerio posiada mechanizm ponownego odczytania indeksu, ale może on zadziałać w około sześć godzin i w ciągu tych 6 godzin aktualność zadania w kalendarzu może zostać nieco utracona.
Aby przetestować synchronizację już teraz, możesz usunąć plik w odpowiednim zsynchronizowanym katalogu indeks.fld, po ponownym uzyskaniu dostępu do folderu na serwerze pocztowym i jeśli tego pliku brakuje, Kerio ponownie odczyta katalog i dane pojawi się. Wydawałoby się, że to jest rozwiązanie, usuń plik przy zmianie danych, ale nie działa to za każdym razem, ale tylko za pierwszym razem, wtedy Kerio z jakiegoś powodu traci całe zainteresowanie indeksem.fld
Zaczyna też wypluwać niezrozumiałe dla użytkownika komunikaty - o jakimś indeksie i o tym, że już coś tam robi.

Jest jeszcze jedna opcja, żeby coś stworzyć - w momencie tworzenia nowego obiektu serwer nagle orientuje się, że nazwa pliku, który chciał przypisać jest już zajęta, ale to kula śnieżna i jest to opcja ślepa.

Jak to może być?

Jeśli jeszcze raz zwrócimy uwagę na obraz, który jest nam już znany.

Pełna synchronizacja współdzielonych folderów, kontaktów, kalendarzy pomiędzy rozproszonymi serwerami Kerio Connect

Ale w innym samolocie widać bardzo interesujący przycisk, którego teraz potrzebujemy - Ponowne indeksowanie folderów

I rzeczywiście. Jeśli klikniemy ten przycisk na serwerze pocztowym, który nie wie, że coś się już zmieniło w zsynchronizowanych #msgs, otrzymamy stabilny, szybki wynik. Wszystko, co ukryte, stanie się jasne.

W logu widać jak długo trwa ten proces, w moim przypadku przy kilku tysiącach (15 tysiącach) rekordów zajmuje to około 3-4 minut.

Musimy tylko wymyślić, jak nacisnąć ten przycisk, kiedy go potrzebujemy.

Okazało się Kerio mieć własne API

Opis
Dokumentacja

Funkcja realizująca nasze zadanie wygląda następująco:
session = callMethod("Domains.checkPublicFoldersIntegrity",{}, token)

Z tego wszystkiego musimy napisać skrypt, który będzie monitorował stan interesujących nas folderów i jeśli coś się zmieniło, wykona potrzebną nam funkcję.

Chcę powiedzieć, że napisałem kilka różnych wersji skryptów, które wykonują różne kontrole i zdecydowałem się na tę, która wyciąga wszystkie wnioski na podstawie liczby plików.

Implementacja skryptu

Przykład i opis skryptu CMD

Ponownie zaindeksuj.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

Kopia skryptu działa na każdym serwerze pocztowym (można go używać jako usługi, nie są wymagane uprawnienia Adm)

Skrypt odczytuje plik Setup%Computername%.List

Gdzie %NazwaKomputera% to nazwa bieżącego serwera (Katalog może zawierać listę wszystkich serwerów jednocześnie.)

Plik %Computername%.List – zawiera pełne ścieżki synchronizowanych katalogów, każda ścieżka jest zapisana w nowej linii i nie powinna zawierać pustych linii.

Po pierwszym uruchomieniu skrypt wykonuje procedurę indeksowania, niezależnie od tego, czy jest to konieczne, czy nie, a także tworzy indeks ilości plików w każdym synchronizowanym katalogu.

Celem skryptu jest zliczenie wszystkich plików w określonym katalogu.

Na koniec zliczania każdego katalogu, jeśli w przynajmniej jednym katalogu bieżąca wartość plików nie jest zgodna z poprzednią, skrypt usuwa pliki z katalogu głównego synchronizowanego katalogu poczty: index.fld, indexlog.fld, search.fld i rozpoczyna proces indeksowania udostępnionych folderów poczty.

Informacje o wykonaniu zadania są zrzucane do katalogu LOG.

Proces indeksowania
Proces indeksowania sprowadza się do wykonania funkcji Kerio API
Sesja = callMethod("Domains.checkPublicFoldersIntegrity",{}, token)

Przykładową implementację podano w – 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)

http://127.0.0.1:4040 możesz zostawić to tak, jak jest, ale jeśli potrzebujesz HTTPS, Python musi ufać certyfikatowi Kerio.

Również w pliku należy podać konto z uprawnieniami do wykonywania tej funkcji (Adm - publiczne foldery poczty) serwera pocztowego.

Mam nadzieję, że mój artykuł będzie przydatny dla administratorów Kerio Connect.

Źródło: www.habr.com

Dodaj komentarz