fix(bkgpslog):Move chunk cleanup into magicWriteBuffer func
[EVA-2020-02.git] / doc / location / README.org
1 * Location Logging
2 This 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
4 was updated by Steven Baltakatei Sandoval on ~2020-06-30T19:44Z~
5 #+TITLE: Ninfacyzga-01 Manual
6 #+AUTHOR: Steven Baltakatei Sandoval
7 #+EMAIL: baltakatei@gmail.com
8 ** Narrative
9 Ninfacyzga-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
11 converted into the more commonly used GPS data storage formats of GPX
12 and KML. All three types of data are then compressed and encrypted
13 against a set of public keys. The encrypted data is then written to
14 disk. Data produced by the receiver is segmented into 60-second chunks
15 before being processed and written to disk.
16 ** Description
17 *** Hardware
18 **** Raspberry Pi Zero W
19 See the [[https://www.raspberrypi.org/pi-zero-w/][OEM]] webpage for this product.
20 **** PiZ UpTime 2.0
21 See the [[https://alchemy-power.com/piz-uptime-2-0/][OEM]] webpage for this product.
22 *** Software
23 ~bkgpslog~ : The bash script that performs the location data
24 collection and processing. Is an executable file contained within this
25 repository at ~exec/bkgpslog~. It should be copied to
26 ~$HOME/.local/bin~.
27
28 ~gpsd~ : A background daemon app capable of interfacing with the
29 Ozzmaker BerryGPS-IMU's GPS submodule. Installed and initialized by
30 ~apt~.
31
32 ~gpspipe~ : A command line app that polls ~gpsd~ and produces a stream
33 stdout consisting of GPS data lines in NMEA format. Installed via
34 ~apt~.
35
36 ~gpsbabel~ : A command line app that converts GPS data from one format
37 into another. ~bkgpslog~ uses it to convert NMEA data into GPX and
38 KML. Installed via ~apt~.
39
40 ~gzip~ : A simple command line app that compresses stdin into a
41 smaller stdout stream.
42
43 ~age~ : A simple command line app that encrypts stdin against public
44 keys specified in its options. Produces encrypted stdout. Is an
45 executable file contained within this repository at ~exec/age~. It
46 should be copied to ~$HOME/.local/bin~.
47
48 **** Narrative
49 ~bkgpslog~ populates a 60-second buffer with NMEA data from ~gpsd~ via
50 ~gpspipe~. This buffer is used by ~gpsbabel~ to produce GPX and KML
51 versions of the buffer. All 3 buffers are then comprssed with ~gzip~,
52 encrypted with ~age~, and then written to disk.
53
54 *** Output
55 **** File Formats
56 ***** NMEA
57 See the [[https://en.wikipedia.org/wiki/NMEA_0183][Wikipedia page]] for this.
58 ***** GPX
59 See 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.
60 ***** KML
61 See 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.
62 **** Encryption Method
63 Files produced by the bkgpslog script are encrypted against a set of
64 public keys using [[https://github.com/FiloSottile/age][~age~]], a simple command line encryption tool
65 selected over ~gpg~ because of ~age~'s deliberate lack of
66 configurability.
67
68 The public keys are bech32 strings supplied as options to bkgpslog
69 when called. The secret key should *NOT* be stored in Ninfacyzga-01.
70
71 If a key pair was generated using ~age-keygen~, then it is an [[https://en.wikipedia.org/wiki/Curve25519][~X25519~]]
72 key pair. See the [[https://age-encryption.org/v1][~age~ Version 1 specification]].
73
74 An ~ssh-rsa~ or ~ssh-ed25519~ SSH public key string may be used instead of
75 the bech32 public key string produced by ~age-keygen~ for convenience.
76
77 Help information for ~age~ is available by running ~$ age --help~.
78 ***** Encryption Commands
79 Files may be encrypted to several recipients using a command similar to:
80 #+BEGIN_EXAMPLE
81 timeout "60s" gpspipe -r | gpsbabel -i nmea -f - -o gpx -F | age \
82 -r age1kza7pfshy7xwygf9349zgmk7x53mquvedgw9r98qwyyqhssh830qqjzlsw \
83 -r age1ce3pvzrqfcn2pc6zqzglc8ac8yjk3fzukpy08cesqjjwns53xywqmaq7xw \
84 -r age1pu5usxm743sx7rf22985xv2f4s0luzv6r6yx4fa7p8c2zyvp9fvqus2xr5 \
85 > location.gpx.age
86 #+END_EXAMPLE
87
88 In this example, the strings beginning with ~age1...~ are
89 bech32-formatted public key strings.
90
91
92 ***** Decryption Commands
93 Files may be decrypted using a command similar to:
94
95 #+BEGIN_EXAMPLE
96 cat location.gpx.age | age -d -i key.txt > location.gpx
97 #+END_EXAMPLE
98
99 The version of ~age~ used to perform the encryption
100 ** Operating Procedures
101 *** Initial Startup
102 See OEM (Ozzmaker) [[https://ozzmaker.com/berrygps-berrygps-imu-quick-start-guide/][quickstart guide for the BerryGPS-IMU]].
103
104 **** Physical Setup
105
106 BerryGPS-IMU must be electrically connected to the correct pins on the
107 GPIO header of a Raspberry Pi Zero W.
108
109 *Optional*: stack together with PiZ Uptime 2.0 module. No GPIO pins
110 conflict so a simple stacking and soldering with long header pins is
111 possible.
112
113 **** Software Setup
114 ***** Install Executables
115
116 Install Raspbian 10 Buster onto an SD card image. See the Raspberry Pi
117 Foundation [[https://www.raspberrypi.org/documentation/installation/installing-images/README.md][installation instructions]]. Configure WiFi to permit log
118 file transfer. Configure SSH to permit remote administration via the
119 command line interface.
120
121 Make sure to install the ~unattended-upgrades~ package to make sure
122 the latest security patches for packages are installed. See [[https://linux-audit.com/using-unattended-upgrades-on-debian-and-ubuntu/][this page]]
123 for a description of how ~unattended-upgrades~ works.
124
125 Install ~gpsd~, ~gpspipe~, ~git~, and this repository for location
126 logging capability.
127
128 Install ~syncthing~ for log file transfer capability.
129
130 Place ~age~ binary (the one compiled for ARM CPU architecture for
131 Linux) in ~$HOME/.local/bin~.
132
133 ***** Disable Swap File
134 Since standard Raspbian 10 (Buster) install involves copying
135 unencrypted file system image to SD card which is mounted by the
136 Raspberry Pi, system memory may be written to disk in the form of a
137 Swap file as described [[https://ideaheap.com/2013/07/stopping-sd-card-corruption-on-a-raspberry-pi/][here]]. In order to reduce the chance that
138 location log data is ever written to disk, swap file functionality
139 must be disabled[fn:ideaheap_20130731_disableswap].
140
141 Raspbian 10 uses dphys-swapfile to manage a swap file. It may be
142 disabled persistently[fn:rpf_20190702_disableswappersist] by running
143 the following command:
144
145 : sudo systemctl disable dphys-swapfile.service
146
147 To view the status of the swap file in Raspbian 10, run ~free -m~:
148
149 #+BEGIN_EXAMPLE
150 pi@ninfacyzga-01:~$ free -m
151 total used free shared buff/cache available
152 Mem: 432 86 36 21 309 268
153 Swap: 99 0 99
154 #+END_EXAMPLE
155
156 After disabling the swap file and rebooting:
157
158 #+BEGIN_EXAMPLE
159 pi@ninfacyzga-01:~$ free -m
160 total used free shared buff/cache available
161 Mem: 432 89 214 3 128 289
162 Swap: 0 0 0
163 #+END_EXAMPLE
164
165 [fn:ideaheap_20130731_disableswap] Explanation:
166 https://ideaheap.com/2013/07/stopping-sd-card-corruption-on-a-raspberry-pi/
167
168 [fn:rpf_20190702_disableswappersist] Persistant disabling of swap in
169 Raspbian 10 Buster:
170 https://www.raspberrypi.org/forums/viewtopic.php?p=1490692&sid=5c596a124b7805d6b10dab8d3d7caf16#p1490692
171
172 ***** Automatic Start Configuration
173
174 Edit the user cron job list with ~$ crontab -e~ to add the following
175 lines:
176
177 #+BEGIN_EXAMPLE
178 0 * * * * /bin/bash ~/bkgpslog --output ~/dir
179
180 @reboot /bin/bash ~/bkgpslog --output ~/dir
181 #+END_EXAMPLE
182
183 The first line will run ~bkgpslog~ at the start of every hour and save
184 output files to the ~dir~ directory in your home folder.
185
186 The second line will run ~bkgpslog~ when the system starts up.
187
188 ~/bin/bash~ tells ~cron~ to run ~bkgpslog~ with Bash.
189
190 If encryption and compression are required, then the appropriate
191 options must be added. The lines that must be added via ~$ crontab -e~
192 may resemble:
193
194 #+BEGIN_EXAMPLE
195 0 * * * * /bin/bash ~/bkgpslog -c -e -r age1z2...qkv6p -o ~/dir
196
197 @reboot /bin/bash ~/bkgpslog -c -e -r age1z2...qkv6p -o ~/dir
198 #+END_EXAMPLE
199
200 The ~age1z2...qkv6p~ is an ~age~ public key string. Please see the
201 [[*Key Generation][Key Generation]] section for an explanation.
202
203 The options are:
204
205 : -c : tells bkgpslog to compress output
206 : -e : tells bkgpslog log to encrypt output
207 : -r : tells bkgpslog to interpret the next argument as a pubkey string
208 : -o : tells bkgpslog to write output files to the directory represented
209 : by the next argument
210
211 ***** Log Transfer Configuration
212 Log files may be shared to other machines via ~syncthing~. See [[https://docs.syncthing.net/][this]]
213 manual for how to set up a shared folder and add Ninfacyzga-01 as a
214 device. Syncthing's directory synchronization capability allows a
215 remote machine to delete files from Ninfacyzga-01 by deleting from the
216 shared folder that they both share.
217
218 When log files are removed from Ninfacyzga-01 is not within the scope
219 of this document.
220
221 ***** Key Generation
222 An ~age~ encryption key may be generated like so:
223 #+BEGIN_EXAMPLE
224 $ umask # Gets current umask
225 0022 # Note: This is the default umask for Raspbian 10
226 $ umask 066 # So key.txt will have no perms except for owner (you)
227 $ umask # Confirm umask set to 066
228 0066
229 $ age-keygen > key.txt
230 Public key: age1pu5usxm743sx7rf22985xv2f4s0luzv6r6yx4fa7p8c2zyvp9fvqus2xr5
231 $ ls -al key.txt
232 -rw------- 1 baltakatei baltakatei 184 Jun 29 18:28 key.txt
233 $ umask 0022 # Return umask to default value
234 $ umask
235 0022
236 #+END_EXAMPLE
237
238 The resulting public/private keypair data looks like:
239 #+BEGIN_EXAMPLE
240 $ cat key.txt
241 # created: 2020-06-29T18:01:56Z
242 # public key: age1pu5usxm743sx7rf22985xv2f4s0luzv6r6yx4fa7p8c2zyvp9fvqus2xr5
243 AGE-SECRET-KEY-1NEUU5U2XGZGL9UYWNPU5DL99TGJJHFSN4F2E2WCCSDJJ6L5ZMLESNTVTU0
244 #+END_EXAMPLE
245
246 The file ~key.txt~ is not password-protected by default and should be
247 secured like an SSH public key should. The ~$ umask 066~ command run
248 before the ~$ age-keygen > key.txt~ command ensures ~key.txt~ will not
249 be readable, writeable, or executable to anyone except the owner
250 (you).
251
252 *** Normal Startup
253 Turn on Ninfacyzga-01 by supplying 5VDC power to the Raspberry Pi. No
254 further interaction should be required.
255 *** Normal Operation
256 No interaction beyond continually supplying approximately 100mA of
257 5VDC power and occasionally removing log files to conserve disk space
258 is required.
259 **** Log Transfer
260 Log files may be transferred by use of ~syncthing~ shared folders.
261 **** Automatic Updates
262 The ~automatic-upgrades~ package, if installed, should automatically
263 install security patches to packages installed via ~apt~.
264 *** Normal Shutdown
265 The system may be shutdown via SSH by running:
266
267 : $ sudo shutdown -r 0
268
269 *** Unscheduled Shutdown
270 Ninfacyzga-01 as described and setup should tolerate unscheduled power
271 loss. Log files being written every 60 seconds means, at most, 60
272 seconds worth of location data may be lost.
273 *** End of Life Disposal
274 LiPo batteries used by the PiZ Uptime 2.0 module should be disposed of
275 properly with their potential ignitability in mind, especially if they
276 are not fully discharged.
277
278 Consult your local municipality for its "E-Waste Disposal" (or
279 equivalent) policy. Metals used in the Raspberry Pi and related
280 components may be recycled.
281
282 Take extra precuation if lead solder was used in assembling the
283 electronics. Consumer electronics in early 21st century should use
284 lead-free solder.
285