Skip to content
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

websocket address type: allow transport over RFC6455 #891

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .aspell.en.pws
Original file line number Diff line number Diff line change
Expand Up @@ -387,3 +387,5 @@ CHECKSIGVERIFY
IFDUP
sats
anysegwit
WebSocket
websocket
14 changes: 13 additions & 1 deletion 07-routing-gossip.md
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,7 @@ The following `address descriptor` types are defined:
onion service addresses; Encodes:
`[32:32_byte_ed25519_pubkey] || [2:checksum] || [1:version]`, where
`checksum = sha3(".onion checksum" | pubkey || version)[:2]`.
* `6`: WebSocket port; data = `[2:port]` (length 2)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd rather we allow specification of an IP as well here. Though maybe that interacts poorly with the hostname gossip thing? There may likely end up being nodes that would love to allow websocket connections, but sit behind cloudflare/nginx/whatever when doing so, whereas native LN protocol obviously doesn't proxy through a web proxy. Thus, they'd want to be able to specify a different host for websockets. I suppose for cloudflare-proxied nodes (dear god people stop using cloudflare) you'd need a domain name, not an IP, and have to send the HTTP Host header.

Maybe this should be hostname-only? Or maybe two different gossips, one for hostnames and one for ips?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You basically iterate through all the other addresses, trying this port. It's not ideal, but it seemed easier than some kind of specification which indicated which other descriptors it applied to...

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yea, totally fair, I think my broader point here is that we really should consider wss a required part of this, because supporting websockets so browser clients can connect but then not support wss so browser clients can't connect in a secure context seems like it almost completely neuters the value here, sadly. For wss you need a hostname, ultimately, and I think we'd probably want to support a different hostname than the lightning node itself, as the wss part will probably be nginx or some other proxy, hence...I think we should just shove a hostname here :(

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 for wanting wss, we've created a websocket to tcp proxy server for connecting in a browser, but we can't do ws unfortunately.


### Requirements

Expand All @@ -306,12 +307,16 @@ The origin node:
- MUST place address descriptors in ascending order.
- SHOULD NOT place any zero-typed address descriptors anywhere.
- SHOULD use placement only for aligning fields that follow `addresses`.
- MUST NOT create a `type 1` OR `type 2` address descriptor with `port` equal
- MUST NOT create a `type 1`, `type 2` or `type 6` address descriptor with `port` equal
to 0.
- SHOULD ensure `ipv4_addr` AND `ipv6_addr` are routable addresses.
- MUST set `features` according to [BOLT #9](09-features.md#assigned-features-flags)
- SHOULD set `flen` to the minimum length required to hold the `features`
bits it sets.
- MUST NOT add a `type 6` address unless there is also at least one address of different type.
- if it adds a type 6 address:
- MUST allow unencrypted RFC6455<sup>[3](#reference-3)</sup> as a transport when a connection is made to at least one of the other addresses, with the type 6 `port` substituted for that address's `port`
- SHOULD allow this on ALL of the other addresses.

The receiving node:
- if `node_id` is NOT a valid compressed public key:
Expand Down Expand Up @@ -359,6 +364,12 @@ to be ordered in ascending order, unknown ones can be safely ignored.
Additional fields beyond `addresses` may also be added in the future—with
optional padding within `addresses`, if they require certain alignment.

Websockets generally are run on adjacent ports (or even overloaded on
the same port) as existing "raw" transports, so including just the
port is a compromise which avoids replacating all the addresses. It's
ideal if all addresses support this, but it's not a hard requirement:
at least one must.

### Security Considerations for Node Aliases

Node aliases are user-defined and provide a potential avenue for injection
Expand Down Expand Up @@ -1123,6 +1134,7 @@ above.

1. <a id="reference-1">[RFC 1950 "ZLIB Compressed Data Format Specification version 3.3](https://www.ietf.org/rfc/rfc1950.txt)</a>
2. <a id="reference-2">[Maximum Compression Factor](https://zlib.net/zlib_tech.html)</a>
3. <a id="reference-3">[RFC 6455 "The WebSocket Protocol"](https://datatracker.ietf.org/doc/html/rfc6455)

![Creative Commons License](https://i.creativecommons.org/l/by/4.0/88x31.png "License CC-BY")
<br>
Expand Down
32 changes: 32 additions & 0 deletions 08-transport.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ of a node.
* [Handshake State](#handshake-state)
* [Handshake State Initialization](#handshake-state-initialization)
* [Handshake Exchange](#handshake-exchange)
* [Alternate Transport Layers: WebSocket](#websocket)
* [Lightning Message Specification](#lightning-message-specification)
* [Encrypting and Sending Messages](#encrypting-and-sending-messages)
* [Receiving and Decrypting Messages](#receiving-and-decrypting-messages)
Expand Down Expand Up @@ -402,6 +403,36 @@ construction, and 16 bytes for a final authenticating tag.
10. `rn = 0, sn = 0`
* The sending and receiving nonces are initialized to 0.

## Alternate Transport Layers: WebSocket

Normally the transport protocol defined here is performed over TCP/IP,
but it can also be performed over other underlying transports, such as
the WebSocket protocol as specified in
RFC6455<sup>[4](#reference-4)</sup> on ports so-advertized (in the
[node_announcement message](07-routing-gossip.md#the-node_announcement-message).

A client may connect to this port node and initiate a WebSocket; and
operate the protocol over binary WebSocket frames instead of raw TCP/IP.


### Requirements

The initiator:
- MAY attempt to initiate an unencrypted WebSocket as specified in RFC6455<sup>[4](#reference-4)</sup>:
- MUST abort the connection attempt if WebSocket upgrade fails.
- MUST begin the [Handshake Exchange](#handshake-exchange) as initiator
as soon as upgrade succeeds.

The responder:
- if it supports WebSocket connections on a port:
- SHOULD advertize it using a type 5 address its node announcement.
- MUST abort the connection attempt if WebSocket upgrade fails.

Both nodes, after upgrade:
- MUST use binary frames to send and receive messages.
- MUST NOT rely on WebSocket framing for message semantics.


## Lightning Message Specification

At the conclusion of Act Three, both sides have derived the encryption keys, which
Expand Down Expand Up @@ -779,6 +810,7 @@ TODO(roasbeef); fin
1. <a id="reference-1">https://tools.ietf.org/html/rfc8439</a>
2. <a id="reference-2">http://noiseprotocol.org/noise.html</a>
3. <a id="reference-3">https://tools.ietf.org/html/rfc5869</a>
4. <a id="reference-4">https://tools.ietf.org/html/rfc6455</a>

# Authors

Expand Down
1 change: 1 addition & 0 deletions 09-features.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,4 +88,5 @@ This work is licensed under a [Creative Commons Attribution 4.0 International Li
[bolt07-sync]: 07-routing-gossip.md#initial-sync
[bolt07-query]: 07-routing-gossip.md#query-messages
[bolt04-mpp]: 04-onion-routing.md#basic-multi-part-payments
[bolt08-websocket]: 08-transport.md#websocket
[ml-sighash-single-harmful]: https://lists.linuxfoundation.org/pipermail/lightning-dev/2020-September/002796.html