Securing Mosquitto

If your Mosquitto MQTT broker is in the cloud it is a good idea to secure it at least with a user and password.

Mosquitto offers the mosquitto_passwd utility, which allows us to create a user and a password. You will be invited to enter a password and to confirm it:

sudo mosquito_passwd -c /etc/mosquito/passwd   joe

In the /etc/mosquitto directory a file named passwd will be created and in the file will be a user named joe and its encoded password as in the following screenshot:

Now let's add the passwd file into the mosquitto.conf. Use your favorite text editor and change the file /etc/mosquitto.conf to instruct Mosquitto to read and use the passwd file.

The content of the file will be:

Password file location
  • allow_anonymous: It is a boolean value that determines whether clients that connects without providing a username are allowed to connect. If set to false then another means a connection should be created to control authenticated client access.
  • password_file: Sets the path to a password file. If defined, the contents of the file are used to control client access to the broker. If allow_anonymous is set to false, only users defined in this file will be able to connect.

After stopping and restarting the Mosquitto service using the commands:

sudo service mosquitto stop && sudo service mosquitto start  

If a terminal window will try to connect as you did before, we will receive an error message like in the following screenshot:

But subscribing and publishing with the user and the password created before will work. For subscribing the command is:

sudo mosquitto_sub -t living/temperature -u joe -P joe1234  

And for publishing:

sudo mosquitto_pub -t living/temperature -u joe -P joe1234 -m {"t":24.7}  
Make sure you use capital a P for the password and not, p which is for port.

You will get the following result:

Providing username and password

Now let's use ESP8266 to send the username and password to the broker:

#include <ESP8266WiFi.h> 
#include <PubSubClient.h> 

Update these with values suitable for your network:

const char* wifi_network = "WiFi 176-58"; 
const char* password = "P6etRUzaRa"; 
const char* mqtt_serv_address = "192.168.1.116"; 
const char* mqtt_user = "joe"; 
const char* mqtt_passwd = "joe1234"; 
const int   mqtt_port_number = 1883; 
#define OUTDOOR_LIGHT  12 

The mqtt_user will keep the value of the username and the mqtt_passwd will keep the user's password. We will use them in the connect method and pass them to the server:

WiFiClient  espClient;
PubSubClient   client(espClient); 
long  lastMsg = 0;
 
void setup() { 
pinMode(OUTDOOR_LIGHT, OUTPUT);     // Initialize the BUILTIN_LED pin as an output 
Serial.begin(115200); 
setup_wifi(); 
client.setServer(mqtt_serv_address, mqtt_port_number); 
client.setCallback(callback); 
} 
 
void setup_wifi() { 
 
delay(10); 
  // We start by connecting to a WiFi network 
Serial.println(); 
Serial.print("Connecting to "); 
Serial.println(wifi_network); 
 
WiFi.begin(ssid, password); 
 
while (WiFi.status() != WL_CONNECTED) { 
WiFi.begin(wifi_network, password); 
 
Serial.print("."); 
delay(5000); 
  } 
 
Serial.println(""); 
Serial.println("WiFi connected"); 
Serial.println("IP address: "); 
Serial.println(WiFi.localIP()); 
} 
 
 
void callback(char* topic, byte* payload, unsigned int msg_length) {
Serial.print("Message arrived ["); 
Serial.print(topic); 
Serial.print("] "); 
for (int i = 0; i< msg_length; i++) { 
Serial.print((char)payload[i]); 
  } 
Serial.println(); 
 
  // Switch on the LED if an 1 was received as first character 
if ((char)payload[0] == '0') { 
digitalWrite(OUTDOOR_LIGHT, LOW);   // Turn the LED off  
  } else { 
digitalWrite(OUTDOOR_LIGHT, HIGH);  // Turn the LED on 
  } 
} 
 
void reconnect() { 
  // Loop until we're reconnected 
while (!client.connected()) { 
Serial.print("Attempting MQTT connection...");  
 

Attempt to connect to the MQTT Mosquitto broker using the username and the password from mqtt_user and mqtt_passwd:

if (client.connect("ESP8266Client", mqtt_user, mqtt_passwd))  
{ 
  Serial.println("connected"); 
  client.subscribe("outdoor/light"); 
} else { 
  Serial.print("failed, rc="); 
  Serial.print(client.state()); 
  Serial.println(" try again in 5 seconds"); 
  // Wait 5 seconds before retrying 
  delay(5000); 
  } 
 } 
} 
 
void loop() { 
 
if (!client.connected()) { 
    reconnect(); 
} 
client.loop(); 
 
long now = millis(); 
if (now - lastMsg> 2000) { 
    lastMsg = now; 
    String light_state; 
 
    if(digitalRead(OUTDOOR_LIGHT) == HIGH) 
       light_state = "ON"; 
    else 
       light_state = "OFF"; 
 

    Serial.print("Publish message: "); 
    Serial.println(light_state); 
    client.publish("outdoor/light/status", light_state.c_str()); 
  } 
} 

Publishing a message with the payload 1 will trigger the GPIO 12 and turn on the connected LED in a secure way. The ON OFF messages are the state of the GPIO where on ON will have 3V3 and on OFF 0V:

Receiving ON/OFF messages

Now, sending this message from any place in the world will turn on and off any appliance from your house, if instead of the LED we will add a relay board:

Until now small messages were used, by default the maximum size allowed by the PubSubClient is 128 bytes. If your messages are bigger than 128 bytes, go to the PubSubClient.h file and change the value for MQTT_MAX_PACKET_SIZE. 
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.137.217.41