-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Proposal: Improved Browser Connectivity using Secure WebSockets #1331
Comments
This is going to solve a lot of problems for browser nodes 👍 Tangentially related but I put a POC together a while back that does a reverse-DNS lookup on your router's external interface and uses uPNP to configure port forwarding for long enough to do the ACME handshake based on that domain name - https://gist.github.com/achingbrain/8d9a00190f2e13182579d26d138f5b4a - It also means you don't need to run the server on privileged ports. |
@marten-seemann : I've seen conversations from @lidel on this in the past. Please make sure he's looped in. |
There is also protocol/web3-dev-team#70 from 2021. |
There are also some notes in ipfs/in-web-browsers#181,
👉 I suggest we focus on (0) first, and allow users to manually provide certs for domains via config:
When we have this, we could look into (1) and (2). (I'm 👍 for having built-in ACME support but that usually baloons complexity across the stack. This is because when we have ACME, full automation (2) is very close. For example, PoC by @achingbrain is worth exploring, as it would work in many home NATs – the publicly diallable IP could be read via AutoNAT, and thanks to liberal defaults in consumer routers we could attempt to map public port |
I agree this should be out of scope. Providing a subdomain brings us into all kinds of trouble, first and foremost ACME rate-limiting. Reverse DNS seems straightforward enough, but will potentially require some more wiring up into the libp2p stack (just obtaining the cert is only the first half, we also need to advertise a Assuming a wss listener support in go-ws-transport (I have a working prototype that shouldn't be too far from being shippable), both (0) and (1) seem pretty straightforward (this is mostly due to the fact that certmagic is such a terrific library). I created a small wrapper in https://github.com/marten-seemann/go-libp2p-certbot/. It supports both options:
The @achingbrain's POC looks very interesting, but will probably require us to assign (sub)domains, right? Home IP addresses change very frequently, so we'd probably need a way to quickly update DNS records or obtain a new subdomain. That's a whole lot more complexity, and I'd consider this out-of-scope for my proposal here. Let's focus on public nodes with pre-configured domains for now. |
Closing, since we now have WebTransport and that's 100x better than WebSocket. Specifically, it doesn't require any DNS setup. |
This is a proposal to make it easier to use secure websockets (wss). Currently, users wishing to offer wss to the network need to run an HTTPS server (e.g. an nginx) with a valid TLS certificate configured in front of their libp2p node.
Benefits
Browser nodes have limited options to connect to the rest of the libp2p network. There's no way to establish raw TCP or QUIC connections, and WebSockets / WebTransport connections are subject to the Web Security Model (i.e., the server has to present a CA-signed TLS certificate).
The only exception to this rule is WebRTC, which uses self-signed certificates. However, browsers enforce pretty strict limits on the number of concurrent WebRTC connection.
Limitations
It is understood that this is only an option for public nodes, and only if they have a domain name configured. Therefore, only some of the public nodes offer wss support will actually make use of wss. However, this is still a lot better than the status quo, as this is an additional (and not as strictly limited as WebRTC) connection option for libp2p nodes.
Obtaining a Certificate
There are 3 options to get a valid certificate:
In practice, it's only possible to obtain certificates for domain names, but not for IP addresses. It thus only makes sense to dial
/dnsaddr/domain.xyz/wss
addresses. Dialing/ipX/<ip>/tcp/<port>/wss
addresses can still make sense for non-browser use cases, where we can ignore certificate validation errors (or, if we want to be fancy, distinguish between these two uses cases and use a libp2p-tls certificate in that case).Implementation Details
go-ws-transport
will add a new configuration optionWithCertificate(*tls.Config)
. When set, it is possible to listen on/wss
addresses.certmagic looks like it has everything we need, and we can offer all of the 3 options listed above to configure the certificate.
The domain names that we obtain certificates for could be configured manually, or extracted them from
/dnsaddr/
multiaddrs. It is unclear if this logic should be part of libp2p, or left to the application.cc @willscott @vyzo @aschmahmann @aarshkshah1992 @mxinden @Stebalien @patrickwoodhead
The text was updated successfully, but these errors were encountered: