Timesync in a field
Categories: Hacking
This post is part of [tj]’s blog more in June challenge. You should join us and take part - just make 4 posts in June!
As part of the general move to do more radio / do radio in a field, I’m configuring a raspberry pi to be a permanent companion to my radio.
One challenge of the pi is the lack of an RTC, and this isn’t something I’m particularly fussy about fixing with dedicated hardware - typically it’s quite expensive.
I have a portable USB GPS dongle that I’d like to use for APRS/other position data (cgps
displays your Maidenhead locator!), so I might as well make that a permanent fixture and derive system time from GPS. I can’t trust ntp pools, as I probably won’t have internet where I’m using it.
On the surface, this is quite an easy task:
apt install gpsd gpsd-clients ntp
and edit some config files.
Unfortunately, it wasn’t quite so easy.
I ran into two stumbling blocks:
Shared Memory
gpsd
seems to share time data with ntp
via shared memory. Raspberry Pi OS’s default configuration has apparmor enabled, which was preventing ntp
from accessing this.
I had to edit /etc/apparmor.d/tunables/ntp
to contain my GPS device - it now reads:
@{NTPD_DEVICE}="/dev/ttyACM0
I checked that there were entries in the shared memory using ntpshmmon
as root, and I could see slot NTP0 populated. That’s my GPS’ time coming through.
NTP Driver Flags
Following the documentation, I commented out the pool timeservers in the /etc/ntp.conf
and after too much experimentation added the following:
# GPS Serial
server 127.127.28.0
fudge 127.127.27.0 refid GPS flag1 1
I had to go hunting to learn what flag1 1
did - up until I added that, nothing worked at all. According to the manpage, the ntp
flag1-4 are controls for different drivers for ntp
.
As I’m using the SHM driver, the documentation for that tells me that the default mode of operation is to discard the new time if it’s +/- 4 hours from the current system time.flag1 1
disables this check. Given the pi can be off for days at a time, this seems like a sensible default for me.
Everything works and has survived reboot. It takes a few minutes for the time to be set by GPS, but it always catches up.
During this I went down a few false rabbit holes, the most useful lesson from that being: changing the ntp user in /usr/lib/ntp/ntp-systemd/wrapper
to root didn’t fix anything and is probably unwise for system hardening.