Mqtt tls-psk with auth in offline network

Hello,

We’re migrating to MQTT for an offline network (zero internet access) and are trying to test TLS-PSK with username/password. We want to avoid setting up a CA for this offline network so we’re trying to use the TLS-PSK features.

We’re unable to get it working first in our lab. The docs seem pretty simple, but we’re clearly missing something. We followed the example in the tls-psk test itself.

If we disable PSK, the auth works fine on port 1883. So it’s not that issue. We cannot get a successful TLS-PSK connection to work with or without auth (username/password).

There is only one global listener and there is no firewall on the mqtt server in the lab yet. Meaning, everything is wide open on the same physical switch.

Pointers or advice?

The following is our lab config with throwaway values for psk and pwfile.

The OS is Debian 11.

mosquitto.conf:

# pidfile 
pid_file /run/mosquitto/mosquitto.pid

# logging
log_type all
log_dest file /var/log/mosquitto/mosquitto.log
log_timestamp_format %Y-%m-%dT%H:%M:%S
connection_messages true

# persistence
persistence true
persistence_location /var/lib/mosquitto

# authentication
allow_anonymous true
allow_zero_length_clientid true
password_file /etc/mosquitto/pwfile
psk_hint hint
psk_file /etc/mosquitto/psk

# queue mgt
max_queued_messages 0
max_inflight_messages 0

# listeners
listener 8883 
max_connections -1
protocol mqtt

/etc/mosquitto/psk:

1b67ecac-94b4-4238-9678-2ab3e3668402:db272179ae67e2df490c8a26405d77f1963c5c0107c33fb6352eeaca52a83f4830f141b92b14fd9d0f5e360ed96b1f8b1070c07b42638c22afe8ccab2a8a074b

/etc/mosquitto/pwfile:

testclient:$7$101$jCAzf9T9x+VJIf87$2BhJjW4QWOIhIt334VeGqm/hTQ1jq804YhEoNBveAyQujQVDqZ7nb7ocDF98xUaKA5XWX+ZYr4ngQA7r3j5s5g==

using mosquitto_pub or mosquitto_sub:

echo "testing" | mosquitto_pub -L "mqtts://testclient:passwordhere@localhost/privcdnlog" --psk "db272179ae67e2df490c8a26405d77f1963c5c0107c33fb6352eeaca52a83f4830f141b92b14fd9d0f5e360ed96b1f8b1070c07b42638c22afe8ccab2a8a074b" --psk-identity "1b67ecac-94b4-4238-9678-2ab3e3668402" -d -l

results in:

Client (null) sending CONNECT

In the logs we see:

2022-09-08T16:52:51: mosquitto version 2.0.11 running
2022-09-08T16:53:33: New connection from ::1:49772 on port 8883.
2022-09-08T16:53:33: Client <unknown> disconnected due to protocol error.

Using -L with mqtts:// sets the client to using TLS with x509 certificates. The server isn’t configured for using certificates, so it fails.

Try this instead:

echo "testing" | mosquitto_pub -u testclient -P passwordhere -h localhost -t privcdnlog --psk "db272179ae67e2df490c8a26405d77f1963c5c0107c33fb6352eeaca52a83f4830f141b92b14fd9d0f5e360ed96b1f8b1070c07b42638c22afe8ccab2a8a074b" --psk-identity "1b67ecac-94b4-4238-9678-2ab3e3668402" -d -l

Thank you for the quick response. We also tested not using -L to the same result:

echo "testing" | mosquitto_pub -u "testclient" -P "passwordhere" -h "localhost" -t "testlog" --psk "db272179ae67e2df490c8a26405d77f1963c5c0107c33fb6352eeac
a52a83f4830f141b92b14fd9d0f5e360ed96b1f8b1070c07b42638c22afe8ccab2a8a074b" --psk-identity "1b67ecac-94b4-4238-9678-2ab3e3668402" -i "local" -d -l
2022-09-09T13:19:20: New connection from ::1:45822 on port 8883.
2022-09-09T13:19:20: Client <unknown> disconnected due to protocol error.

The listener is on ipv4 and ipv6, but for testing purposes forcing it over ipv4:

echo "testing" | mosquitto_pub -u "testclient" -P "passwordhere" -h "127.0.0.1" -t "testlog" --psk "db272179ae67e2df490c8a26405d77f1963c5c0107c33fb6352eeaca52a83f
4830f141b92b14fd9d0f5e360ed96b1f8b1070c07b42638c22afe8ccab2a8a074b" --psk-identity "1b67ecac-94b4-4238-9678-2ab3e3668402" -i "local" -d -l
2022-09-09T13:31:36: New connection from 127.0.0.1:52816 on port 8883.
2022-09-09T13:31:36: Client <unknown> disconnected due to protocol error.

How do we get more info from the logs about “protocol error”? And the client now sends “local” as an identifier, but it isn’t reflected in the logs.

As a sanity test:

openssl s_server -nocert -psk 123456 and openssl s_client -psk 123456 works fine, so TLS-PSK is enabled and working in openssl itself.

We removed the default debian 11 bullseye mosquitto completely. Installed from the mosquitto repos. Now running 2.0.14 version.

same command line, same config. new error:

2022-09-09T14:22:33: mosquitto version 2.0.14 running
2022-09-09T14:24:00: New connection from ::1:50112 on port 8883.
2022-09-09T14:24:00: Client <unknown> disconnected due to malformed packet.

It seems MOSQ_ERR_MALFORMED_PACKET has more calls in the code. It’s unclear to us if the issue is in handle_connack.c, handle_publish.c, or somewhere else.

The solution is that psk_hint is listener specific, so setting up per listener settings allows tls-psk to work.