SSD Nodes Learn Hosting plans →
Guide Matt ConnorDi Matt Connor · Aggiornato 2026-08-27

Orologio del VPS impreciso: cause e soluzione

Scopri perché l'ora del VPS perde precisione, come leggere chronyc e timedatectl e quale sincronizzazione ripristinare quando il 2FA non accede.

Perché l'orologio del VPS perde precisione

L'orologio di un VPS perde precisione perché nessun componente lo corregge. Il kernel misura il tempo usando un contatore hardware che può avanzare leggermente più o meno rapidamente. Se non è in esecuzione alcun client di sincronizzazione dell'ora, questo piccolo errore aumenta ogni ora. In una macchina virtuale esiste una seconda causa: il guest condivide una CPU fisica con altri guest, quindi durante i periodi in cui non viene pianificato non può contare il tempo.

In un guest KVM attuale, il contatore in sé raramente è il vero problema. La sorgente paravirtuale kvm-clock legge un valore mantenuto dall'host, quindi un guest in buone condizioni mantiene l'ora strettamente allineata a quella dell'host. Gli orologi che mostrano un errore evidente sono generalmente imprecisi per un motivo più semplice. Non è in esecuzione alcun demone di sincronizzazione, oppure ne sono in esecuzione due che interferiscono tra loro, oppure il traffico UDP in uscita sulla porta 123 non esce dalla rete del provider. Un guest sincronizza l'ora tramite l'host o tramite NTP (network time protocol), non tramite il proprio oscillatore.

Che cosa rompe realmente un orologio errato

  • I codici TOTP (password monouso basate sul tempo) per l'autenticazione a due fattori non corrispondono più. Di conseguenza, non è possibile accedere a un server anche quando password e chiave sono corrette.
  • Un certificato emesso un minuto prima viene rifiutato e curl stampa SSL certificate problem: certificate is not yet valid.
  • apt update rifiuta un repository con E: Release file for ... is not valid yet (invalid for another 1d 2h 3min 4s).
  • Le attività pianificate vengono eseguite nel momento sbagliato. Un salto dell'orologio può fare eseguire due volte un'attività e farne saltare un'altra.
  • Non è possibile allineare i log di due server. La sequenza temporale di un incidente deve quindi essere ricostruita per supposizioni.

La tolleranza è inferiore a quanto molti si aspettano. I valori riportati di seguito sono impostazioni predefinite documentate, non misurazioni ottenute durante un test.

ChartHow far the clock can be off before something breaks (documented defaults)
The data behind this chart
[
  {
    "label": "TLS certificate boundary",
    "tolerance_seconds": 0,
    "documented_in": "RFC 5280"
  },
  {
    "label": "chrony steps instead of slewing",
    "tolerance_seconds": 1,
    "documented_in": "Debian and Ubuntu chrony.conf"
  },
  {
    "label": "TOTP code, one time step",
    "tolerance_seconds": 30,
    "documented_in": "RFC 6238"
  },
  {
    "label": "Kerberos clock skew",
    "tolerance_seconds": 300,
    "documented_in": "MIT krb5 default"
  }
]

Un codice TOTP viene calcolato a partire da un contatore che avanza ogni 30 secondi. La maggior parte dei verificatori accetta anche l'intervallo immediatamente precedente o successivo. Un errore di mezzo minuto in una delle due direzioni esaurisce l'intero margine disponibile. Kerberos è molto più permissivo, con una tolleranza predefinita dell'errore di 300 secondi. Un certificato, invece, non ammette praticamente alcuna tolleranza: viene verificato rispetto a istanti fissi, con un periodo di tolleranza di 0 secondi. Di conseguenza, un orologio indietro di un solo secondo rifiuta un certificato perfettamente valido.

I tre orologi e quale conta davvero

L'orologio di sistema è quello che conta. È il CLOCK_REALTIME del kernel: il numero di secondi trascorsi dal 1 gennaio 1970 UTC, mantenuto in memoria e letto da tutto ciò che assegna un timestamp. Le righe dei log, i controlli dei certificati, i codici TOTP e gli orari di modifica dei file derivano tutti da questo orologio. Quando si dice che l'ora del server è errata, si intende questo orologio.

