From 4cdb687f73f850cdbc3f77b93f7e8cf1dde267bb Mon Sep 17 00:00:00 2001 From: Steven Baltakatei Sandoval Date: Fri, 16 Oct 2020 22:44:59 +0000 Subject: [PATCH] chore(doc/location):Remove old exported README cruft --- doc/location/README.html | 799 --------------------------------------- doc/location/README.odt | Bin 16345 -> 0 bytes 2 files changed, 799 deletions(-) delete mode 100644 doc/location/README.html delete mode 100644 doc/location/README.odt diff --git a/doc/location/README.html b/doc/location/README.html deleted file mode 100644 index 69a4789..0000000 --- a/doc/location/README.html +++ /dev/null @@ -1,799 +0,0 @@ - - - - - - - -Ninfacyzga-01 Manual - - - - - - -
-

Ninfacyzga-01 Manual

- -
-

1 Location Logging

-
-

-This document was created by Steven Baltakatei Sandoval on -2020-06-29T12:14Z under a Creative Commons BY-SA 4.0 license. It -was updated by Steven Baltakatei Sandoval on 2020-06-30T19:44Z -

-
-
-

1.1 Narrative

-
-

-Ninfacyzga-01 records (logs) its position in time and space using a -GPS receiver. The NMEA location data produced by the receiver is -converted into the more commonly used GPS data storage formats of GPX -and KML. All three types of data are then compressed and encrypted -against a set of public keys. The encrypted data is then written to -disk. Data produced by the receiver is segmented into 60-second chunks -before being processed and written to disk. -

-
-
-
-

1.2 Description

-
-
-
-

1.2.1 Hardware

-
-
-
    -
  1. Raspberry Pi Zero W
    -
    -

    -See the OEM webpage for this product. -

    -
    -
  2. -
  3. PiZ UpTime 2.0
    -
    -

    -See the OEM webpage for this product. -

    -
    -
  4. -
-
-
-

1.2.2 Software

-
-

-bkgpslog : The bash script that performs the location data -collection and processing. Is an executable file contained within this -repository at exec/bkgpslog. It should be copied to -$HOME/.local/bin. -

- -

-gpsd : A background daemon app capable of interfacing with the -Ozzmaker BerryGPS-IMU's GPS submodule. Installed and initialized by -apt. -

- -

-gpspipe : A command line app that polls gpsd and produces a stream -stdout consisting of GPS data lines in NMEA format. Installed via -apt. -

- -

-gpsbabel : A command line app that converts GPS data from one format -into another. bkgpslog uses it to convert NMEA data into GPX and -KML. Installed via apt. -

- -

-gzip : A simple command line app that compresses stdin into a -smaller stdout stream. -

- -

-age : A simple command line app that encrypts stdin against public -keys specified in its options. Produces encrypted stdout. Is an -executable file contained within this repository at exec/age. It -should be copied to $HOME/.local/bin. -

-
- -
    -
  1. Narrative
    -
    -

    -bkgpslog populates a 60-second buffer with NMEA data from gpsd via -gpspipe. This buffer is used by gpsbabel to produce GPX and KML -versions of the buffer. All 3 buffers are then comprssed with gzip, -encrypted with age, and then written to disk. -

    -
    -
  2. -
-
- -
-

1.2.3 Output

-
-
-
    -
  1. File Formats
    -
      -
    1. NMEA
      -
      -

      -See the Wikipedia page for this. -

      -
      -
    2. -
    3. GPX
      -
      -

      -See the Wikipedia page for this. WGS84 is the datum used. -

      -
      -
    4. -
    5. KML
      -
      -

      -See the Wikipedia page for this. WGS84 is the datum used. -

      -
      -
    6. -
    -
  2. -
  3. Encryption Method
    -
    -

    -Files produced by the bkgpslog script are encrypted against a set of -public keys using age, a simple command line encryption tool -selected over gpg because of age's deliberate lack of -configurability. -

    - -

    -The public keys are bech32 strings supplied as options to bkgpslog -when called. The secret key should NOT be stored in Ninfacyzga-01. -

    - -

    -If a key pair was generated using age-keygen, then it is an X25519 -key pair. See the age Version 1 specification. -

    - -

    -An ssh-rsa or ssh-ed25519 SSH public key string may be used instead of -the bech32 public key string produced by age-keygen for convenience. -

    - -

    -Help information for age is available by running $ age --help. -

    -
    -
      -
    1. Encryption Commands
      -
      -

      -Files may be encrypted to several recipients using a command similar to: -

      -
      -timeout "60s" gpspipe -r | gpsbabel -i nmea -f - -o gpx -F | age \
      --r age1kza7pfshy7xwygf9349zgmk7x53mquvedgw9r98qwyyqhssh830qqjzlsw \
      --r age1ce3pvzrqfcn2pc6zqzglc8ac8yjk3fzukpy08cesqjjwns53xywqmaq7xw \
      --r age1pu5usxm743sx7rf22985xv2f4s0luzv6r6yx4fa7p8c2zyvp9fvqus2xr5 \
      -> location.gpx.age
      -
      - -

      -In this example, the strings beginning with age1... are -bech32-formatted public key strings. -

      -
      -
    2. - - -
    3. Decryption Commands
      -
      -

      -Files may be decrypted using a command similar to: -

      - -
      -cat location.gpx.age | age -d -i key.txt > location.gpx
      -
      - -

      -The version of age used to perform the encryption -

      -
      -
    4. -
    -
  4. -
