Come fare in modo che il tempo, di per sé, non mentisca, se si hanno un milione di dispositivi grandi e piccoli che interagiscono tramite TCP/IP? Infatti, ognuno di essi ha un orologio e il tempo deve essere corretto su tutti. Questo problema non può essere risolto senza NTP.
Immaginiamo per un minuto che in un segmento dell'infrastruttura IT industriale ci siano difficoltà nella sincronizzazione dei servizi temporali. Inizia immediatamente a guastarsi lo stack software enterprise cluster, i domini si sfaldano, i nodi master e standby cercano invano di ripristinare lo status quo.
È anche possibile che un attaccante cerchi intenzionalmente di disturbare l'orario tramite un attacco MiTM o DDoS. In questa situazione può succedere di tutto:
- scadranno le password degli account utente;
- scadranno i certificati X.509;
- l'autenticazione a due fattori TOTP smetterà di funzionare;
- i backup diventeranno "obsoleti" e il sistema li eliminerà;
- si rompirà DNSSec.
È chiaro che ogni dipartimento IT è interessato al corretto funzionamento dei servizi di sincronizzazione del tempo, e sarebbe utile che fossero affidabili e sicuri in uso industriale.
Distruggere NTP in 25 minuti
I protocolli di rete — i millennial hanno una caratteristica, sono da tempo e già non sono più utili, ma sostituirli non è così facile nemmeno quando si raggiunge una massa critica di appassionati e finanziamenti.
La principale lamentela sul classico NTP è l'assenza di meccanismi di protezione affidabili contro gli attacchi degli aggressori. Sono stati fatti vari tentativi per risolvere questo problema. Per questo motivo è stato innanzitutto implementato un meccanismo di chiavi preimpostate (PSK) per lo scambio di chiavi simmetriche.
Sfortunatamente, questo metodo non si è rivelato efficace a causa di una semplice ragione: non si scalda bene. È necessaria una configurazione manuale sul lato client a seconda del server. Ciò significa che non è così semplice aggiungere un altro cliente. Se qualcosa cambia sul server NTP, bisogna riconfigurare tutti i clienti.
Allora è stato inventato AutoKey, ma sono state subito scoperte una serie di gravi vulnerabilità nel design stesso dell'algoritmo e si è dovuto rinunciare. Il problema è che il numero iniziale (seed) contiene appena 32 bit, è troppo poco e non presenta una complessità di calcolo sufficiente per un attacco frontale.
- Key ID — chiave simmetrica a 32 bit;
- MAC (codice di autenticazione del messaggio) — checksum del pacchetto NTP;
L'Autokey viene calcolato come segue.
Autokey=H(Indirizzo-IP- mittente||Indirizzo-IP- ricevente||ID-chiave||Cookie)Dove H() è una funzione di hash crittografico.
Per calcolare il checksum del pacchetto si utilizza la stessa funzione.
MAC=H(Autokey||pacchetto NTP)Così risulta che l'intera integrità dei controlli dei pacchetti dipende dall'autenticità dei cookie. Possedendoli, è possibile ripristinare l'Autokey e poi falsificare il MAC. Tuttavia, il server NTP utilizza un numero iniziale (seed) durante la loro generazione. È qui che si nasconde il trucco.
Cookie=MSB_32(H(IP-Client||IP-Server||0||Seed-Server))La funzione MSB_32 tronca i 32 bit più significativi dal risultato del calcolo dell'hash md5. Il cookie del client non cambia finché i parametri del server rimangono invariati. Dopodiché, l'attaccante deve solo ripristinare il numero iniziale per avere la possibilità di generare cookies autonomamente.
Per iniziare, è necessario connettersi al server NTP come client e ottenere i cookie. Successivamente, l'attaccante ripristina il numero iniziale seguendo un semplice algoritmo di forza bruta.
Algoritmo di attacco per calcolare il numero iniziale mediante forza bruta.
for i=0:2^32 − 1 do
Ci=H(IP-Server||IP-Client||0||i)
if Ci=Cookie then
return i
end if
end forGli indirizzi IP sono noti, quindi non resta che creare 2^32 hash fino a quando il cookie creato non corrisponde a quello ricevuto dal server NTP. Su una normale stazione domestica con Intel Core i5 ci vorranno 25 minuti.
NTS — nuovo Autokey
Non era possibile convivere con tali falle nella sicurezza dell'Autokey e nel 2012 è emerso un protocollo. Con l'intento di svecchiare l'immagine compromessa si decise di rifare il branding, così Autokey v.2 è stato ribattezzato Network Time Security.
Il protocollo NTS è un'estensione della sicurezza NTP e attualmente supporta solo la modalità unicast. Fornisce una protezione crittografica affidabile contro le manipolazioni dei pacchetti, previene il tracciamento, si scala bene, è resistente alla perdita di pacchetti di rete e comporta le minime perdite di precisione che si verificano durante la protezione della connessione.
La connessione NTS consiste in due fasi, in cui vengono utilizzati protocolli di livello inferiore. Nel primo stadio il client e il server concordano su vari parametri di connessione e si scambiano cookie contenenti chiavi insieme a tutto il relativo insieme di dati. Nel secondo stadio avviene il vero e proprio scambio protetto NTS tra il client e il server NTP.

