-
Notifications
You must be signed in to change notification settings - Fork 288
webrtc/: Add libp2p WebRTC browser-to-server spec #412
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
Changes from 8 commits
9677aa2
968d127
64a3dff
7dfcca1
28e341b
b3bd981
dc6fb4e
9728e22
13f6aaa
7ec96db
5f5fd60
84d4c41
9790d1a
4c6320e
449462b
3e9fb70
81249f3
ee09ed4
d451652
b485340
b654f11
9a90f0d
baccb1d
83e7aa0
766bb62
525bc9e
3e9e6df
a29cb45
827def2
e6c23e1
5f7ea61
f5eb1b7
a8a42b5
c8e725a
7e601e7
9e8ec87
cceed49
c5522c4
c89a72a
bc76a06
a0ae9b0
774cd52
ae1020b
4b8e890
285574d
7009f94
373bafe
93df7e3
027b539
865f4f2
a60234c
48f5fe7
7f40491
31ac65d
85364f4
9ce0d45
2570b24
7a8ebc0
f0acbb5
6df6cf3
c19ba8a
65a894a
6fb2750
73516b1
8208f02
6c7f18e
666c9f4
ae5b0d8
7ce6213
a2d1547
ded63c5
54f8264
67e12da
4a52edc
7380483
c063a81
65590f9
8dc6465
daecb5b
6267324
590c3db
a207aa5
ed5c641
42e7a20
3315b5c
2dddfdc
0deaa30
7ac21aa
8803682
b5466fd
4931f87
d5d164b
6775d10
730dca0
faf641d
e2df94c
b268693
3aebc68
50b4e12
c8df617
4de8f96
4dcf801
16e38fb
f635466
5c9b600
961ada2
75c3b5c
9abf638
1cb4093
a46919c
3058fb9
a382f18
44fd082
22fc557
1ddc317
1e3ca59
b1f629a
070ebea
072c317
b8dc6fd
a62fdd2
118a4dc
60ac97a
6846d34
c369f2b
0c4e836
dd9756b
249ebd2
be5cfeb
602f492
1c7956c
b5ac74b
b6e7eb1
2d0478c
4dc788c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,160 @@ | ||
# WebRTC | ||
|
||
| Lifecycle Stage | Maturity | Status | Latest Revision | | ||
|-----------------|---------------|--------|-----------------| | ||
| 1A | Working Draft | Active | | | ||
|
||
Authors: [@mxinden] | ||
|
||
Interest Group: [@marten-seemann] | ||
|
||
## Motivation | ||
|
||
1. **No need for valid TLS certificates.** Enable browsers to connect to public | ||
server nodes without those server nodes providing a TLS certificate within | ||
the browsers trustchain. Note that we can not do this today with our | ||
Websocket transport. | ||
|
||
2. **Hole punching in the browser**: Enable two browsers or a browser and a | ||
non-public server node to connect. | ||
|
||
## Requirements | ||
|
||
- Loading a remote nodes certificate into ones browser trust-store is not an | ||
option, i.e. doesn't scale. | ||
|
||
- No dependency on central STUN and/or TURN servers. | ||
|
||
## Protocol | ||
|
||
Scenario: Browser _A_ wants to connect to server node _B_. | ||
|
||
### Setup - Both _A_ and _B_ | ||
|
||
1. [Generate a | ||
certificate](https://www.w3.org/TR/webrtc/#dom-rtcpeerconnection-generatecertificate). | ||
|
||
2. [Get the certificate's | ||
fingerprint](https://www.w3.org/TR/webrtc/#dom-rtccertificate-getfingerprints). | ||
|
||
### Connection Establishment | ||
|
||
1. Browser _A_ discovers server node _B_'s multiaddr, containing _B_'s IP, UDP | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Typically, we’ll discover multiple WebRTC multiaddrs. IPv4 and IPv6 at the very least. We should specify how this is handled. I assume we’d combine them into the same SDP. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
That's not the case right now (not in Rust implementation at least). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As far as I can tell there is no benefit for combining multiple WebRTC multiaddrs into a single connection attempt in the browser-to-server use-case. @marten-seemann did you had one in mind for the browser-to-server use-case? Agreed that we should combine them for the browser-to-browser use-case, though I would like to delay that discussion to the second iteration of this specification. |
||
port, TLS certificate fingerprint and libp2p peer ID (e.g. | ||
`/ip6/2001:db8::/udp/1234/webrtc/<tls-certificate-fingerprint/p2p/<peer-id>`), | ||
mxinden marked this conversation as resolved.
Show resolved
Hide resolved
mxinden marked this conversation as resolved.
Show resolved
Hide resolved
mxinden marked this conversation as resolved.
Show resolved
Hide resolved
|
||
through some external mechanism. | ||
|
||
2. _A_ create a connection with its local certificate. | ||
mxinden marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
3. _A_ constructs _B_'s SDP offer locally based on _B_'s multiaddr and sets it | ||
mxinden marked this conversation as resolved.
Show resolved
Hide resolved
|
||
via | ||
[`RTCPeerConnection.setRemoteDescription()`](https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/setRemoteDescription). | ||
|
||
4. _A_ establishes the connection to _B_. | ||
|
||
5. _A_ initiates some authentication handshake _X_ to _B_ on a datachannel, | ||
where _X_ allows _A_ and _B_ to authenticate each other's peer IDs. _X_ could | ||
for example be Noise. See WebTransport specification as an example | ||
https://github.com/libp2p/specs/pull/404. Still to be specified here for | ||
mxinden marked this conversation as resolved.
Show resolved
Hide resolved
|
||
WebRTC. | ||
|
||
6. On success of the authentication handshake _X_, the used datachannel is | ||
closed and the plain WebRTC connection is used with its multiplexing | ||
capabilities via datachannels. | ||
|
||
## Open Questions | ||
|
||
_Where _Browser_ is replaced with the major desktop browsers of today (Chrome, | ||
Safari, Edge, Firefox)._ | ||
|
||
### Direct connections | ||
|
||
#### Browser to public server node | ||
|
||
- Can _Browser_ generate a _valid_ SDP packet for the remote node based on the | ||
mxinden marked this conversation as resolved.
Show resolved
Hide resolved
|
||
remote's Multiaddr, where that Multiaddr contains the IP, UDP port and TLS | ||
certificate fingerprint (e.g. | ||
`/ip6/2001:db8::/udp/1234/webrtc/<tls-certificate-fingerprint`)? _Valid_ in | ||
the sense that this generated SDP packet can then be used to establish a | ||
WebRTC connection to the remote. | ||
|
||
mxinden marked this conversation as resolved.
Show resolved
Hide resolved
mxinden marked this conversation as resolved.
Show resolved
Hide resolved
|
||
- Do the major (Go / Rust / ...) WebRTC implementations allow us to accept a | ||
mxinden marked this conversation as resolved.
Show resolved
Hide resolved
|
||
WebRTC connection from a remote node without previously receiving an SDP | ||
packet from such host? | ||
|
||
#### Browser to browser or non-public server node | ||
|
||
- Can _Browser_ know upfront its UDP port which it is listening for incoming | ||
connections on? | ||
|
||
- Can _Browser_ control the lifecycle of its local TLS certificate, i.e. can | ||
mxinden marked this conversation as resolved.
Show resolved
Hide resolved
|
||
_Browser_ use the same TLS certificate for multiple WebRTC connections? | ||
|
||
- Can two _Browsers_ exchange their SDP packets via a third server node using | ||
mxinden marked this conversation as resolved.
Show resolved
Hide resolved
|
||
Circuit Relay v2 and DCUtR? Instead of exchanging the original SDP packets, | ||
could they exchange their multiaddr and construct the remote's SDP packet | ||
mxinden marked this conversation as resolved.
Show resolved
Hide resolved
|
||
based on it? | ||
|
||
### Securing the connection | ||
|
||
While WebRTC offers confidentiality and integrity via TLS, one still needs to | ||
authenticate the remote peer by its libp2p identity. | ||
|
||
- Can a _Browser_ access the fingerprint of its TLS certificate? | ||
mxinden marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
Chrome allows you to access the fingerprint of any locally-created certificate | ||
directly via `RTCCertificate#getFingerprints`. Firefox does not allow you to | ||
do so. Browser compatibility can be found | ||
[here](https://developer.mozilla.org/en-US/docs/Web/API/RTCCertificate). In | ||
practice, this is not an issue since the fingerprint is embedded in the local | ||
SDP string. | ||
|
||
- Is the above proposed #protocol secure? | ||
|
||
### Multiplexing | ||
|
||
- Can we use WebRTC’s data channels in _Browser_ to multiplex a single | ||
mxinden marked this conversation as resolved.
Show resolved
Hide resolved
|
||
connection, or do we need to run an additional multiplexer (e.g. yamux) on top | ||
of a WebRTC connection and WebRTC datachannel? In other words, does WebRTC | ||
provide all functionality of a libp2p muxer like Yamux (e.g. flow control)? | ||
|
||
## Previous, ongoing and related work | ||
|
||
- Proof of concept for the server side in rust-libp2p: | ||
https://github.com/libp2p/rust-libp2p/pull/2622 | ||
mxinden marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
- Proof of concept for the server side (native) and the client side (Rust in | ||
WASM): https://github.com/wngr/libp2p-webrtc | ||
|
||
- WebRTC using STUN and TURN: https://github.com/libp2p/js-libp2p-webrtc-star | ||
|
||
# FAQ | ||
|
||
- _Why exchange the TLS certificate fingerprint in the multiaddr? Why not | ||
base it on the libp2p public key?_ | ||
|
||
Browsers do not allow loading a custom certificate. One can only generate a | ||
certificate via | ||
[rtcpeerconnection-generatecertificate](https://www.w3.org/TR/webrtc/#dom-rtcpeerconnection-generatecertificate). | ||
|
||
- _Why not embed the peer ID in the TLS certificate, thus rendering the | ||
additional "peer certificate" exchange obsolete?_ | ||
|
||
Browsers do not allow editing the properties of the TLS certificate. | ||
|
||
- _How about distributing the multiaddr in a signed peer record, thus rendering | ||
the additional "peer certificate" exchange obsolete?_ | ||
|
||
Signed peer records are not yet rolled out across the many libp2p protocols. | ||
Making the libp2p WebRTC protocol dependent on the former is not deemed worth | ||
it at this point in time. Later versions of the libp2p WebRTC protocol might | ||
adopt this optimization. | ||
|
||
Note, one can role out a new version of the libp2p WebRTC protocol through a | ||
new multiaddr protocol, e.g. `/webrtc-2`. | ||
|
||
- _Why do an authentication handshake on top of an established WebRTC | ||
connection? Why not only exchange signatures of ones TLS fingerprint signed | ||
with ones libp2p private key?_ | ||
|
||
This is prone to replay attacks. |
Uh oh!
There was an error while loading. Please reload this page.