Configuring MQTT On The Raspberry Pi
Configuring MQTT On The Raspberry Pi
MQTT, which originally was an acronym for Message Queue Telemetry Transport, is a
lightweight message queue protocol designed for small data packets sent across high
latency, low bandwidth links. MQTT is a fairly simple protocol and it's perfect for Internet
of Things projects. It's also perfect for this security system project!
The version of MQTT I use in this tutorial is called Mosquitto. It is available via apt, so
installing it is quite easy. There are a number of steps in configuring the Raspberry Pi
component of the security system. As I mentioned, I'm using a Raspberry Pi 3.
As I've mentioned earlier, I'm using the Raspberry Pi 3 running the latest version of
Raspbian Jessie.
Once you have edited the configuration file, restart the service with the command
# edit this code to invert the tests for the values coming from
# the sensors.
# Philip R. Moyer
# Adafruit
# May 2016
# This code is released under a BSD liense and is in the public domain.
#######################################################################
########################
# Libraries
########################
import os
import string
import Adafruit_IO
import time
########################
# Globals
########################
########################
########################
class sensor():
def __init__(self):
self.state = newState
def getState(self):
return self.state
def resetHeartbeat(self):
self.lastSeen = 0
self.name = newName
self.humanName = humanName
def getname(self):
return self.humanName
if ("unknown" == self.state):
self.state = newState
return 0
else:
if (newState != self.state):
self.state = newState
if ("closed" == self.state):
return -1
else:
return 1
return 0
class sensorList():
def __init__(self):
self.sensorList = {}
self.sensorList[sensorName] = sensor()
self.sensorList[sensorName].setname(sensorName, humanName)
return self.sensorList[sensorID].getname()
rv = self.sensorList[sensorID].checkState(monitorState)
if (0 != rv):
# State changed!
if (0 > rv):
print(outBuf)
else:
print(outBuf)
print("Initiating connection to Adafruit.IO")
AIOclient = Adafruit_IO.MQTTClient(adafruitUser,
adafruitKey)
AIOclient.on_connect = AIOconnected
AIOclient.on_disconnect = AIOdisconnected
AIOclient.on_message = AIOmessage
print("Connecting to Adafruit.IO")
AIOclient.connect()
time.sleep(5)
print("Publishing outBuf")
# AIOclient.publish("alarms", outBuf)
AIOclient.publish("alarms", outBuf)
print("Disconnecting")
AIOclient.disconnect()
########################
# Functions
########################
def AIOconnected(client):
# client.subscribe('alarms')
print("Connected to Adafruit.IO")
def AIOdisconnected(client):
print("adafruit.io client disconnected!")
# that uses a 1M ohm R1 and a 470K ohm R2, the "closed" state returns
def returnState(inVal):
return "closed"
return "open"
else:
return "unknown"
########################
# Main
######################
if "__main__" == __name__:
# Set timer
sensList = sensorList()
# The callback for when the client receives a CONNACK response from the server.
client.subscribe("/security")
# The callback for when a PUBLISH message is received from the server.
sensorVoltage = string.atoi(sensorVoltage)
sensorName = sensList.getSensorName(sensorID)
sensList.sensorState(sensorID, returnState(sensorVoltage))
# print(sensorName+" "+returnState(sensorVoltage))
client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message
client.connect(localBroker, localPort, localTimeOut)
# handles reconnecting.
# Other loop*() functions are available that give a threaded interface and a
# manual interface.
client.loop_forever()
quit()
Copy security.py to /home/pi/security.py on the machine that is your MQTT broker. Edit
the program so the parameters are correct for your installation. I recommend keeping the
"/security" topic, though.
You also need to install the Adafruit_IO Python library. You can clone it from the GitHub
repository or click this button to download a Zip file. Put it in the same directory as your
security.py program.
1. #######################################################################
5. #
11. #
12. # Note two: The implementation uses normally-closed reed switches
13. # from China. If you use normally open switches, you'll have to
14. # edit this code to invert the tests for the values coming from
16. #
18. # Adafruit
20. #
21. # This code is released under a BSD liense and is in the public domain.
23. #######################################################################
24.
25. ########################
26. # Libraries
27. ########################
28.
29. import os
34.
35.
36. ########################
37. # Globals
38. ########################
39.
41.
48.
52.
53. # -- You should not need to change anything below this line --
54.
56.
57.
58. ########################
60. ########################
61.
68.
71.
74.
76. self.lastSeen = 0
77.
81.
84.
88. return 0
89. else:
93. return -1
94. else:
95. return 1
96. return 0
97.
98.
101. self.sensorList = {}
102.
106.
109.
111. rv = self.sensorList[sensorID].checkState(monitorState)
112. if (0 != rv):
116. print(outBuf)
117. else:
119. print(outBuf)
127. AIOclient.connect()
128. time.sleep(5)
132. print("Disconnecting")
133. AIOclient.disconnect()
134.
135.
136. ########################
137. # Functions
138. ########################
139.
142. # client.subscribe('alarms')
144.
147.
150.
151.
152. # returnState takes a numeric voltage value from the sensor and
153. # returns the state of the monitored device. With a voltage divider
154. # that uses a 1M ohm R1 and a 470K ohm R2, the "closed" state returns
155. # 1024 and the open state returns between 1 and 40.
156.
162. else:
164.
165.
166. ########################
167. # Main
168. ########################
169.
172.
175.
176. # The callback for when the client receives a CONNACK response from the
server.
179.
182. client.subscribe("/security")
183.
184. # The callback for when a PUBLISH message is received from the server.
191.
195.
197.
198. # Blocking call that processes network traffic, dispatches callbacks and
200. # Other loop*() functions are available that give a threaded interface and a
202. client.loop_forever()
203.
204. quit()
In this post, we want to face the MQTT security aspects with a special regard to the aspects
related to MQTT Mosquitto security.
Generally speaking, the Internet of Things is the upcoming technological revolution where
objects, called smart objects, are connected to the Internet exchanging data and
information. One of the main concerns about IoT is the security aspect. Considering that
IoT will impact our everyday lives and these smart objects are able to acquire and collect
different kinds of information, security is an important aspect. Some of this information is
sensitive (we can think about health data), and it is important to be sure that no one else can
use it except the permitted persons and systems.
In this context, it is important to know how to secure the MQTT protocol and how to
protect your information. In the next paragraphs, we will analyze the steps we have to
follow to secure MQTT using a Raspberry Pi as the MQTT broker.
We will focus our attention on how to create an MQTT over SSL. To make MQTT a
secure protocol, we have to follow these steps:
The final step is configuring Mosquitto MQTT so that it uses these certificates.
Before creating the private key, you should create a directory where you store all the
certificates you will create. In the terminal, write:
The next step is creating an X509 certificate that uses the private key generated in the
previous step. Open the terminal again and, in the same directory you used to store the
private key, write:
In this step, you have to provide different information before creating the certificate as
shown in the picture below:
Once the private key and the certificate are ready, we can move on and create the MQTT
server certificate and private key:
As you can see, we have used the private key generated in the step before. Finally, we can
create the certificate to use in our MQTT Mosquitto Server:
All done! We have completed the steps necessary to secure our MQTT server. You can
verify your certificate:
mosq-ca.crt
mosq-serv.crt
mosq-serv.key
Locate the mosquitto.conf file that holds all the configuration parameters and add the
following lines:
listener 8883
cafile /home/pi/ssl-cert-mosq/mosq-ca.crt
certfile /home/pi/ssl-cert-mosq/mosq-serv.crt
keyfile /home/pi/ssl-cert-mosq/mosq-serv.key
The path /home/pi/ssl-cert-mosq is the path where you stored your certificate. Moreover,
we change the default Mosquitto MQTT port to 8883.
Now you have to stop and restart Mosquitto MQTT so that it can read the new
configuration file:
That's all. Now our MQTT protocol is secure and encrypted. The last step is testing the
configuration and the MQTT server.
Notice that we have enabled the SSL/TSL configuration, providing the mosq-ca.crt creating
during the previous steps.
Now it is time to test if our client gets the message. Select the subscribe menu and
subscribe the MQTT client to a topic (choosing a topic name).