A Minimal Raspberry Pi 3 GPS Time Server

A Raspberry Pi can make an outstanding NTP time server for your network. Below, I document the bare minimum needed to get a Raspberry Pi 3 Model B with the Adafruit Ultimate GPS Hat working as an NTP server.  You can do this, even buying all the parts new, for under $100 USD.

What makes this project interesting is that you end up with potentially a very compact time server – a Pi with a nicely stacked board on top. Just bring network and power to the box, put the box near a window, and it’s otherwise self-contained. For an even simpler deployment, in a corporate environment with PoE switches, use a PoE to USB cable like this one (disclaimer: this is an Amazon affiliate link, so I get a tiny amount of money if you buy something here): PoE to USB Splitter – then all you need is a network cable (no wall wart is required) which supplies connectivity and power.  Note that the PoE (Power over Ethernet) adapter requires that you have ethernet switches that support PoE.  Your business might have these, but you probably don’t have them at home (they cost a lot more money).

The only thing I’m missing is a good case – if anyone knows of a good Raspberry Pi 3 case that fits well with the Adafruit hat installed, I’m very interested — please comment!

Why do you want to do this?  There are several reasons:

  • You have a need for “correct” time on your servers (to do log correlation or for regulatory requirements)
  • You have an asymmetric internet connection.  There is no way for internet time servers to be more accurate than 10ms or so if you have this type of connection – virtually any DSL or cable internet connection.  On these connections, you have a faster download than upload.  That means that that it takes several ms (milliseconds) less time to travel from the internet to your machines than it takes to travel from your machines to the internet.  Because NTP measures round trip delay and divides it by two, assuming equal delay on both paths, your time will be off in such cases. Whether it’s off enough to bother you is a different question!
  • Related to the above, it is very unusual for internet backbone paths to be the same for both directions of your connection.  In fact, this is more common than not. This causes issues with NTP.
  • During network congestion (whether it’s a peering point, a congested NTP server, or your internet connection), you will see additional delay added, typically more in one direction than another.  Right now, NIST’s Maryland servers (time-a.nist.gov, time-b.nist.gov, time-c.nist.gov) have about 70ms of extra delay due to congestion at their end – this makes the time about 35ms off (70 divided by 2) for anyone synchronizing to their servers.
  • You need accurate time on a network not connected to the internet and/or during internet outages
  • You don’t want to be dependent upon volunteer server operators for the correct time
  • You might just like knowing your time is more correct than your friend’s!

There are lots of tutorials on the building NTP servers from Pis, but this one is a bit different because:

  • It’s based on the Pi 3 Model B instead of the 2 or older.  There are some serial oddities on the Pi 3, so you do need to do minor modifications.
  • Most tutorials connect to gpsd via shared memory to fetch the time of day while using the kernel PPS module to get the seconds to start at the right instant.  This means you can have time that is several hundred milliseconds off reality upon startup of NTP.  This can be mitigated slightly by fudging the stratum of the GPS and having internet time services also configured, but it can’t be eliminated completely.
  • I don’t generally manage computers from the console, I use network-based access to do so.  Most tutorials assume it’s convenient to haul a monitor out to the Pi.  This tutorial never requires you to connect a monitor (but you can if you want).
  • This tutorial uses versions of ntpd and gpsd I compiled from more recent sources than come with the stable branch of Raspbian.  The ntp code also has a patch I’ve made to allow it to see both the GPS and PPS devices from gpsd easily.

So, here’s the procedure: Continue reading

Debian/Ubuntu, systemd, NTP, and something called timesyncd

Unix, for years, has had a program called ntpd to use the NTP (Network Time Protocol) service to set time.  The ntpd service is a pretty advanced thing – it can do basic “set your workstation’s time” type of tasks, but it can also do things like talking to atomic clocks, providing time service to other machines via multicast or broadcast, and doing some pretty sophisticated network time synchronization which tries to avoid one or two bad network server clocks from impacting your local time. It also allows for authentication, which is a hard requirement in some environments.  For instane, PCI, the standard for processing credit cards, says, “time data must be protected.”  This is section 10.4.2 of the PCI-DSS, which while not explicitly requiring authentication, is clearly not a bad thing to have authentication.

I love ntpd.

The systemd people on the other hand, apparently hate it.  They went the same direction as some other popular mass-market operating systems and decided NTP is too complex to implement.  So they implemented SNTP (Simple NTP) only, and only in client mode. So it doesn’t function as a server. It doesn’t do authentication. It doesn’t track jitter and delay over time. It doesn’t try to make time jumps only in a forward direction.  It doesn’t do any number of other things to keep your time accurate.

Sure, it was easier for the systemd people’s world view. When a new network interface comes up, this service tries to fetch the proper time based on that network interface’s configuration. That’s cool – but the same thing can be done with NTP fairly easily. And there is a place for SNTP – embedded systems with limited resources. Not on computers with enough processing power to run, say, Unity (Ubuntu’s default GUI).

So here’s how to do replace it with real ntpd:

First, remove the systemd-timesyncd.service startup script:

rm /etc/systemd/system/systemd-timesyncd.service

Next, create /lib/systemd/system/ntp.service with the following contents:

After=network.target auditd.service

ExecStart=/usr/sbin/ntpd -n $NTPD_OPTS
ExecReload=/bin/kill -HUP $MAINPID


Then link this to /etc/systemd/system/ntp.service:

ln -s /lib/systemd/system/ntp.service /etc/systemd/system/ntp.service

Then restart systemd:

systemctl daemon-reload

Now you can start NTP normally:

systemctl start ntp

Now you have workable NTP!