Compare commits

...

No commits in common. "sctpub" and "tcpquic" have entirely different histories.

2 changed files with 232 additions and 170 deletions

170
sctpub.md
View File

@ -1,170 +0,0 @@
# SCTPub
Hi! So this is me trying to explain my plans with SCTPub (ActivityPub over SCTP).
And remember: this is *my* idea, and I don't expect ppl will agree with it, and that's okay! I don't like TLS, doesn't mean I
refuse to use it.
First, I'll talk about the choice of SCTP, and the choice of authentication and authorization mechanisms (which are actually
tightly coupled).
## Why SCTP?
SCTP is a little-known protocol, so the idea was to use it to make it more popular and to experiment with it.
SCTP is in theory capable of seamless proxying such that you can talk to the proxy at the same time as you talk to the target,
but nothing seems to use this feature. It would still be target-controlled and signed, but the proxy would have some control
over caching. For sensitive requests, they would go straight through to the server, without the proxy being able to read it.
This puts the proxy in a position of a semi-trusted middleware. Technically all routers on the internet need to be semi-trusted
middleware, as any of those routers can track you and target you (e.g. with ads) based on that - see:
[ALTER (LTE) attack](https://alter-attack.net/), which explains how a middleware can track (fingerprint) the pages you visit.
Since we already need to somewhat trust the middleware to be able to do anything, we could use that semi-trust state to provide
more efficient caching. This can be used to a) reduce our server load and b) protect against DDoS attempts. So I guess at this
point it'd no longer be "pure" SCTP as it'd involve MITM relations between the server and the middleware, but that's okay.
(I don't think this is the right place to go in-depth into this idea, tho, so I'll stop here. I like to believe mobile
operators would be happy with the possibility of downscaling their link sizes tho. This can even be used for private content
e.g. if you have a large chat group you just encrypt the large data (video, etc) and send the group a key, and the data gets
cached. Crypto is fun.)
## Words about Authentication
Registering on SCTPub would require an username and a password, as well as an email address and a display name (handle). The
username and password never get sent to the server, only the email address and the display name (handle). This means if the
server is MITMd or malicious or a phishing server is used, the user's identity (login information) is still protected.
The login interface:
```
+-------------------------------------+
| Login [x] |
| |
| Username: _____________ |
| Password: _____________ |
| Instance: _____________ |
+-------------------------------------+
```
The registration interface:
```
+-------------------------------------+
| Register [x] |
| |
| Username: _____________ |
| Password: _____________ |
| Instance: _____________ |
| Email: _____________ |
| Handle: _____________ |
+-------------------------------------+
```
The authentication is done using a public key mechanism. The Ed25519 private key is generated:
GO ASK ##crypto @ irc.freenode.net BECAUSE THEY INSIST THAT I'M NOT ALLOWED TO SPECIFY THIS STUFF WHEN TRYING TO MAKE A PORTABLE PROTOCOL
The user should be able to change their username/password (aka login key). The user may have multiple login keys.
Once authenticated, the key is to be replaced with a temporary, non-token-based (i.e. no cookies) session key.
All messages encrypted or signed by the client must include the instance address. All messages received by the instance must
check the instance address. Nonces must also be used but w/e you probably know this better than me. Encryption vs signing
should be chosen as needed depending on the requirements (see also *Why SCTP?* above).
## Words about Authorization
Authorization should also be done with cryptography, and not OAuth. OAuth is awful. Please don't use OAuth. In fact,
authorization should be done with public key *encryption*, not even signing. The keys are revokable. The same
mechanism that allows zero-knowledge authentication can also be used for authorization, as it already provides all of this.
Authorization doesn't need the session keys mechanism described above. In fact, that mechanism is a form of authorization.
User agents may optionally authenticate themselves using an UA key. In other words, messages would be double-signed or
double-encrypted, once by the authorization key, once by the UA key. The authorization key should always be the "inner" key
while the UA key should always be the "outer" key. (e.g. UA signatures also sign the authorization signature.)
This shouldn't be used by client-side UAs like mobile apps or web browsers.
- - -
Now that we have some of the security aspects out of the way, let's talk about the community aspects: moderation, interaction,
friendship, etc.
## Communities
One of the goals of SCTPub is to provide for *communities*, something we lost a long time ago with the downfall of forums.
Y'know, like phpBB and stuff.
As such SCTPub *actively encourages* you to have different accounts on different intances, by not only making it easy to do
so (with the standard User Agent providing an easy way to sign up to other instances), but also through "dark patterns"
(sorry). The main dark pattern is that while ppl can boost your content to other instances' main feeds (separate from your
self-curated feed, more similar to the mastodon "Local Timeline" but including all interactions from local users - boosts,
etc), but you can't post on other instances like this. Ppl from other instances can choose to follow you, and your content
shows up to them, but it's not the same as being in the community. Think like Reddit, but each instance is a different sub.
While there's no technical mechanism to encourage instances to have different rules, I do believe in different instances
having unique rules but still federating together. This would also support this "communities" model, and encourage multiple
accounts.
## Moderation
One of the things I miss a lot from the time we had forums is moderation. Back in the day, some forums, as elitist as it may
be, would require you to participate in a closed-off area before participating in the rest of the community. While I'm not
totally a fan of that idea, I do think a similar idea is warranted: participating locally before federating. This doesn't
(on its own) reduce spam on a local level, but it helps a lot on a federated level. The software *should* still allow
instances to opt into a pre-approval stage where you don't even interact with the locals, tho.
Additionally, to register on other instances, some metadata would be sent across servers. This metadata would be composed
of the originating instance, the target instance, and it would be signed by the user's login key. This metadata is then
used to build a chain of trust (web of trust?) of sorts. Also, because you have to sign it, you actually have full control
over which instances/accounts know about your other accounts.
Depending on the chain of trust model of each instance, you'd either have to go through the moderator-approval stage on the
other instance, or it'd trust you because N other instances trust you, or because N instances on its trusted instances list
trust you, or [...]. There's a lot of flexibility here.
This chain of trust can also be stored, and retrieved at login time, allowing for smooth login across many instances (see
Communities above). If one of your instances is down, that's no big deal - just login on another! I don't have many
accounts across the fediverse because of how hard it is to manage them, but this alone would make it a lot easier.
Moderation requests (e.g. reports) should definitely federate, altho I haven't worked out all of the details with this.
## Interactions
This is a tricky one to explain, because I'm not trying to make another Twitter or Facebook. So bear with me for a second.
Twitter and Facebook have an attention-based model. On Twitter and Facebook you're "supposed" to make posts that bring you
attention, like memes or shitposts or flame wars. Reddit also encourages this to a slightly lesser extent. This is NOT
something I want, even if they're "technically" interactions. (besides, [there's an xkcd for that](https://xkcd.com/1475/))
Instead, we should look at forums. In forums, there's no pressure to have the most shared content. Instead there's pressure
to have the most talked about content. That's what I want when I talk about interactions. I want ppl to talk to me, not
just share my posts. Social isolation is awful, and altho liking and sharing do have their place as forms of non-verbal
communication (and I'm not proposing we remove them), they just aren't always enough.
I want to bring back that cozy feel of forums, while taking it to the next level. The federated nature of the fediverse
allows for ppl to easily interact with eachother, which brings us one step closer to taking it to the next level.
(I could go on about this all day, but I'm really starving and I'd like to finish this ASAP so I can go eat. it's getting
hard to stay focused now.)
## Friendship
Friendship is important, so just allowing interactions across instances while providing a cozy feel isn't enough.
So there should be a way to keep up with your friends, and putting some emphasis on it. But I don't think it should be the
default.
Both Facebook and Twitter have this thing where you can follow ppl. And then you follow too many ppl and it just goes too
fast. You can still follow ppl, and it should be encouraged, and there should be lists like in mastodon (or how reddit used to
have multireddits?) so you can organize things better, but the local timeline, which should be cozy, should be the default.
(Big instances should be discouraged, while subject-specific/topical instances should be encouraged.)
- - -
Okay I'm too hungry to keep going. Cya another time tho. o/
Sorry that this was so long. I needed to write it down somewhere.
You can boost and send comments on the associated ActivityPub post: <https://cybre.space/@SoniEx2/101557574984189610>

232
tcpquic.md Normal file
View File

@ -0,0 +1,232 @@
# Connection Latency
Hi! Let's say you go to visit your favorite website, and it takes 3 seconds to show up. You run a speed test, and your
connection is doing fine at around 100 Mbps. So how come it took 3 seconds to show up? That's what connection latency is.
Let's say our network has 3 nodes:
```text
your phone ---------> our router ---------> the server
<--------- <---------
```
(This is a rather simplistic model, real networks are a lot more complicated. But it'll work for this demonstration.)
Let's say sending a packet between two adjacent nodes takes n seconds. This means that for a packet to go from you to
the server, it takes 2\*n seconds (n seconds to go from you to our router, then another n to go from our router to the
server). As such, we want to keep this n very low. Ideally, it'd be 0, but in practice we're limited by things like the
speed of light.
```text
your phone ---------> our router ---------> the server
<--------- <--DATA---
your phone ---------> our router ---------> the server
<--DATA--- <---------
```
So you might be thinking, "it takes 3 seconds for the server to send me the page?! n is 1.5s?!" No, not quite.
Before the server can send you anything, it first needs to know what you want. You need to tell the server what you want.
So our n is no longer 1.5s but 0.75s instead.
```text
your phone ---HTTP--> our router ---------> the server
<--------- <---------
your phone ---------> our router ---HTTP--> the server
<--------- <---------
your phone ---------> our router ---------> the server
<--------- <--DATA---
your phone ---------> our router ---------> the server
<--DATA--- <---------
```
But that's not all! You can't just ask the server to send you stuff and have it send you stuff! There are things like
spoofing that we need to be concerned about, otherwise we'd get massive DDoS amplification attacks! Instead, meet TCP:
## TCP Connection
Transmission Control Protocol, or TCP, is the protocol used to prevent evil hackers from bringing down the internet. It
accomplishes that by employing a 3-way handshake. So, how does it work? Well, first, you ask for a connection. This is
called a SYN in TCP:
```text
your phone ---SYN---> our router ---------> the server
<--------- <---------
your phone ---------> our router ---SYN---> the server
<--------- <---------
```
This lets the server know you want to send data.
When the server receives the SYN, it then tells you that it got the SYN, and asks *you* for a connection. This is called
a SYN-ACK:
```text
your phone ---------> our router ---------> the server
<--------- <-SYN-ACK-
your phone ---------> our router ---------> the server
<-SYN-ACK- <---------
```
This lets you know the server wants to send data, and acknowledges that you want to send data. But we're not quite done yet.
We still need to acknowledge that the server wants to send data. So, we send an ACK:
```text
your phone ---ACK---> our router ---------> the server
<--------- <---------
your phone ---------> our router ---ACK---> the server
<--------- <---------
```
*Now you can get your data.*
We took 6n to get a connection, and 2n to get our data... and another 2n to request the data. As such, 10n = 3s, or
n = 0.3s... So if we were to simply send a packet to the server and get a similar packet back, it'd take about 1.2s. However,
we're not quite done yet. Before your phone can talk to the server, it needs to know where the server is. When you type an
address into the browser's address bar, that's only the name of the server - we need instructions to get the packets there.
This is where DNS comes in:
## DNS Queries
Domain Name System, or DNS, is the protocol that takes a domain name and converts it into an IP address - the latter is
basically a map/instructions on how to get the packets to the destination.
Thankfully, DNS is usually stored in the router. Additionally, it doesn't use TCP, so there's no 3-way handshake.
```text
your phone ---NAME--> our router ---------> the server
<--------- <---------
your phone ---------> our router ---------> the server
<---IP---- <---------
```
If the router doesn't know a name, it has to ask another router about it. However, this generally only happens once every few
hours, so it's not something we have to worry about.
This adds another 2n to our time. We're up to 12n = 3s, or n = 0.25s. It only takes 1 second to send a packet to the server
and get it back! TCP is awful! ... Not so fast, tho. You might've noticed that the network is busy with only one packet at a
time. Maybe we can do something to improve this. Okay, we can't improve the DNS query, as it's required to happen before we
can do anything. But can we improve the TCP? What if we terminate the TCP at the router?
## Terminating the TCP at the router
While not strictly allowed by the internet specifications, it's not strictly disallowed either. If implemented, our flow can
look like this:
```text
your phone ---NAME--> our router ---------> the server
<--------- <---------
your phone ---------> our router ---------> the server
<---IP---- <---------
your phone ---SYN---> our router ---------> the server
<--------- <---------
your phone ---------> our router ---SYN---> the server
<-SYN-ACK- <---------
your phone ---ACK---> our router ---------> the server
<--------- <-SYN-ACK-
your phone ---HTTP--> our router ---ACK---> the server
<--------- <---------
your phone ---------> our router ---HTTP--> the server
<--------- <---------
your phone ---------> our router ---------> the server
<--------- <--DATA---
your phone ---------> our router ---------> the server
<--DATA--- <---------
```
We're down from 12n to only 9n! With our n = 0.25s, we've shaved off 0.75s from our original 3s! This is a noticeable
improvement.
However, you might've noticed I've been talking about `HTTP` so far. Additionally, you can have both an ACK and an HTTP in
transit at the same time, this shaves off 1n from both our original 12n and our 9n, so we have 11n = 3s and an improvement
of approximately 0.81s. So it's even slightly better.
HTTPS, on the other hand, also has its own handshake after TCP's. I don't wanna get into this, because you can probably see
how ridiculous it's getting by now. This handshake can also be partially terminated by the router, so *it* can also be
optimized slightly, and we can shave off more n's.
But let's look at QUIC real quick:
## QUIC
(I don't know what QUIC stands for.)
QUIC is a protocol that does something similar to TCP, with one major difference: it uses UDP.
User Datagram Protocol, or UDP, is also used by DNS (see above). This means it has no handshake. QUIC implements its own
handshake, on top of UDP. This means QUIC is basically like TCP, but it comes with a serious caveat: being UDP-based, it
DOESN'T benefit from our TCP optimization from earlier!
As such, going QUIC over existing networks has one serious drawback: it adds back those 3n that we were able to shave off!
And if we optimize for QUIC in addition to TCP, we still only manage to shave off those 3n again.
So, is there any room for improvement? Can we shave off more n's?
... Maybe. It would require some changes to the web. More specifically, what if the router could serve some of the content
directly, without ever reaching the server?
That's where we need to change the protocols slightly:
## Terminating "HTTP" at the router
Rather than terminating just TCP at the router, can we go one step further?
Can we create a protocol such that the great majority of the connections look more like this:
```text
your phone ---NAME--> our router ---------> the server
<--------- <---------
your phone ---------> our router ---------> the server
<---IP---- <---------
your phone ---SYN---> our router ---------> the server
<--------- <---------
your phone ---------> our router ---SYN---> the server
<-SYN-ACK- <---------
your phone ---ACK---> our router ---------> the server
<--------- <-SYN-ACK-
your phone --NHTTP--> our router ---ACK---> the server
<--------- <---------
your phone ---------> our router ---------> the server
<--DATA--- <---------
```
(shave off another n if you combine the ACK and the NHTTP)
We just managed to shave off another 2n! While this requires extensive changes to the existing infrastructure, the load
times go from the 2.25s/2.19s from our "Terminating TCP at the router" to an even lower 1.64s! This is almost half the
original 3s! However, this improvement is not as perfect as our "Terminating TCP at the router" and "Partially terminating
HTTPS at the router" - you want your private data to go encrypted all the way to the server, so anything dealing with
private data would be back to the original 3s/2.25s/2.19s depending on optimizations. This is okay tho, as most data on the
web - images, videos, HTML (page layout/behaviour), CSS (also page layout), Javascript (also page behaviour) - are generally
not private. For example, your neighbor probably watches the same videos as you - thus the videos are not private - but your
bank statement is exclusive to you - and as such, private.
- - -
You can boost and send comments on the associated ActivityPub post: <https://cybre.space/@SoniEx2/101563377232093475>