|
1 year ago | |
---|---|---|
.idea | 3 years ago | |
cmd | 2 years ago | |
internal | 2 years ago | |
.gitignore | 2 years ago | |
Dockerfile | 1 year ago | |
LICENSE | 3 years ago | |
Makefile | 1 year ago | |
README.md | 2 years ago | |
SHARES_TODO.txt | 2 years ago | |
go.mod | 2 years ago | |
go.sum | 2 years ago | |
goshawkd.ini.example | 2 years ago | |
goshawkd.service | 2 years ago |
README.md
goshawk
Goshawk is a small fleet management and outdoor tracking project written in Go
Concept
goshawk is a small self-hosted server-based project than keeps track of small self-build trackers and stores the data in a convenient and accessible way on your own server
Requirements
Mission statement: Small, elegant, fast - The server should be able to easily run on a Raspberry pi for years without worrying about.
System requirements
- Webserver: REST-API
- Backend:
- System configuration: Simple configuration file (INI Style)
- System database: SQLite3
- Receiver of location data
- Mosquitto (for owntracks)
- UDP receiver with AES256 encryption
- Via Web-API
- Live-Query
- TCP socket (SSL and non-SSL) with subscribe-pattern ("stream-interface")
Request should be primarily handled via the REST-API. The TCP-Socket serves as observable for live tracking of future applications.
The whole data-storage should be in a single folder to allow easy backup and synchronisation with other servers (for redundancy).
Data requirements
The system is organised around devices. A device is identified via a unique integer id. A device belongs to a single user as owner. A device MUST have an owner (uid) and a name. Devices hold location objects with the following datafields: timestamp, longitude, latitude, altitude, accuracy. Every datafield MUST be set.
A user is identified via a unique integer id, called the uid and carries a unique username that MUST be set. Both, the uid and the username MUST be attributed to a single user. user has also the following attributes, that CAN be set: name, email. user has also a admin flag, that marks a user to be a system manager. System managers are allowed to create and delete users and user tokens, but not to view the data of other users (also not to look at user tokens). username cannot be a number. Currently only alphanumeric characters are allowed for username.
For pushing data to the server, unique access tokens are used. A token is a 256 bit (32 byte) random sequence that is associated to a device id. token has also the fields owner and id, that are also uniquely identifying a token. This double identification is required so system managers can manage user tokens without seeing them. The token value is also used for AES256 en/decryption of data telegrams. A token also has the field state (integer), that allows tokens to be invalidated and not added anymore.
REST-API
The REST-API aims to cover all use-cases. As of now, the REST-API should be the only interface to interact with the goshawk server (except data reception and the stream interface).
Uppercase identifiers in Method indicate variables (e.g. ID stands for the device id in devices/ID). All methods except login/logout require a logged in session.
Method | Description | Action | Parameters | Return |
---|---|---|---|---|
login | Login a user for the Session | GET, POST | username, password | "OK" or "FAIL" |
logout | Logout the session | GET, POST | "OK" | |
devices | Query all devices of user | GET | JSON: Devices array | |
Query a specific device of user | GET | id | JSON: Devices array | |
Create a new device | POST | name | id | |
Update device info | PUT | id, name, owner name and owner are optional | "OK" | |
Delete device | DELETE | id | "OK" | |
devices/ID | Query a specific device of user | GET | JSON: Device | |
Update device info | PUT | id, name, owner name and owner are optional | "OK" | |
users | Get all users in the system | GET | JSON: User array | |
user | Get user information | GET | JSON: User | |
Get user information | GET | uid or username | JSON: User | |
Update user information | PUT | uid, name, email name and email are optional | "OK" | |
Create new user | POST | uid, name, email uid is optional | uid | |
Delete a user | DELETE | uid | "OK" | |
user/NAME | Get user information | GET | JSON: User | |
Update user information | PUT | name, email name and email are optional | "OK" | |
Delete a user | DELETE | "OK" | ||
devices/ID/locations | Get device locations stats | GET | JSON: Location stats (tmin, tmax, count) | |
devices/ID/location | Get device locations | GET | tmin, tmax, limit, offset all parameters are optional | JSON: Locations array |
Insert a device location | POST | timestamp, lon, lat, alt, acc timestamp is optional | "OK" | |
Update a existing device location | PUT | timestamp, lon, lat, alt, acc | "OK" | |
Delete a location point | DELETE | timestamp | "OK" | |
devices/ID/tokens | Get device tokens | GET | showtoken is a optional boolean, defaults to false | JSON: Device tokens |
Create new device token | POST | JSON: Device token | ||
Edit a device token | PUT | id, owner, state owner is optional and assumes the current user | "OK" | |
Delete a device token | DELETE | id, owner | "OK" |
Access is only allowed for own resources, except for system managers.
Receivers
Mosquitto
goshawk is able to interpret owntracks location pushes. Receivers are configured via a listener file.
UDP receiver
goshawk handles incoming UDP location update telegrams. The telegrams look like the following
TOKEN_ID_IV_PAYLOAD # _ will not appear in actual datagram
TOKEN_ID defines the token id (as 8 digit string), where the telegram belongs to. PAYLOAD is then encrypted with the corresponding token of the given token object and looks like the following (if successfully decrypted). IV is the initialisation vector for the given object, consisting of 16 bytes
OK_TIMESTAMP_LON_LAT_ALT_ACC # _ will not appear in actual payload
OK is a two char string "OK" # Magic to recognise successful decryption
TIMESTAMP is a 8 byte long value
LON is a 4 byte floating point value
LAT is a 4 byte floating point value
ALT is a 4 byte floating point value
ACC is a 4 byte floating point value
In total 22 bytes payload
In total we have 46 bytes, consisting of 8 bytes (token_id) + 16 bytes (IV) + 22 bytes (payload).
In order to prevent REPLAY attacks, already inserted locations cannot be updated by the UDP receiver.
Software
Requirements
go (>= v 1.9?)
github.com/mattn/go-sqlite3
golang.org/x/crypto/bcrypt
github.com/eclipse/paho.mqtt.golang
gopkg.in/ini.v1
github.com/gorilla/mux
github.com/gorilla/sessions
golang.org/x/crypto/ssh/terminal
Building
make