Magiselect - Wire Transparent security « handshake »
Nobody has claimed this yet.
- Dominant language
- No language data
- Stars
- 1.8k
- Forks
- 320
- Avg merge
- 11d 15h
- Merged PRs (30d)
- 1
Description
Requirements
With Encrypted-Client-Hello RFC in the work it would help to have plain TLS connections in Libp2p as we can then wrap them in ECH (*we will need to figure out KEM preshared keys).
The quic and webtransport transports are already ECH ready, however for TCP connections we still have the multistream protocol id which blow away any hope of stealthish libp2p.
Spec
Security in the maddr
Add meaning to some maddr components after tcp component indicating to the client they are allowed to skip the multistream part of the handshake.
Server side recommendations
This part of the spec is non normative because we can't check for it. We should evolve it if new things running on top of TCP are added.
A valid implementation is to use a different TCP Port for each protocol you want to support, for example:
/ip6/::1/tcp/4011/tls
/ip6/::1/tcp/4012/noise
and not doing selection, and this usecase should be guaranteed so you can use a TLS / HTTPs reverse proxy switching on the ALPN as your libp2p gateway (allowing to create an anonymity set when using ECH).
However TCP listeners are costy from a user configuration end, it is much easier if the same port can be upgraded to support plain TLS just by doing a bit of magic.
First read three bytes from the inbound stream.
If you failed to read three bytes within your timeout windows, this can be discarded as very likely not a libp2p connection.
If these three bytes are:
- equal to
\x13/mtreat it as multistream. - equal to
GET,HEA,POS,PUT,DEL,CON,OPT,TRAorPATtreat it as an HTTP1.x- next is implementation specific, may do HTTP muxing or treat as websocket transport
- equal to the unhexed
160301,160302,160303or160304treat it as a TLS connection., however handling them allows your TLS server to do a proper rejection and simplify the code complexity.160301and160302might be useless as they are only used for TLS1.0 and TLS1.1 which shouldn't be used
Turns out go'scrypto/tlsalways sends TLS1.0 withclient_versionto 1.2 or 1.3.160303is used both by TLS1.2 and TLS1.3 and160304is TLS1.3, so they must be used as libp2p's TLS spec requires TLS1.3.
- Let
typebe the the three lsb of the third byte as an unsigned integer.
typemust be<= 5(as there is no 6 or 7 wire values).
Letfieldbe the the five msb of the third byte an unsigned integer shifted right three times.
Depending on the value offield:1(identity_key),2(identity_sig) or3(dataremoved in 4b052c0df0b866c246991e59385fb2bf902820b7)typemust be2(LEN), treat it as noise.4(extensions)typemust be2(LEN) or3(SGROUP deprecated), treat it as noise.- Something else, this is not a noise connection.
Notes:
- The noise detection is currently dependent on noise's spec protobuf schema, if we improve it to allow any valid looking protobuf I think it would clash with HTTP and or multistream-select.
- We can be stricter about noise by ensuring the first two length bytes are big enough to make a valid protobuf messages but that looks good enough for me (it would only help rule out non libp2p protocols earlier).
- TLS and Noise don't clash because TLS versions decode with a
0protobuf field ID which is not valid protobuf. - Neither HTTP nor multistream-select clash with noise because I exhaustively checked it: https://go.dev/play/p/N3RpeJ1tkrs
Expected usage.
A server implementing magiselect on one TCP port might announce theses maddrs:
/ip4/1.2.3.4/tcp/12345backward compat multistream-select/ip4/1.2.3.4/tcp/12345/tlsstraight tls/ip4/1.2.3.4/tcp/12345/noisestraight noise/ip4/1.2.3.4/tcp/12345/wswebsocket transport on the same port as tcp transport/ip4/1.2.3.4/tcp/12345/wsswebsocket secure transport on the same port as tcp transport, differentiated from libp2p's TLS due to ALPN.
multistream backward compatibility
Currently go-libp2p's server sends /multistream/1.0.0 before having received anything.
This behavior would change as we need to run detection on the first bytes sent by the client.
https://github.com/libp2p/specs/tree/master/connections says:
Next, both peers will send the multistream protocol id to establish that they want to use multistream-select. Both sides may send the initial multistream protocol id simultaneously, without waiting to receive data from the other side. If either side receives anything other than the multistream protocol id as the first message, they abort the negotiation process.
But I don't see why this is not a compliant implementation:
- Client open connection.
- Client waits to receive
/multistream/1.0.0. - Server receive connection.
- Server waits to receive
/multistream/1.0.0. - 🦗 deadlock
I read this part of the multiformats spec as understanding this as the client should go first:
# open connection + send multistream headers, inc for a protocol not available
> /multistream/1.0.0
> /some-protocol-that-is-not-available
# open connection + signal protocol not available.
< /multistream/1.0.0
< na
I think this can be solved by reviewing known implementations and making sure the client always send /multistream/1.0.0 without waiting on the server and updating the multistream-select spec to reflect that (while still allowing servers to optionally send it early).
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reading the connections specification linked in the issue and the multistream-select behavior quoted there. Trace the proposed TLS, Noise, HTTP, and multistream detection rules and the backward-compatibility concern. Done means the maddr semantics, server detection behavior, and multistream-select expectations are specified consistently.
Written by the indexing model from the issue text.
Assessment
- Domain
- networking, security
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100