shmuelzon / esp32-ble2mqtt

A BLE to MQTT bridge running on an ESP32
MIT License
666 stars 106 forks source link

Can't connect to MQTT over SSL #201

Open ve6rah opened 2 weeks ago

ve6rah commented 2 weeks ago

I'm trying to use ble2mqtt over SSL, however it's not working.

In the logging I see:

2024-09-03 12:38:58.400973 (10.42.1.248): I (1214012) BLE2MQTT: Connected to the network, connecting to MQTT
2024-09-03 12:38:58.403749 (10.42.1.248): I (1214022) MQTT: Connecting MQTT client
2024-09-03 12:38:58.405959 (10.42.1.248): I (1214022) wifi:2024-09-03 12:39:08.241568 (10.42.1.248): E (1224102) esp-tls-mbedtls: No server verification option set in esp_tls_cfg_t structure. Check esp_tls API reference
2024-09-03 12:39:08.243717 (10.42.1.248): E (1224112) esp-tls-mbedtls: Failed to set client configurations, returned [0x8017] (ESP_ERR_MBEDTLS_SSL_SETUP_FAILED)
2024-09-03 12:39:08.245671 (10.42.1.248): E (1224122) esp-tls: create_ssl_handle failed
2024-09-03 12:39:08.247905 (10.42.1.248): E (1224122) esp-tls: Failed to open new connection
2024-09-03 12:39:08.250023 (10.42.1.248): E (1224132) transport_base: Failed to open a new connection
2024-09-03 12:39:08.251708 (10.42.1.248): E (1224142) mqtt_client: Error transport connect
2024-09-03 12:39:08.253483 (10.42.1.248): I (1224142) MQTT: MQTT client disconnected
2024-09-03 12:39:08.255711 (10.42.1.248): I (1224152) BLE2MQTT: Disconnected from MQTT, stopping BLE

The main error seems to be the "No server verification option set", but I'm not sure where to go from here.

My config file is:

{
  "network": {
    "hostname": "BLE2MQTT-001",
    "wifi": {
      "ssid": "redacted",
      "password": "redacted"
    }
  },
  "mqtt": {
    "server": {
      "host": "redacted",
      "port": 8883,
      "ssl": true,
      "username": "redacted",
      "password": "redacted",
      "client_id": "ble2mqtt1"
    },
    "publish": {
      "qos": 0,
      "retain": true
    },
    "topics" :{
      "prefix": "",
      "get_suffix": "/Get",
      "set_suffix": "/Set"
    }
  },
  "log": {
    "host": "10.42.1.62",
    "port": 5000
  }
}
shmuelzon commented 2 weeks ago

Hey, looking a bit on the ESP-IDF implementation of MQTT + SSL, it looks like server verification is optional as far as the MQTT APIs are concerned but less so from the Mbed TLS point. I can think of two ways to overcome this.

  1. Include the expected server certificate in your configuration
  2. Enable the CONFIG_ESP_TLS_SKIP_SERVER_CERT_VERIFY config in your build
ve6rah commented 1 week ago

Hey, looking a bit on the ESP-IDF implementation of MQTT + SSL, it looks like server verification is optional as far as the MQTT APIs are concerned but less so from the Mbed TLS point. I can think of two ways to overcome this.

  1. Include the expected server certificate in your configuration
  2. Enable the CONFIG_ESP_TLS_SKIP_SERVER_CERT_VERIFY config in your build

Thanks. If seems like option 2 probably make more sense, can you elaborate more on how I would accomplish that?

shmuelzon commented 1 week ago

You would need to run idf.py menuconfig to open the configuration menu. Then, hit / to search for the config mentioned above (maybe without the "CONFIG_" prefix) and, once you find it, enable it, save, exit and rebuild with idf.py build.

ve6rah commented 1 week ago

Well I'm able to configure that (though there are big warnings not to). It seems like there should be some safe way of authenticating servers without user intervention?

shmuelzon commented 1 week ago

though there are big warnings not to

That makes sense since most of the reason you want to use TLS in the first place is to verify the server you're connecting to. In order to authenticate the server, as is done in any TLS environment, like your browser, the client needs to have list of approved certificates or approved CA certificates that have signed the CA certificate. I'm assuming your MQTT broker has a server certificate, either one that you've generated for it or one that was generated automatically. Get a hold of that, in the PEM format. Upload it to the ESP32 via the web UI and add the server_cert entry in the configuration file with a path (name) of the certificate file uploaded to the ESP32. If I understand the original error message you got, that should be enough.