Open Stebalien opened 6 years ago
it's been long enough since I looked at the wss/ws issue that I forgot: is it solely because the libraries/page are loaded in the HTTPS context (requiring all ws connections to be secure as well), or is there a reason beyond that?
There are two separate issues here:
Is Go compiled into wasm able to use non-secure websockets to talk to other nodes when running inside a browser, or is it still limited to wss? (given that the code may run in a fully local context - local gateway, where things may be allowed?).
(@lidel perhaps you know?)
@hsanjuan wasm will behave the same way as regular JS. No difference.
TLDR: in browsers, WebSockets execute only within the boundary of secure contexts,
so the only plaintext ws://
you can dial from HTTPS page is on localhost
Most of "rules" in the browser context are related to the concept of secure contexts. Spec is one thing, implementations are hairy, but for the sake of this conversation we can simplify and say "secure context" is a document loaded over TLS tunnel (https://
), but also local machine at http://127.0.0.1
and thanks to our collab with Igalia http://localhost
and http://*.localhost
too (at least in Firefox and Chromium).
Recently introduced implementation of ipfs://
and ipns://
in Brave v1.19 is also marked as a secure context.
AFAIK in the case of WebSockets, rules are straightforward: JS code executed from secure context will only be able to connect to other secure context.
This means a page loaded from secure context should not be able to establish unencrypted WebSocket connection, unless it is to localhost.
To illustrate, below is a simple poc: a server that runs on localhost, and a static html page with JS that connect to it:
You can load the HTML from local gateway or a public page loaded over HTTPS, it works fine in both cases (below Firefox and Brave with Shields turned off):
$ node ws-server.js
received: Hello Server!
I'm http://bafkreihqk4ie7zfeedkexb5yfjo7y4ngcjlcydy3behxwd7hkkptcvlliy.ipfs.localhost:8080/
loaded via Mozilla/5.0 (X11; Linux x86_64; rv:84.0) Gecko/20100101 Firefox/84.0
received: Hello Server!
I'm https://ipfs.io/ipfs/bafkreihqk4ie7zfeedkexb5yfjo7y4ngcjlcydy3behxwd7hkkptcvlliy
loaded via Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.89 Safari/537.36
received: Hello Server!
I'm https://ipfs.io/ipfs/bafkreihqk4ie7zfeedkexb5yfjo7y4ngcjlcydy3behxwd7hkkptcvlliy
loaded via Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.89 Safari/537.36
Thanks @lidel :)
This is coming up over and over again. Any reason not to make this a default ? Unless there is one how do we make this happen ?
It should be pretty safe to enable this on localhost addr (because it is only useful on localhost + if someone wants to add TLS then they put it behind Nginx anyway).
I can make this happen with some help/guidance.
@Stebalien @aschmahmann Is there a prior art or policy for enabling a new transport by default?
/quic
?/ws
addr to the default list of addrs: go-ipfs-config/init.go#L109-L115 – is there more to this?(because it is only useful on localhost + if someone wants to add TLS then they put it behind Nginx anyway).
Is it not useful for nodejs nodes ? I suppose they could dial TCP instead, but still unless there is a reason to have it disabled I'd go with you can disable as a default as opposed you can enable.
http
sites are rare these days, but they could potentially also benefit from having /ws
enabled on nodes even if those aren't setup with TLS.
The main reason not to enable this right now is that we dial all transports in parallel. We already have QUIC+TCP, both IPv6 and IPv4.
Someone would need to take that on as a (possibly mini) project. @vyzo was looking to handle this as part of https://github.com/libp2p/go-libp2p-swarm/pull/250 but it's looking like it'll be... complicated and should happen in a followup patch.
Hm. Actually, this change is much easier than that. We just need to say "if a peer supports both TCP and WS, only try WS if we don't support TCP".
Doing this generically is tricky... but we might just have to be a bit less generic for now.
http sites are rare these days, but they could potentially also benefit from having /ws enabled on nodes even if those aren't setup with TLS.
Yeah, but not enough for us to prioritize this.
why can't you get the certs in go? this guy did for his thing .... i use this for my go project with gorilla mux to serve a ui via HTTPS. it works perfectly so far.
https://blog.kowalczyk.info/article/Jl3G/https-for-free-in-go-with-little-help-of-lets-encrypt.html
Currently, we don't because we considered it useless. Browsers usually still can't dial go nodes because they need a wss listener (https) and we can't get the certs in go.
However, it turns out that our
ws
transport supports proxies out of the box :man_shrugging:. Simply turning on the websocket listeners should open up the network to users behind corporate firewalls. We don't even have to worry about corporate MITMs because we do our own crypto inside the websocket.