November 22, 2016

OwnTracks Part 2: Using Your Location Data

own-tracks-location.jpg

OwnTracks data
The OwnTracks system allows you to track the location of Android or IOS phones, and it places a huge focus on data ownership. In this article, we look at some clients that can be used with the collected data.

The OwnTracks system allows you to track the location of Android or IOS phones, and it places a huge focus on data ownership. You get to decide where your location data is sent and what is done with it. In the previous article of the series, we looked at how to install OwnTracks on a phone and set up a personal MQTT server that collects the location data. This time around, we'll take a look at some of the clients that can be used with the collected location data.

We have already seen a very basic client for our OwnTracks location information by using mosquitto_sub to test that location data is getting through. We will now look at how to set a nice icon for users in the OwnTracks app, take a look at firewall rules to allow MQTT traffic to pass, and then look at the OwnTracks recorder client.

Setting an icon

One of the simplest OwnTracks clients lets you set an icon for each user on your server. Below I am using the image2card.sh script to publish a little headshot for my OwnTracks icon. Just as in the first article, I need to specify the user to publish as, the password, and the certificate of the local CA that I used to set up my mosquitto MQTT server. Notice that my phone is publishing messages on owntracks/ben/g5, and I set the JSON-encoded icon by sending a retained message to owntracks/ben/g5/info. The image I want to use is called ben-headshot.jpg, and I'll describe the user just as "Ben".


$ git clone https://github.com/owntracks/recorder.git
$ ln -s recorder/contrib/faces/image2card.sh .

$ ./image2card.sh  ben-headshot.jpg "Ben"  >| card.json
$ mosquitto_pub -t owntracks/ben/g5/info -f card.json -r -u USERNAME  -P PASSWORD -p 8883  --cafile /etc/mosquitto/conf.d/ca.crt

If you don't know the exact topic that OwnTracks is using to publish your data, use the below mosquitto subscribe command to print each MQTT message that goes through your server. Grab your phone and tap the little upward-pointing arrow (upload) in the OwnTracks app to generate a new MQTT message and see it arrive on the console:


$ mosquitto_sub -v -t '#' -u USERNAME  -P PASSWORD -p 8883  --cafile /etc/mosquitto/conf.d/ca.crt

Firewall rules

If you are running a local MQTT server, then you will want to allow Internet traffic to connect to it using TLS, the default port is 8883. Then OwnTracks can connect over TLS to your server and send the location data. So nobody on the Internet gets to snoop on your location data between OwnTracks and your MQTT server.

If the MQTT server is not on your Internet gateway machine, then you will want to do some Destination Network Address Translation (DNAT) on the gateway machine to allow the MQTT server to be reachable from the Internet. The OwnTracks app will be configured to talk to port 8883 on your public IP address and using DNAT the traffic will be forwarded to the MQTT server on your local network. For example, in the following example, the connection is forwarded from the gateway to the MQTT server machine.

 +---------+         +-------------+        +--------------+
 | Phone   |  <----> | gateway     | <----> | MQTT server  |
 | 1.2.3.4 |         | 2.3.4.5     |        |              |
 |         |         | 192.168.1.2 |        | 192.168.1.30 |
 +---------+         +-------------+        +--------------+  

To allow OwnTracks to connect from the Internet you might use something like the following -- assuming that eth0 is the network interface that connects to the Internet.


iptables -t nat -A PREROUTING  -p tcp --dport 8883 -i eth0  -j DNAT --to-destination 192.168.1.30
iptables -I FORWARD -p tcp -i eth0 --dport 8883 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
iptables -I FORWARD -p tcp -i eth0 --sport 8883 -m state --state     ESTABLISHED,RELATED -j ACCEPT

This raises a sticky case when your phone gets back home and connects to WiFi. This is a major problem because you really want your smart house to know when you are home.

When your phone connects to your house WiFi, it will get an IP address on the local network of the house. When OwnTracks tries to connect to the MQTT sevrer on your public IP address 2.3.4.5 it might be able to send a packet to that address and have the packet forwarded to your MQTT server. The reply packet is unlikely to get back however.

The reply will have issues because the MQTT server will see that the packet came from an address on the local network and will try to reply directly to the phone. Unfortunately, the phone is expecting the reply to come from 2.3.4.5 and not 192.168.1.30 so will drop the packet.

