go-libp2p icon indicating copy to clipboard operation
go-libp2p copied to clipboard

feat: add NetworkCookie option for isolating testnets

Open ivan4th opened this issue 2 years ago • 3 comments

Motivation: sometimes, it's necessary to be able to isolate testnets from the real networks, avoiding some hard-to-diagnose issues. This was previously achievable using Noise Prologue, but was impossible for e.g. QUIC transport.

This adds NetworkCookie libp2p option that prevents peers with different NetworkCookies from connecting to each other. The peers without a NetworkCookie can't connect to or receive a connection from a peer with a NetworkCookie.

This is not a replacement for private networks, just a safeguard against unintended testnet / mainnet interaction.

This PR replaces #2645 which only worked for QUIC and didn't have proper "facade". This change works for all transports.

The usage is as follows

nc := []byte{...}
// or:
// nc, err := crypto.ParseNetworkCookie("0123ab")
// ...
h, err := libp2p.New(libp2p.NetworkCookie(nc), ...)

Implementation details:

  • for TLS, an extra field with the network cookie is added to the TLS extension in a backward-compatible way; the field is included in the signature
  • for Noise, Noise Prologue is used for the network cookie. In case of WebRTC, the prologue is extended with the network cookie if it is specified
  • for the insecure transport, an extra field is added to the exchange message in a backward-compatible way

Additional implementation notes:

  • if you think that "network cookie" is not the proper name for this construct, it can of course be renamed
  • instead of adding an extra argument to the transports / security transports, I've made the network cookie "attachable" to the private key. This might seem a bit strange, but it reduces incompatibilities with existing codebases.

ivan4th avatar Dec 01 '23 03:12 ivan4th

This is a massive change. If you want to make this happen, this will need proper specification in the specs repo before we can make any progress here.

marten-seemann avatar Dec 01 '23 04:12 marten-seemann

@marten-seemann The change is not that big if you don't count the tests, but sure, as there are (backward-compatible) changes on the protocol level I will work on a PR for the specs repo. It's worth noting that the feature will become unnecessary when all the transports get private network support, but IIUC that might take quite some time, so it may make sense to have NetworkCookie for a while and then eventually deprecate it.

ivan4th avatar Dec 01 '23 13:12 ivan4th

This is a wide-reaching spec change and it's not clear that it's the right solution. It definitely requires a spec proposal so we can discuss alternatives.

The usual way to fix this is:

  1. Create independent DHTs by using the ProtocolPrefix DHT option (designed to solve exactly this problem).
  2. Use separate pubsub topics for each network.

Otherwise, it's impossible for peers to connect to both networks at the same time which is actually desirable in some cases. To be clear, private networks were never intended to be used as a way to isolate networks this way, they were designed to provide authentication and privacy.

Stebalien avatar Dec 04 '23 06:12 Stebalien

If we want this to be a change compatible across libp2p clients, a spec needs to be introduced in libp2p/specs.

If you want this just for your use case, you can either use your fork or add some logic to your application to disconnect from a peer if the don't support a certain protocol.

Either way this PR isn't the path forward here.

MarcoPolo avatar Jun 03 '24 18:06 MarcoPolo