MQTT-SN Authentication

This discussion is part of the standardization of MQTT-SN at OASIS. Here is a summary of the current issues we are working on. The issue for authentication is 568.

In the current MQTT-SN specification (1.2), there is no authentication capability included apart from the client id. This applied to the early versions of MQTT as well, so it’s not that surprising as MQTT-SN was derived from MQTT.

Later, userid and password fields were added to the MQTT connect packet, with optional external TLS encryption applied to the TCP/IP connection. In MQTT 5.0 an enhanced authentication capability was added by means of the new AUTH packet.

It’s generally agreed that we should add authentication to MQTT-SN. There are a few considerations which are different to MQTT however. MQTT is aimed at low powered devices, but MQTT-SN is notionally aimed even lower at connectionless network communications such as UDP where packet sizes are limited and TCP capabilities such as fragmentation do not exist.

So we need to be even more aware of data overhead, bloat and efficiency than we do with MQTT. In the base version of MQTT-SN, 1.2, there is a maximum of only one variable length field in each packet. This means that there is no length field apart from that for the whole packet, unlike in MQTT where there are many variable length fields each with its own length. So MQTT-SN is more efficient in terms of the size of each packet, at the expense sometimes of multiplying the number of packets needed. The MQTT-SN will message operations are an example of that.

The MQTT-SN 1.2 connect packet is structured like this:

Length n
(byte 0)
MsgType
(1)
Flags
(2)
ProtocolId
(3)
Duration
(4,5)
ClientId
(6:n-1)
MQTT-SN 1.2 CONNECT packet

The flags byte is an identical format for all the packets that use it, and is fully used – I’ll come back to that in a moment.

To add authentication to MQTT-SN I propose that an additional AUTH flag is added to the connect packet, which tells the server that an AUTH packet is going to be sent following the CONNECT packet. The AUTH packet consists of the following fields:

Length n
(byte 0)
MsgType
(1)
Length m
(2)
Auth Method
(3:m+2)
Auth Data
(m+3:n-1)
Proposed MQTT-SN AUTH packet with two variable length fields

This is designed to allow the operation of SASL framework authentication mechanisms and follows MQTT 5.0 closely. The current list of registered mechanisms includes PLAIN, a single message including the following fields:

  • authorization identity
  • authentication identity
  • password

each separated by a NUL (U+0000) character. Using this mechanism allows the CONNECT packet to be followed by an AUTH packet which includes a userid (authentication identity) and password, and so caters for the simple MQTT like case.

More sophisticated methods can also be used – this should allow any of the registered SASL mechanisms to be used. The server can also send an AUTH packet, either before a CONNACK, or during a session for re-authentication of the client.

It would be neater from a packet structure point of view if the authentication method were a fixed rather than variable length field. However, SASL mechanism names have a maximum length of 20 characters, so including a one-byte length field is going to be more efficient just about all the time.

Another alternative could be to have a one byte code for authentication method. But someone would have to maintain the table of translations from codes to meaning, or leave it to be implementation independent, hindering application portability.

Finally, to fit in the AUTH flag to the connect packet, some space will have to be made. As the CONNECT flags are a completely different set to those used in the other packets I propose that they are separated. The CONNECT flags:

x
(7)
x
(6)
x
(5)
x
(4)
Will
(3)
CleanStart
(2)
x
(1)
Auth
(0)
Proposed CONNECT flags; x means reserved

DUP
(bit 7)
QoS
(6,5)
Retain
(4)
x
(3)
x
(2)
TopicIdType
(1,0)
Proposed flags for other packets

I have left the positions of the existing fields unchanged for continuity, but they could be changed for neatness.

So this is my current first draft proposal. I’d like to get any thoughts that any of you might have. I haven’t used the SASL mechanisms myself so hearing from anyone who has could be particularly useful.

Can MQTT-SN out-perform MQTT?

I don’t know of any rigorous comparisons, mainly because up to now MQTT-SN has found only limited use.

I think MQTT-SN could perform better than MQTT under certain circumstances but I wouldn’t say it’s likely as a blanket statement.  First of all there are the different characteristics of UDP and TCP.  TCP has the reliability and segmentation, so the quality of your connections and payload sizes will be a factor.  For instance, if you have an unreliable (satellite) link, you may need to retry UDP messages yourself which could be worse than letting TCP do it for you.

There is at least one scenario where I think MQTT-SN should perform better than MQTT, and I think it’s a good way of thinking about the comparison.  In IBM we used to from time to time discuss how to get MQSeries used on financial trading floors.  There, TIBCO for one, reigned supreme, and we could not make headway because of performance.  The reason the competition performed better, in terms of message latency, was because they used UDP multicast.  Where MQ used TCP client-server connections for pub-sub (not MQTT but identical topology), TIBCO publishers would send messages to a multicast group.  The filtering for topics interested in was done at the client end – all messages would be received by the client library, but only those subscribed to would be passed on to the application.  I think that content was not encrypted (for speed), because the system was limited to the self-contained and isolated trading floor.  As soon as you add more connectivity you have to think about security, auth and encryption, which slows everything down from the optimal.

A similar solution can be implemented using MQTT-SN QoS -1, at least over UDP and I think could definitely be faster.  But multicast is limited to a LAN or subnet, not available on WANs.  QoS -1 multicast is inherently unreliable – although that’s probably just fine on a network that’s not overloaded.  Whether an MQTT-SN connection oriented UDP solution using MQTT-SN QoS 0, 1 or 2 would be faster than a similar MQTT one, I’m not sure.  The differences could be marginal.

In many cases, I think the fastest solution could be a fat MQTT pipe from the cloud to the MQTT-SN gateway, then MQTT-SN multicast on the LAN.  If you want high security then you might need a connection oriented MQTT-SN solution.  Going completely MQTT-SN instead of MQTT might be faster but I wouldn’t bet on it.  And I expect many solutions will need the extra features of MQTT; they wouldn’t be able to live with the limitations of MQTT-SN.