The iptables commands below aim to solve the case when the phone is connected at home. They perform the same destination network address translation to divert the packet to the MQTT server. The second command performs a source address translation so that the MQTT server will think that the packet came from your Internet gateway machine rather than directly from the phone. This way, the MQTT server will send the reply to the gateway which will then undo the address translation and send the reply back to the phone. The phone then thinks it is sending data to to 2.3.4.5 and getting a reply from 2.3.4.5 and is happy.


iptables -t nat -A PREROUTING  -p tcp --dport 8883 -d 2.3.4.5 -i eth1 -j DNAT --to-destination 192.168.1.30
iptables -t nat -A POSTROUTING -p tcp --dport 8883 -d 192.168.1.30 -s 192.168.1.0/24  -j SNAT --to 192.168.1.2

iptables -I FORWARD -p tcp -i eth1 --dport 8883 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
iptables -I FORWARD -p tcp -i eth1 --sport 8883 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT

You should make sure you are comfortable with what these iptables commands are doing and that they do not allow more traffic to pass than you are comfortable with. DNAT is a fairly common setup that can be found in many articles, doing both SNAT and DNAT as in the above is harder to find examples of.

Recording the data

The OwnTracks Recorder is a client that can record your location history and present a web interface as shown in Figure 1.

own-tracks-recorder.png

OwnTracks recorder
Figure 1: OwnTracks Recorder.

There are three ways to get OwnTracks Recorder installed, using the packages provided, using the docker image, or compiling from source. There are package repositories for Debian, CentOS, and Raspbian. If Docker is your thing, then the setup is described  here. I'll install by compiling from source to keep installation as widely applicable as possible.

I am installing from source using Debian 8.1 on an Orange Pi. Some instructions list the kernel headers as being required, but I found that they were not needed to compile. Instead of running ./configure, you simply copy the config.mk.in and make adjustments as desired. I left the default options in place to help keep installation simple. After that, the standard make and install completes the installation.


# apt-get install build-essential  libcurl4-openssl-dev libmosquitto-dev liblua5.2-dev libsodium-dev libconfig-dev
$ mkdir ~/src
$ cd ~/src
$ git clone https://github.com/owntracks/recorder.git
$ cd ./recorder
$ cp -av config.mk.in config.mk
$ make
$ sudo make install

Configuration is done by editing a file in /etc as shown below. I made the connection to the local MQTT server over TLS so had to specify the path to the certificate file for the MQTT server used in the first article. Again, starting out with the --debug option is useful to make sure recorder program can connect to the MQTT server properly and will receive data as it comes through. Once you are connected, tap the little upward pointing arrow (upload) in the OwnTracks app on your phone to generate a new MQTT message and see it arrive on the console you are running recorder on.


# edit /etc/default/ot-recorder

OTR_PASS="FIXME-THIS-IS-NOT-THE-PASSWORD"
OTR_HOST="localhost"
OTR_PORT=8883
OTR_USER="ben"
OTR_CAFILE="/etc/mosquitto/conf.d/ca.crt"

# ot-recorder --debug  'owntracks/#'
...
+++++ [owntracks/ben/g5 (plen=111, r=0) [{"_type":"location","tid":"g5","lat":0.1234,"lon":5.6789,"batt":77}]]
- 02:36:23 owntracks/ben/g5               tid=g5 loc=0.1234,5.6789 [MOON] 15 Dark Side, The Moon 

Notice in the above that a reverse lookup has been performed on the longitude and latitude sent by OwnTracks on the phone. I've modified the reported data to show a street number on the moon, but you should see something much closer to the location of your phone printed there.

Although it is nice to be able to see the data from the phone on the console, ot-recorder also presents a web interface, which by default is at http://127.0.0.1:8083/. The web interface has three main sections: a map, a table of locations, and a history or locations.

The map shows a Google map with place markers for the current location of all the people who are sending messages to the MQTT server. Each place marker has a click bubble with the address, time, and longitude and latitude reported. The table of locations lets you see the all the people, their location as an address, what time the location was reported, and other data (Figure 2). You can also sort the data by each column. The table of locations is shown below with just me.

recorder-locations.png

Recorder locations
Figure 2: Recorder locations.

If you have been running ot-recorder to collect data over a period of time, the main table allows you to bring up a map for each user to see on a map what places they have been in the last 12 hours, week, or longer.

Wrap Up

Although there are many documents talking about destination network address translation, you really want to do two translations if your phone is going to connect on the Internet and the local network without requiring any configuration changes.

OwnTracks can integrate location data into both openHAB and Home Assistant. I hope to show this in a later article that first covers setting up one of these home IoT solutions.

Learn more about embedded Linux with the Embedded Linux Development course from The Linux Foundation.

Click Here!