L'orologio hardware, chiamato anche RTC (real time clock), è un contatore separato che continua a funzionare mentre la macchina è spenta. Su una macchina fisica è un chip alimentato da una batteria. All'interno di un guest viene emulato dall'hypervisor, quindi è in gran parte un dato del sistema host. Linux lo legge una volta durante il boot per ottenere un valore iniziale, poi mantiene un proprio conteggio. timedatectl lo stampa nella riga RTC time. Su un VPS non eseguire il troubleshooting a partire da quella riga, perché mostra l'idea dell'ora dell'host, non lo stato di sincronizzazione dell'orologio di sistema. In un container di solito non esiste alcun /dev/rtc, quindi hwclock --show fallisce con hwclock: Cannot access the Hardware Clock via any known method.

La sorgente dell'orologio è il meccanismo con cui il kernel conta il tempo tra queste letture. Chiedi al kernel quale sorgente ha selezionato:

cat /sys/devices/system/clocksource/clocksource0/current_clocksource
cat /sys/devices/system/clocksource/clocksource0/available_clocksource

Su KVM vedrai di solito kvm-clock. Legge un valore mantenuto dall'host, ed è per questo che un guest KVM privo di un client NTP continua a mantenere un'ora approssimativamente corretta per un certo periodo. tsc è il contatore interno della CPU. I guest Xen riportano xen, mentre i guest Hyper-V riportano una sorgente hyperv. Non modificare questa impostazione senza una ragione verificata, perché il kernel seleziona già la sorgente migliore disponibile e affidabile su quell'hardware.

Alcuni host rendono disponibile al guest anche un dispositivo PTP (precision time protocol), che consente a chrony di leggere direttamente l'orologio dell'host invece di usare la rete. Vale la pena verificare, anche se su un VPS condiviso spesso non è disponibile:

sudo modprobe ptp_kvm
ls /dev/ptp*
cat /sys/class/ptp/ptp0/clock_name

Se modprobe fallisce o non compare alcun dispositivo, l'host non lo espone e la risposta è usare NTP sulla rete. Se clock_name indica l'orologio virtuale KVM, chrony può utilizzarlo con una riga refclock PHC /dev/ptp0 poll 2 nella propria configurazione.

Leggere lo stato dell'ora sul computer locale

Iniziare con un comando. Risponde alla domanda «c'è qualcosa che mantiene corretta questa ora?» in un'unica schermata.

timedatectl

Leggere queste righe invece di fidarsi di un numero ricordato:

  • Local time e Universal time rappresentano lo stesso istante, visualizzato nel fuso orario locale e in UTC. Se sono identici, il computer usa già UTC.
  • RTC time è l'orologio hardware descritto sopra. Su un VPS, ignorarlo.
  • Time zone indica ciò che il sistema usa per formattare l'ora locale.
  • System clock synchronized è il flag interno del kernel. Un demone di sincronizzazione dell'ora lo imposta quando considera affidabili le proprie sorgenti; quindi no indica che nessun processo ha sincronizzato questo orologio dall'avvio.
  • NTP service fornisce informazioni specifiche su systemd-timesyncd. n/a è normale su un computer che esegue chrony, perché in quel caso timesyncd non è installato. System clock synchronized: yes insieme a NTP service: n/a indica che chrony sta gestendo la sincronizzazione e che il kernel lo conferma.

Successivamente, verificare di quanto l'orologio è fuori sincronia. Non confrontarlo a occhio con il telefono. Se chrony è in esecuzione:

chronyc tracking
chronyc sources -v

chronyc tracking stampa i valori che rispondono a questa domanda. System time è lo scarto corrente rispetto all'ora NTP, seguito dalla parola fast o slow. Last offset è l'entità della correzione più recente. Frequency è l'errore di frequenza misurato da chrony nell'orologio, che chrony sta già compensando. Leap status dovrebbe riportare Normal. Se riporta Not synchronised e Reference ID è 00000000 (), chrony non ha ancora selezionato una sorgente.

chronyc sources -v stampa una legenda sopra l'elenco, quindi non è necessario ricordare i simboli. La maggior parte delle informazioni è contenuta in due colonne. Il carattere di stato all'inizio di ogni riga indica la valutazione che chrony assegna a quella sorgente: * contrassegna la sorgente attualmente utilizzata, mentre ? su ogni riga indica che nessuna sorgente risponde. Reach rappresenta la cronologia delle risposte degli ultimi otto sondaggi, stampata in ottale: 377 indica che tutte e otto le richieste hanno ricevuto risposta, mentre 0 indica che non ne ha ricevuta nessuna.

