
The information on this page does not map to a specific certification objective.
Thanks to Darren Tucker for answering questions about technical details of OpenNTPD.
Just after the book was completed, I discovered that there was a project for a new NTP daemon, called OpenNTPD. This is a replacement for the classic NTP daemon, written by David Mills, that's covered in the book on or about page 157. The classic daemon is included with all Linux distributions and many other operating systems. This new daemon is much simpler and easier to configure. OpenNTPD may be more secure because it runs as an unpriviledged user and uses chroot to insulate itself from the rest of the filesystem. These concepts were covered in the text.
OpenNTPD does not have many of the features of the classic NTP daemon but these are not used in the majority of Linux installations. This results in a daemon that is much smaller. To give you a rough idea of the difference in size, the classic daemon is about 431 KB (on disk) and the OpenNTPD daemon is about 35 KB.
The ease of configuration is obvious just by looking at the possible statements in the /etc/ntpd.conf configuration file:
- listen on address
- Specify one of more IP addresses the daemon should bind to.
- server address
- Specify the IP address or hostname of an NTP server to synchronize to. If you specify a hostname and it resolves to more than one IP address, use the first working address - that is, synchronize to one NTP server.
- servers address
- Specify the IP address or hostname of an NTP server to synchronize to. If you specify a hostname and it resolves to more than one IP address, use all the working addresses - that is, synchronize to more than one NTP server.
Compare this to the much larger set of configuration statements for the classic daemon. The listen on statement caught my interest immediately. The classic daemon binds to all network interfaces. If there's a way to tell the classic daemon to bind to just one or two interfaces, I could not find it.
The difference between the server and servers statements is illustrated in the book in the section that refers to the pool.ntp.org time servers.
Download and Installation
You'll have to download OpenNTPD because it is not included with most Linux distributions at this point. To download it, first go to http://www.openntpd.org. This page tells you that this project is part of the OpenBSD Project. If you want to run OpenNTPD on Linux, you must click the Linux link on the left-hand side of the page to download the Linux version. Download the file to a directory that you have permissions to, such as your home directory.
The file you downloaded will have a name such as openntpd-20050808p.tar.gz.Uncompress and untar the file with this command:
tar xzf openntpd-20050808p.tar.gz
A directory called openntpd-20050808p will be created. Go to that directory with this command:
cd openntpd-20050808p
Execute the following statements:
groupadd _ntp useradd -g _ntp -s /sbin/nologin -d /var/empty/ntp -c 'OpenNTP daemon' _ntp mkdir -p /var/empty/ntp chown 0 /var/empty/ntp chgrp 0 /var/empty/ntp chmod 0755 /var/empty/ntp ./configure --with-builtin-arc4random make make install
The above procedure will install the OpenNTPD binary in /usr/local/sbin and the configuration file in /usr/local/etc. You can change this by adding the --prefix option to the ./configure statement:
./configure --with-builtin-arc4random --prefix=/usr
This will install the OpenNTPD binary in /usr/sbin and the configuration file in /usr/etc. You can install the configuration file in the /etc directory instead by adding the --sysconfdir option:
./configure --with-builtin-arc4random --prefix=/usr --sysconfdir=/etc
This will install the OpenNTPD binary in /usr/sbin, but will place the configuration file in /etc.
Parent/Child
If you run the ps aux command when the daemon is running, you'll see two instances of ntpd running. One is the parent process owned by root and the other is the child process owned by a user such as _ntp. Two processes are required because when corrections need to be made to the local clock, the adjtime() function is called to do it. This function can only be performed by the root user. Also, the child cannot do DNS lookups since /etc/hosts and /etc/resolv.conf are outside the chroot.
Most of the work done by ntpd, such as communicating with remote servers, is done by the child process, which is relatively secure.
Tools
With the classic daemon written by Mills, there were programs, such as ntpq and ntptrace, that could be used to monitor ntp "health". These tools do not work with OpenNTPD. Older ntptrace programs work but newer versions are just a wrapper around ntpq and don't work.
Since you have no tools, you'll want to keep a copy of ntpdate handy that is useful for troubleshoot NTP problems.
Logging
OpenNTPD uses syslog. The facility is "daemon" and the priority varies by message. There is no way currently to bypass syslog and log to a specified file. Here's an example of OpenNTPS slewing its time immediately after it's started up:
Dec 11 14:14:34 easy ntpd[17842]: listening on 127.0.0.1 Dec 11 14:14:34 easy ntpd[17842]: listening on 69.30.46.62 Dec 11 14:14:34 easy ntpd[17842]: listening on ::1 Dec 11 14:14:34 easy ntpd[17842]: listening on fe80::20d:87ff:fef0:637f%eth0 Dec 11 14:14:34 easy ntpd[17842]: ntp engine ready Dec 11 14:14:58 easy ntpd[17842]: peer 69.30.46.55 now valid Dec 11 14:15:27 easy ntpd[17841]: adjusting local clock by -1.480604s Dec 11 14:18:07 easy ntpd[17841]: adjusting local clock by -1.395753s Dec 11 14:19:44 easy ntpd[17841]: adjusting local clock by -1.224373s Dec 11 14:22:59 easy ntpd[17841]: adjusting local clock by -1.049305s Dec 11 14:26:12 easy ntpd[17841]: adjusting local clock by -0.904675s Dec 11 14:28:56 easy ntpd[17841]: adjusting local clock by -0.789492s Dec 11 14:31:01 easy ntpd[17841]: adjusting local clock by -0.673093s Dec 11 14:33:10 easy ntpd[17841]: adjusting local clock by -0.531429s Dec 11 14:35:50 easy ntpd[17841]: adjusting local clock by -0.417767s Dec 11 14:37:57 easy ntpd[17841]: adjusting local clock by -0.190076s
In this example, 17841 is the parent process running as root.
Setting Time
Any program that modifies time has two ways of doing it:
- The system settimeofday() function is used to step the time. A large difference between the system time and the accurate time is fixed by setting the system time to the new value all at once.
- The system adjtime() function is used to slew the time. The system time is changed to the new value by small amounts at a time. If the difference is large, correcting the time using the adjtime() function takes a long time.
When you start the ntpd daemon, it slews the time to the correct value. It does this in increments of about 200 milliseconds every few minutes. At this rate, it can take a long time to bring time into sync.
If you start the ntpd daemon with the -s (lower case s) option, the system clock is stepped using the settimeofday() function as long as the time difference is 180 seconds or less. After the initial time step, the time is slewed with the adjtime() function thereafter.
The -S (upper case S) option seems to be unnecessary.