Jak synchronizacja czasu stała się bezpieczna

Jak synchronizacja czasu stała się bezpieczna
Jak sprawić, by czas per se nie mylił, gdy masz milion dużych i małych urządzeń komunikujących się przez TCP/IP? Przecież na każdym z nich są zegary, a czas powinien być poprawny na wszystkich. Tego problemu nie da się obejść bez NTP.

Wyobraźmy sobie przez chwilę, że w jednym segmencie przemysłowej infrastruktury IT wystąpiły trudności z synchronizacją usług w czasie. Natychmiast zaczyna się psuć klasterowy stos oprogramowania Enterprise, rozpadają się domeny, master i węzły zapasowe bezskutecznie starają się przywrócić status quo.

Możliwa jest też sytuacja, kiedy przestępca celowo próbuje zrujnować czas przez MiTM lub atak DDoS. W takiej sytuacji może wydarzyć się wszystko:

  • wygasną hasła użytkowników;
  • wygasną certyfikaty X.509;
  • dwuetapowa weryfikacja TOTP przestanie działać;
  • backupy 'uzupełnią się' i system je usunie;
  • zepsuje się DNSSec.

Oczywiste jest, że każdy wydział IT jest zainteresowany niezawodnym działaniem usług synchronizacji czasu i dobrze, gdyby były one niezawodne i bezpieczne w przemysłowej eksploatacji.

Złamanie NTP w 25 minut

Protokoły sieciowe – milenialsi mają jedną cechę, od dawna są przestarzałe. i nigdzie nie nadają się, ale zastąpienie ich nie jest takie łatwe, nawet gdy zgromadzi się krytyczna masa entuzjastów i finansowania.

Głównym zarzutem wobec klasycznego NTP jest brak niezawodnych mechanizmów ochrony przed atakami przestępczymi. Podejmowano różne próby rozwiązania tego problemu. W tym celu na początku wdrożono mechanizm wcześniej ustalonych kluczy (PSK) do wymiany kluczy symetrycznych.

Niestety, ten sposób nie sprawdził się z prostego powodu — słabo się skaluje. Wymagana jest ręczna konfiguracja po stronie klienta w zależności od serwera. Oznacza to, że po prostu nie można dodać kolejnego klienta. Jeśli na serwerze NTP coś się zmienia, trzeba przeznaczyć wszystkie klientów.

Następnie wymyślono AutoKey, ale szybko odkryto w nim szereg poważnych luk w samym projekcie algorytmu i trzeba było z niego zrezygnować. Chodzi o to, że początkowa liczba (seed) zawiera tylko 32 bity, co jest zbyt mało i nie zawiera wystarczającej złożoności obliczeniowej dla ataku frontalnego.

  • Key ID – symetryczny 32-bitowy klucz;
  • MAC (kod uwierzytelniania wiadomości) — suma kontrolna pakietu NTP;

Autokey oblicza się w następujący sposób.

Autokey=H(Adres-IP-Nadawcy||Adres-IP-Odbiorcy||KeyID||Ciasteczko)

Gdzie H() — funkcja skrótu kryptograficznego.

Do obliczenia sumy kontrolnej pakiety używa tej samej funkcji.

MAC=H(Autokey||pakiet NTP)

W ten sposób cała integralność weryfikacji pakietów opiera się na autentyczności ciasteczek. Zdobywając je, można odtworzyć autokey, a następnie podrobić MAC. Jednak serwer NTP przy ich generacji używa liczby początkowej (seed). To tu tkwi haczyk.

Ciasteczko=MSB_32(H(IP Klienta||IP Serwera||0||Seed Serwera))

Funkcja MSB_32 odcina 32 najstarsze bity wyniku obliczenia skrótu md5. Ciasteczko klienta nie zmienia się, dopóki parametry serwera są stałe. Potem złodziejowi pozostaje tylko odzyskać liczbę początkową i uzyskać możliwość samodzielnego generowania ciasteczek.

Na początek należy połączyć się z serwerem NTP jako klient i zdobyć ciasteczko. Po tym złodziej wykorzystuje metodę prób i błędów, aby odzyskać liczbę początkową, postępując zgodnie z prostym algorytmem.

