OwnTracks Encrypted Location Node-RED Node

OwnTracks Logo
OwnTracks Logo

At the weekend I ran the London Marathon, while I’m glad I did it, I have no desire to do it again (ask me again in 6 months).

My folks came down to watch me and to help them work out where on the course I was I ran with a phone strapped to my arm running OwnTracks. This was pointing at the semi public broker running on my machine on the end of my broadband. In order to keep some degree of privacy I had enabled the symmetric encryption facility.

As well as my family using the data I had run up a very simple logging script with the mosquitto_sub command to record my progress (I was also tracking it with my Garmin watch, but wanted to see how Owntracks did in comparison).

# mosquitto_sub -t 'owntracks/Ben/#' > track.log

Before I started I hadn’t looked at what sort of encryption was being used, but a little bit of digging in the src and a pointer in the right direction from Jan-Piet Mens got me to the libsodium library. I found a nodejs implementation on npm and hacked up a quick little script to decode the messages.

var readline = require('readline').createInterface({
  input: require('fs').createReadStream('track.json')
});

var sodium = require('libsodium-wrappers');

var StringDecoder = require('string_decoder').StringDecoder;
var decoder = new StringDecoder('utf8');

readline.on('line',function(line){
  var msg = JSON.parse(line);
  if (msg._type == 'encrypted') {
    var cypherText = new Buffer(msg.data, 'base64');
    var nonce = cypherText.slice(0,24);
    var key = new Buffer(32);
    key.fill(0);
    key.write('xxx');
    var clearText = sodium.crypto_secretbox_open_easy(cypherText.slice(24),nonce,key,"text");
    console.log(clearText);
  }
});

Now I had the method worked out it made sense to turn it into a Node-RED node so encrypted location streams could easily be consumed. I also added a little extra functionality, it copied the lat & lon values into a msg.location objects so they can easily be consumed by my node-red-node-geofence node and Dave’s worldmap node. The original decrypted location is left in the msg.payload field.

Owntracks node

The source for the node can be found on github here and the package is on npm here.

To install run the following in your ~/.node-red

npm install node-red-contrib-owntracks

6 thoughts on “OwnTracks Encrypted Location Node-RED Node”

  1. I think there is an issue with Node-Red and the library JSON node that it ignores underscores, so I needed a quick and dirty function block to rename the _type object.

    var msg1 = {payload: msg.payload.replace(/_/g, “”)};
    return msg1;

    1. Sounds like your incoming JSON is broken, the following works just fine:

      ‘{ “_hello”: “world” }’

      But if you have a problem with the Node-RED JSON node then the Google group or the slack channel are the right place to raise it.

  2. Can you explain the ‘secret key’?

    Where is that in Owntracks on the phone? Or am I misunderstanding something?

    I have MQTT node, OwnTracks node, three Geofence nodes and then sort out my location into four zones using a function node. Injecting Lat and Lon values into the Geofence nodes works fine, I just can’t get the OwnTracks bit sorted.

    1. Under the “Advanced” setting you can specify an Encryption key. This is the secret key that the node uses to decrypt the incoming MQTT messages.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.