Welcome to the first talk in the network dev room, peer-to-peer browser connectivity.
We're going to talk a bunch about what we see and the new shiny web transport protocol
and in general how to get the browser connected to a larger network.
First off, before we start, very grateful to be here, thanks to all the organizers, thanks
to all the volunteers making this event possible.
That's wonderful.
Yeah, and then thanks for all of you to be here and listen in.
Cool.
Just quick introduction about myself.
I'm Max.
I'm a software engineer at ProtocolApps.
I'm stewarding the Lippie-to-peee project.
I'll do a brief introduction of what Lippie-to-peee is, so don't worry too much about that.
I'm maintaining the rest implementation of the library.
In the past life, you might know me from my Prometheus time.
I worked a bunch on Prometheus and its integration into Kubernetes is still a little bit active
in that community.
Yeah.
You find me anywhere on the web with Mxenden and then on the website you find emails in
case you want to get in touch.
All right.
So what is Lippie-to-peee?
Just a small disclaimer.
The talk does mention Lippie-to-peee from time to time.
It is not particularly important, so in a sense if you want to build your own Lippie-to-peee
application, all the content here is applicable for you as well.
But if you want to have this pre-built, you can leverage Lippie-to-peee.
So what is Lippie-to-peee?
Lippie-to-peee, as you can infer from the name, I'm guessing, is a peer-to-peee networking
library.
It has one specification, and then that specification is implemented in many, many different languages.
Like, for example, Go, JS, Rust, Nim, C++, Java, but a couple others as well.
The goal of Lippie-to-peee is provide low-level features like encryption, authentication,
hole-punching, and things like that.
And then on top of that, leverage those features to then also provide higher-level protocols.
Like, for example, DHT, distributed hash table, or gossiping protocols, or things like that.
And my big slogan always is Lippie-to-peee is all you need to build peer-to-peee applications
on the internet.
Okay, wonderful.
One small disclaimer that's important later on is that I want to highlight here is Lippie-to-peee
always encrypts and always authenticates, and we'll go into that later on, what that
means.
But that's very important for me.
We don't ship any traffic over the internet that is ever unencrypted or not authenticated,
and in terms of authentication, I'm talking about mutual authentication.
Okay, that's enough introduction for today, and now to the actual topic.
What I want to convey today is how we can get from here, from the left side to the right
side.
So my great motivation is for browsers to be first-class citizens in networked applications.
Now on the very left side, you see the typical internet application today.
So you have a browser.
I'm using the Firefox logo here, but you can use any browser, really.
That tries to interact with a network deprecation somewhere in the internet.
Instead of interacting with the nodes directly, it acts through a server, and that server
acts on behalf of the browser, right?
The browser pretty much never interacts with the whole network.
And to put this with an example, if you, for example, have a file sharing, you want to
share a file.
So for example, from my laptop here, I want to share a file with all of you.
I would usually upload that to the server, and then all of you would download it from
that server.
We would never interact directly.
Now there are many reasons for that to be a good architecture, right?
Browsers usually move a lot.
They might be in the living room, then in a cafe, and then at a conference in FOSDEM.
And they are usually low power, but what's the most hurt argument for this kind of architecture
in terms of that, in comparison to the right architecture, is that you cannot connect to
browsers, and that browsers cannot connect to other nodes.
That's oftentimes hurt, right?
And what I want to kind of convey here today is that you can actually nicely connect a
browser to a whole network, and that the browser actually has a lot of connectivity options
out there, and I want to go through these.
And the next time you design a network deprecation, maybe you want to consider the architecture
on the right versus the architecture on the left.
All right, cool.
When it comes to connectivity for a browser, I want to differentiate this in two dimensions,
and the first dimension is whether my node, whatever, for example, my computer here, is
public or private.
So can it be reachable directly, or is it behind an app or firewall, and or firewall?
In public, you would usually refer to it as a server, and in private, you would, for
example, refer to my laptop or the browser running on my laptop.
Cool.
Then the other dimension, when we talk about connectivity, I want to differentiate in two
platforms, which is browser and non-browser.
Why is this relevant?
Well, there are a lot more platforms, I know, but usually it's the non-browser, which is
very unrestricted, in terms of, for example, I have access to a UDP or a TCP socket, and
then I have the browser, which is very restricted, where sometimes I can't make a connection
without, for example, a valid TLS certificate.
Wonderful.
Okay.
So, and my goal today is kind of, we fill this matrix now with the different options
that we have, and this way I kind of convey the fact that actually browsers can be first
class citizens in network applications.
All right.
So let's talk about public non-browser to public non-browser.
I'm in the network dev room, like this is the easiest one, I'm not going to explain
this much.
Reachability, they're both nodes are public.
We can just reach out them directly over IP and TCP, or then UDP and the shiny new quick.
We don't have firewalls and that on either side, and the platform, which is non-browser,
so for example, an application running on my laptop has direct access to the TCP and
UDP socket.
Cool.
So we have that.
Then private non-browser to public non-browser, again, really easy.
You do this every day by any application on your laptop going to a server.
We don't have any firewalls, and we're not at the receiver side, so on the server side,
the left side is private, but we don't really care as we have the direction from the left
to the right.
And then the platform, again, we're not running in the browser, so we're pretty unrestricted.
We probably have access to a TCP or UDP socket.
Wonderful.
To make this a little bit more complex, what if I'm a public non-browser connecting to
a private non-browser?
So does that mean, for example, on the left that could be a server, and then on the right
that could be some application running on my laptop right now?
What we can do here is something called connection reversal, simply where my laptop connects
to some public node, then whoever wants to reach out to me reaches out to that public
node as well, relayes a message to me, my laptop, and then my laptop dials whoever wanted
to dial me initially.
This is depicted here, so B connects to the relay R, and then A relays a network over
R to B, and then B can actually connect to A, which is commonly referred to as connection
reversal.
In terms of platform, again, we're a non-browser, so access to TCP and UDP socket, so we're
all good.
Cool.
And then the last one I want to fill before it becomes complicated, namely before we introduce
a browser, is private non-browser to private non-browser.
You see this depicted down there as A and B. Reachability really sucks.
Both are probably behind gnats or firewalls, so not much luck either.
So what we need to employ here is a technique called hole punching.
I don't have much time today in this talk, but we have another talk later on.
So if you want to learn all about hole punching or what success rate we have across different,
protocols or IP stacks, join the talk.
I think it's at 11.45.
So we'll go a bunch into that.
Just short, brief one, A and B want to connect.
Both are behind firewalls.
Both connect to a relay R, that R is public.
They coordinate a hole punch over that relay, and then execute that hole punch through both
of their firewalls.
Cool.
In terms of platforms, again, we're not on the browser yet.
So we have access to the TCP and UDP socket.
All good.
Life is pretty easy.
Wonderful.
All right.
Now comes complexity, which is the browser world.
And what we can, what I want to talk about first is what if I'm a private browser.
Now private browser is somewhat of a weird term.
Usually you're not at Faustum and you don't have a public IPv4 or IPv6 address.
So browsers are usually always private, which I'm not suggesting to change.
Definitely not.
There are many security considerations to keep it that way.
But what if I want to connect from a private browser to a public non-browser?
So what if I, for example, want to connect from my laptop within my browser to some server?
Now this, again, sounds pretty easy to everyone, except one small disclaimer.
Again, we don't have a firewall or NAT at the receiver side, right?
A server is public, depending on the firewall rules, obviously, but we can easily reach
out to them.
In terms of platform, we are on the browser, so we're quite restricted in the sense of
what we can do.
Eventually, I want to end up with a byte stream between the two endpoints.
So what I'm restricted to is either web sockets.
Everyone knows that.
So TCP, TLS, HTTP, then an upgrade, and then I have web socket.
The problem with that is I need a valid TLS certificate, so I need the remote server to
either have a signed IP certificate or based on a domain.
So that's a bummer.
What I can do as an alternative in the browser is use the shiny new web transport, which
is basically, I'm simplifying a lot here, but basically web sockets on top of Quick
or HTTP3.
Web transport actually allows us to handle self-signed certificates.
And then as a last alternative, we can use WebRTC to get a byte stream, WebRTC gives
us data channels, so in the end, we can run on IP, UDP, then SCTP, and then use data channels
from WebRTC.
Now before you scream, this is insecure.
The small disclaimer that I did at the beginning is in case you built this yourself, you still
need to figure out proper authentication, right?
Best would be mutual authentication, because self-signed certificates, you're not part
of the authority trust chain, but otherwise, yeah, these are your options.
So web socket, web transport, and WebRTC.
Cool.
So what if I want to connect from a public non-browser to a private browser?
We had this in the past, a couple of slides back.
In terms of reachability, my left side is reachable, my right side is not reachable,
so what I can do, I don't need to do fancy hole punching, I can just do connection reversal
right over the relay, where A asks B basically to dial it back over the relay.
In terms of platform, we don't have direct access to the TCP or UDP socket, given that
on the right side, we have a browser in the whole stack, so that's a bummer.
We can do web sockets in case we have a valid TLS certificate signed by some authority.
If not, we can do web transport and WebRTC.
Cool.
And now comes the very hard part, or not very hard part, but a little bit more difficult
part, which is private browser to private browser, or what is basically the same is,
was it private non-browser to private browser, or private browser to private non-browser,
all the red boxes down there.
In terms of reachability, we need to leverage hole punching at this point.
Both end points are behind the firewall and are not.
So again, we'll go more into details on how hole punching works.
Probably a lot of you are really familiar with that.
In terms of platforms, at least one of our two sides are behind our browsers.
So that means we don't have access to TCP or UDP socket directly.
Why am I always saying no access to TCP and UDP?
That's relevant because you don't control the ports, and this way you don't have the
capability of hole punching yourself.
But what the browser gives us is WebRTC.
WebRTC has hole punching built in, so what we can do is leverage WebRTC and some signaling
server R in the middle to then do the actual hole punch.
WebSockets doesn't work because we can't hole punch with WebSockets and WebTransport
doesn't work either because we can't hole punch with WebTransport either.
Okay, wonderful.
And that concludes the whole matrix, and what I'm pretty much showing here is you can connect
the browser to everyone out there that runs on IP, and that means your application can
actually make the browser a first-class citizen within your network.
Cool.
That's all from my end.
Yeah, I'll be around the venue for quite a bit.
If you want to learn more about LiPi2P in general, which makes all this nicely packaged
for you, you can visit docs.lippi2p.io.
If you want to see all the nitty-gritty details about the different transports and what that
means for, I don't know, for example, you sign TLS certificate or where you can hole punch,
that would be on connectivity.lippi2p.io.
There are various forums, there's a specification online, and then all the implementations are
open source, so you can just check that out on github.com slash lippi2p.
Cool.
That's all from my end.
Thank you very much.