basically tech

3 OpenNTPD on Linux

Wednesday 11th October, 2006

I like my desktop to show the correct time. As for my servers, I consider it essential. There are a number of solutions for this. Depending on your platform, these include:

The focus of this article is OpenNTPD running on Linux, although I imagine that much of this will be relevant for other supported operating systems.

OpenNTPD was written as part of the OpenBSD project. The goals of OpenNTPD include:

  • maximum security (no surprise there with the OpenBSD pedigree of this software)
  • ease of use
    • OpenNTPD was designed with a lean implementation, sufficient for the majority of systems. There was never any desire to support obscure systems or configurations.
    • minimum configuration.
    • it should just work quietly in the background.
    • reasonable accuracy, not down to the last microsecond (the developer quotes an accuracy of around about 50ms).

OpenNTPD was developed because of some concerns with NTP - with the license (which seems okay to me, but I am not a lawyer), with security (xntpd runs as root, although some recent versions do drop privileges on some OSes), and with the complexity of the configuration.

Installation considerations

When downloading the source code, make sure you choose the portable releases, unless you are compiling and installing on OpenBSD, in which case there's a port already available for you. As with OpenSSH, the base source code is designed specifically for OpenBSD, while the portable releases run on all other supported operating systems.

Installation is straightforward. If you're compiling from source, it would be good to read the INSTALL file. Before you start compiling, you'll need to create an unprivileged group and user for privilege separation purposes. The default user (if you don't specify one when you run configure) is _ntp.

# groupadd _ntp
# useradd -g _ntp -s /sbin/nologin -d /var/empty/ntp -c 'OpenNTP daemon' _ntp

You'll also need to create a home directory for that user. The home directory is very important because that's where ntpd will chroot to when it drops privileges. Note that the ntpd home directory belongs to root, and that the ntpd user does not have permission to write in this directory.

# mkdir -p /var/empty/ntp
# chown 0 /var/empty/ntp
# chgrp 0 /var/empty/ntp
# chmod 0755 /var/empty/ntp

Some distros use the ubiquitous nobody user and group for ntpd privilege seperation. Debian creates a new user and group, both called ntpd.

If you deviate from the defaults in any way, you will need to apply some configure options, so read the INSTALL file.

Configuration

Once you have OpenNTPD installed, you can start to configure your system:

Edit your ntpd.conf file. If you compiled from source with default settings, this will be /usr/local/etc/ntpd.conf:

# $OpenBSD: ntpd.conf,v 1.7 2004/07/20 17:38:35 henning Exp $
# sample ntpd configuration file, see ntpd.conf(5)

# Addresses to listen on (ntpd does not listen by default)
#listen on *
#listen on 127.0.0.1
#listen on ::1

# sync to a single server
#server ntp.example.org

# use a random selection of 8 public stratum 2 servers
# see http://twiki.ntp.org/bin/view/Servers/NTPPoolServers
servers pool.ntp.org

the only unhashed line

servers pool.ntp.org

directs ntpd to randomly select 8 secondary public time servers. These are (probably all) running the NTP software which was a somewhat maligned earlier in this article!

server(s)

If you want to use a single time server as a reference, use the server parameter rather than the plural servers parameter, but remember to comment out the servers parameter. Note that you can set multiple server instances, but there is a crucial difference from the servers parameter: If there are multiple server instances, ntpd will try to synchronise to the first in the list, if it is unavailable, then it moves to the second, and so on. However with the servers parameter, ntpd will try to synchronise to all (up to 8 if a pool is specified) of the servers listed.

stratum?

For NTP purposes, stratum is the distance from the reference clock. Hence a stratum 0 device is effectively the reference clock. A stratum 1 server is directly connected (not networked) to the stratum 0 device. A stratum 2 server is one which gets it's time (via NTP) from a stratum 1 server. A stratum 3 server gets it's time from a stratum 2 server, etc. This means that my servers and my desktop are each a stratum 3 time source!

The NTP website indicates that due to Internet lag/interference, each stratum below stratum 1 adds an inaccuracy of between 10-100ms; so stratum 2 accuracy may be out by 10-100ms, stratum 3 by 20-200ms, etc. Recalling that the approximate accuracy of ntpd lies within 50ms, this doesn't sound too bad anymore.

NTP server pools

This default setting is probably good enough, but I like to choose from a pool of servers closer to home. Point your browser to http://twiki.ntp.org/bin/view/Servers/NTPPoolServers.

You'll see NTP servers are pooled into sub-zones, by continents, and sub-sub-zones, by country. The closer you get to your country, the less likely you are to have network issues.

Select a pool which has at least 12 servers in it. The reason to choose at least 12, when OpenNTPD only looks for 8 servers to synchronise with is because some of these servers occasionally go offline. My desktop is in the UK, so I have chosen uk.pool.ntp.org as my servers pool. At the time of writing, uk.pool.ntp.org has 61 NTP servers in the pool, so that's fine for me! Alternatively, you could choose europe.pool.ntp.org.

UTC

Note that if you are running a server in, say, the USA, but you wish to have the time set for UK time, then you do not have to choose servers from uk.pool.ntp.org. NTP servers use UTC (Coordinated Universal Time)*, so choose an NTP pool geographically close to your server, which in this case would be us.pool.ntp.org.

listen on

This parameter allows you to choose one or many interfaces on which to listen so as to provide an NTP service. A point to note is that ntpd will not serve time, even if this parameter is set until it has synchronised its own clock to a reasonable level. This can take a while, even if the clock is accurate to begin with, since the time adjustments ntpd makes are quite small ... my host took a couple of days to sychronise. I have never implemented the listen on parameter myself, so I cannot comment further on this.

rc script

OpenNTPD should be started each time your host reboots. Each distro comes with it's own rc script for OpenNTPD, but if you have had to compile your own, the following should suffice as a base to work from:

#!/bin/bash

NTPD_CONF=/usr/local/etc/ntpd.conf

if [ ! -f $NTPD_CONF ]
  then
   echo "Could not find $NTPD_CONF"
   exit 1
fi

# -s : Set the time immediately at startup if the
#      local clock is off by more than 180 seconds.
PARAMS="-s"

PID=`pidof -o %25PPID /usr/local/sbin/ntpd`
case "$1" in
  start)
    echo "Starting OpenNTPD"
    [ -z "$PID" ] && /usr/local/sbin/ntpd $PARAMS
    if [ $? -gt 0 ]; then
      echo "Failed"
    else
      PID=`pidof -o %25PPID /usr/local/sbin/ntpd`
      echo $PID >/var/run/openntpd.pid
      echo "Done"
    fi
    ;;
  stop)
    echo "Stopping OpenNTPD"
    [ ! -z "$PID" ]  && kill $PID &>/dev/null
    if [ $? -gt 0 ]; then
      echo "Failed"
    else
      echo "Done"
    fi
    ;;
  restart)
    $0 stop
    $0 start
    ;;
  *)
    echo "usage: $0 {start|stop|restart}"  
