[zeromq-dev] ZMQ and the internet - desired/necessary features

Merijn Verstraaten merijn at inconsistent.nl
Mon Oct 22 11:42:18 CEST 2012

On Oct 22, 2012, at 01:10 , Ian Barber wrote:
> As well as the normal IP level filtering/firewalling, there is currently the flexibility to specify TCP accept parameters, with the sockopt ZMQ_TCP_ACCEPT_FILTER. That gives you some broad filtering of who can connect, which would be good enough for many situations. 

ZMQ_TCP_ACCEPT_FILTER doesn't really help in the case where you want to allow untrusted clients to connect, as they could jump through whatever authentication hoop required to be added to the ACCEPT filter and then still connect using an existing identity, resulting in a denial of service.

> That said, just inspecting and dropping bad messages would probably work as well. For your case (a connected, valid client starts doing Bad Things) I would say for PUB/SUB there is only a HWM controllable risk, but for ROUTER there would be value in being able to kick off a certain identity.

For inbound messages this is obviously sufficient, for outbound messages you'd also want the ability to stop bad identities from misrouting/DOS'ing valid outbound messages.

> I would definitely try and nail down more precisely the kind of scenario you're concerned about, and work out the most minimal change that could resolve it.

Minimal scenario I'm worried about consists of two orthogonal issues:
ROUTER: Clients connecting with identities that hijack existing connection/"reserved" identities (i.e. internal infrastructure use).
PUB/XPUB: Clients subscribing to to topics they shouldn't.

> Be aware that TCP is just one of the transports, and for core library features we should be looking for as wide support as we can reasonably achieve (so I should be able to handle a bad client over IPC etc.).

Most reasonable implementations I think should work for any transport, except maybe inproc, but authentication for inproc transport doesn't really make sense anyway...

On Oct 22, 2012, at 06:52 , Pieter Hintjens wrote:
> On Mon, Oct 22, 2012 at 8:10 AM, Ian Barber <ian.barber at gmail.com> wrote:
>> The bad person snooping problem I would handle over the top of ZeroMQ rather
>> than trying to solve at that layer - it's much easier (and generally more
>> pleasant) to separate message delivery from distribution using a bit of
>> crypto.
> Yes, indeed. I'd leave the sockets for what they are - queuing and
> routing engines - and add security at the transport and firewall
> layer. In any case without strong encryption you just shift the bar.
> Hostiles can still snoop and spoof and intercept.
> What would be ideal is a tls:// transport. Cue dramatic music…

I agree that securing the transport is the only sensible way to deal with MITM/snoopers on the network, trying to protect against those in ZMQ itself (aside from a possible TLS/whatever transport) in pointless.

However, I disagree that using crypto to control delivery of PUB messages is the easiest solution to authenticating broadcasts. If subscription authorisations are semi-static then this is indeed a good solution, but if subscription authorisations are transient then you introduce a lot of complication and overhead. Any time any client needs to be unsubscribed from a subscription you have to rekey all remaining clients authorised for that subscription. Being able to unsubscribe a connection on the server side is much more elegant. Granted, this won't work with the epgm transport's client side filtering, but then it seems unlikely that someone would run those over an untrusted network.

I'm willing to concede that you could perhaps deal with the subscription authorisation issue by doing subscriptions server side (one SUB socket per client) and then forwarding to a ROUTER that sends to the appropriate client, it's just that that design makes me wish there was a more elegant build in way to do this with ZMQ.

In summary, I think:
The minimal scenario ROUTER needs to be able to deal with to be usable on a public network is clients setting malicious identities. This means:
 - Check whether identity is allowed before letting client connect
 - Disconnecting a given identity
 - Not allowing connections using an identity that is already connected

I think these should be implementable for all transports, except maybe epgm? (although an implementation for inproc seems fairly silly) I think it's still worth implementing even without support for epgm (which I don't think is commonly used on public networks anyway?).

PUB/XPUB can be used on public networks, but to avoid frequent rekeying between clients and server it would be a "nice to have" if PUB/XPUB could:
 - Conditionally accept incoming connections
 - Conditionally accept incoming subscriptions
 - Disconnect a specific connection
 - Unsubscribe a specific connection

Clearly won't work for epgm, since it has clients side subscription filtering. But don't see why it couldn't work for the other transports. As mentioned earlier, this is completely orthogonal to transport security (i.e. preventing MITM/snooping) and more to avoid application level snooping my valid clients with limited authorisation.


More information about the zeromq-dev mailing list