-
-
-
-

1.3 Operating Procedures

-
-
-
-

1.3.1 Initial Startup

-
-

-See OEM (Ozzmaker) quickstart guide for the BerryGPS-IMU. -

-
- -
    -
  1. Physical Setup
    -
    -

    -BerryGPS-IMU must be electrically connected to the correct pins on the -GPIO header of a Raspberry Pi Zero W. -

    - -

    -Optional: stack together with PiZ Uptime 2.0 module. No GPIO pins -conflict so a simple stacking and soldering with long header pins is -possible. -

    -
    -
  2. - -
  3. Software Setup
    -
      -
    1. Install Executables
      -
      -

      -Install Raspbian 10 Buster onto an SD card image. See the Raspberry Pi -Foundation installation instructions. Configure WiFi to permit log -file transfer. Configure SSH to permit remote administration via the -command line interface. -

      - -

      -Make sure to install the unattended-upgrades package to make sure -the latest security patches for packages are installed. See this page -for a description of how unattended-upgrades works. -

      - -

      -Install gpsd, gpspipe, git, and this repository for location -logging capability. -

      - -

      -Install syncthing for log file transfer capability. -

      - -

      -Place age binary (the one compiled for ARM CPU architecture for -Linux) in $HOME/.local/bin. -

      -
      -
    2. - -
    3. Disable Swap File
      -
      -

      -Since standard Raspbian 10 (Buster) install involves copying -unencrypted file system image to SD card which is mounted by the -Raspberry Pi, system memory may be written to disk in the form of a -Swap file as described here. In order to reduce the chance that -location log data is ever written to disk, swap file functionality -must be disabled1. -

      - -

      -Raspbian 10 uses dphys-swapfile to manage a swap file. It may be -disabled persistently2 by running -the following command: -

      - -
      -sudo systemctl disable dphys-swapfile.service
      -
      -
      - -

      -To view the status of the swap file in Raspbian 10, run free -m: -

      - -
      -pi@ninfacyzga-01:~$ free -m
      -          total    used    free  shared  buff/cache   available
      -Mem:        432      86      36      21         309         268
      -Swap:        99       0      99
      -
      - -

      -After disabling the swap file and rebooting: -

      - -
      -pi@ninfacyzga-01:~$ free -m
      -          total    used    free  shared  buff/cache   available
      -Mem:        432      89     214       3         128         289
      -Swap:         0       0       0
      -
      -
      -
    4. - -
    5. Automatic Start Configuration
      -
      -

      -Edit the user cron job list with $ crontab -e to add the following -lines: -

      - -
      -0 * * * * /bin/bash ~/bkgpslog --output ~/dir
      -
      -@reboot /bin/bash ~/bkgpslog --output ~/dir
      -
      - -

      -The first line will run bkgpslog at the start of every hour and save -output files to the dir directory in your home folder. -

      - -

      -The second line will run bkgpslog when the system starts up. -

      - -

      -/bin/bash tells cron to run bkgpslog with Bash. -

      - -

      -If encryption and compression are required, then the appropriate -options must be added. The lines that must be added via $ crontab -e -may resemble: -

      - -
      -0 * * * * /bin/bash ~/bkgpslog -c -e -r age1z2...qkv6p -o ~/dir
      -
      -@reboot /bin/bash ~/bkgpslog -c -e -r age1z2...qkv6p -o ~/dir
      -
      - -

      -The age1z2...qkv6p is an age public key string. Please see the -Key Generation section for an explanation. -

      - -

      -The options are: -

      - -
      --c : tells bkgpslog to compress output
      --e : tells bkgpslog log to encrypt output
      --r : tells bkgpslog to interpret the next argument as a pubkey string
      --o : tells bkgpslog to write output files to the directory represented
      -       by the next argument
      -
      -
      -
      -
    6. - -
    7. Log Transfer Configuration
      -
      -

      -Log files may be shared to other machines via syncthing. See this -manual for how to set up a shared folder and add Ninfacyzga-01 as a -device. Syncthing's directory synchronization capability allows a -remote machine to delete files from Ninfacyzga-01 by deleting from the -shared folder that they both share. -

      - -

      -When log files are removed from Ninfacyzga-01 is not within the scope -of this document. -

      -
      -
    8. - -
    9. Key Generation
      -
      -

      -An age encryption key may be generated like so: -

      -
      -$ umask          # Gets current umask
      -0022             # Note: This is the default umask for Raspbian 10
      -$ umask 066      # So key.txt will have no perms except for owner (you)
      -$ umask          # Confirm umask set to 066
      -0066
      -$ age-keygen > key.txt
      -Public key: age1pu5usxm743sx7rf22985xv2f4s0luzv6r6yx4fa7p8c2zyvp9fvqus2xr5
      -$ ls -al key.txt
      --rw------- 1 baltakatei baltakatei 184 Jun 29 18:28 key.txt
      -$ umask 0022     # Return umask to default value
      -$ umask          
      -0022
      -
      - -

      -The resulting public/private keypair data looks like: -

      -
      -$ cat key.txt
      -# created: 2020-06-29T18:01:56Z
      -# public key: age1pu5usxm743sx7rf22985xv2f4s0luzv6r6yx4fa7p8c2zyvp9fvqus2xr5
      -AGE-SECRET-KEY-1NEUU5U2XGZGL9UYWNPU5DL99TGJJHFSN4F2E2WCCSDJJ6L5ZMLESNTVTU0
      -
      - -

      -The file key.txt is not password-protected by default and should be -secured like an SSH public key should. The $ umask 066 command run -before the $ age-keygen > key.txt command ensures key.txt will not -be readable, writeable, or executable to anyone except the owner -(you). -

      -
      -
    10. -
    -
  4. -
