Wdrożenie
OpenLDAP master-master z TLS i ppolicy
LDAP jest w firmie tak centralnym punktem, że jego awaria oznacza, że nikt się nigdzie nie zaloguje — ani do VPN-a, ani do Wildfly, ani do systemu, który akurat rano potrzebuje działu księgowego. Jeden serwer to jeden punkt awarii, którego nie akceptuję przy usłudze tej rangi. Replikacja master-master w OpenLDAP daje dwa równorzędne serwery, z których każdy przyjmuje zapisy — bez roli „master do zapisu, slave tylko do odczytu”, którą trzeba by ręcznie przełączać przy awarii.
Dlaczego master-master, nie master-slave
Konfiguracja master-slave (provider-consumer) jest prostsza i w wielu miejscach wystarczająca — jeden serwer zapisuje, reszta tylko czyta i serwuje zapytania. Problem pojawia się przy awarii mastera: coś musi ręcznie albo automatycznie przepiąć zapisy na inny węzeł, a to dodatkowa logika i dodatkowy punkt, który może zawieść w najgorszym momencie. Master-master eliminuje ten krok — obie strony przyjmują zapisy równolegle, a syncrepl w trybie mirrormode wymienia zmiany między nimi w obie strony.
syncrepl w trybie mirrormode
Każdy z dwóch serwerów ma w konfiguracji wpis syncrepl wskazujący na drugiego, plus mirrormode on, które mówi OpenLDAP-owi, że to nie jest zwykła replikacja provider-consumer:
dn: olcDatabase={1}mdb,cn=config
changetype: modify
add: olcSyncRepl
olcSyncRepl: rid=001 provider=ldaps://ldap01.internal:636
bindmethod=simple binddn="cn=repl,dc=example,dc=com"
credentials="<hasło>" searchbase="dc=example,dc=com"
type=refreshAndPersist retry="5 5 300 +"
starttls=critical tls_cert=/etc/ldap/certs/ldap02.pem
tls_key=/etc/ldap/certs/ldap02.key
tls_cacert=/etc/ldap/certs/ca.pem
-
add: olcMirrorMode
olcMirrorMode: TRUE
Numer rid musi być unikalny na każdym serwerze i różny między obiema stronami — to częsty błąd przy kopiowaniu konfiguracji „z jednego na drugi”: zostawia się ten sam rid po obu stronach i replikacja milczy albo się duplikuje w logach bez jasnego komunikatu błędu.
TLS między replikami — kolejność certyfikatów
Ruch replikacyjny między serwerami niesie hashe haseł i pełną treść katalogu, więc szyfrowanie między nimi nie jest opcjonalne, nawet w sieci wewnętrznej, która teoretycznie jest „zaufana”. Tu trafiłem na pułapkę, która kosztowała mnie więcej czasu niż powinna: kolejność, w jakiej generuje się i wdraża certyfikaty, ma znaczenie.
- Najpierw własne CA (albo firmowe, jeśli już istnieje) — bez tego każdy serwer wystawiałby sobie certyfikat samopodpisany, którego drugi nie zweryfikuje.
- Certyfikat dla każdego serwera musi mieć w
SANzarówno FQDN, po którym łączy się drugi replika, jak i ewentualny alias, jeśli klienci LDAP używają innej nazwy niż replikacja. - CA cert musi trafić na oba serwery przed pierwszym uruchomieniem
syncrepl— inaczej pierwsza próba połączenia kończy się cichym błędem weryfikacji TLS, a w loguslapdwidać tylko ogólne „TLS: can't connect”, bez wskazania, że chodzi o brakujące CA. - Restart
slapdpo podmianie certyfikatu jest obowiązkowy — OpenLDAP nie podejmuje nowego certyfikatu na gorąco.
# szybka weryfikacja, że replika faktycznie mówi TLS
openssl s_client -connect ldap02.internal:636 -CAfile /etc/ldap/certs/ca.pem
# log slapd przy problemach z replikacją — poziom -1 to wszystko
slapd -d sync -h "ldap:/// ldaps:///"
slapd. Monitoring rozjazdu contextCSN między serwerami to jedyny sensowny sposób, żeby wyłapać to zanim zauważy użytkownik.
Polityki haseł: overlay ppolicy
Sam LDAP nie wymusza niczego w kwestii haseł — długość, rotacja, blokada konta po nieudanych próbach logowania to domena overlay ppolicy, zgodnego z RFC dotyczącym Password Policy dla LDAP. Włącza się go per baza, a konkretne reguły opisuje jako osobny wpis w katalogu:
dn: cn=default,ou=policies,dc=example,dc=com
objectClass: pwdPolicy
objectClass: pwdPolicyChecker
cn: default
pwdAttribute: userPassword
pwdMinLength: 12
pwdMaxAge: 7776000
pwdExpireWarning: 604800
pwdInHistory: 5
pwdMaxFailure: 5
pwdLockoutDuration: 900
pwdLockout: TRUE
pwdMustChange: TRUE
pwdGraceAuthNLimit: 0
W praktyce: hasło minimum 12 znaków, ważność 90 dni (7776000 sekund) z tygodniowym ostrzeżeniem przed wygaśnięciem, pięć ostatnich haseł zapamiętanych żeby nie dało się wracać do starego, blokada konta na 15 minut po pięciu nieudanych próbach. Te liczby dobieramy pod politykę bezpieczeństwa firmy — overlay tylko je egzekwuje, nie narzuca konkretnych wartości.
ppolicy w replikacji master-master
Tu jest druga pułapka. Atrybuty operacyjne ppolicy — liczba nieudanych prób, znacznik czasu blokady — też są replikowane jak zwykłe zmiany w katalogu. Jeśli użytkownik trafi na dwa różne serwery przy kolejnych próbach logowania (typowe za load balancerem), licznik nieudanych prób musi się zgadzać po obu stronach, inaczej konto zablokuje się „niespodziewanie” na jednym serwerze, mimo że administrator widzi inny stan na drugim. W praktyce oznacza to, że replikacja musi nadążać w czasie rzeczywistym — opóźnienie rzędu sekund jest tu nieszkodliwe, ale przy poważniejszych opóźnieniach sieciowych między lokalizacjami warto rozważyć, czy oba serwery faktycznie powinny obsługiwać ruch produkcyjny jednocześnie, czy jeden ma być czysto zapasowy.
Polityka haseł, która istnieje tylko w dokumencie PDF, nie istnieje. ppolicy to ten sam wymóg, ale egzekwowany przez serwer, a nie przez pamięć administratora.
Co bym zrobił inaczej na starcie
- Ustawiłbym monitoring
contextCSNod pierwszego dnia, nie po pierwszym niewyjaśnionym rozjeździe danych. - Testowałbym TLS między replikami
openssl s_clientprzed włączeniemsyncrepl, a nie po fakcie, kiedy błąd trzeba wyłuskać z logu. - Dokumentowałbym
ridkażdej relacji replikacji w jednym miejscu — przy więcej niż dwóch serwerach łatwo o kolizję numerów.
Oba serwery LDAP stoją u mnie za parą HAProxy w trybie active-active, z health checkiem sprawdzającym, czy dany węzeł w ogóle odpowiada na ldaps:// — bez tego klient mógłby trafić na serwer, który akurat traci połączenie z drugą repliką.