Show HN: Weron – A Peer-to-Peer VPN Based on WebRTC Written in Go (github.com)
Hey HN! I just released weron, a P2P VPN that uses WebRTC for transport which I've been working on for the last couple of months. It can create both layer 2/Ethernet and layer 3/IP overlay networks, and the underlying transport layer can be easily embedded to write your own P2P apps with Go. Compared to for example Tailscale, WireGuard and ZeroTier, its much harder to block on a network level and also significantly easier to set up, while not sacrifing much performance.
I'd love to get your feedback :)
51 comments
[ 2.6 ms ] story [ 108 ms ] thread(Note: I work on Orchid, a decentralized market for bandwidth built on Ethereum and WebRTC, which has a multi-hop-capable VPN client for various platforms available.)
More or less! Compared to say OpenVPN there is no central server that all traffic is routed through (unless you choose to activate TURN of course, see the `--force-relay` flag), so hosting it is much cheaper as the only public part of the infrastructure is the part that exchanges the candidates ^^ Its pretty close to how n2n[1] does it, but has proper NAT hole punching support due to the WebRTC backend.
> When you do that, are you building a full-connected overlay network [...]
Yes! Its a full mesh; it seems to scale pretty well to a fairly large number of nodes, although I haven't tested it with more than ~100 peers in a single community yet. If the overhead of maintaining all of the connections is too much or peering between nodes in an issue, TURN can help to connect those peers with the rest of the mesh. Orchid looks interesting!
[1] https://github.com/ntop/n2n
From what I vaguely remember when I tried playing around with this stuff, some NAT's / routers have some sort of port randomization thing so that the same ports don't always reach the desired location behind it.
Does WebRTC make that port connection persistent due to the streaming nature of it; is that the idea? Does the stream ever break and does it require getting ip and port information from the STUN and ICE servers again? If so, how often does that happen?
While I'm not involved in the project whatsoever, I'd expect that to work in most scenarios considering they've explicitly mentioned it. It's not a guarantee however and can get circumvented if the network owner wants to
https://en.wikipedia.org/wiki/Hole_punching_(networking)#:~:....
However the choice to hardcode Google as a default STUN server is off-putting. IMHO, 2008's n2n would never set a third party server as a default. https://luca.ntop.org/n2n.pdf
https://pkg.go.dev/github.com/libp2p/go-libp2p-webrtc-direct...
Just because home users must involve commercial third parties, e.g., ISP, cloud hosting, etc., in order to listen on globally reachable IP addresses does not also mean that users must also let those third parties have control over the software users run from those addresses.
https://github.com/pion/turn
There is another way of combining WebRTC and Wireguard.
Netbird uses ICE protocol (used in WebRTC) for NAT traversal and then reuses that punched holes to establish a direct Wireguard tunnel.
https://github.com/netbirdio/netbird
P.S. I'm author of Netbird (formerly know as Wiretrustee)
re: concerns about STUN I would love to experiment with adding NAT-PMP/PCP support to pion/ice. STUN server usage seems to be a major sticking point for people. Talked about it a bit here [0]. I am all for doing it, just would like to know the code is actually wanted before writing it :)
[0] https://mobile.twitter.com/_pion/status/1522365018855165952
[1] https://github.com/pojntfx/stfs
Tailscale at least bundles in an HTTPS fallback for those situations. I’m not sure that claim holds up.
I'm looking forward to doing a lot more with overlay networks in the short term, I've been playing with a variety of them over the last 18 months or so and just need to pick something and start deploying it.
are the webrtc streams running at a constant bitrate or can the streams be detected by doing traffic timing analysis?
(i once looked at adding constant bitrate support to wireguard but ultimately abandoned it as it was looking to be excessively complicated)
[1] https://github.com/pion/webrtc
i suspect that it might be possible to identify major websites being loaded by simply analyzing packet sizes and timings, but maybe not in http/2 world.
where it gets complicated is avoiding creation of new side channels. you need a very stable clock for pumping out the data and as you hint at, congestion control to avoid latency by actively adjusting the bitrate.
i was looking at doing this in the kernel implementation of wireguard, but those parts of the kernel didn't seem a good fit for this kind of time sensitive constant spinning algorithm.
if anyone is interested in this, would love to collaborate.
Many years ago I had each peer run their own smtpd listening on the n2n TAP interface. It was peer-to-peer, encrypted email. This can be done for many other protocols, too. With Layer 2 overlay, there are no middlemen. Direct connectivity to friends and family with no need for Google/Facebook.
Layer 2 overlay networks with n2n can be significantly faster if automatic encryption is turned off. In that case, the user can encrypt and sign sensitive files with a separate program before sending them through the TAP interface. It works quite well.
Weron also allows tunneling - just specify a TURN server on `--ice` and enable `--force-relay`, in which case it will probably scale to well over 100 nodes ^^ The signaling servers are fully horizontally scalable, so that you can benefit from a faster backbone on a global scale scenario - Redis coordinates messages, kicks etc. between them and a Postgres database maintains central state, such as credentials for persistent communities and client counts.
In terms of key rotation & encryption - weron heavily depends on DTLS as provided by Pion/WebRTC and thus inherits similar security properties. It is not possible to disable encryption of WebRTC, but tbf the performance benefits of using plain SCTP don't seem to be worth it as the RTT latency and resulting decrease in throughput[1] is the dominant performance bottleneck.
[1] https://tuhat.helsinki.fi/ws/portalfiles/portal/167373638/Es...
I'll test out Weron and hopefully I dont need to tunnel it through shadowsocks.
Disclaimer: I'm author of netbirdio - a similar project.
Using WebRTC makes it possible to have a tunnel from the browser directly. Combined with a virtual terminal it just makes it even cooler!
@pojntfx what do you think about that? Feasible with your implementation?
I've been playing with such functionality in Netbird but since it depends on Wireguard it is a bit tricky :)
Would love to have your feedback as well on our project
https://github.com/netbirdio/netbird