Algorytm ataku na obliczenie liczby początkowej metodą prób i błędów.

   for i=0:2^32 − 1 do
        Ci=H(IP Serwera||IP Klienta||0||i)
        if Ci=Ciasteczko then
            return i
        end if 
    end for

Adresy IP są znane, więc pozostaje tylko stworzyć 2^32 skrótów, aż stworzone ciasteczko zgodzi się z tym, które otrzymano od serwera NTP. Na zwykłej domowej stacji z Intel Core i5 zajmie to 25 minut.

NTS — nowy Autokey

Nie można było pogodzić się z takimi lukami w zabezpieczeniach Autokey, więc w 2012 roku pojawił się nowa wersja protokół. W celu skompromitowanego tytułu postanowiono przeprowadzić rebranding, tak Autokey v.2 nazwano Network Time Security.

Protokół NTS jest rozszerzeniem zabezpieczeń NTP i obecnie obsługuje tylko tryb jednokierunkowy (unicast). Daje niezawodne kryptograficzne zabezpieczenie przed manipulacjami pakietami, zapobiega śledzeniu, dobrze się skalowuje, jest odporny na utratę pakietów sieciowych i prowadzi do minimalnych strat dokładności, które występują w procesie zabezpieczania połączenia.

Połączenie NTS składa się z dwóch etapów, w których używane są protokoły niższego poziomu. Na pierwszym etapie klient i serwer ustalają różne parametry połączenia i wymieniają ciasteczka, zawierające klucze z całym towarzyszącym zestawem danych. Na drugim etapie odbywa się właściwa zabezpieczona sesja NTS między klientem a serwerem NTP.

Jak synchronizacja czasu stała się bezpieczna

NTS składa się z dwóch protokołów niskiego poziomu: Network Time Security Key Exchange (NTS-KE), inicjującego bezpieczne połączenie na warstwie TLS, oraz NTPv4 — ostatniej wersji protokołu NTP. Nieco więcej o tym poniżej.

Pierwszy etap — NTS KE

Na tym etapie klient NTP inicjuje sesję TLS 1.2/1.3 na oddzielnym połączeniu TCP z serwerem NTS KE. W trakcie tej sesji następuje kilka działań.

  • Strony ustalają parametry AEAD algorytmu na drugim etapie.
  • Strony ustalają drugi protokół niskiego poziomu, jednak na razie wspierany jest tylko NTPv4.
  • Strony ustalają adres IP i port serwera NTP.
  • Serwer NTS KE wydaje ciastka pod NTPv4.
  • Strony wydobywają z materiału ciastka parę kluczy symetrycznych (C2S i S2C).

Takie podejście ma dużą zaletę, ponieważ cała szkoła przesyłania tajnych informacji o parametrach połączenia spoczywa na sprawdzonym i niezawodnym protokole TLS. Tym samym znika potrzeba wymyślania własnego rozwiązania dla bezpiecznego uścisku NTP.

Drugi etap — NTP zabezpieczony przez NTS

Na drugim etapie klient bezpiecznie synchronizuje czas z serwerem NTP. W tym celu przesyła cztery specjalne rozszerzenia (extension fields) w struktury pakietu NTPv4.

  • Rozszerzenie Unique Identifier zawiera losowy nonce, aby zapobiec atakom przez powtórzenie.
  • Rozszerzenie NTS Cookie zawiera jedno z dostępnych u klienta ciastka NTP. Ponieważ tylko klient ma symetryczne klucze AAED C2S i S2C, serwer NTP musi je wydobyć z materiału ciastka.
  • Rozszerzenie NTS Cookie Placeholder to sposób, w jaki klient może zażądać dodatkowych ciastek od serwera. To rozszerzenie jest konieczne, aby odpowiedź serwera NTP nie była znacznie dłuższa od żądania. Pozwala to zapobiec atakom wzmacniającym.
  • Rozszerzenie NTS Authenticator and Encrypted Extension Fields zawiera szyfr algorytmu AAED z kluczem C2S, nagłówkiem NTP, znacznikami czasowymi, oraz wspomnianymi wcześniej EF jako danymi towarzyszącymi. Bez tego rozszerzenia możliwe jest sfałszowanie znaczników czasowych.

