Keeping the clock on time
Keeping the clock on time

Keeping the computer clock synchronize as close as possible with the rest of the world is important for a number of reasons, form just being on time when the calendar events warning goes off, to more IT stuff like making sure that file synchronization with remote servers works properly.

The network protocol everyone uses for this is NTP (Network Time Protocol) and there are several implementation one can choose from (and as usually Microsoft totally messed it up with it's windows time service).

On a device that is most of the times connected, although it's to different networks, but is sometimes on its own I think it makes sense to use something that can adapt itself to its environment. So I went in search for a NTP program that was created with this on/off in mind and behold I found chrony, a small and easy to configure NTP client and server (I'll be using it only as a client).

When installing gentoo (my favourite linux distribution) on my current laptop I decided to give NetworkManager another try. Although it's a bloated piece of software (just look at the number of dependencies it has) it has become more or less pervasive in the Linux desktop (what a pitty) so I guess I should get familiar with it. Somewhere in the not so distant past it also started to allow for scripts to be run when a network interface became connected or disconnected, unfortunately in a very basic way. When any of those events takes place the scripts that are in the dispatcher.d directory will be called with two arguments: the name of the interface and the "status" (up or down).

Rather basic but enough to use chrony.

First step is of course installing chrony. Then create a file that will contain a key for the access to the chrony daemon. I created it in /etc/chrony/chrony.keys. The content of that file is just one number and a string separated by a space. Several keys can be defined by using several lines, although I don't really understand the advantage of that. Something like:

1 keypassword
2 secondkey

After creating the keys file we can now edit /etc/chrony/chrony.conf to configure the daemon. Here is my configuration:

## selected servers by running
##   netselect -s 4 -t 3 pool.ntp.org
server 95.211.148.1 offline
server 83.98.155.30 offline

keyfile /etc/chrony/chrony.keys
commandkey 1
driftfile /etc/chrony/chrony.drift

You can see that I set two NTP servers but mark them as being offline. I will use a NetworkManager dispatcher script to bring them on or off line. netselect is a wonderful tool to find out the IP addresses of servers that are closest to you.

This static definition of the NTP servers is a Achilles heel of this current configuration and I might look into making it more dynamic in the future (for example the dhcp lease might include information on NTP server in the current network).

Then at last we have to provide the dispatch script for NetworkManager to use. I named it 10.chrony and placed it in the directory /etc/NetworkManager/dispatcher.d:

    1: #!/bin/bash
    2: 
    3: INTERFACE=$1 # The interface which is brought up or down
    4: STATUS=$2 # The new state of the interface
    5: 
    6: CHRONY_PASSWORD=`cat /etc/chrony/chrony.keys | cut -d " " -f 2`
    7: 
    8: case "$STATUS" in
    9:  'up') # $INTERFACE is up
   10: 
   11:   /usr/bin/chronyc <<EOF
   12: password $CHRONY_PASSWORD
   13: online
   14: EOF
   15: 
   16:   ;;
   17:  'down') # $INTERFACE is down
   18:   # Check for active interface and down if no one active
   19: 
   20:   if [ ! `nm-tool|grep State|cut -f2 -d' '` = "connected" ]; then
   21: 
   22:   /usr/bin/chronyc <<EOF
   23: password $CHRONY_PASSWORD
   24: offline
   25: EOF
   26: 
   27:   fi
   28:  ;;
   29: esac

What the script does is read the key from the chrony key file and then use the chrony command line interface to change its state to online or offline (only if all interface are offline).