libp2p / specs

Technical specifications for the libp2p networking stack
https://libp2p.io
1.55k stars 273 forks source link

SECIO: [Feature Request] Possibilty of dumping keys #46

Closed mkg20001 closed 3 years ago

mkg20001 commented 6 years ago

Currently there is no way to dump the keys in order to decrypt traffic for debugging purposes. I am currently writing https://github.com/mkg20001/libp2p-dissector so I wanted to request this here instead of creating my own unofficial hack.

Stebalien commented 6 years ago

I take it you want the internal symmetric session keys? We use DH so extracting the private keys ahead of time won't be sufficient.

FYI, you can actually disable encryption entirely with the --disable-transport-encryption flag (although your node will then refuse to connect to any secure nodes).

mkg20001 commented 6 years ago

I take it you want the internal symmetric session keys? We use DH so extracting the private keys ahead of time won't be sufficient.

Yes

FYI, you can actually disable encryption entirely with the --disable-transport-encryption flag (although your node will then refuse to connect to any secure nodes).

That's why I want to add this

Stebalien commented 6 years ago

Can you think of a way to do this non-invasively? I.e., in a way that doesn't add a bunch of hacks?

mkg20001 commented 6 years ago

One way would be to add an environment variable like KEYLOGFILE similar to how that's handled in SSL/TLS. The keys could be dumped in a simple protobuf format into the file specified by the env variable.

raulk commented 6 years ago

I wonder if this functionality could be part of a dedicated control plane protocol for libp2p, e.g. /p2p-instrument/1.0.0. This would be a highly privileged channel that could restrict inbound connections via a Protector (pnet, or similar) to allow only inbounds from localhost or IPC.

In this manner, we use libp2p's own mechanisms to provide meta-functionality like dumping secrets, or metrics, for debugging and monitoring tools. In the future we could do other things. Such a solution would avoid making libp2p depend on the filesystem, as that comes with complexities of its own (e.g. cleanup).

Just a fleeting thought, not married to the idea ;-)

Stebalien commented 6 years ago

The problem here is that this needs access to ephemeral, internal, secio-specific secrets. However, we generally do need some form of "stats" feature so we could expose these secrets that way (it's just that wiring all this up will be non-trivial).

mkg20001 commented 5 years ago

However, we generally do need some form of "stats" feature so we could expose these secrets that way (it's just that wiring all this up will be non-trivial).

I don't think it should be anywhere in stats.

I wonder if this functionality could be part of a dedicated control plane protocol for libp2p, e.g. /p2p-instrument/1.0.0. This would be a highly privileged channel that could restrict inbound connections via a Protector (pnet, or similar) to allow only inbounds from localhost or IPC.

I wouldn't ever recommend exposing this via the network


The best way to implement this, would be by using an environment variable (or in the case of the browser a globally defined variable that contains a function that is called whenever new keymaterial is available, so an extension could move it to a file - but this is the only exception since the browser lacks an FS api) That's hard to mess with, since it has to be set before startup and can only be accessed with a full compromise (at least userspace RCE capabilities) of the machine the node is running on (besides memory-based attacks) Additionally this way no keys get uselessly stored (as would be the case if this would ever be accessible from the network and enabled by default)

So basically something like an environment variable named SECIO_KEY_DUMP_FILE could be added which would contain a path to a file where a protocolbuffers serialized object containing the keymaterial is being continuously written and separated by length-prefixes.

Effectively a stream of:

<LP><SECIODump{keys, peerIDRemote, peerIDLocal}>

with the following .proto:

message SECIODump {
  bytes keys = 1;
  bytes peerIDRemote = 2;
  bytes peerIDLocal = 3;
}
Stebalien commented 5 years ago

What if we had a build flag, environment variable, and then a loud message printed on start? Rebuilding with a custom flag is usually easy enough.

mkg20001 commented 5 years ago

It's a bit cumbersome having to rebuild ipfs, unless official debug releases get published with that flag, so one can easily switch the binaries

Additionally js doesn't have build flags

Stebalien commented 5 years ago

Assuming go is installed, IPFS can be built and installed with.

> go get -tags=key-dumping github.com/ipfs/go-ipfs/cmd/ipfs@v0.4.22

Given that this should only be used by people who really know what they're doing, I'd like to optimize for redundant checks over ease of use.

Stebalien commented 5 years ago

Why I'd like this to be a build flag: https://textslashplain.com/2019/08/11/spying-on-https/

mkg20001 commented 5 years ago

My argument wasn't strictly against the build flag, but instead I proposed that prebuilt binaries with that flag (so as to be useable as a drop-in replacement for debugging purposes) should be available

Stebalien commented 5 years ago

Ah. Fair enough.

raulk commented 4 years ago

@michaelvoronov has a fork of go-libp2p-secio that dumps keys in a keylog file here: https://github.com/libp2p/go-libp2p-secio/compare/master...michaelvoronov:master

mikevoronov commented 4 years ago

Hi, after spending some time with dissecting IPFS traffic, I realized that it is also needed to dump timestamps when keys were generated (especially if we want a heuristic dissector). I'm experimenting with IPFS now, but ready to discuss and prepare PR if needed.

raulk commented 4 years ago

@michaelvoronov Hey! Yes, it would be fantastic to get a PR on the secio repo for this!

mxinden commented 3 years ago

I am closing here since SECIO has been deprecated. Please open up a new issue in case you would like to see a similar feature for another authentication / encryption protocol or would like to continue the discussion on the metaprotocol /p2p-instrument/1.0.0.