Se invece la sincronizzazione è gestita da systemd-timesyncd:

timedatectl timesync-status
timedatectl show-timesync --all

timesync-status stampa il server con cui comunica, l'intervallo tra i sondaggi e un valore Offset. Se il comando restituisce un errore relativo al servizio invece di stampare lo stato, timesyncd non è il demone che gestisce l'ora su questo computer. Anche questo risponde alla domanda iniziale.

Per un controllo approssimativo rispetto a una sorgente esterna, senza strumenti aggiuntivi, confrontare l'orologio con l'header HTTP pubblico Date, fornito in GMT con una risoluzione di un secondo:

date -u
curl -sI https://www.cloudflare.com | grep -i '^date:'

Una differenza di uno o due secondi è normale e non indica alcun problema. Una differenza di un minuto indica un errore nella configurazione.

chrony o systemd-timesyncd su una VPS

Ubuntu e Debian includono systemd-timesyncd per impostazione predefinita. È un client SNTP (simple network time protocol): interroga un server alla volta e avvicina gradualmente l’orologio all’ora indicata. Su una macchina che resta online e parte con un’ora approssimativamente corretta, è sufficiente e ha un costo operativo quasi nullo.

chrony è un’implementazione NTP completa e rappresenta la scelta predefinita migliore su una macchina virtuale, per motivi visibili anche nel suo output. Interroga più sorgenti contemporaneamente e scarta quelle che forniscono valori discordanti. Misura l’errore di frequenza dell’orologio e lo scrive in un file di drift, quindi corregge la tendenza dell’orologio invece di inseguire ogni singolo campione. Inoltre recupera rapidamente dalle due condizioni tipiche di una VM che non si verificano su un server fisico: l’host può sospenderla e la VM può essere spostata su un altro host mentre è in esecuzione. Quando viene reso disponibile un dispositivo PTP dell’host, è chrony a leggerlo.

sudo apt update && sudo apt install -y chrony
systemctl status chrony --no-pager
chronyc sources -v
chronyc tracking

Leggi l’output di apt durante l’esecuzione. Su Debian e Ubuntu, i pacchetti chrony e systemd-timesyncd forniscono entrambi time-daemon, quindi apt rimuove timesyncd mentre installa chrony. Questo comportamento è corretto e previsto. Non eseguire mai entrambi i servizi, perché due demoni che impostano lo stesso orologio entrano in conflitto e, finché restano attivi, non è possibile considerare attendibile l’offset riportato da nessuno dei due. Su Rocky e AlmaLinux, installa il pacchetto con sudo dnf install -y chrony, dove l’unità si chiama chronyd anziché chrony.

Il file di configurazione si trova in /etc/chrony/chrony.conf su Debian e Ubuntu e in /etc/chrony.conf su Rocky e Alma. La configurazione predefinita della distribuzione è già adeguata per una VPS, quindi modificala solo per un motivo specifico. È utile comprendere due direttive:

  • Le righe pool e server definiscono le sorgenti dell’ora. L’aggiunta di iburst indica a chrony di inviare un burst rapido all’avvio, in modo che la prima sincronizzazione avvenga in pochi secondi anziché in alcuni minuti.
  • makestep stabilisce quando chrony deve correggere bruscamente l’orologio anziché modificarlo gradualmente. Verifica il valore configurato con grep -n makestep /etc/chrony/chrony.conf. Il valore predefinito su Debian e Ubuntu, makestep 1 3, significa quanto segue: durante i primi tre aggiornamenti dopo l’avvio di chronyd, l’orologio viene corretto bruscamente se lo scarto supera un secondo; in seguito viene corretto soltanto tramite slewing.

Se vuoi autenticare il traffico dell’ora per proteggerlo da manomissioni lungo il percorso, chrony 4 e versioni successive supportano NTS (network time security). Verifica prima la versione con chronyd -v e tieni presente che NTS richiede anche l’apertura della porta TCP 4460 in uscita, oltre alla porta UDP 123:

server time.cloudflare.com iburst nts

Riavvia il servizio e verifica il risultato prima di considerarlo affidabile. Se la configurazione non può essere analizzata, non resterà attivo alcun demone dell’ora e l’orologio non te lo segnalerà.

sudo systemctl restart chrony
chronyc sources -v
chronyc tracking

Perché un orologio in ritardo di alcuni minuti continua a essere in ritardo

Un demone per la sincronizzazione dell'ora può correggere lo scarto in due modi. Con lo slew accelera o rallenta l'orologio finché l'errore scompare. In questo modo il tempo avanza sempre e nessuna marca temporale viene ripetuta o saltata. Con lo step passa direttamente al valore corretto. È rapido, ma può spostare l'orologio all'indietro. Questo è rischioso per tutto ciò che misura il tempo trascorso usando l'orologio di sistema. Per questo entrambi i demoni preferiscono lo slew.

Questa preferenza spiega perché un orologio molto fuori sincronizzazione può restare errato a lungo. chrony esegue lo step solo all'interno dell'intervallo consentito da makestep, che per impostazione predefinita corrisponde ai primi aggiornamenti dopo l'avvio del demone. Se chronyd è in esecuzione da una settimana e rileva un errore di quaranta secondi, lo corregge con lo slew. Correggere quaranta secondi in questo modo richiede molto più tempo di quanto si voglia aspettare. Forza la correzione una sola volta, in modo intenzionale e in un momento di bassa attività:

sudo chronyc makestep
chronyc tracking

chronyc tracking dovrebbe ora riportare uno scarto System time prossimo allo zero, mentre Last offset dovrebbe mostrare l'entità della correzione appena applicata. Prima di eseguire il comando su un host con un database attivo, valuta il rischio: un orologio che torna indietro può confondere il software che presume che il tempo avanzi soltanto. Riavviare il demone è una versione più graduale della stessa correzione, perché l'intervallo makestep si riapre all'avvio.

I container condividono l'orologio dell'host

Un container non dispone di un proprio orologio civile, quindi al suo interno non c'è nulla da sincronizzare. I namespace temporali di Linux virtualizzano soltanto gli orologi monotoni e quelli relativi all'avvio. CLOCK_REALTIME non è virtualizzato, quindi il container legge lo stesso orologio di sistema dell'host su cui è in esecuzione. Correggendo l'orologio sull'host, si corregge nello stesso momento quello di ogni container eseguito su quell'host.

Da questo derivano alcune conseguenze. Non installare chrony o ntpd in un'immagine, perché nella migliore delle ipotesi non produce alcun effetto. L'impostazione della data all'interno di un container senza privilegi non va a buon fine e restituisce date: cannot set date: Operation not permitted, perché per questa chiamata il kernel richiede CAP_SYS_TIME. La concessione di CAP_SYS_TIME non assegna al container un orologio privato: gli permette di modificare l'orologio dell'host e quindi anche quello di tutti gli altri container.

Un fuso orario diverso all'interno di un container non indica un problema dell'orologio. Un'immagine che include il proprio /etc/localtime visualizza lo stesso istante formattato per un altro fuso, quindi date sembra errato anche se l'orologio è corretto. Imposta TZ=UTC nell'ambiente del container per eliminare la confusione. Il runtime scelto non cambia nulla in questo caso; il confronto tra Podman e Docker rootless descrive invece ciò che cambia.

Fusi orari: UTC sul server, ora locale per le persone

Impostate la macchina su UTC e lasciatela così.

timedatectl list-timezones | grep -i utc
sudo timedatectl set-timezone UTC
timedatectl

UTC non applica l'ora legale, e questo è l'argomento principale. Un'attività giornaliera alle 02:30 in un fuso che applica l'ora legale viene eseguita due volte nel giorno in cui gli orologi tornano indietro e non viene eseguita affatto nel giorno in cui avanzano. man 8 cron documenta la gestione speciale degli spostamenti inferiori a tre ore: le attività saltate a causa di un avanzamento vengono eseguite poco dopo la modifica, mentre quelle che si trovano nell'ora ripetuta a causa di un arretramento non vengono eseguite una seconda volta. Questo comportamento è ragionevole, ma non dovreste doverlo analizzare alle 03:00. Con UTC l'attività viene eseguita una volta al giorno, ogni giorno dell'anno. Se una vostra attività manca del tutto invece di essere eseguita a un'ora insolita, è più probabile che la causa sia un'attività cron che non viene mai eseguita senza produrre errori.

