NTP Basics

The Network Time Protocol was invented some years ago as a way to accurately synchronize time across the Internet. While the daemon that comes with almost all Unix like operating systems is quite easy to configure and use, there is always the first leap of getting it running in the first place.

There were time protocols before NTP, but they suffered problems due to the inherent time it takes data to transfer across physical mediums. They worked great for getting a somewhat accurate gauge of the current date and time, but could not guarantee any level of accuracy, especially across connections of varying lag time. NTP was specifically designed to deal with these common situations.

The most commonly used program to implement NTP is the daemon ntpd. There is also a client program that can query a NTP server and set the local time ntpdate. While the ntpdate program might sound like the client counterpart to ntpd, the daemon is a self contained solution and ideally is the only program you need to configure and use. There is another program included with the package, ntpq, used for querying some of the inner workings of a running ntpd daemon.

The 'Client' ntpdate

If you just need to update the time on your computer once, the quick command to do so is:
root@aislynn# ntpdate ntp.stoneyforest.net
If you are curious, you can add the -q -u arguments and ntpdate will query the time server on an unprivileged port, then report the different between the server's time and your computer's time. This is terribly useful when you are first configuring a server and need to get the time synchronized quickly. By default, the daemon will not synchronize if there is a very large time difference and many computer come with the CMOS clock randomly set.

Additionally on computers that do not have a RTC battery for the on-board clock (no battery means it will not track time while it is powered off) there are options for setting the clock at boot time. Specifically the -b argument changes how ntpdate updates the system time and should be used at boot time (only). On FreeBSD you can have the clock set by the rc scripts by adding the following to your /etc/rc.conf file:
ntpdate_enable="YES"			#Run ntpdate to sync time on boot.
ntpdate_host="ntp.example.com"		#Whitespace separated list of servers.

The ntpd daemon

The ntpd daemon is configured through the ntp.conf file, usually located in /etc. At a minimum the file needs to specify at least one time source, another NTP server unless you have a hardware clock device. Finding a reliable time server could be a challenging task, luckily the NTP Pool Project makes finding them easy. The project tracks hundreds of reliable servers across the world and aggregates them through DNS. To use their pool, simply use the hostnames of the form number.country_code.pool.org. For example if you live in the United States you might use 0.us.pool.org. The following configuration line is sufficient to configure ntp.conf:
server 0.us.pool.org
restrict default ignore
Using multiple time server is highly recommended. If you use just one as the above line does, and that server is off, your computers time will track that single server and lose time as well. If NTP tracks two servers the daemon will select one as the primary and track it; the process by which it selects a primary is complicated and slightly arbitrary when there are only two to pick from. The best practice is to select at least three or four servers. I commonly use a configuration file that begins with:
server 0.us.pool.org
server 1.us.pool.org
server 2.us.pool.org
server 3.us.pool.org
restrict default ignore
This configuration will track four different servers and is very likely to keep time accurately. One disadvantage to using the NTP Pool Project is that your time servers are selected randomly from the available pool each time your servers starts. If you find one that seems to be particularly stable, you will likely not track it the next time you reboot. By the same occurrence if you find several unstable servers (which is unlikely as the project removes unreliable servers from their service) then your servers will select new servers on the next restart.

Time tracking is very important to a number of services and businesses; it is also important to a number of different institutions and agencies. Many universities and government agencies keep track of time from clock devices (usually GPS receivers or atomic clocks, though other devices exist). One such agency is the United States Naval Observatory in Colorado Springs, CO. They maintain atomic clocks with excellent precision and a small cluster of computers to serve that time of NTP.

The USNO and many other Stratum 1 Servers have graciously allowed public access to their NTP servers with the request that individual sites allow no more than 3 clients to connect to their services, that traffic be kept to a reasonable minimum, and that those clients that connect also operate a stratum 2 server (meaning other clients can/do connect). Their services are heavily loaded because they are extremely reliable; running a service of this calibre can be quite expensive. I appreciate and respect the services that they provide and ask that you do the same.
Knowing of the USNO's reliable time service, you can incorporate this into your configuration file, adding preference and limiting the amount of traffic to it. You might use something like this:
server tick.usno.navy.mil prefer minpoll 10 maxpoll 16
server ntp-oar.usno.navy.mil minpoll 10 maxpoll 16
server ntp-gatech.usno.navy.mil minpoll 10 maxpoll 16

