Webtorrent: Idea: WebSockets as an alternative to WebRTC

Created on 29 Aug 2018  路  55Comments  路  Source: webtorrent/webtorrent

Lots of torrent clients can't add WebRTC support because the protocol is too complicated and difficult to integrate. This is slowing WebTorrent adoption in traditional desktop torrent clients. See https://github.com/transmission/transmission/issues/47, for example.

I've been thinking about this a bit. It's probably possible to make something work over WebSockets. Here's a rough sketch.

  1. Desktop peers would run a WebSocket server and do whatever NAT hole punching they normally do (UPnP, NAT-PMP, tell the user to set up static port mapping, or just hope that the user has a public IP).

  2. Browser peers would discover desktop peers through normal means, so probably trackers and PEX for now (and eventually we could聽extend the DHT to support WebSocket in addition to UDP).

3a. Browser peers connect to desktop peers using WebSocket using an address like ws://12.34.56.78 when possible.

3b. One complication is that the browser blocks connections to insecure origins (ws://) from secure origins (https://). So ws:// can't be used all of the time. Ideally, we could use wss:// instead. However that requires the WebSocket server to have a domain name and a certificate signed by a CA. 馃槩

3c. Here's a workaround. Say a user on a secure web origin wants to connect to a desktop peer at 12.34.56.78. They would connect to wss://12-34-56-78.force-tls.com. The force-tls.com domain would聽have DNS set up to return whatever IP is passed in the subdomain. So the DNS for 12-34-56-78.force-tls.com would resolve to 12.34.56.78. The force-tls.com domain would use wildcard certificate to ensure that all of these domains are signed. The secret key for this certificate would be public and any torrent app could use it in their WebSocket server.

3d. So, in this system, TLS isn't actually being used for security. This is just a hack to help secure origins (https://) connect to WebSocket servers running in desktop peers without requiring those desktop peers to buy a domain name and get a TLS certificate that is trusted by the browser peers' browsers.

3e. Anyone could run one of these "force TLS" services cheaply. They're generic and have nothing to do with the BitTorrent protocol, so it's likely risk-free to just聽run one of these as a public service, not unlike a DHT bootstrap node. It's just a DNS server that maps 12-34-56-78.force-tls.com to the IP address 12.34.56.78.

  1. Browser to browser connections, as well as desktop to browser connections would continue to require WebRTC. But if a desktop client does not want to support WebRTC (understandably), then they can still provide value to browser peers by running a WebSocket server to allow browser peers to initiate connections to them.

Thoughts?

(I originally brainstormed this idea with @mafintosh and I was inspired by @diasdavid's work on js-ipfs.)

areprotocol question

Most helpful comment

I don't want to sound disrespectful but I would rather focus on the integrability of WebRTC (data channels) than on alternative solutions. From a user's perspective, one does the initial offer/answer dance (which is fairly easy) and then data channels are pretty much identical to WebSocket (the stack is of course not but, if anything, that should be a secondary problem).

I've offered RAWRTC as a library and my expertise in several issues regarding WebTorrent. Apart from one single person (see https://github.com/arvidn/libtorrent/issues/223#issuecomment-401406830), I have been given zero feedback. Just absolute silence. Maybe people are put off by something before they even try it? I don't know because I'm not getting any feedback. From my perspective, it looks like there is no demand or no one is willing to implement it in which case an alternative wouldn't help. I hope I'm wrong and people just held back their feedback for whatever reason because I would like to hear it.

All 55 comments

Quoting myself on https://github.com/webtorrent/webtorrent/issues/896#issuecomment-252378531 to say that this can all be done through http 2 instead of WS. About the dynamic dns forwarding, it's great. I could setup *.dynamic.btorrent.xyz wildcard or something like as a default and connect to use Cloudflare to point the subdomains to the IPs.

@DiegoRBaquero Just to be clear, the comment you linked seems to be about an potential alternative to HTTP WebSeeds that聽would use WebSockets instead. This issue is about using WebSockets as an alternative to WebRTC for actual peer-to-peer connections.

As for whether to use HTTP2 or WebSocket, I wasn't aware that HTTP2 was a replacement for WebSockets. Can it really do bidirectional real-time communication? HTTP2 Server Push is not sufficient.

Also, we need to keep in mind ease of implementation as the whole point of this is to find something simpler than WebRTC for torrent app implementors. So we should consider what is easiest for聽implementors.

I don't want to sound disrespectful but I would rather focus on the integrability of WebRTC (data channels) than on alternative solutions. From a user's perspective, one does the initial offer/answer dance (which is fairly easy) and then data channels are pretty much identical to WebSocket (the stack is of course not but, if anything, that should be a secondary problem).

I've offered RAWRTC as a library and my expertise in several issues regarding WebTorrent. Apart from one single person (see https://github.com/arvidn/libtorrent/issues/223#issuecomment-401406830), I have been given zero feedback. Just absolute silence. Maybe people are put off by something before they even try it? I don't know because I'm not getting any feedback. From my perspective, it looks like there is no demand or no one is willing to implement it in which case an alternative wouldn't help. I hope I'm wrong and people just held back their feedback for whatever reason because I would like to hear it.

I haven't had the time to make an attempt to use rawrtc聽even in webtorrent-hybrid, but I agree that should probably be attempted first. If that's actually easy to use, then perhaps this is a solved problem. My information on the quality of WebRTC DataChannel libraries is actually a bit out of date (2017-era).

Has an attempt been made to update webtorrent-hyrbid to use rawrtc?

how about using letsencrypt.org for the certificates over wss? It's free and they must be renewed every 90 days but that can easily be automated.

@chovy Each desktop clients would still need a domain name. You can't issue a TLS certificate for an IP address, I believe.

@lgrahl

From my perspective, it looks like there is no demand or no one is willing to implement it in which case an alternative wouldn't help.

There are Transmission folks saying they would be much more enthusiastic about supporting WebTorrent if it worked with WebSockets instead of (or as well as) WebRTC. Eg see:
https://github.com/transmission/transmission/issues/47#issuecomment-416740849

As a user of an ancient netbook, I find PeerTube unusable, and I suspect WebRTC is the culprit, because none of the voice chat apps that use it (eg Jitsi Meet) work properly for me either. So although I can't help with implementation, I'd definitely +1 a WebSockets option.

you can use it on localhost.

@strypey: One person said that. And I'm sorry, but WebSocket with manual hole punching on one side and the workaround to get around the insecure origin problem on the other side is, from an application perspective, more complex than WebRTC on both sides and thereby loses its elegance (which it undoubtedly has, but not in a P2P environment).

You're applying your experience with one particular application (PeerTube), for one specific implementation, on your specific device onto a whole technology. And frankly, WebRTC A/V is very different to WebRTC data channels. The way Jitsi Meet delivers video streams is entirely different to the way PeerTube does. One is real-time, the other is not. But you have a point regarding CPU usage which hasn't been investigated thoroughly yet, see https://github.com/sctplab/usrsctp/issues/245. At the moment, none of the browser vendors seem to have an interest in resolving such issues... or perhaps its a lack of resources... or it's a matter of priority. However, the lack of interest or priority may change if we keep using it and WebTorrent becomes more popular. But it will not if we keep away from it because of bugs.

In the end, you may still conclude that WebRTC data channels are insufficient for whatever reason. But then it would probably still make more sense to wait for QUIC in WebRTC and see if that's any better before jumping onto WebSockets.

Erm... to me it sounds more complicated setting up a local server trying to get browsers peers able to connect to desktop peers throught ws: or wss with a IP.

I'm in favor of WebRTC for some reason. may be something @lgrahl said...

From a desktop perspektiv:

if you want to communicate with browsers (without any special plugins), WebRTC is the only choice at the moment.

one does the initial offer/answer dance (which is fairly easy) and then data channels are pretty much identical to a WebSocket

and that the only mean of communication for browser-to-browser is WebRTC, so why should we involve another transport protocol with websockets? that sounds just like more work.

The secret key for this certificate would be public and any torrent app could use it in their WebSocket server.

This is where I'm not sure about the feasibility of the idea. Browsers are able to blacklist unsafe public keys. For example, Google has this public blacklist.

Technically, this websocket connection wouldn't be safe, so there is a possibility that the public key ends up in this kind of lists.

has anyone else consider the security aspect also?
what you might possible leak to any other site.

Person A visit evil.com
evil.com now knows your ip-adress and try open a websocket to wss://your-ip.force-tls.com
what can evil.com now do to you?

@strypey PeerTube is not the appropriate project to measure WebTorrent/WebRTC performances:

  • Most videos are directly sent by the server, without use of WebRTC
  • We are streaming videos so it's quite an important overhead
  • We use other libraries that could cause performance issues (videojs, angular etc)

From my perspective, I was really interested in rawrtc (when I discovered it on the libtorrent issue), with a great support provided by @lgrahl. So I'm a little disappointed that he did not get any feedback (this is not a reproach, I know what FOSS is).

@lgrahl

One person said that.

Did you read the whole thread? It's been brought up a number of times. Possibly by the same person, but there are a number of points raised for why WebSockets seems easier to implement from a desktop client POV. We all want to see desktop torrent clients support WebTorrent, increasing its network effect. Let's not close ourselves off to any ideas that might make it more likely to happen, at least not without thoroughly investigating and discussing their pros and cons.

@strypey Sure I read the whole thread. Here are the two arguments I've seen (let me know if there is something I've overseen):

1. "No easy to use libraries"

I've offered RAWRTC which aims to be easy to use. Okay, granted, I have not posted that in this particular issue but I did in the libtorrent issue. Anyhow, no one contacted me on how to use it for WebTorrent or to provide feedback. The only conclusion I can possibly draw from this is that no one tried.

2. "Too complex"

Like I said, it's a complex technology but from an API perspective, this isn't that more complex than the approach described here. And when I'm saying that, I'm also factoring in that the hole punching procedures (which will not be as effective since we're talking about TCP here) already exist in the desktop clients.

I've written a demo for RAWRTC a while ago which allows to access a terminal via WebRTC data channels. It also uses WebSockets for signalling. The demo needs updating to use the peer connection API instead of the more low-level ORTC API. But even with that low-level API, I wouldn't call the demo too complex.

I'd much rather see an attempt at RAWRTC integration than yet another protocol :-/

Also, I'm concerned about the proposal to intentionally break TLS by sharing the private key. Where do you plan on buying your certificate from? I would expect any legitimate CA to possibly add this cert to a revocation list, which of course torrent desktop software could ignore but browsers will definitely check.

@lgrahl I'm very interested in RAWRTC, seems cool. but unfortunately I have no knowledge of c/c++ or the WebRTC spec for that mather (if i did i would help contributing). Only know some stuff about the WebRTC api in javascript

Having a solid library for writing server-side WebRTC applications would have other benefits. For example, most multiplayer browser games I'm aware of use Websockets because there isn't an easy way to write game network servers for WebRTC. This isn't ideal because WebRTC is capable of significantly lower latency and gives you more UDP-like control which is beneficial for game and other latency-sensitive apps.

Personally, I would consider contributing to an effort to create such a library, but there's little chance I'd invest any time contributing to a complex Websocket hack for working around the limitations of the web. As complicated as WebRTC is, it solves tangible problems (NAT traversal, peer negotiation, etc) that you'd have to figure out yourself anyway if you were using UDP.

@lgrahl is RAWR easily wrappable by other languages, ie Python, Node, Rust, etc? Is there any chance it could ever be compiled to WebAssembly and work in the browser?

@anderspitman I don't see why it should be hard to create bindings. But if it isn't easy to create bindings, we will figure something out. For Python, I suggest the awesome aiortc but a binding should be fine, too. Although it's probably not required, for Node, we may want to map the underlying event loop to Node's event loop. Bindings for Rust shouldn't be hard (and a rewrite in Rust is on my long-term to do list).

Since the API is intentionally very similar to the WebRTC API (and the ORTC API), there is no need to compile it to WebAssembly. It already exists in the browser. :slightly_smiling_face:

Awesome to hear you're interested in a Rust WebRTC implementation. I considered starting one myself but it really is a large task.

The idea with compiling to WebAssembly would be to allow WebRTC apps to be written in a language like Rust, and seamlessly compiled for native or for the browser. That's more of a longshot anyway though. As far as I know the plumbing for directly accessing things like the WebRTC API from WASM are still a ways off, and who knows how much WASM-specific logic you'd have to put in to RAWR to make it work.

If you have some time you can follow this thread from 2015 https://lists.w3.org/Archives/Public/public-webapps/2015OctDec/0187.html, this is only one thread among many I wrote about this subject

As I predicted it will come back in the future, and this is happening here

And as you will notice, nobody gave a serious example in this thread of why ws with https is insecure, and why some exceptions are accepted for WebRTC but not WS, contradicting the rules

TLS should not be tied to a stupid domain but to an entity, that could use letsencrypt also, but this does not exist

Then the solution could be to weight for this on the W3C lists (unlikely to have a prompt effect)... or just not using https for webtorrent (not sure what is the benefit of using https, still more secure than nothing but still also can't insure that the code loaded is the right one)

@feross ideas:

  • Use the existing websocket connection that webrtc webtorrent peers are currently using to discover eachother i.e. allow not just "announce", "offer", "answer" to be sent over this websocket but also bittorrent protocol communications. So if there is a wss tracker entry then pure bittorrent clients can know that they can use that tracker to communicate with webtorrent peers in the swarm.

  • This will place additional load on websocket trackers. To reduce load on the existing trackers that you guys are running we could create a "tracker swarm" where each tracker only handles a segment of the infoHash space. What this looks like is the current websocket tracker but it creates a p2p mesh with all other copies of itself that are running on other servers (this can be done with bittorrent-dht already and a custom extension protocol). Trackers in the "tracker swarm" all send heartbeat pings which include their peerId. Trackers only handle announce & traffic for infoHashes for which they are the closest known peerId to the infoHash. There can be overlap for reliability and connecting/disconnecting trackers. This is similar to how in the mainline DHT nodes store data if they are the "closest" to the infoHash. Effectively we are re-creating something like the mainline DHT except with websocket tracker servers. The more people that run a "tracker swarm" node the healthier this network becomes, but it still works with just one. Great blog-post by @arvidn on global ordering and the distance metric which is relevant.

  • An alternative to the above approach is a "DHT gateway mesh". Currently the mainline DHT only supports storing IP addresses. We create a new krpc extension which is like the existing announce but allows storage of full WebRTC answers and offers. The websocket tracker now acts as a gateway proxying announces/offers/answers into the mainline DHT for nodes running this new krpc alternative.

Key to the above two solutions would be making it very easy to deploy new tracker-swarm nodes. This could be done with scripts to help people deploy using e.g. Ansible. The key will be to make running a "websocket tracker mesh node" as easy as possible so many people can do it.

There are different tradeoffs in security and performance in these ideas. Would love to discuss if you think this has any merit.

@chr15m would I be understanding your suggestion right if I assert that all of the peer-to-peer traffic in your scheme goes through the tracker, rather than directly to that peer?

This seems more like a TURN server's role in standard WebRTC and VoIP, but in a fashion integrated with the tracker protocol.

It would require a lot of bandwidth, and it wouldn't be especially peer-to-peer though it could be decentralized as you point out.

@scanlime all of the p2p traffic between traditional bittorrent clients and webtorrent clients would pass through a websocket proxy. Traffic between WebRTC peers would still go directly and traffic on the traditional network would still go directly.

This is indeed similar to a TURN server, and yes it would require a lot of bandwidth and is a point of centralization. The only way to make it viable would be as a decentralized mesh like the tor network.

There is already centralization in browser WebTorrent during peer discovery where a few wss trackers are used.

The Tor network is certainly not decentralized, adding ws centralization point(s) for a decentralized system such as webtorrent is, I think, not a good idea

What is the issue with getting rid of https?

Again, no disrespect intended... this is all technically fascinating. But trying to reduce complexity (which is the main argument against WebRTC so far) by adding yet another layer of complexity is mind-boggling to me.

The issue of getting rid of HTTPS is that it requires to get rid of HTTPS on the serving page, too. That policy is not going away any time soon (and I highly doubt it ever will be).

I have not followed since some time the development of webtorrent, so might not be aware of everything, but got attracted by this issue since this is related to the very same problem that I have advertised everywhere some years ago, which is obviously absurd and a clear misdesign

Adding ws for me is quite simple, the desktop clients will just pipe the info as they do for webrtc, many implementations exist, a minimal and efficient one is here: https://github.com/Ayms/websocket

Everybody knows that https is better than nothing, now https cannot guarantee you that you will get the right thing from the serving page (only a third party can guarantee this), so when it comes to balance the advantages of keeping it versus removing it...

@Ayms WebTorrent already has this centralization point. It uses a central websocket server for peer discovery under default settings.

@lgrahl yes completely agree these schemes are sub-optimal. The best outcome would be for bittorrent clients to speak WebRTC directly. I guess @feross is looking for some solution within reach of the WebTorrent developers to improve the situation before that happens. If it was easy to add WebRTC support to bittorrent I guess somebody would have done it already and further, the webtorrent developers possibly lack the time/interest/skills to do that work and issue PR against libtorrent.

WebTorrent already has this centralization point. It uses a central websocket server for peer discovery under default settings.

For bootstraping purposes only I suppose?

@Ayms yes, and for continued introduction of newly joining peers. So peers within a swarm continuously use the specified websocket server to welcome new peers.

Some of the complexity arises because WebTorrent browser peers require both a WebRTC offer and answer to be exchanged. Under the pure BitTorrent protocol a peer only needs to know the IP address of a different peer to connect - so no such offer/answer exchange is necessary (which is a DHT works very well).

Some of the complexity arises because WebTorrent browser peers require both a WebRTC offer and answer to be exchanged. Under the pure BitTorrent protocol a peer only needs to know the IP address of a different peer to connect - so no such offer/answer exchange is necessary (which is a DHT works very well).

Exactly, that's my point, if I remember well at the origin webtorrent was inside browsers only, then desktop peers were added, so it seems very logical to use them now that they are here with something that eliminates some useless complexity of webrtc in their case, ie ws and/or xhr

@Ayms yes and then we face the TLS issue that @feross raised.

You suggested:

not using https for webtorrent

Then you are excluding webtorrent from every site which uses HTTPS. In addition you have to explain to people why it is suddenly a good idea to serve and browse websites without an encrypted connection (it's not).

The centralized CA trust model is terrible (the SSH security model is much better) but it's the only one we have. It's necessary to work within those limitations.

@feross could the desktop client use Acme protocol to request a Let's Encrypt certificate?

Then you are excluding webtorrent from every site which uses HTTPS

No, why? You can have both http/https

In addition you have to explain to people why it is suddenly a good idea to serve and browse websites without an encrypted connection (it's not).

It can be, that's not an absolute rule, the Tor project was/is using ws for flash proxy, Peersm project (mine) also and was forced to revert to http for the serving page (at that time Chrome was allowing ws with https but then removed this possibility), but again even if better than nothing https does not really protect more the code loading

The centralized CA trust model is terrible (the SSH security model is much better) but it's the only one we have. It's necessary to work within those limitations.

Yes, using the desktop clients with ws/xhr should be the default in fact, webrtc is of no use here, there is no way to bypass seriously the ws/https limitation, so if the big deal is about the code loading only, then it could be considered as a non issue

I am suggesting only here, if everybody thinks that this does not fit with webtorrent, then that's it, but I don't see why

And as far as I know letsencrypt could be easily implemented in desktop clients but only works with domains

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.

Can't rejectUnauthorized and/or requestCert be set to false when creating the Websocket connection?

I don't think that WSS is as important as one would think. BitTorrent is already relying on unencrypted connections for the DHT and for non-WebRTC traffic, and while regular WS doesn't have the transport encryption that DataChannels have, it doesn't lower the threat model at all compared to hybrid torrent clients.

Edit: Whoops, forgot that HTTPS pages won't allow unsecure WS connections. 馃槄

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.

Bump since this is still relevant.

Ipfs won 馃檮

I mostly like ipfs b/c hashes each individual file and it treats it as one torrent (kinda)

Imagen having a torrent with

  • Torrent1: sintel.mp4 & sintel.eng.srt
  • Torrent2: sintel.mp4 & sintel.sv.srt

They can't share peers that have the sintel movie.
Don't know if merkle trees and new hash algorithms solves this... don't have big understanding of it https://github.com/bittorrent/bittorrent.org/pull/59

@Fenny what are you referring to? Did I miss some news?

I mostly like ipfs b/c hashes each individual file and it treats it as one torrent (kinda)

I like IPFS for the same reasons, but I have to comment that this is not always the case (e.g. https://github.com/ipfs/go-ipfs/issues/4318)

Ipfs won :roll_eyes:

Even if that was the case, I don't see all currently existing/seeded torrents being immediately turned into IPFS so I think traditional torrent clients supporting webtorrent would be important for archiving purpouses and keeping the content that is now seeded by traditional clients available for webtorrent clients.

I don't understand what you folks are discussing here. Is this related to the issue or is it off-topic?

Off topic

As far I could understood the issue with Let's Encrypt is the domain requirement, but @feross suggested a "force-tls.com" service which would allow any IP get a domain. If you join both ideas it's possible to use Let's Encrypt without the domain requirement: just use a wildcard domain like the force-tls.com idea.

Let's Encrypt allows domain validation via HTTP, TLS and DNS, so I think this service needs to have an API to change the TXT record of the domain to avoid clients having to open 80 or 443 ports.

Browsers would not blacklist a specific public key as now each client would have its own private key (so it's quite safer than the single private key idea). In the other hand, if this service uses the user IPs as the domain prefix, like suggested before, if someone changes IP frequently it would be a problem as the client would need a new certificate each time, it would cause a high load on Let's Encrypt and it can blacklist this domain.

Changing the identifier to a server generated ID could be a good improvement: the clients asks the force-tls.com service a hostname, it returns a long random one (to avoid someone registering something like secure-paypal-webpage-by.force-tls.com) and an auth token to allow the client to update the A and TXT records. At this point it's almost like a dynamic DNS service, except the user can't choose a specific hostname.

The only serious solution is to convince Mozilla, Google & co that ws should be allowed inside a https page, I tried hard before (w3c, etc), the rule is just stupid, everybody said I was the stupid, let's see, pretty sure that they will change it one day (FF thinking for example to implement Tor natively, talking about dtls self signed certificates, like webrtc, so they deviate from their rules when they like)
Another way is letsencrypt natively not tied to a domain, nobody understands it

nit, xip.io should be just-as-useable as sslip.io with Let's Encrypt. Note that historically Let's Encrypt has avoided issuing certificates for raw IP addresses (as have many issuers), but with the publication of RFC 8738 it looks like this may be changing (see: letsencrypt.org/upcoming-features).

@normanr this is great news!

I am the person who originally suggested using WebSockets instead of (or in addition to) WebRTC datachannels.

After reading this discussion, I no longer believe that this is desirable. While WebSockets are a small and elegant solution, the security restrictions of web browsers make them difficult to use for peer-to-peer communication.

A more productive endeavour would be to write a small, debuggable WebRTC library in C (no C++) that can be used by Transmission and friends.

@jech WebRTC support is underway in libtorrent: https://github.com/arvidn/libtorrent/pull/4123

A more productive endeavour would be to write a small, debuggable WebRTC library in C (no C++) that can be used by Transmission and friends.

That would be RAWRTC, right? No need to reinvent the wheel. Also, @lgrahl (the RAWRTC developer) has offered help multiple times, so if there is interest he'll surely be happy to assist.

FYI, not sure this would be usable here but the Tor project team has a WebRTC implementation for Snowflake also (on client and server side but not used for the server side since they use ws for now and then probably have the very same issue discussed here)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

mikeal picture mikeal  路  4Comments

Weedshaker picture Weedshaker  路  7Comments

norzak picture norzak  路  6Comments

lacker picture lacker  路  6Comments

marcu87 picture marcu87  路  5Comments