Jak synchronizacja czasu stała się bezpieczna

Po otrzymaniu żądania od klienta, serwer sprawdza autentyczność pakietu NTP. W tym celu musi odszyfrować ciastka, wydobyć algorytm AAED i klucze. Po pomyślnej weryfikacji pakietu NTP serwer odpowiada klientowi w następującym formacie.

  • Rozszerzenie Unique Identifier to lustrzane odbicie żądania klienta, środek przeciwdziałający atakom przez powtórzenie.
  • Rozszerzenie NTS Cookie zawiera dodatkowe ciastka do kontynuacji sesji.
  • Rozszerzenie NTS Authenticator i Zaszyfrowane Pola Rozszerzenia zawiera szyfr AEAD z kluczem S2C.

Drugie uściski dłoni można powtarzać wielokrotnie, pomijając pierwszy etap, ponieważ każde żądanie i odpowiedź daje klientowi dodatkowe ciasteczka. To daje przewagę, że relatywnie zasobochłonne operacje TLS obliczenia i przesyłania danych PKI są dzielone na liczbę powtórnych żądań. Jest to szczególnie wygodne dla wyspecjalizowanych zegarów FPGA, kiedy cała podstawowa funkcjonalność może być zapakowana w kilka funkcji z zakresu kryptografii symetrycznej, przesyłając cały stos TLS na inne urządzenie.

NTPSec

Na czym polega wyjątkowość NTP? Mimo że autor projektu Dave Mills starał się jak najlepiej udokumentować swój kod, rzadki programista jest w stanie zrozumieć zawiłości 35-letnich algorytmów synchronizacji czasu. Część kodu została napisana przed erą POSIX, a API Unix znacznie różniło się od tego, które jest stosowane dzisiaj. Ponadto potrzebna jest wiedza z zakresu statystyki, aby oczyścić sygnał z zakłóceń na hałaśliwych liniach.

NTS nie było pierwszą próbą naprawienia NTP. Po tym, jak przestępcy nauczyli się wykorzystywać luki w NTP do wzmacniania ataków DDoS, stało się jasne, że potrzebne są radykalne zmiany. I podczas gdy szkice NTS były opracowywane i dopracowywane, National Science Foundation USA pod koniec 2014 roku pilnie przyznał grant na modernizację NTP.

Grupą roboczą kierował nie byle kto, a Eric Steven Raymond — jeden z założycieli i filarów społeczności Open Source oraz autor książki Katedra i Bazar. Na początku Eric i jego towarzysze spróbowali przenieść kod NTP z platformy BitKeeper na git, ale tak się nie stało. Lider projektu Harlan Stenn był przeciwny temu rozwiązaniu i negocjacje utknęły w martwym punkcie. Wtedy postanowiono forkować kod projektu, w ten sposób powstał NTPSec.

Solidne doświadczenie, w tym praca nad GPSD, matematyczne zaplecze i magiczna umiejętność czytania starego kodu — Eric Raymond był właśnie tym hakerem, który mógł poprowadzić taki projekt. W zespole znalazł się specjalista do migracji kodu i w zaledwie 10 tygodni NTP osiedliło sięna GitLabie. Praca ruszyła.

Zespół Erica Raymonda zajął się sprawą tak samo, jak Auguste Rodin przy pracy z blokiem kamienia. Usuwając 175 KLOC starego kodu, udało im się znacząco zmniejszyć powierzchnię ataku, zamykając wiele luk bezpieczeństwa.

Oto niepełna lista, która została dotknięta:

  • Niedocumentowane, przestarzałe lub uszkodzone refclock.
  • Nieużywana biblioteka ICS.
  • libopts/autogen.
  • Stary kod dla systemu Windows.
  • ntpdc.
  • Autokey.
  • Kod C z ntpq przepisany na Pythona.
  • Kod C z sntp/ntpdig przepisany na Pythona.

Oprócz oczyszczenia kodu, projekt miał także inne zadania. Oto niepełna lista osiągnięć:

  • Zdecydowanie wzmocniono zabezpieczenia kodu przed przepełnieniem bufora. Aby zapobiec przepełnieniu bufora, wszystkie niebezpieczne funkcje stringowe (strcpy / strcat / strtok / sprintf / vsprintf / gets) zostały zastąpione bezpiecznymi wersjami, które wdrażają ograniczenia size'u bufora.
  • Dodano wsparcie dla NTS.
  • Dziesięciokrotnie zwiększono dokładność kroku czasowego dzięki synchronizacji z fizycznym sprzętem. To dlatego, że nowoczesne zegary komputerowe stały się znacznie dokładniejsze niż te, które istniały w czasie powstawania NTP. Największe korzyści odniosły GPSDO i dedykowane radiostacje czasu.
  • Liczba języków programowania została ograniczona do dwóch. Zamiast skryptów Perl, awk i nawet S, teraz mamy czysty Python. Dzięki temu zwiększyły się możliwości ponownego użycia kodu.
  • Zamiast chaotycznych skryptów autotools, projekt zaczął używać systemu budowania oprogramowania. waf.
  • Zaktualizowano i zreorganizowano dokumentację projektu. Z sprzecznego i miejscami archaicznego zbioru dokumentów stworzono całkiem znośną dokumentację. Każda kluczowa opcja wiersza poleceń oraz każda encja konfiguracji mają teraz jedną wersję prawdy. Dodatkowo, strony podręcznika i dokumentacja internetowa są teraz tworzone z tych samych podstawowych plików.

NTPSec jest dostępny dla wielu dystrybucji Linuxa. Obecnie stabilna wersja to 1.1.8, dla Gentoo Linux — przedostatnia.

(1:696)$ sudo emerge -av ntpsec
To są pakiety, które zostaną scalone, w kolejności:
Obliczanie zależności... gotowe!
[ebuild   R    ] net-misc/ntpsec-1.1.7-r1::gentoo  USE="samba seccomp -debug -doc -early -gdb -heat -libbsd -nist -ntpviz -rclock_arbiter -rclock_generic -rclock_gpsd -rclock_hpgps -rclock_jjy -rclock_local -rclock_modem -rclock_neoclock -rclock_nmea -rclock_oncore -rclock_pps -rclock_shm -rclock_spectracom -rclock_trimble -rclock_truetime -rclock_zyfer -smear -tests" PYTHON_TARGETS="python3_6" 0 KiB
Całkowita liczba: 1 pakiet (1 reinstalacja), wielkość pobrań: 0 KiB
Czy chcesz połączyć te pakiety? [Tak/Nie]

Chrony

Podejście do zastąpienia starego NTP bardziej bezpiecznym odpowiednikiem miało jeszcze jedną próbę. Chrony, w przeciwieństwie do NTPSec, został napisany od podstaw i zaprojektowany do niezawodnej pracy w szerokim zakresie warunków, w tym niestabilnych połączeń sieciowych, częściowej dostępności lub przeciążeń sieci oraz zmian temperatury. Ponadto chrony ma inne zalety:

  • chrony może szybciej synchronizować zegary systemowe z większą dokładnością;
  • chrony jest mniejszy, zużywa mniej pamięci i angażuje procesor tylko wtedy, gdy jest to konieczne. To duży plus dla oszczędności zasobów i energii;
  • chrony obsługuje znaczniki czasowe na poziomie sprzętowym w systemie Linux, co zapewnia niezwykle dokładną synchronizację w lokalnych sieciach.

Jednak chrony nie ma niektórych funkcji starego NTP, takich jak klienci i serwery multicast oraz broadcast. Dodatkowo klasyczny NTP obsługuje większą liczbę systemów operacyjnych i platform.

Aby wyłączyć funkcjonalność serwera i zapytań NTP do procesu chronyd, wystarczy wpisać port 0 w pliku chrony.conf. Robi się to w przypadkach, gdy nie ma potrzeby obsługiwania czasu dla klientów NTP lub węzłów peer-to-peer. Od wersji 2.0 port serwera NTP jest otwarty tylko wtedy, gdy dostęp jest dozwolony przez dyrektywę allow lub odpowiednią komendę, lub gdy skonfigurowany jest węzeł NTP peer-to-peer, albo używana jest dyrektywa broadcast.

Program składa się z dwóch modułów.

  • chronyd — usługa działająca w tle. Otrzymuje informacje o różnicy czasu zegarów systemowych w porównaniu do zewnętrznego serwera czasu i koryguje lokalny czas. Realizuje również protokół NTP i może działać jako klient lub serwer.
  • chronyc — narzędzie wiersza poleceń do monitorowania i kontrolowania programu. Służy do szczegółowej konfiguracji różnych parametrów usługi, na przykład pozwala na dodawanie lub usuwanie serwerów NTP podczas gdy chronyd nadal działa.

Od siódmej wersji RedHat Linux używa chrony jako usługa synchronizacji czasu. Pakiet jest również dostępny dla innych dystrybucji Linux. Najnowsza stabilna wersja 3.5, przygotowuje się do wydania wersji 4.0.

(1:712)$ sudo emerge -av chrony
To są pakiety, które zostaną scalone, w kolejności:
Obliczanie zależności... gotowe!
[binary  N     ] net-misc/chrony-3.5-r2::gentoo  USE="adns caps cmdmon ipv6 ntp phc readline refclock rtc seccomp (-html) -libedit -pps (-selinux)" 246 KiB
Łącznie: 1 pakiet (1 nowy, 1 binarny), rozmiar pobrań: 246 KiB
Czy chcesz scalic te pakiety? [Tak/Nie]

Jak skonfigurować własny zdalny serwer chrony w internecie do synchronizacji czasu w sieci biurowej. Oto przykład konfiguracji na VPS.

Przykład konfiguracji Chrony na RHEL / CentOS na VPS

Teraz spróbujmy uruchomić nasz własny serwer NTP na VPS. To naprawdę proste, wystarczy wybrać odpowiedni plan na stronie RuVDS, uzyskać gotowy serwer i wpisać kilkanaście prostych komend. Dla naszych celów ta opcja będzie odpowiednia.

Jak synchronizacja czasu stała się bezpieczna

Przechodzimy do konfiguracji usługi i na początek instalujemy pakiet chrony.

[root@server ~]$ yum install chrony

RHEL 8 / CentOS 8 używają innego menedżera pakietów.

[root@server ~]$ dnf install chrony

Po zainstalowaniu chrony należy uruchomić i aktywować usługę.

[root@server ~]$ systemctl enable chrony --now

W razie potrzeby można wprowadzić zmiany w /etc/chrony.conf, zastępując serwery NPT najbliższymi lokalnymi, aby skrócić czas odpowiedzi.

# Use public servers from the pool.ntp.org project.
# Please consider joining the pool (http://www.pool.ntp.org/join.html).
server 0.ru.pool.ntp.org iburst
server 1.ru.pool.ntp.org iburst
server 2.ru.pool.ntp.org iburst
server 3.ru.pool.ntp.org iburst

Następnie konfigurujemy synchronizację serwera NTP z węzłami z określonego puli.

[root@server ~]$ timedatectl set-ntp true
[root@server ~]$ systemctl restart chronyd.service

Należy również otworzyć port NTP, w przeciwnym razie zapora sieciowa zablokuje przychodzące połączenia z węzłów klienckich.

[root@server ~]$ firewall-cmd --add-service=ntp --permanent 
[root@server ~]$ firewall-cmd --reload

Po stronie klienta wystarczy poprawnie ustawić strefę czasową.

[root@client ~]$ timedatectl set-timezone Europe/Moscow

W pliku /etc/chrony.conf należy wskazać adres IP lub nazwę hosta naszego serwera VPS, na którym działa serwer NTP chrony.

server my.vps.server

I w końcu uruchamiamy synchronizację czasu na kliencie.

[root@client ~]$ systemctl enable --now chronyd
[root@client ~]$ timedatectl set-ntp true

Następnym razem opowiem o możliwościach synchronizacji czasu bez dostępu do internetu.

Jak synchronizacja czasu stała się bezpieczna

Jak synchronizacja czasu stała się bezpieczna

Źródło: habr.com

Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS 🔥 Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS | ProHoster