The School for Sysadmins Who Can’t Timesync Good and Wanna Learn To Do Other Stuff Good Too, part 3 – NTP installation and configuration

(Part 1 one of this series gave the background and rationale, and part 2 covered the basics of how NTP works.)

Getting NTP

Depending on how you install Linux, you might already have a pretty workable NTP client, but for the tools we’ll be working with, we’ll need the NTP reference implementation server.  On Ubuntu (these examples use 16.04 “xenial xerus”, but the instructions should work on all current Debian-derived distributions), you can install this with the usual packaging tools:

ubuntu@machine-5:~$ sudo apt-get install ntp
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following additional packages will be installed:
Suggested packages:
The following NEW packages will be installed:
  libopts25 ntp
0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded.
Need to get 577 kB of archives.
After this operation, 1,791 kB of additional disk space will be used.
Do you want to continue? [Y/n] y
Get:1 xenial/main amd64 libopts25 amd64 1:5.18.7-3 [57.8 kB]
Get:2 xenial-updates/main amd64 ntp amd64 1:4.2.8p4+dfsg-3ubuntu5.3 [520 kB]
Fetched 577 kB in 0s (9,198 kB/s)
Selecting previously unselected package libopts25:amd64.
(Reading database ... 87077 files and directories currently installed.)
Preparing to unpack .../libopts25_1%3a5.18.7-3_amd64.deb ...
Unpacking libopts25:amd64 (1:5.18.7-3) ...
Selecting previously unselected package ntp.
Preparing to unpack .../ntp_1%3a4.2.8p4+dfsg-3ubuntu5.3_amd64.deb ...
Unpacking ntp (1:4.2.8p4+dfsg-3ubuntu5.3) ...
Processing triggers for libc-bin (2.23-0ubuntu3) ...
Processing triggers for systemd (229-4ubuntu10) ...
Processing triggers for ureadahead (0.100.0-19) ...
Processing triggers for man-db (2.7.5-1) ...
Setting up libopts25:amd64 (1:5.18.7-3) ...
Setting up ntp (1:4.2.8p4+dfsg-3ubuntu5.3) ...
Processing triggers for libc-bin (2.23-0ubuntu3) ...
Processing triggers for systemd (229-4ubuntu10) ...
Processing triggers for ureadahead (0.100.0-19) ...

Here are some of the components of the ntp package with which you might want to be familiar (use dpkg -L ntp on Ubuntu & other Debian-based distributions to see all the contents of the package; on Red Hat-based distributions, use rpm -qf ntp):

the main configuration file; if you make changes to this file, you’ll need to restart ntpd with sudo service ntp restart to activate them
statistics logging, if enabled, writes its logs here
the main NTP server process; you won’t usually need to use this directly
prints the exact time according to NTP
NTP query – this is the most important tool for troubleshooting
traces from your local server to stratum 1; sometimes helpful if you run a local reference clock, but if you’re using publicly available NTP servers, you’ll probably end up with a rather dull result like this:

ubuntu@machine-5:~$ ntptrace
localhost: stratum 3, offset -0.000445, synch distance 0.011506 timed out, nothing received
***Request timed out

This is because of the default security restrictions on querying NTP – more on this later.

On Ubuntu, NTP ships with a default NTP AppArmor profile which limits its capabilities; distributions which use SELinux by default probably ship with similar restrictions.
a hook which allows clients to receive their NTP server list via DHCP; we won’t be using this, but be aware that in the default Ubuntu configuration, if your network supplies NTP servers via DHCP, its settings will override the settings in /etc/ntp.conf.

Initial configuration

Straight after installation you should have a pretty usable NTP server, assuming you have Internet access which allows outbound traffic to UDP port 123 (some ISPs block this).  Here’s the default configuration on Ubuntu 16.04 LTS (with comments removed):

ubuntu@machine-5:~$ grep '^[^#]' /etc/ntp.conf
driftfile /var/lib/ntp/ntp.drift
statistics loopstats peerstats clockstats
filegen loopstats file loopstats type day enable
filegen peerstats file peerstats type day enable
filegen clockstats file clockstats type day enable
pool iburst
pool iburst
pool iburst
pool iburst
restrict -4 default kod notrap nomodify nopeer noquery limited
restrict -6 default kod notrap nomodify nopeer noquery limited
restrict ::1
restrict source notrap nomodify noquery

Let’s break down the configuration:

  1. driftfile – The drift (a.k.a. frequency) is the estimated error rate (in parts-per-million) of the local clock. The NTP daemon saves its estimate every hour to the file named here so that it doesn’t have to recalculate this error rate on startup.  If the file doesn’t exist, ntpd will assume that the error rate is zero and recalculate it from scratch, so it’s harmless to delete the file.  But leaving it there helps get your clock headed the right way faster on startup.
  2. statistics & filegen – these direct ntpd to create various types of statistics, if the statsdir directive is enabled (which it’s not here).  You probably don’t need the stats files unless you are running a stratum 1 server, or are especially interested in the quality of your individual time sources.
  3. pool – this defines the sources of time for your NTP server; traditionally, “server” was used here, but the pool directive introduced in recent versions offers much improved behaviour, and should nearly always be used in preference to server.  The source may be a hostname or IP address, but hostnames are preferred, since recent versions of ntpd will retry DNS lookups and switch to a new pool server if connectivity is lost.  The “iburst” option at the end of the line causes ntpd to use 6 polls (as opposed to just 1) when initially contacting the source.  Using this is nearly always recommended, as it helps get your clock synced sooner.  The time sources used here are the public servers available in the NTP pool, plus the public Ubuntu NTP servers run by Canonical (my employer).
  4. restrict – the default set of restrictions allows use of pool servers, and permits querying of associations (the records about time sources) from the local host, but does not allow querying from elsewhere.  Clients can still use this server as a time source (firewall rules permitting).  Querying of the association list is something which was historically used in reflective DDoS attacks, so the default restrictions should be kept in place unless you have a good reason to do otherwise. [citation required]

If you have average time synchronisation needs, the default configuration will probably work just fine and you won’t have to change anything, with the possible exception of the time sources. A common configuration change you might make is changing [0-3] to the pool servers for your country or region.  For example, my home network’s NTP servers use [0-3]  For a full list of the available pools, check the global list, then drill down by continent and country.

Don’t necessarily just assume that your region/country servers are close, though.  Recently I was working on a customer’s system located in South America and found that the US pool servers were much closer in terms of network latency than the South American ones! You should watch carefully which sources are supplied to you from the NTP pool and change them if the pool returns servers which are not physically nearby. (Where “nearby” generally means within a few thousand km; a rough rule of thumb for “average” use is: time sources should be less than 100 ms away.)

In part 4 of this series we’ll look at monitoring and troubleshooting your NTP service.

Leave a Reply