Why the spec says that in case of client ID clash, it is the old client that gets kicked out?

907 views
Skip to first unread message

marco.m

unread,
Sep 10, 2013, 9:08:01 AM9/10/13
to mq...@googlegroups.com
Hi all,

I just love MQTT :-)

in section 3.1 "Connect" of the MQTT 3.1 specs, it says: "If a client with the same Client ID is already connected to the server, the "older" client must be disconnected by the server before completing the CONNECT flow of the new client".

This to me looks the opposite of how it should be for the following reasons:
- It is a DoS because I can cause other clients to be kicked off
- it is an easy source of kick-off loops if two clients with the same ID just keep reconnecting (which they would do by default with a client library).
- it is difficult to work around if I don't want random client ID, because it is the wrong client that gets disconnected.

As a client, if I want to control my client ID and not use a random one, I'd prefer to be told by the broker that my client ID is already taken, so that I can take appropriate measures (change my client ID, alert somebody is this is a bug, ...).

Are you aware of any MQTT application that relies on this behaviour? I am probably going to modify Mosquitto to invert the behaviour, and I am wondering if this could have any potential ill side-effects...

thanks
marco.m

Nicholas O'Leary

unread,
Sep 10, 2013, 4:09:51 PM9/10/13
to mq...@googlegroups.com
Hi Marco,

the main side-effect is that you will no longer be compliant with the MQTT spec. The OASIS standardisation work reaffirms this requirement: If the ClientId represents a client already connected to the server then the server MUST 
disconnect the existing client.

>> - It is a DoS because I can cause other clients to be kicked off
True, but if you are running a public broker where random clients can try to connect, you really should also be using authentication/authorisation to prevent this.

>> - it is an easy source of kick-off loops if two clients with the same ID just keep reconnecting (which they would do by default with a client library).
None of the client libraries I know of have a 'default' client ID that would lead to this behaviour.

>> - it is difficult to work around if I don't want random client ID, because it is the wrong client that gets disconnected.
What do you mean by 'wrong client gets disconnected'? It is not difficult to work around. Clients should identify themselves properly.


Regards,
Nick




--
--
To learn more about MQTT please visit http://mqtt.org
 
To post to this group, send email to mq...@googlegroups.com
To unsubscribe from this group, send email to
mqtt+uns...@googlegroups.com
 
For more options, visit this group at
http://groups.google.com/group/mqtt
 
---
You received this message because you are subscribed to the Google Groups "MQ Telemetry Transport" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mqtt+uns...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Raphael Cohn

unread,
Sep 10, 2013, 5:06:10 PM9/10/13
to mq...@googlegroups.com
Thie behaviour is actually essential for long-running apps. It allows a client to take over a stalled connection in a high availability / reliability set up, eg when a client virtual server/ box dies and is automatically replaced. Other mq protocols have similar behaviours. In AMQP it's called "link stealing".


Sent from Samsung Mobile

marco.m

unread,
Sep 11, 2013, 2:09:07 AM9/11/13
to mq...@googlegroups.com, Raphael Cohn
Hey Raphael,

ahhh, now I understand. A little voice was telling me that there must be a reason for this apparently counter-intuitive behavior.

thanks
marco.m

marco.m

unread,
Sep 11, 2013, 2:37:24 AM9/11/13
to mq...@googlegroups.com
Hey Nick,

[btw, thanks for making node red opensource. I still haven't played with it but the idea is so good :-)]

inline


On Tuesday, September 10, 2013 10:09:51 PM UTC+2, knolleary wrote:
Hi Marco,

the main side-effect is that you will no longer be compliant with the MQTT spec. The OASIS standardisation work reaffirms this requirement: If the ClientId represents a client already connected to the server then the server MUST 
disconnect the existing client.

OK. The main reason I asked this question is exactly because I would break compliance and I wasn't sure. Now with Raphael's answer and yours I know the situation and the rationale. I have to think a bit more before going ahead :-)


 >> - It is a DoS because I can cause other clients to be kicked off
True, but if you are running a public broker where random clients can try to connect, you really should also be using authentication/authorisation to prevent this.

Yes, I will be using authentication, no anonymous clients will be allowed. Still, a DoS is possible, either maliciously or as a bug in constructing the client ID (again, assuming the design calls for specific client ID without random components).

If the DoS is malicious, I can track the identity behind the client ID (identity or MQTT username != client ID) and eventually revoke it, but the DoS already happened.
 

>> - it is an easy source of kick-off loops if two clients with the same ID just keep reconnecting (which they would do by default with a client library).
None of the client libraries I know of have a 'default' client ID that would lead to this behaviour.

I wasn't clear. Let me explain with more details:

Say the clientID is built as tag1-tag2-tag3, where there is an algorithm to determine the tag names in a way to avoid duplicates. If there is a bug in the algorithm or malice, it is possible to have a clash. Yes I could add a random 4th tag to reduce the likelihood of the clash, and probably this is what I will do if I want to stay compliant.

But, in case of clash, the client library by default will reconnect, and the kick off loop will begin. This is what I meant with "by default": the fact that it reconnects automatically. Tested with Mosquitto client lib. And this default is the only sensible behavior: if you are disconnected, then reconnect.


