e557366978 | ||
---|---|---|
bin | ||
cgi-bin | ||
configs | ||
time-from-gps | ||
watcher-daemon | ||
README.md | ||
auth |
README.md
Info
These are instructions on how to make a Raspberry Pi into a time server, with the help of a GPS addon board.
The result should be that the Pi will continuously get current time from the GPS unit, which will be then served outside via a NTP daemon. The NTP deamon will not run if the GPS unit does not have a signal (so as not to announce wrong time). A simple web interface is provided, to monitor the status of the GPS, NTP daemon, and some other server status data.
Note that this setup is not secure, so don't let the net see your Pi! (I.e. use it behind a firewall or something.)
Installation
... from a freshly installed raspbian:
Finish configuring the raspberry
SSH daemon should be running by default. The first run should be either with a keyboard and a monitor, or plugged into a router (so that we can ssh into it, a DHCP client is waiting on the ethernet port).
sudo raspi-config
Install some stuff
We want a gps daemon, some clients, and some misc utils that I can't do without.
sudo apt-get install git htop gpsd gpsd-clients supervisor lighttpd
Adjust network config
Edit /etc/network/interfaces
. I wanted two static configs on the ethernet port, so changed iface eth0 inet dhcp
to
auto eth0
iface eth0 inet static
address 192.168.3.14
netmask 255.255.255.0
gateway 192.168.3.1
auto eth0:0
iface eth0:0 inet static
address 192.168.0.1
netmask 255.255.255.0
To get the GPS add-on board communicating with gpsd
We need to change the default configuration (getty on the serial port), so that linux doesn't try to communicate/access the serial port, which now has a GPS unit attached to. So:
- remove console on
ttyAMA0
from/boot/config.txt
- comment out getty on
ttyAMA0
from/etc/inittab
(probably last line)
Make sure gpsd does not start automatically
Make it does not start on boot (will be managed by supervisord
).
sudo dpkg-reconfigure gpsd
Make sure NTP daemon does not start automatically
Also make sure it doesn't start automatically. Also will be managed by supervisord
:
sudo update-rc.d ntp disable
Make sure lighttpd does not start automatically
sudo update-rc.d lighttpd disable
Get the files!
Get the files and put them into /opt/gps-timekeep
(this path is hardcoded into things -- I'm lazy).
sudo mkdir /opt/gps-timekeep
sudo chown pi:pi /opt/gps-timekeep
cd /opt
git clone https://github.com/flabbergast/gps-timekeep.git
Alternatively, download a zip by clicking on "Download ZIP" in the right column, unpack it, and copy the contents of gps-timekeep-master
into /opt/timekeep
.
This will get you configurations files for the daemons (will be used by supervisor), gps-watcher
and time-from-gps
python scripts and a python cgi script which displays system info and lets you edit some config files. What remains to be done is:
sudo cp /opt/gps-timekeep/configs/daemons.conf /etc/supervisor/conf.d
to configure supervisord
, and restart it
sudo /etc/init.d/supervisor stop
sudo /etc/init.d/supervisor start
Now you should have access to a basic info web page (on port 80
) and to supervisord
web interface (on port 9001
).
Password protection
The "Further info and configuration" webpage, as well as access to supervisord
, is password protected (don't feel protected by this, it's not really secure). The name:pass is admin:muflon
. There is a web form to change this, but making it work is another privilege escalation (see also "Optional extras" below), so requires making two files writable by the lighttpd
process. So:
sudo chgrp www-data /etc/supervisor/conf.d/daemons.conf
sudo chown g+w /etc/supervisor/conf.d/daemons.conf
The other file, /opt/gps-timekeep/auth
should be set up OK already, but just in case it isn't:
chmod 0666 /opt/gps-timekeep/auth
If you want to remove the password protection:
- Edit
/etc/supervisor/conf.d/daemons.conf
and remove the two lines (username
andpassword
). - Remove
/opt/gps-timekeep/auth
. - Edit
/opt/gps-timekeep/configs/lighttpd.conf
and comment out theauth.require
block.
Optional extras
Some actions from the web interface require privilege escalation (I couldn't convince lighttpd
to run as root), so:
If you want to be able to edit the system configuration from the web interface, you'll need to change the permissions of the corresponding files so that they are writable by the user/group as which the lighttpd
web server runs. For instance:
sudo chgrp www-data /etc/network/interfaces
sudo chown g+w /etc/network/interfaces
This changes the group of /etc/network/interfaces
to www-data
and makes it group-writable.
Similarly, if you want to be able to reboot from the web interface, you need to make it possible for the www-data
user to execute /sbin/reboot
. The easiest (and most unsafe) way is to make /sbin/halt
(to which /sbin/reboot
is a symbolic link) setuid root:
sudo chmod +s /sbin/halt
(Archlinux users need to edit configs/lighttpd.conf
and change the user and group to http
.)
Some info on how it's all set up
Hardware side:
- A GPS unit talks to the Pi via the serial port
/dev/ttyAMA0
, and produces PPS pulse on GPIO pin 18 (every second).
Software side:
- Official dependencies:
supervisor
,lighttpd
,gpsd
,ntpd
,python 2.7
(andgps
python module, the debian package ispython-gps
). - All the daemons and programs related to this stuff are run through supervisor daemon. So the expectation is that the used software is installed, but not automatically run by the system.
- Beware: things are hardcoded to run from
/opt/gps-timekeep
! Also some assumptions that a debian-based system is used are in place (e.g./etc/network/interfaces
,/sbin/reboot -> /sbin/halt
,www-data
forlighttpd
user/group) lighttpd
runs to provide a "web interface". Its main function is to provide info about the status of things.- The communication with the GPS hardware is done via
gpsd
daemon. This one is supposed to be running all the time, and all the other programs get GPS info through it. Among other things, it writes the current time received from GPS ("coarse time") to a "shared memory" segment, where it can be read byntpd
. - The time service to the "outside" is provided by
ntpd
daemon. It reads the shared memory segment to get GPS time. However, there are a couple of quirks/issues:- Because pi's kernel does not have the right configuration,
ntpd
can't use the PPS signal from the GPS unit directly. So a workaround daemon,rpi_gpio_ntp
, needs to be running to receive the PPS pulses and write the precise time to the shared memory segment to be read byntpd
. The thing is thatrpi_gpio_ntp
needs to start only after GPS has a fix and the system time is approximately correct (I'm not sure how it works and why, this observation comes from my experience). - Sometimes, after boot,
ntpd
refuses to read time from the shared memory segment for some reason, and restarting things doesn't help me. A "fix", which seems to work for me is to set the system time to an approximately correct time before starting any daemons.
- Because pi's kernel does not have the right configuration,
- So to deal with the things above, there are two extra python programs:
time-from-gps.py
: this is a "startup" script. It waits until GPS reports a fix and a time, and subsequently sets the system time (to an approximately correct one) and starts the other daemon:gps-watcher.py
: monitors the GPS for signal. If there's no signal, it stopdntpd
andrpi_gpio_ntp
. If there is signal, it starts them up. Also, it regenerates the basic static html page (every 2-3 seconds).
- Other web interface elements:
supervisord
runs its own web interface on port 9001.- One python CGI script is provided (
serverconfig.py
), which gives more system info, and lets you edit/etc/network/interfaces
and reboot the Pi (see "Optional Extras" for what's needed to make this work).
Other notes (about configuration, etc...)
-
gpsd
parameters should contain-n
. This is so that gpsd starts listening to the GPS device even before a client (like cgps or such) asks for it. we need this so that the timekeeping starts right away on boot. -
To test if
rpi_gpio_ntp
receives the pulses, run (the18
is the GPIO pin on which the PPS pulse is sent):sudo rpi_gpio_ntp -g 18 -d
It should print one line every second (when the pulse comes).
-
ntpd
configuration: Thetime1
parameter forfudge
ofSHM
source is an observed value to make the offset of this source smallish (<5ms). It's more-less the time which is takes the GPS unit to transmit info over serial and then gpsd to process and enter into the shared memory. It's likely to be larger (cca 0.350) for GPS units attached over USB. -
Current status of the NTP daemon can be observed by running
ntpq -p
orntpq -pn
(-n
for not reverse resolving IP addresses). Most important things about the output:- the very first column indicates status of a source:
*
means currently used/selected,x
means not used - the
reach
column should have377
for theUPPS
source (means ntpd "sees" the source). It changes for a while after ntpd restart, then it should stabilize on377
. - the
offset
is in milliseconds. Shouldn't be too big; less than 1 for theUPPS
source, or at least single digits.
- the very first column indicates status of a source:
-
lighttpd
is set up to use/run/www
as the main document root, since the status page is updated every 2-3 seconds and so we want to use atmpfs
filesystem. In other words, stuff from there lives only in the memory and disappears on every reboot!
Sources / Credits
- GPS addon board This is the one I used. Communicates through the serial port and generates PPS on GPIO 18 (pin 12).
- A very comprehensive guide with pretty much everything in it. Maybe too detailed, so slightly hard to navigate through. Also explains the other possibility to get PPS: patch and recompile the kernel.
- rpi_gpio_ntp source code