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.
The first line of the configuration file looks like this:
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:
List of Servers for Synchronization
The configuration file lists which NTP servers our system will synchronize with. By default, the list looks like this:
server 0.ubuntu.pool.ntp.org server 1.ubuntu.pool.ntp.org server 2.ubuntu.pool.ntp.org server 3.ubuntu.pool.ntp.org
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 0.ubuntu.pool.ntp.org iburst server 1.ubuntu.pool.ntp.org iburst server 2.ubuntu.pool.ntp.org iburst server 3.ubuntu.pool.ntp.org iburst
We can also give preference to a server using the prefer option:
server 0.ubuntu.pool.ntp.org 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 pool.ntp.org in the server address listed in /etc/ntp.conf:
- Asia — asia.pool.ntp.org
- Europe — europe.pool.ntp.org
- Africa — africa.pool.ntp.org
- North America — north-america.pool.ntp.org
- South America — south-america.pool.ntp.org
- Oceania — oceania.pool.ntp.org
You can also add a subdomain for individual countries (see here). Russia has its own subdomain: ru.pool.ntp.org.
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 192.168.1.0 mask 255.255.255.0 nomodify notrap
We can additionally grant the local host unlimited access to the NTP server:
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 ============================================================================== *220.127.116.11 18.104.22.168 2 u 207 256 37 10.985 -215.79 256.992 +22.214.171.124 126.96.36.199 2 u 193 256 37 32.623 -207.70 259.121 +188.8.131.52 184.108.40.206 2 u 198 256 37 0.621 -216.90 257.037 +220.127.116.11 18.104.22.168 2 u 193 256 37 32.028 -207.41 259.863 +22.214.171.124 126.96.36.199 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: 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: synchronized to 188.8.131.52, stratum=2 7 Jul 15:17:17 ntpd: kernel time sync disabled 0041 7 Jul 15:17:21 ntpd: 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 192.168.1.1
You can check the present status of ntpd with the following command:
$ ntpdc -c sysinfo
The printout will look like the following:
system peer: 184.108.40.206 system peer mode: client leap indicator: 11 stratum: 3 precision: −21 root distance: 0.01314 s root dispersion: 1.66203 s reference ID: [220.127.116.11] 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.