server 0.us.pool.ntp.org minpoll 7 maxpoll 12
server 1.us.pool.ntp.org minpoll 8 maxpoll 14
server 2.us.pool.ntp.org minpoll 8 maxpoll 14
server 3.us.pool.ntp.org minpoll 9 maxpoll 15
This configuration has preference for the USNO time server in Washington DC, and includes USNO affiliated servers at Ohio State University and Georgia Institute of Technology. The minpoll and maxpoll arguments have been added to each server to decrease the frequency at which servers are polled. Because there are seven servers configured, they do not all need to be polled constantly. Higher numbers mean they are polled less frequently.
Every computers internal clock is inherently flawed. It is not a matter of clocks being incapable of keeping time, it is simply economics. A clock that is only off by a few second every year is very cheap to produce. Making it more accurate is very expensive. However, clocks are usually off by the same amount on a reasonably consistent basis. The NTP daemon can keep track of this and use this knowledge to its advantage. To enable this functionality you only need to specify a file where it should keep track of this information; you can do so by adding a line like this:
driftfile /var/db/drift.ntp
Be sure this file exists and is writable by the daemon. On FreeBSD systems the location already exists by default and the ntpd service is run as root, which has permission to create the file.

One last section I like to add to ntp.conf is for logging. I like to have a log of what the daemon is doing, when it synchronizes with other servers and and errors that occur. I do this by adding the following lines to my configuration files:
logfile /var/log/ntp.log
logconfig +sysall +syncall

Checking on the daemon

Once the daemon is up and running you may want to check what stratum it is operating at, and which servers is it has decided to track. When the daemon first starts it will be stratum 16, the highest, which also means that no client will synchronize against it. This is kept until the daemon can start tracking time with other servers and establish the stability of the local clock.

Example - Using ntpdate and ntpq to check on the daemon:
root@aislynn# ntpdate -q -u localhost
server ::1, stratum 2, offset -0.000009, delay 0.02573
server 127.0.0.1, stratum 2, offset -0.000009, delay 0.02571
16 Jan 23:06:38 ntpdate[61207]: adjust time server 127.0.0.1 offset -0.000009 sec
root@aislynn# ntpq -p
     remote           refid      st t when poll reach   delay   offset  jitter
==============================================================================
*tick.usno.navy. .USNO.           1 u   9h   9h  377   53.410    1.111   1.586
+navobs1.oar.net .USNO.           1 u   9h   9h  377   51.972    1.797   0.651
+navobs1.gatech. .GPS.            1 u 264m   9h  377   81.376   15.563  14.921
-i1.fwwds.com    69.25.96.13      2 u 234m 273m  375  104.573   -7.725  18.239
-host2.kingrst.c 173.14.47.149    2 u 264m 273m  377   36.122   -4.944   0.390
-ntp.yoinks.net  139.78.135.14    2 u 235m 273m  377   72.340   -2.142   1.443
-clock-b.develoo 164.67.62.212    2 u 234m 273m  377  118.425  -19.547  10.078
The "*" before the first line means that particular server has been selected as the server being tracked. The daemon has decided that it has the most stable time and the local time should follow that server. The lines beginning with "+" are alternates to the primary, they will be selected if the primary falls out of favor or any reason. The lines marked with "-" are less desirable alternates and will not be used unless the primary and preferred alternates are unavailable. Of any of these lines began with a blank space " ", that line would indicate a server whose time or availability has been deemed so unreliable that it will not be used in any circumstances. This most commonly happens when a time server is not reachable.
More information on best practices for various size networks and advanced NTP topics coming soon in my FreeBSD » NTP category.