Introduction
In this post I will cover setting up a ntp/chrony server on Ubuntu 22.04 using a Satellite GPS Receiver. I have also recently published another post on Chrony, which goes a bit more into basic commands. That post can be found here.
Hardware
- Linux Host – Nvidia Jetson Orin Nano 4GB
- GPS/GNSS – GlobalSat BU-353-W11
Note: the GlobalSat BU-353-W11 does not support 1pps. It’s designed primarily for positioning and navigation, not precision timing. We can use it as our timesource for chrony, with a typical accuracy: ±50–150 ms. Good enough for a lab.
Hardware Detection
After plugging in the USB cable on the GNSS module, check for a new USB device.
# lsusb
Bus 001 Device 004: ID 1546:01a7 U-Blox AG [u-blox 7]
Output from dmegs also shows the device was detected properly
[347055.572498] usb 1-2.4: new full-speed USB device number 4 using tegra-xusb
[347055.768706] cdc_acm 1-2.4:1.0: ttyACM0: USB ACM device
[347055.768784] usbcore: registered new interface driver cdc_acm
[347055.768788] cdc_acm: USB Abstract Control Model driver for USB modems and ISDN adapters
In the output above you can see the device was detected ttyACM0. Now we need to confirm how the device was enumerated. As you can see the device is owned by root and the group is dialout
# ls -l /dev/ttyACM*
crw-rw---- 1 root dialout 166, 0 Dec 29 13:40 /dev/ttyACM0
You can run a quick check to confirm that the device is functioning as shown below
# cat /dev/ttyACM0
$GPTXT,01,01,02,u-blox ag - www.u-blox.com*50
$GPTXT,01,01,02,HW UBX-G70xx 00070000 FF7FFFFFo*69
$GPTXT,01,01,02,ROM CORE 1.00 (59842) Jun 27 2012 17:43:52*59
$GPGGA,201055.00,3356.15827,N,08345.15611,W,2,12,0.80,280.0,M,-31.5,M,,0000*67
-----------truncated----------------
GPSD
To use a GPS/GNSS antenna with chronyd on Linux for time synchronization and location sharing, we will use the gpsd service to manage the GPS hardware and make its data accessible to other applications, including chronyd
Package Installation
# sudo apt update
# sudo apt install gpsd gpsd-clients chrony pps-tools
GPSD Configuration
Identify the GPS device: The device will likely be /dev/ttyUSB0, /dev/ttyACM0, or similar. You can verify this by running cat /dev/ttyUSB0 (replace ttyUSB0 with your suspected device) and looking for NMEA strings (lines starting with $GPGGA, $GNRMC, etc.).
Edit the gpsd configuration file: Open /etc/default/gpsd and set the DEVICES, GPSD_OPTIONS, and USBAUTO variables.
START_DAEMON="true"
GPSD_OPTIONS="-n -b"
DEVICES="/dev/ttyACM0"
USBAUTO="false"
GPSD_SOCKET="/var/run/gpsd.sock"
For reference here are configuration params for GPSD_OPTIONS
| Flag | Argument | Meaning | Notes |
|---|---|---|---|
-n | none | Start reading GPS immediately | Required for chrony/NTP |
-b | none | Read-only mode (no device writes) | Recommended for USB pucks |
-N | none | Run in foreground | Debug only |
-D | <level> | Debug verbosity | Use -D 2 or -D 3 |
-F | <path> | Control socket path | Needed for manual runs |
-s | <baud> | Force serial baud rate | UART devices only |
-S | <port> | TCP listening port | Rare; usually disabled |
-G | none | Allow remote TCP clients | Avoid on servers |
-l | none | List drivers and exit | Diagnostic |
-V | none | Show version and exit | Informational |
-h | none | Help output | Reference |
Enable and start gpsd
# sudo systemctl enable gpsd
# sudo systemctl restart gpsd
Verify gpsd is receiving data
# cgps -s
Output below

Interpreting the output from cgps
High-Level Status (The Big Picture)
- (Satellites) Seen / Used: 13 / 11
- Fix: 3D DGPS FIX – means the receiver has solved all three spatial dimensions: (Latitude, Longitude, Altitude)
- Time is valid
- Position accuracy: ~5–10 feet horizontal
Satellite Section (Right Pane)
Seen 13 / Used 11
This means:
- The receiver can currently see 13 satellites
- 11 of those are strong enough to be used in the solution
This is quite a healthy signal for a device sitting inside up against a window.
Anything above:
- 4 used → valid 3D fix
- 8+ used → very solid geometry
- 10–12 used → excellent (we are here)
Constellations
GP= GPS- U.S. GPS constellation
- Medium Earth Orbit (≈20,200 km)
- ~30 active satellites worldwide
SB= SBAS (WAAS corrections)- Satellite-Based Augmentation System
- Broadcast correction data
- Improve accuracy of GPS measurements
- Do not provide independent position fixes
The presence of SBAS satellites indicates differential reminder data is available, improving accuracy.
Fix & Timing (Left Pane)
Fix State
Status: 3D DGPS FIX (1 secs)
- 3D = Latitude, longitude, altitude solved
- DGPS = WAAS corrections applied
- (1 secs) = Fix age (very fresh)
Time Quality
Time: 2025-12-29T20:32:22.000Z
Time offset: 0.078609772 s
Chrony
Install Chrony via apt
# apt install chrony -y
Configure Chrony
Edit /etc/chrony/chrony.conf. This config has been tested on Ubuntu 22.04, YMMV on other Linux versions.
Explanation of Chrony Config for GPSD
| Option | Purpose |
|---|---|
SOCK /var/run/gpsd.sock | Read time from gpsd |
refid GPS | Label in chrony output |
poll 4 | Poll every 16 seconds |
precision 1e-1 | ~100 ms accuracy (realistic for NMEA) |
delay 0.2 | USB + NMEA latency |
makestep 1.0 3 | Allow initial step corrections |
Start and Enable
# systemctl enable chrony.service
# systemctl start chrony.service
After a few minutes, we should start to see pre-configured clients appear in the output of the command below
# chronyc clients
Hostname NTP Drop Int IntL Last Cmd Drop Int Last
=============================================================================
scar.lab 5 0 6 - 30 0 0 - -
Chrony Client-side Setup
Ubuntu Client
$ sudo apt install chrony -y
Configure the to listen to the chrony server address 10.1.10.10. Comment out any other server or pool directives in /etc/chrony/chrony.conf.
server 10.1.10.11
Start and enable the service.
$ sudo systemctl enable chrony --now
Check configured time source for chrony
$ chronyc -n sources -v
What the above output tells you
- All NTP servers/pools configured for this client
- Which source is currently selected
- Reachability and time quality
Key indicators
| Symbol | Meaning |
|---|---|
^* | Current sync source |
^+ | Candidate source |
^- | Reachable, not selected |
^? | Unusable / not trusted yet |
Cisco Catalyst Client Config
Use the commands below to configure your Cisco switch to use the new timesource
# Enter global configuration mode
configure terminal
# Define the NTP server
ntp server 10.1.10.11
# (Optional) Set the switch to use its own hardware clock if it loses sync
ntp master 10
# Exit and save
end
write memory