>> - it is difficult to work around if I don't want random client ID, because it is the wrong client that gets disconnected.
What do you mean by 'wrong client gets disconnected'? It is not difficult to work around. Clients should identify themselves properly.

Let me explain based on the tag1-tag2-tag3 of the previous answer:

At time t0 client1 builds its client ID as foo-bar-pizza (hey I am Italian :-) and connects to the broker.
At time t1 client2 is buggy and builds its client ID as foo-bar-pizza too and connects to the broker.
At time t2 Upon receiving the connection request of client2, the broker will kick off client1
At time t3 Poor client1 reconnects.
When broker receives connection request from client1, kicks out client2
and the loop begins

The workaround I was mentioning is that at t3, client1 before reconnecting must change its client ID. In this scenario, client1 is "the wrong client" to be disconnected, and "the wrong client" to have to change its ID.

To summarize: either I add a long enough random string to the client ID, or I change the broker behavior to become not compliant. I have to think about it.

thanks
marco.m

Roger Light

unread,
Sep 11, 2013, 3:05:03 AM9/11/13
to mq...@googlegroups.com

Hi Marco,

Another possibility would be to require that client id == username. It ought to be easy to enforce this at the broker.

Cheers,

Roger

marco.m

unread,
Sep 11, 2013, 7:23:32 AM9/11/13
to mq...@googlegroups.com, ro...@atchoo.org
Hey Roger :-)

Yes, I was considering also that option (enforcing a prefix of the Client ID to be == the username) at the broker. If I go that route, I'll provide a (configurable) patch to Mosquitto.

thanks
marco.m

Karl Palsson

unread,
Sep 11, 2013, 7:49:40 AM9/11/13
to mq...@googlegroups.com
On Tue, Sep 10, 2013 at 11:37:24PM -0700, marco.m wrote:
> Yes, I will be using authentication, no anonymous clients will be allowed.
> Still, a DoS is possible, either maliciously or as a bug in constructing
> the client ID (again, assuming the design calls for specific client ID
> without random components).
>
> If the DoS is malicious, I can track the identity behind the client ID
> (identity or MQTT username != client ID) and eventually revoke it, but the
> DoS already happened.

Our approach to this is to simply not allow clients to provide their own ID. We have a
(https) webservice that assigns them a mqtt client id and the TLS-PSK that goes with
it. (We let them provide a "hint" that we may or may not use in the id that we give back,
so the client id can have _something_ human friendly in it, but we simply don't trust the
mqtt client to provide a guaranteed unique client id)

The DoS then is that they can keep attempting SSL connections, but there's no way for them to try and
guess/determine another users mqtt client id and affect that user in anyway. (Unless they get that
users TLS-PSK of course, but if they get that, then we're not talking about DoS anymore)

> >> - it is an easy source of kick-off loops if two clients with the same ID
> > just keep reconnecting (which they would do by default with a client
> > library).
> > None of the client libraries I know of have a 'default' client ID that
> > would lead to this behaviour.
> >
>
> I wasn't clear. Let me explain with more details:
>
> Say the clientID is built as tag1-tag2-tag3, where there is an algorithm to
> determine the tag names in a way to avoid duplicates. If there is a bug in
> the algorithm or malice, it is possible to have a clash. Yes I could add a
> random 4th tag to reduce the likelihood of the clash, and probably this is
> what I will do if I want to stay compliant.

Yep, see above .)

Note of course, that these (generally) require a sane broker that doesn't enforce the [rude words] 23
char clientid limit.

Cheers,
Karl P

> >> - it is difficult to work around if I don't want random client ID,
> > because it is the wrong client that gets disconnected.
> > What do you mean by 'wrong client gets disconnected'? It is not difficult
> > to work around. Clients should identify themselves properly.
> >
>
> Let me explain based on the tag1-tag2-tag3 of the previous answer:
>
> At time t0 client1 builds its client ID as foo-bar-pizza (hey I am Italian
> :-) and connects to the broker.
> At time t1 client2 is buggy and builds its client ID as foo-bar-pizza too
> and connects to the broker.
> At time t2 Upon receiving the connection request of client2, the broker
> will kick off client1
> At time t3 Poor client1 reconnects.
> When broker receives connection request from client1, kicks out client2
> and the loop begins
>
> The workaround I was mentioning is that at t3, client1 before reconnecting
> must change its client ID. In this scenario, client1 is "the wrong client"
> to be disconnected, and "the wrong client" to have to change its ID.
>
> To summarize: either I add a long enough random string to the client ID, or
> I change the broker behavior to become not compliant. I have to think about
> it.
>
> thanks
> marco.m
>

marco.m

unread,
Sep 11, 2013, 11:30:34 AM9/11/13
to mq...@googlegroups.com
Hey Karl,

thanks for explaining how you do it.

Although in my case I cannot use an OOB mechanism like yours (HTTPS), you are confirming that what I want to do (a human readable client ID with a given set of guarantees) can make sense :-)

thanks
marco.m

kasisripada17

unread,
Oct 18, 2016, 12:33:29 PM10/18/16
to MQTT
is there any way to know the client is online or not?
Reply all
Reply to author
Forward
0 new messages