As part of the recent developments exploring the further integration of the device module as developed by @nchaveiro into emoncms and the input interface I have been working on a way to simplify the setup procedure of WIFI devices running EmonESP.
The idea is to reduce the setup requirement of an EmonESP node down to just signing on to a local network and for the additional settings such as MQTT authentication details to be transferred by a special mechanism from the basestation to the EmonESP node.
A user logging in to emoncms on their basestation (emonbase/emonpi) would see a notification saying that device called say “EmonTx WIFI” on ip address 192.168.1.103 would like to connect, with the option to “Allow” or “Deny”.
If the connection is allowed the MQTT username and password would essentially be made available specifically to the IP address of the requesting device for a brief time. Ideally the whole process would take place over a HTTPS/TLS connection.
Initial basestation discovery could be performed by using hostnames such as emonpi.local but in the event that this fails or is unreliable there would be a fall back to a UDP Broadcast method.
I would be interested to hear of peoples experience with hostname reliability on different networks, I’ve had a bit of trouble with getting hostnames to work reliably or at all on the emonesp and so my prototyping so far has used a UDP Broadcast from the basestation.
Initial device discovery and MQTT authentication
- WIFI device attempts to connect to emonpi.local hostname or picks up UDP broadcast.
- WIFI device sends an authentication request to a special API on the basestation.
- Base station receives authentication request and in doing so now knows the smart meter’s IP Address.
- Base station displays message to user in an authenticated context:
“Device “EmonTx WIFI” is requesting a connection, allow or deny access” - User clicks “Allow”
- Hub provides ideally a TLS enabled API with access restricted to the IP Address of the requesting device temporarily, to which the WIFI Device connects in order to retrieve the MQTT authentication details.
- WIFI Device saves MQTT authentication details
- WIFI Device attempts MQTTS connection
- WIFI Device publishes data
Re-discovery of new ip address - using UDP Broadcast
- WIFI Device waits for UDP Broadcast from base station
- WIFI Device attempts secure connection to UDP Broadcast detected IP Address.
I can see one potential issue where an attacker places another device on the network which sends a UDP broadcast or changes/pushes the hostname of the original basestation from emonpi.local to emonpi-2.local. The WIFI device would then attempt a mqtt connection to the impersonating device giving the MQTT details to the impersonating device.
Im not sure what the best way of addressing this would be, but it does rely on a compromised local area network to begin with, interested in anyone’s thoughts?
Prototype 1
I have a prototype of the above working and implemented in the device-integration branch of emoncms. The code that handles the authentication request API can be found here:
https://github.com/emoncms/emoncms/blob/device-integration/Modules/device/device_controller.php#L35
A request to
http://emonpi.local/emoncms/device/auth/request.json
will return the message “request registered”
The emoncms inputs interface then shows the following notification:
Once allow has been clicked by the user a subsequent auth/request API call, limited to the devices IP Address and within a time limited 60 second window, returns the MQTT details.
The “fetchmqttauth_async” branch of EmonESP handles the WIFI device part primarily handled in the file autoauth.cpp here: https://github.com/openenergymonitor/EmonESP/blob/fetchmqttauth_async/src/autoauth.cpp
Can anyone see any big holes in this approach? suggestions welcome.