Skip to content

Proposal: Improved Browser Connectivity using Secure WebSockets #1331

@marten-seemann

Description

@marten-seemann

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:

  1. Import an existing key / cert file. This is probably not used very commonly nowadays.
  2. Use the ACE HTTP or TLS challenge. Note that this involves starting a HTTP or endpoint on port 80 or 443, respectively (this is a limitation imposed by the ACME protocol). Note that this will pose a problem for nodes that run a HTTP(S) server on their node, or nodes which can't bind to ports < 1024.
  3. Use DNS challenges. This will require user configuration, as DNS entries have to be modified temporarily to pass the ACME challenge (see the certmagic documentation for details)

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 option WithCertificate(*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

Metadata

Metadata

Assignees

No one assigned

    Labels

    effort/daysEstimated to take multiple days, but less than a weekexp/intermediatePrior experience is likely helpfulkind/enhancementA net-new feature or improvement to an existing feature

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions