NTP synchronization & configuration on Debian/Ubuntu

Following thread Network Time? , it might be useful to present the most widespread options or Network Time Protocol implementations for GNU/Linux Debian and Ubuntu. It is not a reference for installation as there are already many posts and videos on the subject, but merely a memo and brief overview of their use and main differences.


:clock2: Main NTP implementations for Debian/Ubuntu

ntp

The oldest of all, and the most complete as well since it’s the Official Reference Implementation of NTP from ntp.org. As any other implementation, there is one daemon, i.e. ntpd, whose role is to synchronize on a NTP server or a list thereof (pool) and client, i.e. ntpq, to query and/or interact with. The main configuration file is /etc/ntp.conf

ntpq example
$ ntpq -pn
     remote           refid      st t when poll reach   delay   offset  jitter
==============================================================================
 0.fr.pool.ntp.o .POOL.          16 p    -   64    0    0.000   +0.000   0.000
 1.fr.pool.ntp.o .POOL.          16 p    -   64    0    0.000   +0.000   0.000
 2.fr.pool.ntp.o .POOL.          16 p    -   64    0    0.000   +0.000   0.000
 3.fr.pool.ntp.o .POOL.          16 p    -   64    0    0.000   +0.000   0.000
#51.254.83.231   145.238.203.14   2 u   91  128    7   11.471   -3.803   1.814
+178.33.111.49   5.196.160.139    3 u   90  128    7    9.544   -2.768   0.762
*94.23.2.80      145.238.203.14   2 u   89  128    7    8.739   -2.804   0.890
-5.196.160.139   145.238.203.14   2 u   89  128    7    8.549   -2.911   0.940
#51.77.12.38     85.199.214.101   2 u   88  128    7   10.013   -2.638   3.667
+162.159.200.1   10.19.9.101      3 u   90  128    7    7.160   -2.625   0.380
-51.15.182.163   193.190.230.37   2 u   90  128    7    7.398   -3.610   4.583
#51.158.147.92   161.143.24.141   2 u   88  128    7   15.063   -2.033   3.134
#194.177.34.116  86.90.58.100     3 u   89  128    7    6.527   -2.187   5.044
#162.159.200.123 10.19.9.101      3 u   88  128    7    5.970   -2.628   0.760
-92.222.117.115  210.100.177.101  2 u   91  128    7   11.830   -2.921   4.010
-212.83.187.62   79.143.250.42    2 u   91  128    7    6.376   -2.154   4.372
+51.68.44.27     212.83.158.83    3 u   91  128    7   11.125   -2.539   4.845
-129.250.35.250  249.224.99.213   2 u   89  128    7    6.245   -2.270   0.720
#37.187.104.44   193.190.230.37   2 u   58  128    7   10.323   -2.425   0.502
-163.172.150.183 10.194.3.3       4 u   44  128   17    6.861   -3.416   0.959

Whenever synchronized you’ll have a line starting with ‘*’ indicating the NTP server in use. ntpq provides many commands, all listed on inline help (ntpq then help). After some time it will create the file /var/lib/ntp/ntp.drift, its content shows how much your clock is drifting in PPM (parts per million). A rate of drift of 1 PPM being the equivalent to 1μs per second or 86.4ms per day.

systemd-timesyncd

Part of the systemd project, this NTP daemon is by far the most simple to configure and use.

systemd-timesyncd service example
# Like any other systemd service, enabled with
$ systemctl enable systemd-timesyncd
# Started with
$ systemctl start systemd-timesyncd
# Check current status with
$ systemctl status systemd-timesyncd
# and journal with
$ journalctl -efu systemd-timesyncd
# reload daemons configuration after a change
$ systemctl daemon-reload

Its configuration is defined in /etc/systemd/timesyncd.conf (see timesyncd.conf(5) manpage for details). And to query the NTP synchronization status, the tool timedatectl is provided with systemd package, it also enables changing TZ (Time Zone).

