Synchronizing Servers with NTP

For an operating system and all of its services to run smoothly, the system clock has to be accurate. If it’s off by just a few seconds, the results could be disastrous.

For example, if machines share files over a local network, their clocks have to be synchronized to establish when exactly data is modified. Inaccurate clocks could create version conflicts or cause data to be overwritten.

There would also be issues running cron jobs. With an inaccurate clock, launch times would be fuzzy at best, and it would be incredibly difficult to properly analyze logs and troubleshoot system errors.

That’s just the tip of the iceberg.

To avoid these issues, system clocks have to synchronize. In Linux, this is done using an NTP (Network Time Protocol). In this article, we’ll be going step-by-step to install and configure an NTP on a server. Let’s start with a brief, theoretical introduction.

How NTPs Work

NTPs rely on a hierarchical structure of time sources divided into levels, called strata. Stratum 0 is the reference (an atomic clock or GPS clock); NTP servers don’t operate here.

NTP servers on stratum 1 synchronize to the atomic clock and act as references for stratum 2 servers. Stratum 2 servers synchronize to stratum 1, but can also synchronize with themselves. Servers from stratum 3 all the way down to stratum 256 synchronize the same way.

The NTP hierarchy is both redundant and fault-tolerant. If a connection to a higher-stratum server fails, backup servers perform the synchronization themselves. Redundancy is provided by the constant availability of NTP servers; by drawing data from multiple sources (servers), the NTP can calculate a more accurate time.

Installing and Configuring NTP Servers

The most well known and commonly used time sync software is the ntpd daemon. Depending on the settings in the configuration file (we’ll discuss this further on), it can act as both a server or client (i.e. it can receive the time from remote hosts and send it to others). We’ll look at how to install and configure this daemon in Ubuntu below.


NTP software is included in most modern Linux distributions and is installed from the standard package manager:

$ sudo apt-get install ntp


Once the software is installed, open /etc/ntp.conf in the text editor. All program settings are saved here. Let’s take a closer look.

Logging Parameters

The first line of the configuration file looks like this:

driftfile /var/lib/ntp/ntp.drift

This shows the file where information on the clock’s offset frequency is saved. Values received from previous time corrections are saved here. If other NTP servers are unavailable for any reason, this is where the value will be taken from.
Next, we’re shown which file the synchronization log is saved to:

logfile /var/log/ntp.log

List of Servers for Synchronization

The configuration file lists which NTP servers our system will synchronize with. By default, the list looks like this:


Each line indicates the group of servers that tell our server the correct time. To improve the accuracy of our synchronization, we can use the iburst option (this means that not one, but several packets must be sent for synchronization):

server iburst
server iburst
server iburst
server iburst

We can also give preference to a server using the prefer option:

server iburst prefer

NTP servers are scattered all over the world (available public NTP servers). To ensure a more accurate system clock, we recommend synchronizing only with ntp servers in the same geographic region as your server. To do this, add the regional subdomain to in the server address listed in /etc/ntp.conf:

  • Asia —
  • Europe —
  • Africa —
  • North America —
  • South America —
  • Oceania —

You can also add a subdomain for individual countries (see here). Russia has its own subdomain:

Backup Time Servers

If an NTP server goes offline for any reason, it can still transfer data on its system clock for synchronization. This is done by adding the following line to the configuration file:



Lately, It’s become more common for NTP servers to be used for increasing traffic in DDoS attacks (see here). To protect our server, we’ll limit the number of external clients. By default, the following limits are set in /etc/ntp.conf:

restrict −4 default kod notrap nomodify nopeer noquery
restrict −6 default kod notrap nomodify nopeer noquery

The nomodify, notrap, nopeer, and noquery parameters prohibit the client from modifying the server. The kod (kiss of death) parameter provides additional protection: a client sending too many requests will first receive a kod packet (a service failure warning) and then be disconnected from the server.

To enable machines on the local network to synchronize with an NTP server, we add the following lines to the configuration file:

restrict mask nomodify notrap

We can additionally grant the local host unlimited access to the NTP server:


Testing Synchronization

After making all of the necessary changes and saving the configuration file, we restart the NTP server:

$ service restart ntp

We then run the following command:

$ ntpq -pn

A table will be printed out:

remote           refid   	st t when poll reach    delay  offset  jitter
*    2 u  207  256   37   10.985  -215.79 256.992
+     2 u  193  256   37   32.623  -207.70 259.121
+     2 u  198  256   37    0.621  -216.90 257.037
+    2 u  193  256   37   32.028  -207.41 259.863
+    2 u  192  256   37   50.573  -206.62 259.542

The following parameters are shown in the table:

  • remote — address of server with exact time (here we see the server list from the configuration file)
  • refid — top-level server (the time server our server synchronizes to)
  • st — the server stratum
  • t — peer type (u- unicast, m- multicast)
  • when — time of last synchronization
  • poll — time it took for NTP daemon to synchronize with peer, in seconds
  • reach — server availability status; after eight successful synchronization attempts, value will be 377
  • delay — response delay from server
  • offset — time difference between our server and synchronization server; a positive value means that our clock is fast, negative means it’s slow
  • jitter — time offset on remote server

The following symbols may be displayed to the left of the server address:

  • * synchronization server (current time source)
  • + server ready for update (which we can synchronize with)
  • — server not recommended for synchronization
  • x server unavailable

You can test if a server from the list is suitable for synchronization with using the following command:

ntpdate -q 

server хх.ххх.ххх.ххх, stratum 2, offset −0.127936, delay 0.02600
7 Jul 14:30:23 ntpdate[7716]: adjust time server хх.ххх.ххх.ххх offset −0.127936 sec

From the printout above, we can see that the server is suitable for synchronization: stratum – 2, offset – 0.127936 ms, delay – 0.026 ms.

We can also see the synchronization results (if successful or with errors) in the logs:

7 Jul 15:17:17 ntpd[5059]: synchronized to, stratum=2
7 Jul 15:17:17 ntpd[5059]: kernel time sync disabled 0041
7 Jul 15:17:21 ntpd[5059]: kernel time sync enabled 0001

Configuring Local Date and Time

Using the ntpdate command, we can set the local date and time on our server by sending a request to the NTP server:

$ ntpdate -u

You can check the present status of ntpd with the following command:

$ ntpdc -c sysinfo

The printout will look like the following:

system peer:
system peer mode: client
leap indicator: 11
stratum: 3
precision: −21
root distance: 0.01314 s
root dispersion: 1.66203 s
reference ID: []
reference time: d768a894.3824a929 Thu, Jul 10 2014 9:52:20.219
system flags: auth monitor ntp kernel stats 
jitter: 0.393768 s
stability: 0.000 ppm
broadcastdelay: 0.000000 s
authdelay: 0.000000 s

Original publication date: July 11, 2014.