How to setup a ZMQ PUB/SUB pattern to serve only for pre-authorized subscriber(s)
Asked Answered
D

2

5

How can I implement or do kind of "hack" in PUB-SUB pattern to get an ability to publish only to authorized subscribers, disconnect unauthorized subscribers etc?

I googled for this problem, but all the answers very similar to set subscribe filter in subscriber side.

But I want, as I said, publish my updates from PUB only to those clients that passed an authorization, or have some secret key, that was received in REQ-REP.

Thanks for any ideas.

Dituri answered 11/6, 2015 at 15:8 Comment(3)
Maybe you could encrypt the publications, so that only subscribers that have received the decryption key can read them.Templas
Well, i thought about that. But in my opinion it is very time/resource-expensive due to 80% of publications are images parts already encoded to base64 because of my needs. So i'll use this variant in a last way. But thanksDituri
While the volume of pre-processing may be immense, these crypto-layer services might have been pre-scheduled / pre-computed in a distributed processing manner, so that the messaging-layer just PUB-s the content intended for a specific recipient. All remarks in the principal Answer below remain in place.Braque
T
8

Read Chapter 5 of The Guide, specifically the section called "Pros and Cons of Pub-Sub".

There are many problems with what you're trying to accomplish in the way you're trying to accomplish it (but there are solutions, if you're willing to change your architecture).

  • Presumably you need the PUB socket to be generally accessible to the world, whether that's the world at large or just a world consisting of some sockets which are authorized and some sockets which are not. If not, you can just control access (via firewall) to the PUB socket itself to only authorized machines/sockets.
  • When a PUB socket receives a new connection, it doesn't know whether the subscriber is authorized or not. PUB cannot receive actual communication from SUB sockets, so there's no way for the SUB socket to communicate its authorization directly. XPUB/XSUB sockets break this limitation, but it won't help you (see below).
  • No matter how you communicate a SUB socket's authorization to a PUB socket, I'm not aware of any way for the PUB socket to kill or ignore the SUB socket's connection if it is not authorized. This means that an untrusted SUB socket can subscribe ALL ('') and receive all messages from the PUB socket, and the PUB socket can't do anything about it. If you trust the SUB socket to police itself (you create the connecting socket and control the machines it's deployed on), then you have options to just subscribe to a "control" topic, send an authorization, and have the PUB socket feed back the channels/topics that you are allowed to subscribe to.

So, this pretty much kills it for achieving general security in a PUB/SUB paradigm that is publicly accessible.

Here are your options:

  1. Abandon PUB/SUB - The only way you can control exactly which peer you send to every single time on the sending side (that I'm aware of) is with a ROUTER socket. If you use ROUTER/DEALER, the DEALER socket can send it's authorization, the ROUTER socket stores that with its ID, and when something needs to be sent out, it just finds all connected sockets that are authorized and sends it, sequentially, to each of them. Whether this is feasible or not depends on the number of sockets and the workload (size and number of messages).
  2. Encrypt your messages - You've already said this is your last resort, but it may be the only feasible answer. As I said above, any SUB socket that can access your PUB socket can just subscribe to ALL ('') messages being sent out, with no oversight. You cannot effectively hide your PUB socket address/port, you cannot hide any messages being sent out over that PUB socket, but you can hide the content of those messages with encryption. Proper method of key sharing depends on your situation.
Technique answered 12/6, 2015 at 15:7 Comment(3)
As an addition, I'll note that if you don't use encryption, a malicious party can always grab your communication in transit under any circumstances. Whether that matters or not in your situation, I don't know. However, if you're on ZMQ >4.0, then you can use the baked in connection-level encryption, which at least protects data from outside snoopers.Technique
I'm with pyzmq, the python interface to it, and i wonder how i could get that connection-level encryption. how do i activate that?Dalmatian
@Dalmatian it's been some years since I've actively used ZMQ for anything, but we're well beyond the official support of crypto in ZMQ, so it should be accessible from within pyzmq. The closest I found in a few minutes of searching was this: pyzmq.readthedocs.io/en/latest/api/zmq.auth.htmlTechnique
B
2

As Jason has shown you an excellent review on why ( do not forget to add a +1 to his remarkable answer, ok? ), let me add my two cents on how:

Q: How?

A: Forget about PUB/SUB archetype and create a case-specific one

Yes. ZeroMQ is rather a very powerful can-do toolbox, than a box-of-candies you are forbidden to taste and choose from to assemble your next super-code.

This way your code is and remains in power of setting both controls and measures for otherwise uncontrollable SUB-side code behaviour.

Creating one's own, composite, layered messaging solution is the very power ZeroMQ brings to your designs. There you realise you are the master of distributed system design. Besides the academic examples, no one uses the plain primitive-behaviour-archetypes, but typically composes more robust and reality-proof composite messaging patterns for the production-grade solutions.

There is no simple one-liner to make your system use-case work.


While it need not answer all your details, you may want to read remarks

Braque answered 12/6, 2015 at 20:29 Comment(1)
Thanks for answer! Ok, i'll not forget add an [+1] not only to Jason, but for everyone who answered to me as soon as i get 15-reputation :)Dituri

© 2022 - 2024 — McMap. All rights reserved.