NTS è composto da due protocolli di livello inferiore: Network Time Security Key Exchange (NTS-KE), inizializzazione di una connessione sicura sopra TLS, e NTPv4 — l'ultima incarnazione del protocollo NTP. Maggiori dettagli su questo argomento di seguito.
Primo passo — NTS KE
In questa fase, il client NTP avvia una sessione TLS 1.2/1.3 su una connessione TCP separata con il server NTS KE. Durante questa sessione si svolgono le seguenti operazioni.
- Le parti definiscono i parametri dell'algoritmo per la seconda fase.
- Le parti definiscono il secondo protocollo di livello inferiore, ma attualmente solo NTPv4 è supportato.
- Le parti definiscono l'indirizzo IP e la porta del server NTP.
- Il server NTS KE fornisce cookie per NTPv4.
- Le parti estraggono dalla materia dei cookie una coppia di chiavi simmetriche (C2S e S2C).
Questo approccio ha un grande vantaggio nel fatto che tutto il carico di trasmissione delle informazioni riservate sui parametri di connessione ricade su un protocollo TLS collaudato e affidabile. Ciò elimina la necessità di inventare una propria soluzione per l'handshake NTP sicuro.
Secondo passo — NTP protetto da NTS
Nella seconda fase, il client sincronizza in modo sicuro l'orario con il server NTP. A tale scopo, invia quattro estensioni speciali (extension field) nella struttura del pacchetto NTPv4.
- L'estensione Unique Identifier contiene un nonce casuale per prevenire attacchi di ripetizione.
- L'estensione NTS Cookie contiene uno dei cookie NTP disponibili per il client. Poiché solo il client dispone delle chiavi simmetriche AAED C2S e S2C, il server NTP deve estrarle dalla materia del cookie.
- L'estensione NTS Cookie Placeholder è un modo per il client di richiedere cookie aggiuntivi dal server. Questa estensione è necessaria affinché la risposta del server NTP non sia significativamente più lunga della richiesta. Questo aiuta a prevenire attacchi di amplificazione.
- L'estensione NTS Authenticator and Encrypted Extension Fields contiene l'algoritmo di cifratura AAED con la chiave C2S, l'intestazione NTP, i timestamp e le suddette EF come dati accessori. Senza questa estensione, è possibile falsificare i timestamp.

