chore(doc/time):Update README
[EVA-2020-02.git] / doc / location / README.org
... / ...
CommitLineData
1* Location Logging
2This document was created by Steven Baltakatei Sandoval on
3~2020-06-29T12:14Z~ under a [[https://creativecommons.org/licenses/by-sa/4.0/][Creative Commons BY-SA 4.0 license]]. It
4was updated by Steven Baltakatei Sandoval on ~2020-07-23T21:49Z~
5#+TITLE: Ninfacyzga-01 Manual
6#+AUTHOR: Steven Baltakatei Sandoval
7#+EMAIL: baltakatei@gmail.com
8** Narrative
9Ninfacyzga-01 records (logs) its position in time and space using a
10[[https://en.wikipedia.org/wiki/Satellite_navigation_device][GPS receiver]]. The NMEA location data produced by the receiver is
11converted into the more commonly used GPS data storage formats of GPX
12and KML. All three types of data are then compressed and encrypted
13against a set of public keys. The encrypted data is then written to
14disk. Data produced by the receiver is segmented into 60-second chunks
15before being processed and written to disk.
16** Description
17*** Hardware
18**** Raspberry Pi Zero W
19See the [[https://www.raspberrypi.org/pi-zero-w/][OEM]] webpage for this product.
20**** PiZ UpTime 2.0
21See the [[https://alchemy-power.com/piz-uptime-2-0/][OEM]] webpage for this product.
22*** Software
23~bklog~ : A bash script that saves its stdin stream to a tar file. The
24file may be compressed by ~gzip~ and encrypted by ~age~. It is an
25executable file contained within this repository at ~exec/bklog~. It
26should be copied to ~$HOME/.local/bin~.
27
28~bkgpslog~ : A legacy bash script similar to ~bklog~ but narrower in
29scope in that it only records output from ~gpspipe~.
30
31~gpsd~ : A background daemon app capable of interfacing with the
32Ozzmaker BerryGPS-IMU's GPS submodule. Installed and initialized by
33~apt~.
34
35~gpspipe~ : A command line app that polls ~gpsd~ and produces a stream
36stdout consisting of GPS data lines in NMEA format. Installed via
37~apt~.
38
39~gpsbabel~ : A command line app that converts GPS data from one format
40into another. ~bklog~ may be used to convert NMEA data into GPX and
41KML. Installed via ~apt~.
42
43~gzip~ : A simple command line app that compresses stdin into a
44smaller stdout stream.
45
46~age~ : A simple command line app that encrypts stdin against public
47keys specified in its options. Produces encrypted stdout. Is an
48executable file contained within this repository at ~exec/age~. It
49should be copied to ~$HOME/.local/bin~.
50
51**** Narrative
52~bklog~ may be used to log location data by receiving stdout produced
53by ~gpspipe~. ~bklog~ contains options that allow file writes to be
54performed at adjustable time intervals (default: 300 seconds),
55compressed (with ~gzip~), and encrypted (with ~age~). Files are
56written in the form of appendages to a ~tar~ archive saved to a
57specified location. The NMEA data produced by ~gpspipe~ may be
58processed via a ~gpsbabel~ command string specified as an option to
59~bklog~, assuming ~gpsbabel~ is installed.
60
61*** Output
62
63Several output file formats have been tested with ~bklog~.
64
65**** File Formats
66***** NMEA
67~NMEA~ is an acronym for National marine Electronics Association. The
68NMEA format described in this document follows the NMEA 0183
69standard. It is a newline-delimited streaming text format that encodes
70global positioning system (GPS) data such as WGS84 location, time and
71date information, satellite count, accuracy, and other
72information. Each line is an "NMEA sentence". Descriptions of various
73NMEA sentences can be found on [[http://aprs.gids.nl/nmea/][this]] webpage.
74
75See the [[https://en.wikipedia.org/wiki/NMEA_0183][Wikipedia page for NMEA 0183]] for this. This file format is the
76default output of the ~gpspipe -r~ command.
77***** GPX
78See the [[https://en.wikipedia.org/wiki/GPS_Exchange_Format][Wikipedia page]] for this. [[http://wiki.gis.com/wiki/index.php/WGS84][WGS84]] is the datum used. An NMEA file
79may be converted to this format using ~gpsbabel~.
80***** KML
81See the [[https://en.wikipedia.org/wiki/Keyhole_Markup_Language][Wikipedia page]] for this. [[http://wiki.gis.com/wiki/index.php/WGS84][WGS84]] is the datum used. An NMEA file
82may be converted to this format using ~gpsbabel~.
83
84**** Encryption Method
85Files produced by the bkgpslog script are encrypted against a set of
86public keys using [[https://github.com/FiloSottile/age][~age~]], a simple command line encryption tool
87selected over ~gpg~ because of ~age~'s deliberate lack of
88configurability.
89
90The public keys are bech32 strings supplied as options to bkgpslog
91when called. The secret key should *NOT* be stored in Ninfacyzga-01.
92
93If a key pair was generated using ~age-keygen~, then it is an [[https://en.wikipedia.org/wiki/Curve25519][~X25519~]]
94key pair. See the [[https://age-encryption.org/v1][~age~ Version 1 specification]].
95
96An ~ssh-rsa~ or ~ssh-ed25519~ SSH public key string may be used instead of
97the bech32 public key string produced by ~age-keygen~ for convenience.
98
99Help information for ~age~ is available by running ~$ age --help~.
100***** Encryption Commands
101****** Encryption through ~age~
102In order to illustrate how ~bklog~ encrypts files, below is an example
103command illustrating how ~age~ may be used to encrypt a file.
104
105#+BEGIN_EXAMPLE
106$ echo "asdf" | age -r \
107age1kza7pfshy7xwygf9349zgmk7x53mquvedgw9r98qwyyqhssh830qqjzlsw \
108> "$HOME/secret_file"
109#+END_EXAMPLE
110
111The resulting ~secret-file~ is a binary blob with a plaintext header
112indicating how the blob was encrypted (which version of age was used,
113which public key was used).
114
115****** Encryption through ~bklog~
116~bklog~ may instructed to encrypt files via the ~-e~ and ~-r [pubkey
117string]~ options. An example is shown below:
118
119#+BEGIN_EXAMPLE
120$ gpspipe -r | bklog -e \
121-r age1kza7pfshy7xwygf9349zgmk7x53mquvedgw9r98qwyyqhssh830qqjzlsw \
122-r age1ce3pvzrqfcn2pc6zqzglc8ac8yjk3fzukpy08cesqjjwns53xywqmaq7xw \
123-r age1pu5usxm743sx7rf22985xv2f4s0luzv6r6yx4fa7p8c2zyvp9fvqus2xr5 \
124-o "$HOME/Location"
125#+END_EXAMPLE
126
127~bklog~ may be instructed via the ~-e~ and ~-R~ options to watch a
128directory in order to locate public key strings in its files. ~bklog~
129reads the first line of each file and interprets it as a public key
130string.
131
132In this example, the strings beginning with ~age1...~ are
133bech32-formatted public key strings. Please see the [[*Key Generation][Key Generation]]
134section for an explanation.
135
136Since ~age~ also accepts ~ssh~ public key strings, these may also be
137used if they are of the following form (no comment).
138
139: ssh-rsa AAAAB3NzaC1yc2EAAAADAQABA…AACAQDLnJbPs7CjwPT+OxXd
140
141***** Decryption Commands
142Files may be decrypted using a command similar to:
143
144#+BEGIN_EXAMPLE
145cat location.gpx.age | age -d -i key.txt > location.gpx
146#+END_EXAMPLE
147
148The version of ~age~ used to perform the encryption
149
150** Operating Procedures
151*** Initial Startup
152See OEM (Ozzmaker) [[https://ozzmaker.com/berrygps-berrygps-imu-quick-start-guide/][quickstart guide for the BerryGPS-IMU]].
153
154**** Physical Setup
155
156BerryGPS-IMU must be electrically connected to the correct pins on the
157GPIO header of a Raspberry Pi Zero W.
158
159*Optional*: stack together with PiZ Uptime 2.0 module. No GPIO pins
160conflict so a simple stacking and soldering with long header pins is
161possible.
162
163**** Software Setup
164***** Install Executables
165
166Install Raspbian 10 Buster onto an SD card image. See the Raspberry Pi
167Foundation [[https://www.raspberrypi.org/documentation/installation/installing-images/README.md][installation instructions]]. Configure WiFi to permit log
168file transfer. Configure SSH to permit remote administration via the
169command line interface.
170
171Make sure to install the ~unattended-upgrades~ package to make sure
172the latest security patches for packages are installed. See [[https://linux-audit.com/using-unattended-upgrades-on-debian-and-ubuntu/][this page]]
173for a description of how ~unattended-upgrades~ works.
174
175Install ~gpsd~, ~gpspipe~, ~git~, and this repository for location
176logging capability.
177
178Install ~syncthing~ for log file transfer capability.
179
180Place ~age~ binary (the one compiled for ARM CPU architecture for
181Linux) in ~$HOME/.local/bin~.
182
183***** Disable Swap File
184Since standard Raspbian 10 (Buster) install involves copying
185unencrypted file system image to SD card which is mounted by the
186Raspberry Pi, system memory may be written to disk in the form of a
187Swap file as described [[https://ideaheap.com/2013/07/stopping-sd-card-corruption-on-a-raspberry-pi/][here]]. In order to reduce the chance that
188location log data is ever written to disk, swap file functionality
189must be disabled[fn:ideaheap_20130731_disableswap].
190
191Raspbian 10 uses dphys-swapfile to manage a swap file. It may be
192disabled persistently[fn:rpf_20190702_disableswappersist] by running
193the following command:
194
195: sudo systemctl disable dphys-swapfile.service
196
197To view the status of the swap file in Raspbian 10, run ~free -m~:
198
199#+BEGIN_EXAMPLE
200pi@ninfacyzga-01:~$ free -m
201 total used free shared buff/cache available
202Mem: 432 86 36 21 309 268
203Swap: 99 0 99
204#+END_EXAMPLE
205
206After disabling the swap file and rebooting:
207
208#+BEGIN_EXAMPLE
209pi@ninfacyzga-01:~$ free -m
210 total used free shared buff/cache available
211Mem: 432 89 214 3 128 289
212Swap: 0 0 0
213#+END_EXAMPLE
214
215[fn:ideaheap_20130731_disableswap] Explanation:
216https://ideaheap.com/2013/07/stopping-sd-card-corruption-on-a-raspberry-pi/
217
218[fn:rpf_20190702_disableswappersist] Persistant disabling of swap in
219Raspbian 10 Buster:
220https://www.raspberrypi.org/forums/viewtopic.php?p=1490692&sid=5c596a124b7805d6b10dab8d3d7caf16#p1490692
221
222***** Automatic Start Configuration
223
224It is recommended to create a daily ~cron~ job that executes a bash
225script that starts ~bklog~ jobs to record location along with other
226types of data recording. An example of such a script is below:
227
228#+BEGIN_EXAMPLE
229#!/bin/bash
230
231# Log location
232gpspipe -r | /bin/bash "$HOME/.local/bin/bklog" -c -e -z "UTC" -t "/dev/shm" \
233 -r age1kza7pfshy7xwygf9349zgmk7x53mquvedgw9r98qwyyqhssh830qqjzlsw \
234 -r age1ce3pvzrqfcn2pc6zqzglc8ac8yjk3fzukpy08cesqjjwns53xywqmaq7xw \
235 -R "$HOME/.config/bklog/recipients" -w ".nmea" -b "300" -B "day" \
236 -o "$HOME/Sync/Evanescent_Location" -l "location" \
237 -p "gpsbabel -i nmea -f - -o gpx -F - " ".gpx" \
238 -p "gpsbabel -i nmea -f - -o kml -F - " ".kml" &
239# Log pressure
240python ~/.local/bin/bmp388.py | /bin/bash "$HOME/git-OC/ninfacyzga-01/exec/bklog" \
241 -c -e -z "UTC" -t "/dev/shm" \
242 -r age1kza7pfshy7xwygf9349zgmk7x53mquvedgw9r98qwyyqhssh830qqjzlsw \
243 -r age1ce3pvzrqfcn2pc6zqzglc8ac8yjk3fzukpy08cesqjjwns53xywqmaq7xw \
244 -R "$HOME/.config/bklog/recipients" -w ".txt" -b "300" -B "day" \
245 -o "$HOME/Sync/Evanescent_Location" -l "pressure" &
246#+END_EXAMPLE
247
248This script, if it were saved at
249~"$HOME/.local/bin/cron/dailylog.sh"~ would then be added as a
250line in the ~crontab~ file as shown below:
251
252#+BEGIN_EXAMPLE
253$ crontab -e
2540 0 * * * /bin/bash ~/.local/bin/cron/dailylog.sh
255@reboot /bin/bash ~/.local/bin/cron/dailylog.sh
256#+END_EXAMPLE
257
258In the example script, the options are:
259
260: -c : tells bklog to compress output
261: -e : tells bklog log to encrypt output
262: -r : tells bklog to interpret the next argument as a pubkey string
263: -R : tells bklog to interpret the next argument as a directory
264: where public keys may be found (first line of each file is
265: read).
266: -o : tells bklog to write output files to the directory represented
267: -t : tells bklog to interpret the next argument as a directory
268: for storing temporary files
269: by the next argument
270: -p : tells bklog a command string through which output is piped
271: before being compressed and encrypted. Also expected is a
272: file extension to be appended before the compression and
273: encryption file extensions.
274: -w : tells bklog to save the unprocessed stdin with a specified
275: file extension (instead of the default '.stdin').
276: -b : tells bklog how long each buffer round (time between file
277: writes) lasts in seconds.
278: -B : specifies the time-to-live for the bklog script. A valid value may
279: one of the time elements such as "day" or "hour".
280: -l : specfies a custom string to be used in output file names to
281: help differentiate tar files produced via bklog from different
282: sources of data.
283: -z : specifies a time zone to be used to determine the script time-to-live.
284: By default, bklog uses whatever time is specified by the TZ
285: environment variable.
286
287***** Log Transfer Configuration
288Log files may be shared to other machines via ~syncthing~. See [[https://docs.syncthing.net/][this]]
289manual for how to set up a shared folder and add Ninfacyzga-01 as a
290device. Syncthing's directory synchronization capability allows a
291remote machine to delete files from Ninfacyzga-01 by deleting from the
292shared folder that they both share.
293
294When log files are removed from Ninfacyzga-01 is not within the scope
295of this document.
296
297***** Key Generation
298An ~age~ encryption key may be generated like so:
299#+BEGIN_EXAMPLE
300$ umask # Gets current umask
3010022 # Note: This is the default umask for Raspbian 10
302$ umask 066 # So key.txt will have no perms except for owner (you)
303$ umask # Confirm umask set to 066
3040066
305$ age-keygen > key.txt
306Public key: age1pu5usxm743sx7rf22985xv2f4s0luzv6r6yx4fa7p8c2zyvp9fvqus2xr5
307$ ls -al key.txt
308-rw------- 1 baltakatei baltakatei 184 Jun 29 18:28 key.txt
309$ umask 0022 # Return umask to default value
310$ umask
3110022
312#+END_EXAMPLE
313
314The resulting public/private keypair data looks like:
315#+BEGIN_EXAMPLE
316$ cat key.txt
317# created: 2020-06-29T18:01:56Z
318# public key: age1pu5usxm743sx7rf22985xv2f4s0luzv6r6yx4fa7p8c2zyvp9fvqus2xr5
319AGE-SECRET-KEY-1NEUU5U2XGZGL9UYWNPU5DL99TGJJHFSN4F2E2WCCSDJJ6L5ZMLESNTVTU0
320#+END_EXAMPLE
321
322The file ~key.txt~ is not password-protected by default and should be
323secured like an SSH public key should. The ~$ umask 066~ command run
324before the ~$ age-keygen > key.txt~ command ensures ~key.txt~ will not
325be readable, writeable, or executable to anyone except the owner
326(you).
327
328*** Normal Startup
329Turn on Ninfacyzga-01 by supplying 5VDC power to the Raspberry Pi. No
330further interaction should be required.
331*** Normal Operation
332No interaction beyond continually supplying approximately 100mA of
3335VDC power and occasionally removing log files to conserve disk space
334is required.
335**** Log Transfer
336Log files may be transferred by use of ~syncthing~ shared folders.
337**** Automatic Updates
338The ~automatic-upgrades~ package, if installed, should automatically
339install security patches to packages installed via ~apt~.
340*** Normal Shutdown
341The system may be shutdown via SSH by running:
342
343: $ sudo shutdown -r 0
344
345*** Unscheduled Shutdown
346Ninfacyzga-01 as described and setup should tolerate unscheduled power
347loss. Log files being written every 60 seconds means, at most, 60
348seconds worth of location data may be lost.
349*** End of Life Disposal
350LiPo batteries used by the PiZ Uptime 2.0 module should be disposed of
351properly with their potential ignitability in mind, especially if they
352are not fully discharged.
353
354Consult your local municipality for its "E-Waste Disposal" (or
355equivalent) policy. Metals used in the Raspberry Pi and related
356components may be recycled.
357
358Take extra precuation if lead solder was used in assembling the
359electronics. Consumer electronics in early 21st century should use
360lead-free solder.