Uploaded image for project: 'JGroups'
  1. JGroups
  2. JGRP-2021

ENCRYPT: prevent messages from non-members


    • Icon: Feature Request Feature Request
    • Resolution: Done
    • Icon: Major Major
    • 4.0
    • None
    • None

      Although JGroups provides message encryption (ENCRYPT) and cluster admission control (AUTH), it does not prevent malicious attacks.

      For example, if a rogue node creates a minimal stack without encryption or authentication, then it is possible for that member to

      • Send messages to the cluster
      • Capture an existing message from a cluster member P, change it (e.g. the seqno) and resend it spooking P's address
      • Install a new view including itself
      • Possibly install a new shared key in ENCRYPT, thereby being able to receive cluster messages


      1. Prevent cluster members from delivering messages from a non-member (exceptions are join requests from new members and merge requests)
      2. Prevent a non-member from receiving any cluster messages

      The first goal also prevents rogue views from getting installed, or new shared secrets from being installed into ENCRYPT.

      Proposed solution

      • Use ENCRYPT for encryption of the payload and the headers
      • Now every message carries an encrypt header
      • (Let's assume for the moment that ENCRYPT is configured to use a shared key)
      • When a message is received, it is decrypted using the shared key (this can only be done by members having the shared key)
        • If the message doesn't have an encrypt header, it will be dropped
      • For some messages that carry their information in the payload rather than the headers, we don't even need to encrypt the entire message (which is faster), e.g.
        • Views and MergeViews: they are stored in the payload (GMS)
        • A new secret key sent by the key server is also stored in the payload (ENCRYPT)
        • We encrypt a phrase with the secret key. Everyone who has the shared key will be able to decrypt it and thus pass a message up. Messages from a non-member would be dropped.
        • Could the above also be done by the sender signing a phrase with its private key and the receiver decrypting it with the sender's public key, to enforce non-repudiation?
        • Hmm, this would be prone to replay attacks, so either the phrase would have to be changed every time, or the ENCRYT header would have to be encrypted as well (encrypt_entire_msg==true.
      • ALTERNATIVE II: digital signature
        • The sender creates a hash from the message (digest) and encrypts the digest with its secret key, and ships it with the message
        • The receiver decrypts the digest, computes the digest from the message and drops the message if the digests don't match
        • The diff to the first alternative is that a receiver doesn't even need to deliver the message and stop at (failing) de-serialization.
        • Downside: additional work to be done and space used when sending the signature with every message

      Scenarios to test (ENCRYPTTest)

      Catching a message from some member P, modifying it and re-sending it on behalf of P
      • A rogue member R could catch a message from P by simply joining the same multicast group and port
      • R could then increment the last seqno seen, e.g. 23, to 24 and send the message on behalf of P
      • However, the decryption won't work because R doesn't have the shared key. Also, modifying the headers and resending the message won't work as R cannot get at the headers because they're encrypted, too
      • R could still resend the captured message but that's useless as (a) one of the retransmission protocols (UNICAST3 or NAKACK2) will drop the duplicate message
      Installing a rogue view
      • This requires ENCRYPT to sit somewhere below GMS
      • R sends a new view consisting of the existing view plus R
      • If ENCRYPT passes the message up because it doesn't discard message without encrypt header, GMS will install the new view!
      The rogue node installing a new secret key in all members (ENCRYPT)
      • R sends a SECRETKEY msg with a new shared key, encrypted with its public key
      • Everyone install the new shared secret and R can now receive encrypted messages from cluster members!
      Non-member R sending a message encrypted with its own secret key
      • Cluster members would receive that message and decrypt it with their own (different) shared key, leading to garbage in the payload
      • The message would get delivered to the application but de-serialization would fail as the payload is garbage
        • See ALTERNATIVE above to prevent cluster members from delivering messages from rogue members in the first place


      • Rogue non-member R
      • Resending of captures (and unmodified) cluster messages by R: YES (however, those messages will get dropped by either NAKACK2 or UNICAST3 as duplicates)
      • Capturing and resending of messages as new messages by R (e.g. by incrementing the seqno): YES if ENCRYPT.encrypt_entire_msg is false, NO if true
      • Reception of cluster messages by R: YES, but R won't be able to read the contents as the payload is encrypted
      • Cluster members receiving messages from R: YES, but applications will throw an exception trying to read the contents of the payload as it is encrypted, and decryption failed as the secret key was wrong.


      • How do we handle (unicast) JOINs from non-members?
      • Ditto for merge requests (unicasts)

            rhn-engineering-bban Bela Ban
            rhn-engineering-bban Bela Ban
            1 Vote for this issue
            9 Start watching this issue