MQTT TLS connection to AWS

I have AWS IoT core set up as an MQTT broker, and I have created a set of Things with accompanying certificates. When I use a desktop MQTT client like MQTTX, I am able to use these certificates to connect to AWS and subscribe to the relevant topics. When subscribing/publishing I see the messages going back and forth.

Now I tried to replicate this in a simple Elixir app, but I cannot establish a TLS connection to AWS using either Tortoise or emqtt. I believe the issue is the same as both library’s use Erlang’s ssl library.

The strange thing is, I am able to establish a connection using emqtt if I compile it and use the CLI. When I debug that connection, I notice there are a few extra ssl_opt’s configured. I am able to set all of those extra opts besides partial_chain. These are the opts I use so far:

[
  host: "abcdef-ats.iot.eu-west-1.amazonaws.com",
  port: 8883,
  client_id: "endeavour",
  clean_start: false,
  name: :endeavour,
  ssl: true,
  version: ~c"tlsv1.3",
  ssl_opts: [
    handshake: :full,
    verify_fun:
      {&:ssl_verify_hostname.verify_fun/3, [check_hostname: ~c"iot.eu-west-1.amazonaws.com"]},
    secure_renegotiation: true,
    certs_keys: [
      %{
        certfile: ~c"/path/to/certfile",
        keyfile: ~c"/path/to/keyfile"
      }
    ],
    reuse_sessions: true,
    customize_hostname_check: [match_fun: :public_key.pkix_verify_hostname_match_fun(:https)],
    protocol: :tls,
    crl_check: false,
    session_tickets: :disabled,
    fallback: false,
    cacertfile: ~c"/path/to/cacertfile",
    verify: :verify_none,
    server_name_indication: ~c"iot.eu-west-1.amazonaws.com",
    log_level: :debug
  ]
]

Hi James,

Here is a previous answer I gave for something that could be similar.
I’m able to connect to rabbitmq using amqps protocol with such options.
Hope this could help you, cheers,

Sébastien.

1 Like

Unfortunately the settings mentioned above didn’t work, but in the meantime I got in touch with AWS support and with their help I got it to work.

I made a mistake with respect to the SNI which was causing my connection to crash. We were able to debug it because I was able to make a succesful connection when I used emqtt’s cli.

When I supply the following settings to emqtt it works:

[
  host: "your-ats-domain.iot.eu-west-1.amazonaws.com",
  port: 8883,
  clientid: "yourclientid",
  clean_start: false,
  name: :yourname,
  ssl: true,
  ssl_opts: [
    versions: [:"tlsv1.2"],
    certs_keys: [
      %{
        certfile: ~c"/path/to/certfile",
        keyfile: ~c"/path/to/keyfile"
      }
    ],
    customize_hostname_check: [match_fun: :public_key.pkix_verify_hostname_match_fun(:https)],
    cacertfile: ~c"/path/to/cacertfile",
    verify: :verify_peer,
    server_name_indication: ~c"your-ats-domain.iot.eu-west-1.amazonaws.com"
  ]
]