Lo stesso argomento vale per la lettura dei log. journalctl formatta i timestamp nel fuso orario di sistema, mentre journalctl --utc forza UTC. Due server in due fusi diversi trasformano ogni incidente in un esercizio di conversione, e le conversioni eseguite sotto pressione sono una causa comune di errori nella ricostruzione della sequenza temporale. Mantenete i sistemi su UTC, memorizzate i timestamp in UTC e convertiteli una sola volta, quando vengono letti da una persona. Chi vuole visualizzare l'ora locale per un singolo comando può richiederla senza modificare la macchina:

TZ=Europe/Berlin date

Un'altra riga dell'output di timedatectl rientra in questa sezione. RTC in local TZ dovrebbe essere impostato su no. Impostarlo su yes è una soluzione temporanea per il dual boot di Windows su un laptop; su un server aggiunge soltanto uno scostamento che in seguito potrebbe causare errori. Quando è impostato, timedatectl stampa un avviso che indica che il sistema è configurato per leggere l'ora dell'RTC nel fuso orario locale.

Risoluzione dei problemi in base al sintomo

Il codice a due fattori viene rifiutato su un server. Controlla l'orologio prima di verificare qualsiasi altra cosa. Il codice deriva da un contatore che avanza ogni 30 secondi. Un server indietro di 90 secondi calcola quindi un codice relativo a un intervallo già superato dal telefono. timedatectl mostrerà System clock synchronized: no oppure chronyc tracking segnalerà uno scostamento System time elevato. Si tratta di un errore diverso dal rifiuto diretto di una chiave, che visualizza un messaggio specifico ed è trattato nella guida agli errori di autenticazione con publickey.

apt update indica che un file Release non è ancora valido. Il messaggio completo indica il repository e per quanto tempo resterà non valido, ad esempio is not valid yet (invalid for another 1d 2h 3min 4s). L'orologio del sistema è indietro rispetto alla data contenuta nel file Release del repository. La durata indicata misura direttamente di quanto è indietro l'orologio. Correggi l'orologio. Non disabilitare il controllo della data di apt per superare l'errore, perché quel controllo impedisce a qualcuno di fornirti un indice dei pacchetti obsoleto.

Ogni riga delle sorgenti mostra lo stato non raggiungibile e Reach è 0. Nessuno risponde. Controlla quindi il traffico in uscita invece della configurazione. NTP usa la porta UDP 123 in uscita e alcune reti filtrano o reindirizzano questo traffico. sudo chronyc ntpdata stampa i contatori per ogni sorgente, inclusi Total TX e Total RX. Se il contatore TX aumenta mentre RX resta a zero, i pacchetti escono ma non arriva alcuna risposta. Questo indica un firewall tra il sistema e la sorgente.

L'orologio era corretto, poi ha subito un salto. Gli eventi dell'host possono causare questo comportamento. Il ripristino di uno snapshot, una macchina guest sospesa o una migrazione live verso un altro host possono lasciare l'ora della guest indietro rispetto a quella reale. chrony rileva il problema al polling successivo e corregge l'orologio. systemd-timesyncd potrebbe invece attendere prima un intervallo di polling lungo. Verifica che il demone venga avviato al boot con systemctl is-enabled chrony, perché un demone avviato manualmente non sarà più attivo dopo il riavvio successivo.

Lo scostamento è ridotto, ma non si stabilizza mai. Controlla il CPU steal. Una guest che non viene schedulata quando deve ricevere l'interrupt del timer acquisisce i campioni in ritardo. Lo scostamento quindi varia invece di convergere. top mostra questo valore nella figura st della riga della CPU. Interpretazione del CPU steal time su un host condiviso spiega il significato di questo valore e come intervenire.

Un certificato appena emesso viene rifiutato perché non è ancora valido. curl stampa SSL certificate problem: certificate is not yet valid e i browser mostrano un messaggio simile. Il certificato è corretto; è indietro l'orologio che lo verifica. Il problema può riguardare il client o il server, quindi controlla entrambi. Se il server che ha emesso il certificato è quello con l'orologio errato, la guida ai certificati di certbot e nginx descrive la procedura di rinnovo per la stessa configurazione.

Aggiungilo ai controlli che esegui già

La sincronizzazione dell'ora è un'impostazione applicata all'avvio che può smettere di funzionare senza segnalazioni dopo mesi. È esattamente il tipo di problema che un controllo periodico rileva, mentre la memoria può dimenticarlo. timedatectl e chronyc tracking richiedono due secondi per essere letti insieme. Eseguili come parte di primi dieci minuti su un nuovo VPS, quindi ripetili quando segui la checklist di manutenzione ordinaria dei server Linux. Se preferisci eseguire automaticamente il controllo e ricevere una segnalazione quando l'offset aumenta, la creazione di un servizio e di un timer systemd illustra il modello per una piccola unità che genera report secondo una pianificazione. Un controllo di questo tipo è un breve script, non un daemon; perciò richiede Type=oneshot invece dell'impostazione predefinita. La panoramica dei tipi di servizio systemd spiega perché scegliere quello errato lascia un'unità che segnala un esito positivo che non ha mai ottenuto.

FAQ

Come posso verificare se l'orologio del mio VPS è sincronizzato?

Eseguire timedatectl e leggere la riga System clock synchronized. Questo è il flag del kernel, impostato dal demone che disciplina l'orologio. Pertanto, su un sistema che usa chrony, la presenza contemporanea di yes e NTP service: n/a è normale e indica uno stato corretto. Per conoscere l'entità dell'errore, eseguire chronyc tracking e leggere System time oppure, se è systemd-timesyncd a gestire la sincronizzazione, eseguire timedatectl timesync-status e leggere Offset. Per un controllo rispetto a una fonte esterna al sistema, confrontare date -u con l'header Date restituito da un qualsiasi sito HTTPS.

Devo usare chrony o systemd-timesyncd su un VPS?

Usare chrony per tutti i sistemi importanti. systemd-timesyncd è un client SNTP che segue un solo server. È adatto a un sistema che rimane online e parte con un orario già abbastanza preciso. chrony interroga più fonti, scarta quelle non concordanti, apprende l'errore di frequenza dell'orologio e recupera rapidamente dopo una pausa dell'host o una migrazione live. L'installazione di chrony su Debian o Ubuntu rimuove automaticamente systemd-timesyncd, perché entrambi i pacchetti forniscono time-daemon. Non eseguire mai due demoni di sincronizzazione dell'ora contemporaneamente.

Perché i miei codici TOTP non funzionano su un server, ma funzionano ovunque altrove?

Perché un codice TOTP è una funzione dell'ora corrente. Il codice deriva da un contatore che avanza ogni 30 secondi. Pertanto, il server e il telefono devono concordare sull'intervallo temporale corrente. La maggior parte dei verificatori accetta l'intervallo precedente o quello successivo. Questo concede un margine di circa mezzo minuto in entrambe le direzioni. Controllare timedatectl su quel server. Se System clock synchronized restituisce no, correggere la sincronizzazione. I codici torneranno a corrispondere senza modificare il secret condiviso.

Posso impostare l'ora all'interno di un container Docker?

No, e non è necessario. Un container condivide il CLOCK_REALTIME dell'host, perché gli spazi dei nomi temporali di Linux virtualizzano soltanto gli orologi monotonic e di avvio. Un container senza privilegi riceve date: cannot set date: Operation not permitted. L'aggiunta di CAP_SYS_TIME gli consente di modificare l'orologio dell'host, invece di assegnargli un orologio indipendente. Sincronizzare quindi l'host. Un'ora locale diversa all'interno di un container è un'impostazione del fuso orario. Impostare TZ nell'ambiente del container.

Un server deve usare UTC o l'ora locale?

UTC, applicando l'ora locale nel momento in cui una persona legge l'output. UTC non cambia con l'ora legale. Pertanto, un'attività giornaliera viene eseguita una volta al giorno per tutto l'anno e i timestamp di server diversi sono allineati senza conversioni. Impostarla con sudo timedatectl set-timezone UTC. Chi desidera visualizzare l'ora locale può anteporre un singolo comando, ad esempio TZ=America/New_York date. Questo non modifica l'orologio di sistema.