timedatectl examples
$ timedatectl status
               Local time: sam. 2021-06-05 02:41:20 CEST
           Universal time: sam. 2021-06-05 00:41:20 UTC
                 RTC time: sam. 2021-06-05 00:41:20
                Time zone: Europe/Paris (CEST, +0200)
System clock synchronized: yes
              NTP service: active
          RTC in local TZ: no

$ timedatectl show
Timezone=Europe/Paris
LocalRTC=no
CanNTP=yes
NTP=yes
NTPSynchronized=yes
TimeUSec=Sat 2021-06-05 02:41:38 CEST
RTCTimeUSec=Sat 2021-06-05 02:41:38 CEST

$ timedatectl show-timesync
SystemNTPServers=0.fr.pool.ntp.org 1.fr.pool.ntp.org 2.fr.pool.ntp.org 3.fr.pool.ntp.org
FallbackNTPServers=0.debian.pool.ntp.org 1.debian.pool.ntp.org 2.debian.pool.ntp.org 3.debian.pool.ntp.org
ServerName=3.fr.pool.ntp.org
ServerAddress=162.159.200.123
RootDistanceMaxUSec=5s
PollIntervalMinUSec=32s
PollIntervalMaxUSec=34min 8s
PollIntervalUSec=34min 8s
NTPMessage={ Leap=0, Version=4, Mode=4, Stratum=3, Precision=-24, RootDelay=12.420ms, RootDispersion=289us, Reference=A130965, OriginateTimestamp=Sat 2021-06-05 02:42:21 CEST, ReceiveTimestamp=Sat 2021-06-05 02:42:21 CEST, TransmitTimestamp=Sat 2021-06-05 02:42:21 CEST, DestinationTimestamp=Sat 2021-06-05 02:42:21 CEST, Ignored=no PacketCount=39, Jitter=14.840ms }
Frequency=463653

chrony

A versatile implementation which aims to work well under degraded conditions and offers pretty good performances under normal conditions of operation according to this comparison. That being said, cardano-node requires NTP synchronization, although you won’t get much added benefit with a local time difference under 10 μs over one under 100 μs. The daemon is chronyd and the client chronyc. Its main configuration file is /etc/chrony/chrony.conf (time sources are by default in /etc/chrony/sources.d, follow the README). And the driftfile for Chrony is /var/lib/chrony/chrony.drift.

chronyc examples
$ chronyc sources
MS Name/IP address         Stratum Poll Reach LastRx Last sample               
===============================================================================
^- berlix.fraho.eu               2   6   377     2   +166us[ +166us] +/-   13ms
^* dedibox.demongeot.biz         2   6   377    64   -895us[ -924us] +/- 5077us
^- 82-64-45-50.subs.proxad.>     1   6   377    64   +414us[ +414us] +/- 7477us
^- server.bertold.org            2   6   377     1   -534us[ -534us] +/-   53ms
^+ ntppub.darksky.io             2   6    77    10   -711us[ -711us] +/-   13ms
^+ default.ippi.com              2   6    77    10  +1615us[+1615us] +/- 6512us
^- x.ns.gin.ntt.net              2   6    77     9  -1463us[-1463us] +/-   59ms
^- par.cyberbits.eu              2   6    77    10   +176us[ +176us] +/-   36ms
^- 51-158-147-92.rev.poneyt>     2   6    77     9  -3450us[-3450us] +/-   55ms
^- ntp4.rbx-fr.hosts.301-mo>     2   6    77     9   -609us[ -609us] +/-   27ms
^+ amy.chl.la                    2   6    77     9   -658us[ -658us] +/- 8671us
^- ks3370497.kimsufi.com         2   6    77     9  -1202us[-1202us] +/-   59ms
^? villisika.miuku.net           2   6     1     1   -663us[ -663us] +/-   11ms
^- time.cloudflare.com           3   6    77     8   -222us[ -222us] +/- 9882us
^+ time.cloudflare.com           3   6    77     8   +602us[ +602us] +/- 9072us
^? 27.ip-51-68-44.eu             3   6     1     1   +190us[ +190us] +/- 8483us
^- flightplandatabase.com        2   6    77     8  +1469us[+1469us] +/-   37ms
^- ns1.univ-montp3.fr            2   6    77     6   +213us[ +213us] +/-   40ms
^- inbox.srvmin.network          3   6    77     8  -1503us[-1503us] +/-   48ms
^- siberut.ordimatic.net         2   6    77     7   -271us[ -271us] +/-   26ms

