Raspberry Pi 3 Stratum 1 NTP Server

This is an update of the previous post. I’m now using Raspbian Buster with NTPsec (which I package in Debian).

Hardware:

I’m in the U.S., so I ordered only the GPS board and case from Uputronics to save on shipping.

Other GPS HATs (and cases) can be used. Consult the Stratum-1-Microserver HOWTO for GPIO pin changes.

1. Download a Raspbian Buster image, typically the Raspbian Buster Lite image, which is command line only.

2. Unzip the image:
$ unzip 2019-09-26-raspbian-buster-lite.zip

3. Write the image to a Micro SD card:
$ sudo dd if=2019-09-26-raspbian-buster-lite.img of=/dev/mmcblk0

4. Insert the SD card into the Raspberry Pi. Stick the heatsink to the processor. Assemble the case with the Raspberry Pi in it as you go. Connect the GPS antenna and place it near a window. Connect a keyboard, mouse, and monitor. Power up the Raspberry Pi.

5. Login as “pi” as the username and “raspberry” as the password. Set your own password:
$ passwd

Alternatively, add your own user and delete the “pi” user:

$ sudo adduser YOURUSERNAME
$ sudo usermod -a -G adm,audio,cdrom,dialout,games,gpio,i2c,input,netdev,plugdev,spi,sudo,users,video YOURUSERNAME
$ exit
Log back in with your username.
$ sudo deluser pi

6. Set your locale:

$ sudo apt update
$ sudo apt install locales
$ sudo dpkg-reconfigure locales

7. Set your time zone:
$ sudo dpkg-reconfigure tzdata

8. Set your hostname:

$ sudo vi /etc/hosts
$ sudo vi /etc/hostname

9. Optimize system performance:

$ sudo sed -i "s|$| nohz=off|" /boot/cmdline.txt
$ sudo vi /etc/default/cpufrequtils
Set: GOVERNOR="performance"

10. Reconfigure serial for GPS:

$ sudo apt -y purge bluez bluez-firmware
$ sudo sed -i "s|console=serial0,115200 ||" /boot/cmdline.txt
$ sudo vi /boot/config.txt
Add these lines to the end:
dtoverlay=pi3-disable-bt
enable_uart=1
dtoverlay=pps-gpio,gpiopin=18

11. Update and install software:

$ sudo apt -y dist-upgrade
$ sudo apt -y install cpufrequtils gpsd gpsd-clients pps-tools ntpsec ntpsec-ntpviz

Note: Installing ntpsec-ntpviz is optional, and skipping it will avoid bringing in Apache.

12. Configure gpsd:

$ sudo sed -i 's|DEVICES="|\0/dev/ttyAMA0 /dev/pps0|' \
/etc/default/gpsd
$ sudo sed -i 's|GPSD_OPTIONS="|\0-n|' /etc/default/gpsd
$ sudo mkdir -p /etc/systemd/system/ntpsec.service.d
$ sudo vi /etc/systemd/system/ntpsec.service.d/gpsd.conf
[Unit]
After=gpsd.service
Wants=gpsd.service

$ sudo mkdir -p /etc/systemd/system/gpsd.service.d
$ sudo vi /etc/systemd/system/gpsd.service.d/stationary.conf
[Service]
ExecStartPre=/usr/bin/gpsctl -t 'u-blox' -b -x '\\x06\\x24\\xFF\\xFF\\x02\\x03\\x00\\x00\\x00\\x00\\x10\\x27\\x00\\x00\\x05\\x00\\xFA\\x00\\xFA\\x00\\x64\\x00\\x2C\\x01\\x00\\x3C\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00' $DEVICES

The stationary.conf bit is not required. This sends a command to the GPS to put it into “stationary mode”. By telling the GPS module that it is not moving, it can optimize its calculations, which should slightly improve timing performance. However, whether this matters for NTP-level accuracy is doubtful. I have no done any analysis.

13. Configure ntpd:

sudo vi /etc/default/ntpsec
Set:
IGNORE_DHCP="yes"


sudo vi /etc/ntpsec/ntp.conf
Add these two lines before the "pool" entries:
server 127.127.28.2 minpoll 1 maxpoll 1 prefer
fudge 127.127.28.2 refid PPS

Note: If you want to be able to set the clock without network access, also comment out:
tos minclock 4 minsane 3

15. Reboot:
$ sudo reboot

16. Check that things look right:
$ watch ntpq -p

After a bit, you should see “SHM(2)” selected, which will be indicated by an asterisk in front of that line.

When finished, you can kill the watch command with Control-C.

If the PPS is not working, first check the GPS status:
$ gpsmon

Once the GPS is locked, check the PPS status:
$ sudo ppstest /dev/pps0

Sources:

FreeBSD Code of Conduct

Slashdot linked to the FreeBSD Code of Conduct. The article claims there is some controversy, so that’s what the comments focus on. I wrote:

Having just read the Code of Conduct, it seem generally fine. Some of my concerns are that the rules are too broad, and some are that they are too narrow.

The “Comments that reinforce systemic oppression related to” wording seems super vague. This portion has the highest potential for abusive use. To be clear, I’m fine with all the protected criteria that come in that rule. I’d much prefer replacing that with “Harassing comments related to”

The “unwelcome comments” thing is pretty broad. If someone says to me on IRC, “I’m tired all the time.” and I say, “You should stop eating so much junk food and get some exercise.”, I’m now in trouble if they feel that comment is unwelcome. With this rule, the only option for me is to never engage in such a conversation. Is that helpful or harmful to building relationships and living fulfilling lives? I think it’s more harmful than helpful. Now, I agree that continually nagging that person to eat healthy is inappropriate. If this was limited to “repeated”, “after being asked to stop”, or similar, it would be better.

I have some concerns about the “dead” names thing. I get and agree with the point: use the names people pick for themselves. As long as this isn’t enforced robotically, it should be fine. There are some legitimate reasons to use names that were in use in times in the past. For example, I think citations to publications should use the name of the author at the time it was published, because the point of the citation is to help you find the publication. This is supported by, for example, an APA Style Blog post. The issue of whether to change one’s name is complicated for the individual and has implications for the wider community.

For another example, yesterday I was considering replying to a years-old mailing list comment, and quoting some text. The author of the quoted text is trans and has changed names. Am I required to edit the “On DATE, NAME wrote:” line? To be clear, in new text, I would address this person using their new name (and have actually done so). I said in a follow up comment: I actually struggled with this for several minutes before ultimately deciding to just drop the “On DATE, NAME” bit. I ultimately determined the answer to my own question, so I dropped the email before sending it.

I personally don’t see a problem with person A saying “*hugs*” to person B without (advance) consent. Though, this is situational. If someone says, “Sorry for the delay on this bug, I’ve been distracted. My dog died.”, I see no problem with “Sorry to hear about your dog. *hugs*”. On the other hand, something like “You’re such a special snowflake. *hugs*” is an improper ad hominem attack. Even in the first example, I do have a problem if they keep doing it after being told by person B to stop, so that rule is fine. On the other hand, saying “*backrub*” out of the blue does seem across the line. I’m struggling to think of an example where that would be unambiguously appropriate.

I’m not sure why the “as necessary to protect vulnerable people from intentional abuse” exception exists to the “outing” rule. Why would it be necessary or acceptable to out someone to protect them? I said in a follow up comment: In terms of the exception to the “outing” rule, I was assuming that the person being outed was the vulnerable person. I see my error now, and this makes sense.

“Publication of non-harassing private communication without consent.” is problematic as a blanket rule. If someone says something important publicly which is materially contradicted by private statements, that might be necessary (albeit tacky) to share, even if those private statements are non-harrassing.

“Knowingly making harmful false claims about a person.” I would strike harmful. Why is it necessary that the false claims be harmful?

Raspberry Pi 3 Stratum 1 NTP Server (Ubuntu)

Please use the updated version instead.

Hardware:

I’m in the U.S., so I ordered only the GPS board and case from Uputronics to save on shipping.

Other GPS HATs (and cases) can be used. Consult the Stratum-1-Microserver HOWTO for GPIO pin changes in step 12.

1. From Ubuntu Pi Flavour Maker, download the Ubuntu Server Minimal 16.04 image. Note that this is only available using BitTorrent (for bandwidth reasons).

2. Write the image to a Micro SD card.

3. Insert the SD card into the Raspberry Pi. Stick the heatsink to the processor. Assemble the case with the Raspberry Pi in it as you go. Connect the GPS antenna and place it near a window. Connect a keyboard, mouse, and monitor. Power up the Raspberry Pi.

4. Login with “ubuntu” as the username and “ubuntu” as the password. Set your own password:
passwd

5. Become root:
sudo -s

6. Generate the missing locale:
locale-gen en_US.UTF-8

7. Disable a broken service:
systemctl disable ureadahead

8. Resize the partition to fill your Micro SD card:
fdisk /dev/mmcblk0
“Delete the second partition (d, 2), then recreate it using the defaults (n, p, 2, enter, enter), then write and exit (w).” — Ubuntu Pi Flavour Maker FAQ

9. Set your time zone:
dpkg-reconfigure tzdata

10. Set your hostname:
vi /etc/hosts
vi /etc/hostname

11. Actually, I think we want to leave this alone. I can’t reproduce any problem, and keeping fake-hwclock, as designed, makes the clock far less wrong on initial boot (before ntpd steps the clock). Disable fake-hwclock, which otherwise breaks PPS in NTP at boot:
systemctl disable fake-hwclock

12. Disable Bluetooth, as we need the UART for GPS:
echo dtoverlay=pi3-disable-bt >> /boot/config.txt
echo enable_uart=1 >> /boot/config.txt
echo dtoverlay=pps-gpio,gpiopin=18 >> /boot/config.txt
systemctl disable hciuart
apt -y purge bluez bluez-firmware

13. Set maximum performance for consistent timing:
sed -i "s|$| nohz=off|" /boot/cmdline.txt
systemctl disable ondemand
echo 'GOVERNOR="performance"' > /etc/default/cpufrequtils

14. Install software:
apt update
apt -y dist-upgrade
apt -y install cpufrequtils gpsd gpsd-clients ntp pps-tools

15. Configure gpsd:

sed -i 's|DEVICES="|\0/dev/ttyAMA0 /dev/pps0|' \
    /etc/default/gpsd
sed -i 's|GPSD_OPTIONS="|\0-n|' /etc/default/gpsd
mkdir -p /etc/systemd/system/ntp.service.d
cat >/etc/systemd/system/ntp.service.d/gpsd.conf <<EOF
[Unit]
After=gpsd.service
Wants=gpsd.service
EOF
mkdir -p /etc/systemd/system/gpsd.service.d
cat >/etc/systemd/system/gpsd.service.d/stationary.conf <<EOF
[Service]
ExecStartPre=/usr/bin/gpsctl -t 'u-blox' -b -x '\\\\x06\\\\x24\\\\xFF\\\\xFF\\\\x02\\\\x03\\\\x00\\\\x00\\\\x00\\\\x00\\\\x10\\\\x27\\\\x00\\\\x00\\\\x05\\\\x00\\\\xFA\\\\x00\\\\xFA\\\\x00\\\\x64\\\\x00\\\\x2C\\\\x01\\\\x00\\\\x3C\\\\x00\\\\x00\\\\x00\\\\x00\\\\x00\\\\x00\\\\x00\\\\x00\\\\x00\\\\x00\\\\x00\\\\x00' \$DEVICES
EOF

