Невозможно подключить ESP32 к Mosquitto на Raspberry с использованием сертификатов

Я установил брокер Mosquitto в Raspberry в своей локальной сети. Я сгенерировал сертификаты в Raspberry следующим образом:

sudo openssl genrsa -out ca.key 2048
sudo openssl req -new -x509 -days 3600 -key ca.key -out ca.crt
sudo openssl genrsa -out server.key 2048
sudo openssl req -new -out server.csr -key server.key
sudo openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 3600

Я изменил файл конфигурации Mosqutto (.conf) следующим образом:

allow_anonymous false
cafile /etc/mosquitto/certs/ca.crt
certfile /etc/mosquitto/certs/server.crt
keyfile /etc/mosquitto/certs/server.key
tls_version tlsv1.2

Я перезапустил Mosquitto, все в порядке

Я загрузил файл ca.crt из Raspberry на свой компьютер с помощью Filezilla. с моего ПК я использую MQTT.fx для подключения, я устанавливаю сертификат. ХОРОШО РАБОТАЕТ

Проблема: с ESP32 я не могу подключиться, когда устанавливаю сертификат с помощью espClient.setCACert(ca_cert); Подключение MQTT...

[E][ssl_client.cpp:33] handle_error():X509 — Сертификат проверка не удалась, например, CRL, CA или проверка подписи не удалась

Кто-нибудь может мне помочь, я не могу понять, то ли чего-то не хватает в коде, то ли это какая-то ошибка при генерации сертификатов

Пожалуйста, помогите Большое спасибо Михаил

это мой код:

#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <PubSubClient.h>
#include <ESPmDNS.h>

/* change it with your ssid-password */
const char* ssid = "XXXXXX";
const char* password = "XXXXXXX";
/* this is the MDNS name of PC where you installed MQTT Server */
const char* serverHostname = "home";

const char* ca_cert = \ 
"-----BEGIN CERTIFICATE-----\n" \
"MIIDmDCCAoCgAwIBAgIJAKV4GE+4y/G4MA0GCSqGSIb3DQEBCwUAMGExCzAJBgNV\n" \
"BAYTAlRWMRAwDgYDVQQIDAdUcmV2aXNvMRUwEwYDVQQHDAxDYXN0ZWxmcmFuY28x\n" \
"DDAKBgNVBAoMA1BTUzEMMAoGA1UECwwDUFNTMQ0wCwYDVQQDDARob21lMB4XDTE5\n" \
"MDkwODE3NDIzOFoXDTI5MDcxNzE3NDIzOFowYTELMAkGA1UEBhMCVFYxEDAOBgNV\n" \
"BAgMB1RyZXZpc28xFTATBgNVBAcMDENhc3RlbGZyYW5jbzEMMAoGA1UECgwDUFNT\n" \
"MQwwCgYDVQQLDANQU1MxDTALBgNVBAMMBGhvbWUwggEiMA0GCSqGSIb3DQEBAQUA\n" \
"A4IBDwAwggEKAoIBAQC2rPN7VQXtzLCl1LufJkzLK9xedrbW72K2vBZ34VNOl+tG\n" \
"ffNx2QQLQC0Jh5GzB79dZweqAjCRBbIEpx0IGvHWrHDUQMJrvg4BcmDr0eqNCup/\n" \
"tBItlEcCdvmWFfm3IBezOVBDFiQWmC4jvAC/G3DPlftHiPI1k3cDewKNJEJykxeD\n" \
"8H/4KTAz+wJXyGZiviZYv8OYOTRMa3nEhg1vaQTMgCwEVBavg5fsEQkZLArBNJQM\n" \
"Gmw0qDdJEMDGOGWPogxRAKrxvNnXr4mIebzPj9/UTrJnfzVOPEHZ9Uz5BU/psGCL\n" \
"cnMkBeNEa/JyLR14Hu8e+xa/pOCpJ9Dqhi/BTji5AgMBAAGjUzBRMB0GA1UdDgQW\n" \
"BBRIz+15SpOBqo0O+vOtgYvPj4LqWDAfBgNVHSMEGDAWgBRIz+15SpOBqo0O+vOt\n" \
"gYvPj4LqWDAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQC08Crs\n" \
"w7LPX+Bd80NwPuxgBmMU4U/pCw8AyzzSgckHmay0K8KuHXhSvZjdl6i0gjG/2xLa\n" \
"ghCtfFGIXPu1Lu226bhTWigmuFLYasG1MivTDz2LeUTFPQrtEO8KdsRUarPZW3Fj\n" \
"nOMyVDdzE4+HxvzvARDc1QbE9SX2ozQcNKQp4oRpunfT2+/OyzYgfMVA7MVKvehX\n" \
"VH49fRF1P1Ajizqr2eHDFImcMQTzepRT7IjfOiQ/8PoqrZGvGenMj5so1I9MtgyK\n" \
"gVUf1ZWPBgxmhVfla6vYBZiTGuZMHSDuF6/yFC1QnoXVq7K+bbIhAE8lsPNuOY7V\n" \
"dKidKIfBJiN378CC\n" \
"-----END CERTIFICATE-----\n";

/* create an instance of WiFiClientSecure */
WiFiClientSecure espClient;
PubSubClient client(espClient);

/*LED GPIO pin*/
const char led = 5;

/* topics */
#define COUNTER_TOPIC    "smarthome/room1/counter"
#define LED_TOPIC     "smarthome/room1/led" /* 1=on, 0=off */

long lastMsg = 0;
char msg[20];
int counter = 0;

void receivedCallback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message received: ");
  Serial.println(topic);

  Serial.print("payload: ");
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }
  Serial.println();
  /* we got '1' -> on */
  if ((char)payload[0] == '1') {
    digitalWrite(led, HIGH); 
  } else {
    /* we got '0' -> on */
    digitalWrite(led, LOW);
  }

}

void mqttconnect() {
  /* Loop until reconnected */
  while (!client.connected()) {
    Serial.print("MQTT connecting ...");
    /* client ID */
    String clientId = "ESP32Client";
    /* connect now */
    if (client.connect(clientId.c_str(),"XXXXX","XXXXXX")) {
      Serial.println("connected");
      /* subscribe topic */
      client.subscribe(LED_TOPIC);
    } else {
      Serial.print("failed, status code =");
      Serial.print(client.state());
      Serial.println("try again in 5 seconds");
      /* Wait 5 seconds before retrying */
      delay(5000);
    }
  }
}

void setup() {
  Serial.begin(9600);
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  /* set led as output to control led on-off */
  pinMode(led, OUTPUT);

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  /*setup MDNS for ESP32 */
  if (!MDNS.begin("esp32")) {
      Serial.println("Error setting up MDNS responder!");
      while(1) {
          delay(1000);
      }
  }
  /* get the IP address of server by MDNS name */
  Serial.println("mDNS responder started");
  IPAddress serverIp = MDNS.queryHost(serverHostname);
  Serial.print("IP address of server: ");
  Serial.println(serverIp.toString());
  /* set SSL/TLS certificate */
  espClient.setCACert(ca_cert);
  /* configure the MQTT server with IPaddress and port */
  client.setServer(serverIp, 26391);
  /* this receivedCallback function will be invoked 
  when client received subscribed topic */
  client.setCallback(receivedCallback);

}
void loop() {
  /* if client was disconnected then try to reconnect again */
  if (!client.connected()) {
    mqttconnect();
  }
  /* this function will listen for incomming 
  subscribed topic-process-invoke receivedCallback */
  client.loop();
  /* we increase counter every 3 secs
  we count until 3 secs reached to avoid blocking program if using delay()*/
  long now = millis();
  if (now - lastMsg > 3000) {
    lastMsg = now;
    if (counter < 100) {
      counter++;
      snprintf (msg, 20, "%d", counter);
      /* publish the message */
      client.publish(COUNTER_TOPIC, msg);
    }else {
      counter = 0;  
    }
  }
}

, 👍1

Обсуждение

См. https://github.com/espressif/arduino-esp32/issues/2875 и https://github.com/TwilioDevEd/sync-for-iot-examples/blob/master/Espressif_ESP32/Quickstart/certificates.hpp. Работает ли это при добавлении R перед строковой константой для ca_cert?, @Maximilian Gerhardt

Привет Максимилиан, Я попробовал, как было рекомендовано, но я получаю ту же ошибку даже с R - Подключение MQTT ... [E] [ssl_client.cpp: 33] handle_error (): X509 - Ошибка проверки сертификата, например, CRL, CA или проверка подписи. [E][ssl_client.cpp:35] handle_error(): Код сообщения MbedTLS: -9984 [E][WiFiClientSecure.cpp:132] connect(): start_ssl_client: -9984 - у вас есть предложения для меня?, @Michele

У вас есть полный журнал mbedtls за весь сеанс? Тогда вам может понадобиться установить самый подробный уровень отладки в Arduin IDE., @Maximilian Gerhardt

Я нашел решение, проблема была связана с генерацией сертификатов. OU должна быть разной для каждого сгенерированного файла. SUBJECT_CA="/C=SE/ST=Стокгольм/L=Стокгольм/O=himinds/OU=CA/CN=192.168.0.11" SUBJECT_SERVER="/C=SE/ST=Стокгольм/L=Стокгольм/O=himinds/OU=Server/CN=192.168.0.11" SUBJECT_CLIENT="/C=SE/ST=Стокгольм/L=Стокгольм/O=himinds/OU=Client/CN=192.168.0.11", @Michele

Доброе утро, сначала я хотел бы сказать, что я бразилец, поэтому я использую переводчик, если что-то пойдет не так, пожалуйста, не волнуйтесь. Да ладно, у меня такая же проблема, я думаю проблема в сертификате rsrs, подскажите пожалуйста, как вы решили свою проблему? Спасибо., @Bruno Papait

@Michele Вы можете опубликовать это как ответ, @sempaiscuba

Спасибо за вашу помощь, но не могли бы вы сказать мне, в какой папке я создаю этот скрипт? У меня все еще та же проблема. Спасибо, @Bruno Papait

Привет, не важно, какой скрипт вы создаете, однако из родной малины, мкдир тест, компакт-диск тест, sudo nano test.sh, вставьте скрипт и сохраните. chmod +x test.sh затем запустите скрипт с помощью ./test.sh, @Michele


1 ответ


1

@sempaiscuba и Bruno Я решил проблему, повторно сгенерировав сертификаты таким образом. вам нужно сделать этот удобный скрипт в Raspiberry

#!/bin/bash

IP="192.168.0.11"
SUBJECT_CA="/C=SE/ST=Italy/L=Roma/O=himinds/OU=CA/CN=$IP"
SUBJECT_SERVER="/C=SE/ST=Italy/L=Roma/O=himinds/OU=Server/CN=$IP"
SUBJECT_CLIENT="/C=SE/ST=Italy/L=Roma/O=himinds/OU=Client/CN=$IP"

function generate_CA () {
   echo "$SUBJECT_CA"
   openssl req -x509 -nodes -sha256 -newkey rsa:2048 -subj "$SUBJECT_CA"  -days 365 -keyout ca.key -out ca.crt
}

function generate_server () {
   echo "$SUBJECT_SERVER"
   openssl req -nodes -sha256 -new -subj "$SUBJECT_SERVER" -keyout server.key -out server.csr
   openssl x509 -req -sha256 -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 365
}

function generate_client () {
   echo "$SUBJECT_CLIENT"
   openssl req -new -nodes -sha256 -subj "$SUBJECT_CLIENT" -out client.csr -keyout client.key 
   openssl x509 -req -sha256 -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out client.crt -days 365
}

function copy_keys_to_broker () {
   sudo cp ca.crt /etc/mosquitto/certs/
   sudo cp server.crt /etc/mosquitto/certs/
   sudo cp server.key /etc/mosquitto/certs/
}

generate_CA
generate_server
generate_client
copy_keys_to_broker

по мере того, как вы видите изменения организационной единицы для каждого файла. Не забудьте перезапустить Mosquitto

sudo systemctl stop mosquitto.service
sudo systemctl start mosquitto.service

дайте мне знать, как это происходит пока Мишель

,