$ chronyc sourcestats 
Name/IP Address            NP  NR  Span  Frequency  Freq Skew  Offset  Std Dev
==============================================================================
berlix.fraho.eu             8   5   328     -1.418     11.045    -60us   692us
dedibox.demongeot.biz       9   5   331     -3.029     11.471   -893us   646us
82-64-45-50.subs.proxad.>   9   5   331     -0.578     15.723   +194us  1074us
server.bertold.org          8   5   328     -4.252     18.700  -1199us  1101us
ntppub.darksky.io           6   5   140     +0.703      7.383   -760us   125us
default.ippi.com            6   6   140    +15.186    134.836  +1937us  1897us
x.ns.gin.ntt.net            6   4   141     -1.263     23.618  -1298us   320us
par.cyberbits.eu            6   4   140     -5.652     39.217   +197us   532us
51-158-147-92.rev.poneyt>   6   4   141     -2.095     47.257  -2663us   576us
ntp4.rbx-fr.hosts.301-mo>   6   4   141     -2.532     59.627   -479us   590us
amy.chl.la                  6   4   141     -5.284     70.770   -669us  1088us
ks3370497.kimsufi.com       6   4   140     -6.331    107.020  -1235us  1424us
villisika.miuku.net         2   0     2     -0.459   2000.000  -1301us  4000ms
time.cloudflare.com         6   4   141     -5.891     60.204   -505us   842us
time.cloudflare.com         6   5   141     -5.285     50.719   +333us   875us
27.ip-51-68-44.eu           2   0     2     -0.459   2000.000  -4784us  4000ms
flightplandatabase.com      6   5   140     +5.823     17.732  +1374us   309us
ns1.univ-montp3.fr          6   5   141     +0.615     55.842    +22us  1052us
inbox.srvmin.network        6   4   140     -4.253     47.107  -1252us   617us
siberut.ordimatic.net       6   3   140     -7.194     24.103   -489us   421us

$ watch -n1 -d "sudo chronyc sourcestats && echo && sudo chronyc sources"

Choice of a reliable and accurate time source

Even though the NTP protocol makes it able to synchronize in spite of the network jitter, the choice of a reliable and close NTP server is equally important, as it will lower the bias introduced and thus, improve the accuracy. Moreover on a local network, instead of having n machines all synchronizing on a remote NTP server it’s possible, and advised even, to use one of them as a reference (NTP server) and make other hosts synchronize on it as clients. NTP is a hierarchical protocol after all.

Regarding your main NTP daemon, either you rely on well-known services (stratum 2) or you may use a pool of NTP server. Hence, the use of ntp.org initiative. You could define pool.ntp.org in your conf and the DNS will provide you with a set of 4 NTP servers IP addresses. You might as well precise the country of origin so that the NTP servers are chosen accordingly.

For instance and for France either you rely on fr.pool.ntp.org and the DNS will give you a fresh set of 4 IP addresses of servers in this pool (rotating list) or you might use one or all of the subdomains

    0.fr.pool.ntp.org
    1.fr.pool.ntp.org
    2.fr.pool.ntp.org
    3.fr.pool.ntp.org

And each one of them will give you a set of 4 (different) IP addresses from the pool. Although NTP servers are the easiest time sources to use, they’re not the only ones, you could also leverage for instance atomic clocks used by GPS satellites by relying on gpsd package and an external device.