minetest / minetest

Luanti (formerly Minetest) is an open source voxel game-creation platform with easy modding and game creation
https://www.minetest.net/
Other
10.81k stars 2.03k forks source link

Add QUIC support for Minetest #15261

Open paradust7 opened 1 month ago

paradust7 commented 1 month ago

Problem

In the current Minetest protocol, servers are unauthenticated and the connection is unencrypted. It is therefore always possible for a MITM to hijack or snoop on a connection after a successful login.

Additionally, the protocol uses UDP, and so must implement features such as reliability (re-transmission), flow control, packet re-ordering, and channels. The implementations of these features are necessarily simple and unlikely to be optimal, compared to implementations by well-funded network engineering teams.

Solutions

Minetest can make use of QUIC as an alternative to UDP for establishing connections to a server.

How QUIC works

QUIC uses the same security mechanism as https, so a connection to a server with a host name will be secure by default. The server operator will need to generate a certificate for their domain or subdomain, e.g., using Let's Encrypt or other provider.

Connecting to a server by IP will still be encrypted, but using an unverified certificate (which could be self-signed). The user will be warned that this is insecure. The server's certificate will be cached, so that subsequent connects expect the same certificate. If the certificate changes, the user will be loudly warned. This can't prevent a MITM attack from occurring on the very first connect, but it can detect and prevent future attacks.

After the TLS handshake, QUIC connections remain encrypted using a negotiated ephemeral cipher. The details are handled by the QUIC protocol.

How Minetest can use QUIC

QUIC provides channels (streams), reliable transmission, and in-order packet delivery. Minetest's protocol currently emulates these things over UDP. It will be possible to use QUIC for all of these features, in addition to raw datagrams (rfc 9221) for plain UDP-like delivery.

It may also be possible to have Minetest serve both the UDP protocol and QUIC protocol on the same port. (Investigation is needed)

paradust7 commented 1 month ago

As usual, I am volunteering myself to implement this, and will be upstreaming if possible. This issue is to track comments and progress. :tada:

sfan5 commented 1 month ago

related: #10206, #14970 tangentially related to #4184 (this would also rid us of our terrible netcode)

The server operator will need to generate a certificate for their domain or subdomain, e.g., using Let's Encrypt or other provider. Connecting to a server by IP will still be encrypted, but using an unverified certificate (which could be self-signed). The user will be warned that this is insecure. [...]. If the certificate changes, the user will be loudly warned.

In related discussions the consensus more or less was that requiring certificate PKI is bad UX for the server owner, player or even both.

It may also be possible to have Minetest serve both the UDP protocol and QUIC protocol on the same port. (Investigation is needed)

IMO this is quite important to have for a streamlined upgrade experience (and also to prevent admins from making mistakes where only one of the protocols works). This is in principle always possible as long as the QUIC implementation supports abstracting socket access and doesn't insist directly touching sockets on its own. Because our own protocol will have a different magic number.

paradust7 commented 1 month ago

In related discussions the consensus more or less was that requiring certificate PKI is bad UX for the server owner, player or even both.

For dedicated server owners, I don't think it is too much to ask. If they already have a website at the same domain, they would only need to copy the existing certificate. Otherwise, an invocation of "certbot" would be able to generate one. I will be sure to write up detailed instructions.

Luckily, the player doesn't need to do anything with certificates. Everyone else running a server can use a default self-signed certificate.

Later, it would be possible to add support for secure reverse tunneling proxies. This would enable non-tech-savvy players to host games behind a NAT and without a certificate, while maintaining full security. The UX for this would be:

The proxy doesn't need to be trusted, because the shared secret will be unknown to the proxy. If it tries to MITM, it will fail validation.

IMO this is quite important to have for a streamlined upgrade experience (and also to prevent admins from making mistakes where only one of the protocols works).

Agreed

This is in principle always possible as long as the QUIC implementation supports abstracting socket access and doesn't insist directly touching sockets on its own. Because our own protocol will have a different magic number.

Agreed.

swagtoy commented 1 month ago

This is a good excuse for me to finally learn QUIC, but let me QUICly drop some late-night thoughts that comes to mind.

Why do we NEED to encrypt all of the games packets? For embedded devices, that could make some extra useless work, considering how fast QUIC encryption is. I can understand encrypted chat logs, maybe some modchannel stuff, given the modder so pleases, but for every packet?

I mean, man, id be mad if I got my base griefed because the grayhair at Mcdonalds picked up some peculiar packets. For MITM attacks I can understand, but a WPA like handshake at the beginning could do the trick to prevent this, not overall encryption. If a player so direly fears having his Mese shards stolen by the college wifi pest, shall we make it an option for the client to demand? Chat logs is an a-ok thing to encrypt. Intimacy is real and privacy should be respected in such scenarios.

(yes, encryption isnt heavy, but id prefer compression over encryption here, some people play on dialup toasters being oven baked in a hot room)


Overall, is encrypting the entire network data a big deal? Absolutely not. But is it required. Most certainly not either. It boils down to a weird "Gemini" problem. When 96.8% of the Gemini content is just plain-text websites, using obviously unencrypted DNS, then why on earth was forcing TLS a requirement at specification level?

paradust7 commented 1 month ago

Why do we NEED to encrypt all of the games packets? For embedded devices, that could make some extra useless work, considering how fast QUIC encryption is. I can understand encrypted chat logs, maybe some modchannel stuff, given the modder so pleases, but for every packet?

In QUIC encryption is not optional. All traffic is encrypted, and I don't think it would be wise to tamper with this. The implementation is expected to be fast enough that this is not a problem. Even if it were possible, I don't think it would make sense to cede security decisions to individual mods. The existing protocol can still be used if someone has a need.

(yes, encryption isnt heavy, but id prefer compression over encryption here, some people play on dialup toasters being oven baked in a hot room)

There's no conflict here. The data can be compressed before it is encrypted. This is already done in the minetest protocol for bulk node data. Compression is much more CPU intensive than encryption.

appgurueu commented 1 month ago

Damn, paradust beat me to it :)

All traffic is encrypted, and I don't think it would be wise to tamper with this.

I strongly agree. Think about it: Which packets can you safely assume will be free of the need for confidentiality and integrity in general? It is rather arbitrary to just pick chat and nothing else. Essentially none of the heavier packets can be assumed to not need these things. Mapblocks? Could contain private data in metadata or even node patterns. Interactions need their integrity protected, think luablocks. Objects? Could contain private data, and again interactions may need protection of integrity.

The implementation is expected to be fast enough that this is not a problem.

Also this. Why think about this when we can afford to just not to, and be better off in the integrity and confidentiality departments?

(And as paradust noted, even if we're missing something here, the old protocol remains as a fallback.)

sfan5 commented 1 month ago

I suggest we don't start a general encryption debate here, because consensus among the core team already exists (or does it?) that we should eventually do it.

swagtoy commented 1 month ago

Mapblocks? Could contain private data in metadata or even node patterns. Interactions need their integrity protected, think luablocks. Objects? Could contain private data, and again interactions may need protection of integrity.

@appgurueu Thats true, so ill leave it here. If i were to get deep then id go as far to say offering control from the Lua api, but thats incredibly user (modder) unfriendly and overkill when just encrypting everything will lightly do the job.

And if its optional? Then lets ship it ;) Nothing wrong with that

Update: ill stub in one more thought before dropping, but i mainly just meant movement being encrypted might be funky, anything else is fine, and to a degree movement isnt too demanding I think (?)

HybridDog commented 3 weeks ago

My opinion about QUIC: https://github.com/minetest/minetest/issues/10206#issuecomment-1275094664