Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Let users of libp2p decide on authentication scheme #185

Closed
Warchant opened this issue Jul 8, 2019 · 5 comments
Closed

Let users of libp2p decide on authentication scheme #185

Warchant opened this issue Jul 8, 2019 · 5 comments

Comments

@Warchant
Copy link

Warchant commented Jul 8, 2019

So, according to noise spec there are 3 source payload security properties:

  1. No authentication. This payload may have been sent by any party, including an active attacker.
  2. Sender authentication vulnerable to key-compromise impersonation (KCI).
  3. Sender authentication resistant to key-compromise impersonation (KCI).

And 6 destination payload security properties:

  1. No confidentiality. This payload is sent in cleartext.
  2. Encryption to an ephemeral recipient.
  3. Encryption to a known recipient, forward secrecy for sender compromise only, vulnerable to replay.
  4. Encryption to a known recipient, weak forward secrecy
  5. Encryption to a known recipient, weak forward secrecy if the sender's private key has been compromised
  6. Encryption to a known recipient, strong forward secrecy

I, as a user of a perfect p2p library (which libp2p is), would want to configure my security adaptors to provide desired properties depending on my application (with some wise defaults).

Current implementations require dialer to know responder's peer id to do authentication. This requirement reduces number of different use-cases when libp2p can be applied.

This issue is a result of a discussion in #184.

@Warchant
Copy link
Author

Warchant commented Jul 8, 2019

This actually can be accomplished by integrating Noise. To use it, User would just create Noise security adaptor with a set of handshake patterns.

Example in pseudocode:

// security adaptor is created with desired handshakes
Noise noise(
  "Noise_XX_25519_AESGCM_SHA256",
  "Noise_IK_448_ChaChaPoly_BLAKE2b",
  ...
);

// then attached to a host (implementation specific)
Host h;
h.addSecurity(noise);

Since specific handshake pattern is a string, it can be added to a list of supported protocols and then negotiated by multiselect:

(v1):
/noise/34/Noise_XX_25519_AESGCM_SHA256
/noise/34/Noise_IK_448_ChaChaPoly_BLAKE2b

or

(v2):
/noise/Noise_XX_25519_AESGCM_SHA256/34
/noise/Noise_IK_448_ChaChaPoly_BLAKE2b/34

or

(v3):
/Noise_XX_25519_AESGCM_SHA256/34
/Noise_IK_448_ChaChaPoly_BLAKE2b/34

Note that 34 here is a noise spec revision.

@Stebalien
Copy link
Member

What are the use-cases you have in mind? The only use-case I can think of is bootstrapping of peers on the local network by guessing.

The hard requirement is that both sides of the connection need some kind of peer ID. Libp2p treats them like are like PIDs and pretty much all parts of libp2p break without them (which is why the "insecure" transport is currently broken). On the other hand, they can (in theory) be ephemeral.

Concerns:

  • My concern with respect to implementation is the libp2p interface. This feature is already technically possible at the protocol level for both TLS and SECIO. However, all the interfaces assume that peers are addressed by peer ID. Allowing peers to be addressed by multiaddr alone would require pretty significant changes and therefore pretty significant motivation.
  • My concern with respect to supporting it at all is the "middlebox" problem. ISPs love to "helpfully" man in the middle connections to "improve" end-user experience. One of the goals of libp2p is to restore the end-to-end principle so meddling ISPs can't do this.

However, you're right that being able to connect to a peer without knowing their peer ID is something a flexible network stack should support and I've personally wanted to be able to do this just for debugging (e.g., there's a peer running on some random IP, who is it?). It just needs some pretty significant motivation.

@mxinden
Copy link
Member

mxinden commented Apr 6, 2021

However, you're right that being able to connect to a peer without knowing their peer ID is something a flexible network stack should support and I've personally wanted to be able to do this just for debugging

@Stebalien do I understand correctly that go-libp2p does not allow connecting to an address without the peer ID of the node behind given address? I.e. does go-libp2p not offer a version of Connect taking an address only?

As a reference point in rust-libp2p there is both a dial with a peer ID and a dial_addr for an address only.

@aschmahmann
Copy link
Contributor

@mxinden yep, go-libp2p requires a peerID in order to make a connection.

If the application layer wants to find some out of band way to communicate the peerID with different security requirements (e.g. stored in a DNS TXT record, an HTTP server on some predetermined port on the same IP address, etc.) they can.

As an aside: IIRC most of the security negotiation protocols in use will compare the inbound public key to the peerID and error out if they aren't compatible. This means that if I really wanted an insecure dial it could likely be done via some wrapper that dials /some/address/p2p/BogusID and then on error retries with the peerID it just learned about in the failed security protocol negotiation.

@mxinden
Copy link
Member

mxinden commented Apr 7, 2021

Thanks @aschmahmann for the clarification.

I am closing here since (a) the discussion has stalled and (b) we are still missing a use-case. Please follow-up with a comment in case you would like to continue this discussion.

In case dialing an unknown node by its address only is a missing feature in go-libp2p I would suggest starting this discussion in one of the go-libp2p-* repositories.

@mxinden mxinden closed this as completed Apr 7, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants