Shadowbeetle

Shadowbeetle

MQTT TLS Debug help

I’m trying to debug a hostname check TLS issue.

I’m using Tortoise to connect to my MQTT broker hosted at HiveMQ cloud using TLS. Everything is fine, until I’m trying to set verify: :verify_peer. I’m completely lost, as I can connect from the Phoenix app to other brokers just fine, eg. to test.mosquitto.org. Moreover, I can connect to my HiveMQ broker with TLS using mosquitto_sub and supposedly, It verifies the cert I’m passing to it using the --cafile option.

Here is an example config that works:

mosquitto_sub -v -h test.mosquitto.org -t "#" -p 8885 -u ro -P readonly --cafile ~/mosquitto_test/mosquitto.org.crt`
  config :napos, :mqtt,
    server: {
      Tortoise311.Transport.SSL,
      # TODO: on prod we should remove verify_none and use the server's cert chain, we should remove
      host: "test.mosquitto.org",
      port: 8885,
      cacertfile: "path/to/mosquitto.org.crt" |> String.to_charlist(),
      verify: :verify_peer
    },
    # ClientID needs to be unique!
    client_id: System.get_env("MQTT_CLIENTID", "random_string_just_to_avoid_collision"),
    user_name: "ro",
    password: "readonly",
    handler: {Napos.DeviceQueueHandler, []},
    subscriptions: [
      {"#", 1},
    ]

According to the Tortoise docs the cacertfile should be passed as a charlist, though it worked with a string as well for me.

The test.mosquitto.org cert can be downloaded from here, while the hivemq cloud cert can be downloaded from here.

My HiveMQ config is exactly the same as above, only replacing the cert file, user, password, URL and port fields with their respective values for HiveMQ. The connection even with TLS works fine, until I try to remove verify: verify_none, or set it to verify: :verify_peer. Then I get this:

GenServer {Tortoise.Registry, {Tortoise.Connection, "serverkjbagskjbagbjklagbksajgbsalgfalfa"}} terminating
** (stop) {:tls_alert, {:handshake_failure, ~c"TLS client: In state certify at ssl_handshake.erl:2135 generated CLIENT ALERT: Fatal - Handshake Failure\n {bad_cert,hostname_check_failed}"}}

From what I can tell reading the code, it simply passes all parameters to :ssl.connect/4, so seeing the hostname check failure, I tried to set :sni to the hostname of the broker, though I’m not sure I understand the :ssl docs on :sni correctly.

Right now I’m a bit stuck. As parts of what I need to do either work with another client on the same broker, or from the same app on another broker, I don’t really know where to look further, or how could I get more verbose info on what might be going wrong.

Marked As Solved

jjcarstens

jjcarstens

Nerves Core Team

These are typical SSL settings I have for connected to AWS MQTT. My guess is you might need to custom hostname check for https. Also, what you linked was the SNI type definition but not sure if you used the atom :sni so just for clarity, the whole option needs to be spelled out:

server_name_indication: ~c"test.mosquitto.org",
customize_hostname_check: [match_fun: :public_key.pkix_verify_hostname_match_fun(:https)],
verify: :verify_peer,
versions: [:"tlsv1.2"]

If that doesn’t work, set log_level: :debug in the SSL options to get more output. It might provide the hostname it is trying to validate. It might be that you need to set SNI to just mosquito.org depending on their cert.

The pitfall with all this is that command lines typically have magic to find all the system ssl bits with standard folders, but erlang is very explicit and needs every piece provided to it. So it tends to be trial and error :face_exhaling:

Where Next?

Popular in Questions Top

JDanielMartinez
Hi! May someone helps me, please! I have two apps into an umbrella project: the first one is Database, which manages queries, and the se...
New
sergio
In Ruby, I can go: User.find_by(email: "foobar@email.com").update(email: "hello@email.com") How can I do something similar in Elixir? ...
New
pmjoe
I have a relationship of love and hate with Elixir. Lots of things are just absolutely right, but there are some things that are kind of ...
New
lessless
I believe there are people here who are dealing with CSV files import on the daily basis, and since Excel is a really popular tool there ...
New
tduccuong
Hi, is there any work on GUI with Elixir, that is similar to Electron/Javascript? My idea is to bundle Phoenix and BEAM into a single se...
New
Jim
As a follow up to my earlier question: I have the code compiling and running but not getting a successful login from the rest server. ...
New
lastday4you
I wanted to check elixir version in phoenix because i found that my elixir is 1.5 but when i use Enum.chunk_by it said the function is un...
New
kostonstyle
Hi all I want to have a unix time, from the current time plus 1 hour. DateTime.now + 1 hour How to get it in elixir? Thanks
New
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID<0.412.0> terminating ** (Postgrex.Error) FATAL...
New
Qqwy
Original source of discussion: This topic on the Pragmatic Programmers' Functional Web Development with Elixir, OTP, and Phoenix forum. ...
New

Other popular topics Top

sorentwo
Hello! tl;dr Announcing Oban, an Ecto based job processing library with a focus on reliability and historical observability. After spen...
977 41022 311
New
sergio
In Ruby, I can go: User.find_by(email: "foobar@email.com").update(email: "hello@email.com") How can I do something similar in Elixir? ...
New
malloryerik
Hi, this is for people who, like me, have had some friction using .html.heex templates in VSCode. The solution seems to be, in a hyphena...
New
vertexbuffer
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
New
lastday4you
I wanted to check elixir version in phoenix because i found that my elixir is 1.5 but when i use Enum.chunk_by it said the function is un...
New
vac
Hi, I'm quite new in Elixir and I'm trying to format a string to a PEM format. I have the certificate value like MIIDBTCCAe2...... and ...
New
mcarvalho
What is the difference between System.get_env and Application.get_env? For example, what are best practices to use one versus another.
New
chensan
I have a User schema with a :from_id field set to type :string: defmodule TweetBot.Repo.Migrations.CreateUsers do use Ecto.Migration ...
New
fayddelight
I tried installing elixir 1.11.2 erlang 23.3.4 via asdf in my zsh shell. Enabled the versions locally and globally. When I list them ...
New
electic
Hi, I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
New

We're in Beta

About us Mission Statement