Ricevuta una richiesta dal client, il server verifica l'autenticità del pacchetto NTP. A tal fine, deve decifrare i cookie, estrarre l'algoritmo AAED e le chiavi. Dopo aver verificato con successo la validità del pacchetto NTP, il server risponde al client nel seguente formato.
- L'estensione Unique Identifier è una copia speculare della richiesta del client, una misura contro gli attacchi di ripetizione.
- L'estensione NTS Cookie fornisce ulteriori cookie per continuare la sessione.
- L'estensione NTS Authenticator e i campi di estensione crittografati contengono un cifrario AEAD con chiave S2C.
Il secondo handshake può essere ripetuto molte volte, saltando il primo passaggio, poiché ogni richiesta e risposta forniscono al client cookie aggiuntivi. Questo offre il vantaggio che le operazioni TLS relativamente dispendiose di calcolo e trasmissione dei dati PKI sono suddivise in un numero di richieste ripetute. Questo è particolarmente conveniente per i cronometri FPGA specializzati, dove l'intera funzionalità principale può essere confezionata in poche funzioni dell'area della crittografia simmetrica, trasferendo l'intero stack TLS su un altro dispositivo.
NTPSec
Qual è la particolarità di NTP? Nonostante l'autore del progetto, Dave Mills, si sia impegnato a documentare al meglio il suo codice, raramente un programmatore sarà in grado di districarsi tra le complessità degli algoritmi di sincronizzazione temporale di 35 anni fa. Parte del codice è stata scritta prima dell'era POSIX e l'API Unix di allora era molto diversa da quella attuale. Inoltre, sono necessarie conoscenze di statistica per filtrare il segnale dai disturbi su linee rumorose.
NTS non è stata la prima tentativo di riparare il NTP. Dopo che gli aggressori hanno imparato a sfruttare le vulnerabilità del NTP per amplificare gli attacchi DDoS, è diventato chiaro che erano necessarie modifiche radicali. E mentre si preparavano e perfezionavano le bozze di NTS, la National Science Foundation degli Stati Uniti ha urgentemente stanziato fondi a fine 2014 per la modernizzazione del NTP.
Il gruppo di lavoro è stato guidato da non uno qualsiasi, ma da — uno dei fondatori e dei pilastri della comunità Open Source e autore del libro . Per prima cosa, Eric e i suoi compagnni hanno cercato di trasferire il codice NTP dalla piattaforma BitKeeper a git, ma non è andata come sperato. Il leader del progetto Harlan Stenn era contrario a questa decisione e i colloqui sono giunti a un punto morto. Fu allora deciso di forkare il codice del progetto, dando vita a NTPSec.
L'ampia esperienza, compreso il lavoro su GPSD, la formazione matematica e l'abilità unica di leggere codice antico — Eric Raymond era esattamente l'hacker che poteva portare avanti un progetto del genere. Nel team c'era uno specialista nella migrazione del codice e in sole 10 settimane NTP su GitLab. Il lavoro è iniziato con fervore.
Il team di Eric Raymond ha affrontato il compito esattamente come Auguste Rodin ha fatto con un blocco di pietra. Rimuovendo 175 KLOC di codice obsoleto, sono riusciti a ridurre significativamente la superficie di attacco, chiudendo molte vulnerabilità di sicurezza.
Ecco un elenco non esaustivo di ciò che è stato colpito:
- Refclock non documentate, obsolete o rotte.
- Libreria ICS non utilizzata.
- libopts/autogen.
- Codice obsolete per Windows.
- ntpdc.
- Autokey.
- Il codice C di ntpq è stato riscritto in Python.
- Il codice C di sntp/ntpdig è stato riscritto in Python.
Oltre alla pulizia del codice, il progetto aveva anche altre attività. Ecco un elenco non esaustivo dei risultati:
- Significativa miglioramento della protezione del codice da overflow di buffer. Per prevenire l'overflow di buffer, tutte le funzioni di stringa non sicure (strcpy / strcat / strtok / sprintf / vsprintf / gets) sono state sostituite con versioni sicure che implementano un limite di dimensione del buffer.
- Aggiunto supporto per NTS.
- Dieci volte aumentata la precisione dei passi temporali grazie al collegamento dell'hardware fisico. Questo è dovuto al fatto che gli orologi dei computer moderni sono diventati molto più precisi rispetto a quelli al momento della nascita di NTP. GPSDO e stazioni radio temporali dedicate ne hanno beneficiato di più.
- Il numero di linguaggi di programmazione è stato ridotto a due. Invece di script Perl, awk e persino S, ora c'è solo Python. Questo ha aumentato le possibilità di riutilizzo del codice.
- Invece della confusione degli script, autotools il progetto ha iniziato a utilizzare un sistema di build per il software. .
- Abbiamo aggiornato e riorganizzato la documentazione del progetto. Da una raccolta di documenti contraddittori e in parte arcaici, abbiamo creato una documentazione accettabile. Ogni chiave della riga di comando e ogni entità di configurazione ora hanno una versione unica della verità. Inoltre, le pagine di manuale e la documentazione web vengono ora create dagli stessi file di base.
NTPSec è disponibile per diverse distribuzioni Linux. Attualmente, l'ultima versione stabile è 1.1.8, per Gentoo Linux è la penultima.
(1:696)$ sudo emerge -av ntpsec
Questi sono i pacchetti che verrebbero uniti, in ordine:
Calcolo delle dipendenze... fatto!
[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
Totale: 1 pacchetto (1 reinstallazione), Dimensione dei download: 0 KiB
Vuoi unire questi pacchetti? [Sì/No]
Chrony
C'è stata un'altra possibilità di sostituire il vecchio NTP con un'alternativa più sicura. Chrony, a differenza di NTPSec, è stato scritto da zero ed è progettato per funzionare in modo affidabile in una vasta gamma di condizioni, comprese le connessioni di rete instabili, la disponibilità parziale o il sovraccarico della rete e le variazioni di temperatura. Inoltre, chrony ha altri vantaggi:
- chrony può sincronizzare più rapidamente gli orologi di sistema con maggiore precisione;
- chrony è più leggero, consuma meno memoria e accede al processore solo quando necessario. Questo rappresenta un grande vantaggio per il risparmio di risorse ed energia;
- chrony supporta i timestamp a livello hardware in Linux, il che garantisce una sincronizzazione estremamente precisa nelle reti locali.
Tuttavia, chrony non offre alcune funzionalità del vecchio NTP, come il client/server multicast e broadcast. Inoltre, il classico NTP supporta un numero maggiore di sistemi operativi e piattaforme.
Per disabilitare la funzionalità del server e le richieste NTP al processo chronyd, è sufficiente impostare port 0 nel file chrony.conf. Questo viene fatto nei casi in cui non è necessario fornire tempo ai client NTP o ai nodi peer. A partire dalla versione 2.0, la porta del server NTP è aperta solo nei casi in cui l'accesso è consentito dalla direttiva allow o dal comando corrispondente, oppure se è configurato un nodo peer NTP, o è utilizzata la direttiva broadcast.
Il programma è composto da due moduli.
- chronyd è un servizio che funziona in background. Riceve informazioni sulla differenza tra l'orologio di sistema e il server esterno di riferimento e corregge l'orario locale. Implementa anche il protocollo NTP e può funzionare come client o server.
- chronyc è un'utilità da riga di comando per monitorare e controllare il programma. Viene utilizzata per ottimizzare vari parametri del servizio, ad esempio permette di aggiungere o rimuovere server NTP mentre chronyd continua a funzionare.
A partire dalla settima versione di RedHat Linux chrony come servizio di sincronizzazione del tempo. Il pacchetto è disponibile anche per altre distribuzioni Linux. L'ultima versione stabile è 3.5, è prevista l'uscita della v4.0.
(1:712)$ sudo emerge -av chrony
Questi sono i pacchetti che verrebbero fusi, in ordine:
Calcolo delle dipendenze... eseguito!
[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
Totale: 1 pacchetto (1 nuovo, 1 binario), dimensione dei download: 246 KiB
Vuoi unire questi pacchetti? [Sì/No]
Come configurare un proprio server remoto chrony su Internet per la sincronizzazione dell'ora nella rete aziendale. Di seguito un esempio di configurazione su VPS.
Esempio di configurazione di Chrony su RHEL / CentOS su VPS
Adesso esercitiamoci un po' e alziamo il nostro server NTP su VPS. È molto semplice, basta scegliere il piano adatto sul sito RuVDS, ottenere un server pronto e digitare una dozzina di comandi semplici. Per i nostri scopi, questa opzione è più che adeguata.

Passiamo alla configurazione del servizio e come primo passo installiamo il pacchetto chrony.
[root@server ~]$ yum install chronyRHEL 8 / CentOS 8 utilizzano un altro gestore di pacchetti.
[root@server ~]$ dnf install chronyDopo aver installato chrony, è necessario avviare e attivare il servizio.
[root@server ~]$ systemctl enable chrony --nowSe si desidera, è possibile apportare modifiche a /etc/chrony.conf, sostituendo i server NPT con quelli locali più vicini per ridurre il tempo di risposta.
# 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
Successivamente, configuriamo la sincronizzazione del server NTP con i nodi del pool specificato.
[root@server ~]$ timedatectl set-ntp true
[root@server ~]$ systemctl restart chronyd.service
È anche necessario aprire la porta NTP all'esterno, altrimenti il firewall bloccherà le connessioni in entrata dai nodi client.
[root@server ~]$ firewall-cmd --add-service=ntp --permanent
[root@server ~]$ firewall-cmd --reload
Sul lato client, è sufficiente impostare correttamente il fuso orario.
[root@client ~]$ timedatectl set-timezone Europe/MoscowNel file /etc/chrony.conf specificare l'IP o il nome host del nostro server VPS, dove è in esecuzione il server NTP chrony.
server my.vps.serverE infine avviare la sincronizzazione dell'ora sul client.
[root@client ~]$ systemctl enable --now chronyd
[root@client ~]$ timedatectl set-ntp true
La prossima volta parlerò delle opzioni di sincronizzazione dell'ora senza Internet.
Fonte: habr.com
