[zeromq-dev] Topics for ZMTP 3.0

Ciprian Dorin Craciun ciprian.craciun at gmail.com
Mon Jun 10 14:34:51 CEST 2013


>>     The same observation can be made for all the cases.  Moreover the
>> reconnection handling seems a little bit fuzzy to me (at a first
>> glance), some cases allowing reconnect, some not, and in all cases you
>> can't deduce what has actually happened with the other peer.  Maybe
>> all cases should be handled with an exponential backoff approach.
>
> Could be. I'm not sure what the best approach is here. The goal was to
> detect failed authentication as different crashed peer, without any
> explicit error code in the first case (I want the server to simply
> drop connections from invalid clients). In the former, clients don't
> want to reconnect, but in the latter they do. In practice it's no more
> than a hint.
>
> It might turn out that an explicit "rejected" response is better than
> cutting the connection.

    Indeed a rejection message should ease the debugging.

    For example I appreciate the error handling of the SPDY protocol
(and based on that the future HTTP 2.0).  It allows you to pin-point
which of the multiplexed streams caused the error, which was the
latest interpreted message of that stream, etc.

    For that matter I think you should throw a closer look at SPDY's
framing, although in SPDY the accent is on multiplexing, content and
flow control.


> Over clear text, there are so many attack possibilities I think we
> have to assume that'll only be used in constrained environments.

    I think this is the main "Achilles' heal" of ZeroMQ:  the
"advised" (better said "required") controlled environment.  You can't
use ZeroMQ "over the Internet" without special measures...


>>     (D) In the case of an "encrypted" connection, the specification
>> says that the messages are "wrapped" in commands.  This means that an
>> attacker can identify how many messages, and how large, each peer has
>> exchanged.
>
> Yes, indeed. However this can be masked by the mechanism, e.g.
> resizing messages, adding fake ones, etc.

    I don't think it's advised to apply "chaffing" to obscure the
payloads, mainly because it overloads the network, and I don't think
it provides enough security.


>>     Maybe the "safest" solution is to require the following:
>>     * completely specify (in the ZMTP specification) a few transport
>> security mechanisms; (just for example like: use RC4, or use AES 128
>> in CTR mode, etc.;)
>
> We can certainly add some conventional mechanisms. The reason for
> choosing CurveCP as the starting point was to not claim that space.
> People have already discussed a DTLS mechanism which seems ideal.

    Then, if DTLS already seems a good enough solution, why not choose
that as the specified solution?


>>     (E.1) I find it odd that the "connection meta-data" is a
>> by-product of the security, thus reducing the reuse potential of the
>> ZAP protocol.
>
> True. It seems wise to not send any meta-data until after
> authentication, to reduce the information one can gain by probing a
> system. What I expect is that we'll expand ZAP with meta-data to send
> back to the peer after successful authentication.
>
> Meta-data has to be encrypted by the mechanism (if it encrypts), but
> the three mechanisms so far use the same format for meta-data (a
> key/value table).

    This solution still doesn't address my main concern, that of the
security solution (via ZAP) needing to support meta-data handling,
even though that meta-data doesn't refer to the security itself.

    My proposal would be something like this:
    * phase (1) establish channel, and negotiate ZMTP version (the handshake);
    * phase (2) via commands, and delegated through ZAP, negotiate security;
    * (after this security is applied;)
    * phase (3) (currently missing and folded in phase (2)) negotiate
any other connection related meta-data (like socket type, identity,
etc.);
    * phase (4) switch to message mode;


>>     (E.2) Shouldn't the "identity" be mandatory?
>
> It's optional for sockets that talk to ROUTER sockets, and not used on
> other sockets.

    I don't get this, mainly because I didn't follow closely enough
ZeroMQ developments.  But isn't the identity of the remote peer chosen
by that remote peer itself?  In this new version the identity is
chosen by the local peer?

    I would think that enforcing identity specification could at least
help in debugging, manly because it's the only way in which you can
determine the source of a message (if the source isn't embedded in the
message by the application).


>>     (F) As an observation, I've once read the specification for SOAP,
>> and found a very nice feature that I've failed to see in other
>> "transport" mechanisms: mandatory vs optional envelope elements (I
>> think "elements" were called?).  For example we could say something
>> like this in ZMTP:  all commands have a "mandatory" flag, that if
>> present the other peer must either understand them or fail;  if not
>> mandatory they can be ignored, but replied back as not-understood.
>
> I'd have to see what problem this solves in ZMTP; the goal above all
> is to keep this simple.

    It could be used by future ZMTP libraries to "augment" the
protocol without actually inventing a new version of it.  (However as
said the implementers should refrain on putting too much logic in
these extensions.)

    A practical example of this:  imagine that commands with the a
"mandatory" flag already existed in v1 of the protocol.  In that case
"subscriptions" could have been pushed by the `SUB` sockets to `PUB`
sockets as an "optional" command, without introducing a new type of
socket, and without breaking the older libraries, because these
commands would have been ignored.


>>     (G) For the purpose of replying back if a command is not
>> understood, or for asynchronous parallel commands, wouldn't it be
>> better if all the commands are identified with a unique identifier
>> chosen by the sender?
>
> We're very far from needing this level of dialog. E.g. for CurveZMQ:
>
> curvezmq = C:hello S:welcome C:initiate S:ready *message
>
> ZAP needs it so the caller can re-route replies correctly.


    I understand that there needs to be a balance between simplicity
and functionality, and why ZMTP strives not to be AMQP.  However the
main problem with ZMTP (v1) was its "extreme" simplicity, which we now
pay by having a third completely incompatible protocol, whose
versioning negotiation relies on sending half of well defined
messages...

    As such a little "extensibility" wouldn't hurt in the long term.
For example adding a few bytes (in the form of a required frame) to
each command wouldn't cost much (especially since even ZAP demands
it).  (The same reasoning could be applied to the "mandatory" flag,
even though in v3.0 it can be said to be "always on".)


>>     As a general remark, I think ZMTP is still balanced in terms of
>> complexity and what it offers.  Good work!
>
> Thanks for the feedback. If you don't mind I'll add you to the list of
> contributors to ZMTP.

    Thanks for adding me to the contributors list, however I don't
think I've contributed much. :)  (However if my time permits, I'll
want to experiment with a pure Erlang implementation of ZMTP v3.)

    Ciprian.



More information about the zeromq-dev mailing list