16. Configure ntp
cat >/etc/ntp.conf <<EOF
# /etc/ntp.conf, configuration for ntpd; see ntp.conf(5) for help

driftfile /var/lib/ntp/ntp.drift
leapfile /usr/share/zoneinfo/leap-seconds.list

statsdir /var/log/ntpstats/
statistics loopstats peerstats clockstats
filegen loopstats file loopstats type day enable
filegen peerstats file peerstats type day enable
filegen clockstats file clockstats type day enable

# Specify one or more NTP servers.

# Stratum 0 (GPS)
server 127.127.28.2 minpoll 1 maxpoll 1 prefer
fudge 127.127.28.2 refid PPS

# Use servers from the NTP Pool Project. Approved by Ubuntu Technical Board
# on 2011-02-08 (LP: #104525). See http://www.pool.ntp.org/join.html for
# more information.
pool 0.ubuntu.pool.ntp.org iburst preempt
pool 1.ubuntu.pool.ntp.org iburst preempt
pool 2.ubuntu.pool.ntp.org iburst preempt
pool 3.ubuntu.pool.ntp.org iburst preempt

# Use Ubuntu's ntp server as a fallback.
pool ntp.ubuntu.com preempt

server 127.127.28.0 noselect
fudge 127.127.28.0 time1 0 refid GPS

# Access control configuration; see /usr/share/doc/ntp-doc/html/accopt.html
# for details. This page might also be helpful:
# http://support.ntp.org/bin/view/Support/AccessRestrictions
#
# Note that "restrict" applies to both servers and clients, so a configuration
# that might be intended to block requests from certain clients could also end
# up blocking replies from your own upstream servers.

# By default, exchange time with everybody, but don't allow configuration.
restrict -4 default kod notrap nomodify nopeer noquery limited
restrict -6 default kod notrap nomodify nopeer noquery limited

# Local users may interrogate the ntp server more closely.
restrict 127.0.0.1
restrict ::1

# Needed for adding pool entries
restrict source notrap nomodify noquery
EOF

17. Reboot:
reboot

18. Resize the filesystem:
sudo resize2fs /dev/mmcblk0p2

19. Check that things look right:
ntpq -p

20. Wait ~24 hours for everything to stabilize. You want to allow for the drift to be calculated. Once the PPS offset is tiny (e.g. 0.010 or so), you know things are good.

21. At this point, wait for midnight to roll around so the stats are rotated. Then wait at least another 4 hours.

22. Calculate the correct offset for the GPS serial data:

awk '/(SHM\(0\)|127\.127\.28\.0/ { sum -= $5 ; cnt++; } END { print sum / cnt; }' /var/log/ntpstats/peerstats

23. Add that value from the GPS’s time1 in /etc/ntp.conf. If this is the first time you’re doing it, the existing value is zero, so just use it directly.

24. Restart ntp:
sudo systemctl ntp restart

25. The offset on the GPS line should now be less than 3 or so. You can repeat steps 21 through 24 if want to try to get closer.

26. Remove noselect from the GPS line in /etc/ntp.conf:
sudo vi /etc/ntp.conf

27. Restart ntp:
sudo systemctl ntp restart

Sources:

My tcpdump Idiom

This is how I like to run tcpdump these days:
sudo tcpdump -U -s 0 -w - port 80 | tee DESCRIPTION-$(date +%s).pcap | tcpdump -lvvnr -

This dumps out a .pcap file I can open in Wireshark later, but also shows the tcpdump human-readable representation in real-time.

Ubuntu Maverick Release Party

What: Ubuntu Maverick Release Party
Where: rlaager’s House
When: Sunday, October 10, 2010 @ 2:00-5:00

Please respond to rlaager@wiktel.com by 1:00 Sunday if you’re coming. I don’t want to sit around waiting if nobody is coming. 🙂

Of course, bring your computer (if portable) for the install/upgrade to Maverick.