esac
exit 0

If you start your machine and you are not connected to the internet, you will notice a significant wait while ntpd times out. You could build some sort of check into the rc script. If this happens often (for instance with a laptop), I would recommend using something like chrony. It is only a little more complex to set up. :-)

Once ntpd is running, you can check the connections it has made. Here is the output on my desktop PC:

# netstat -u -p

Active Internet connections (w/o servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name   
udp        0      0 aquilonia:32771         skylar.fbagroup.co.:ntp ESTABLISHED 2504/ntpd           
udp        0      0 aquilonia:32772         gw.roaima.co.uk:ntp     ESTABLISHED 2504/ntpd           
udp        0      0 aquilonia:33050         ginny.provu.co.uk:ntp   ESTABLISHED 2504/ntpd           
udp        0      0 aquilonia:33051         cobra.first4it.co.u:ntp ESTABLISHED 2504/ntpd           
udp        0      0 aquilonia:33053         shrewd.pub.knigma.o:ntp ESTABLISHED 2504/ntpd           
udp        0      0 aquilonia:34275         cheddar.halon.org.u:ntp ESTABLISHED 2504/ntpd           
udp        0      0 aquilonia:34290         81-5-136-18.dsl.ecl:ntp ESTABLISHED 2504/ntpd           
udp        0      0 aquilonia:32883         mail.happy-fish.org:ntp ESTABLISHED 2504/ntpd

And just confirm that ntpd is using PID 2504:

# ps -ef | grep ntp

nobody    2504     1  0 Oct09 ?        00:00:00 /usr/sbin/ntpd -s
root      2505     1  0 Oct09 ?        00:00:00 /usr/sbin/ntpd -s

Notice that there are two processes: one running as nobody makes the connections, and any system time change requests get passed to the second (running as root) for execution. There are also checks made to ensure the authenticity of such requests.

log entries

OpenNTPD logs to /var/log/messages or /var/log/syslog. Initially, there may be a flurry of entries, but as ntpd gets the time right, the frequency of entries should slow down.

*UTC/CUT/TUC

The use of UTC to stand for Coordinated Universal Time is apparently a compromise. French speakers wanted TUC (Temps Universel Coordonné), while English speakers wanted CUT (Coordinated Universal Time). Using "UTC" seems to have satisfied both parties. I imagine that each side were sufficiently placated by the knowledge that "the other side" didn't get things precisely their way.

Home