I have a raspberry pi 3 with raspbian stretch as its operating system. I have installed and fully configured a MQTT broker on the raspberry pi following this tutorial: https://www.digitalocean.com/community/tutorials/how-to-install-and-secure-the-mosquitto-mqtt-messaging-broker-on-ubuntu-16-04 Everything works fine and well on the broker's side. The certificates get renewed after 60 days and you can only connect to port 1883 via the localhost and the other ports (8883 and 8083) are open but can only be accessed using TLS version 1.2 and for the latter also using websockets. Below you can find the code of my configuration of mosquitto (/etc/mosquitto/conf.d/default.conf).
allow_anonymous false
password_file /etc/mosquitto/passwd
listener 1883 localhost
listener 8883
certfile /etc/letsencrypt/live/home.kamidesigns.be/cert.pem
cafile /etc/letsencrypt/live/home.kamidesigns.be/chain.pem
keyfile /etc/letsencrypt/live/home.kamidesigns.be/privkey.pem
tls_version tlsv1.2
listener 8083
protocol websockets
certfile /etc/letsencrypt/live/home.kamidesigns.be/cert.pem
cafile /etc/letsencrypt/live/home.kamidesigns.be/chain.pem
keyfile /etc/letsencrypt/live/home.kamidesigns.be/privkey.pem
tls_version tlsv1.2
I also bought a ESP8266 Wemos D1 Mini to connect to this broker in a secure way. I used the pubsubclient library from this link: https: //github.com/knolleary/pubsubclient for my MQTT client. I use the master branch of this link: https://github.com/esp8266/Arduino for my secure SSL connection. Below you see the code I used for programming my Wemos D1 Mini
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <time.h>
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("] ");
for (int i = 0; i < length; i++) {
Serial.print((char)payload[i]);
}
Serial.println();
}
const char* ssid = "ssid";
const char* password = "wifipassword";
const char* host = "home.kamidesigns.be";
const int port = 8883;
WiFiClientSecure espClient;
PubSubClient client(host, port, callback, espClient);
long lastMsg = 0;
char msg[50];
int value = 0;
void setup() {
Serial.begin(115200);
Serial.println();
Serial.print("connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
// Synchronize time useing SNTP. This is necessary to verify that
// the TLS certificates offered by the server are currently valid.
Serial.print("Setting time using SNTP");
configTime(8 * 3600, 0, "pool.ntp.org", "time.nist.gov");
time_t now = time(nullptr);
while (now < 1000) {
delay(500);
Serial.print(".");
now = time(nullptr);
}
Serial.println("");
struct tm timeinfo;
gmtime_r(&now, &timeinfo);
Serial.print("Current time: ");
Serial.print(asctime(&timeinfo));
}
void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
// Attempt to connect
if (client.connect("ESP8266LightController","username","password")) {
Serial.println("connected");
// Once connected, publish an announcement...
client.publish("outTopic", "hello world");
// ... and resubscribe
client.subscribe("inTopic");
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(5000);
}
}
}
When I start my Wemos D1, the serial monitor says: connecting to ssid .. WiFi connected IP address: 192.168.0.213 Setting time using SNTP. Current time: Sat Oct 14 02:26:25 2017 Attempting MQTT connection...connected
This is good and it is exactly what I wanted but I'm confused by how my Wemos D1 is able to connect to port 8883 without it verifying the certificate chain of the server? Remember that I never uploaded a certificate to the Wemos D1 or implemented a certificate into the code, and still it can connect.
One of 2 options
- The WiFiClientSecure includes a list of public CA certs and is verifying your certificate against this list
- The WiFiClientSecure defaults to not verifying remote certs by default.
Looking at this issue it looks like option 2 is most likely as it implies you have to verify the cert yourself after the connection.
来源:https://stackoverflow.com/questions/46736158/ssl-certificate-verification-on-esp8266-wemos-d1-mini-with-mqtt-broker