-
- -
-

1.3.2 Normal Startup

-
-

-Turn on Ninfacyzga-01 by supplying 5VDC power to the Raspberry Pi. No -further interaction should be required. -

-
-
-
-

1.3.3 Normal Operation

-
-

-No interaction beyond continually supplying approximately 100mA of -5VDC power and occasionally removing log files to conserve disk space -is required. -

-
-
    -
  1. Log Transfer
    -
    -

    -Log files may be transferred by use of syncthing shared folders. -

    -
    -
  2. -
  3. Automatic Updates
    -
    -

    -The automatic-upgrades package, if installed, should automatically -install security patches to packages installed via apt. -

    -
    -
  4. -
-
-
-

1.3.4 Normal Shutdown

-
-

-The system may be shutdown via SSH by running: -

- -
-$ sudo shutdown -r 0
-
-
-
-
- -
-

1.3.5 Unscheduled Shutdown

-
-

-Ninfacyzga-01 as described and setup should tolerate unscheduled power -loss. Log files being written every 60 seconds means, at most, 60 -seconds worth of location data may be lost. -

-
-
-
-

1.3.6 End of Life Disposal

-
-

-LiPo batteries used by the PiZ Uptime 2.0 module should be disposed of -properly with their potential ignitability in mind, especially if they -are not fully discharged. -

- -

-Consult your local municipality for its "E-Waste Disposal" (or -equivalent) policy. Metals used in the Raspberry Pi and related -components may be recycled. -

- -

-Take extra precuation if lead solder was used in assembling the -electronics. Consumer electronics in early 21st century should use -lead-free solder. -

-
-
-
-
-
-
-

Author: Steven Baltakatei Sandoval

-

Created: 2020-06-30 Tue 19:45

-

Validate

-
- - diff --git a/doc/location/README.odt b/doc/location/README.odt deleted file mode 100644 index 43483169031e6430f002b9ea2478f0a11fa2ad67..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16345 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