WebSocket multiplayer on HTML5 platform with self-signed certificates
Asked Answered
B

8

0

Hello everyone, I'll try to keep this concise.
The setup: Dedicated server hosted on a DigitalOcean droplet created using WebSocketMultiplayerPeer.
Client served on a the HTML5 platform, also created with WebSocketMultiplayerPeer.
I have the dedicated server running on the droplet. If I attempt to connect to it using a client created with the Run Project button on the editor, I can connect to the server using the server's IP and play the game with no issues.
If I try to do the same but with the client running on the browser instead, I get this error:
And simultaneously on the server, I get this error: mbedtls error: returned -0x7780
I am using a "wss://ip_here:port_here" address. I am also using TLS options created with TLSOptions.client_unsafe and TLSOptions.server. The certificate I am using is a self-signed certificate generated using the crypto class, similar to this video:
So, from what I can gather this can be resolved by using a CA-approved certification. My understanding is that this doesn't work due to this (from the TLSOptions API)

Note: On the Web platform, TLS verification is always enforced against the CA list of the web browser. This is considered a security feature.

Is there no way to use a self-signed certificate? It's perfectly fine if there are safety warnings and such, this isn't intended for mass distribution, this will only be played by a small group. The HTML platform is being used for convenience.

Bono answered 18/10, 2023 at 20:33 Comment(0)
D
0

Bono From the doc you quoted sounds like there isn't a way to use a self-signed cert in web build (unless maybe you made your own custom build of the engine, which is probably not worth the trouble). But Let's Encrypt provides free signed certs, depending on your hosting plan you might be able to set up one of those:

https://letsencrypt.org/getting-started/

Dowie answered 18/10, 2023 at 23:44 Comment(0)
B
0

Dowie Hey, thanks for the reply. I actually already did the process to obtain a signed cert through Let's Encrypt for the website which is serving the client. This seems to be working properly. The files I got through that were the following:
cert.pem
chain.pem
fullchain.pem
privkey.pem
Can I simply re-use those files in the TLSOptions objects for the Godot project? If so, I assume privkey.pem corresponds to the key given to the server, but which file should I use for the trusted_chain/certificate object?

Bono answered 18/10, 2023 at 23:54 Comment(0)
B
0

I attempted to use the Let's Encrypt files as the certificate and key of the godot project, but got the same error as before. I had to rename privkey.pem to privkey.key and the others to .crt so that godot detected them properly. I used privkey.key as the key and tried both cert.crt and fullchain,crt as the certification, but both had the same result.
edit: correction, the error with cert.crt is _do_handshake: TLS handshake error: -9984
edit2: and with fullchain.crt the error is instead TLS handshake error: -27648
For all this the error on the server's side stays the same. For both the client fails in _godot_js_websocket_create.

Bono answered 19/10, 2023 at 1:39 Comment(0)
D
0

Oh no, you definitely do NOT want to add your server's private keys to the project, that would compromise the server's security. Although if you're using a Let's Encrypt cert then you do not have a self-signed one, you have one signed by LE which is a generally accepted CA. So either you don't have the LE cert deployed correctly, or your problem is not actually due to a self-signed cert.

Dowie answered 19/10, 2023 at 3:0 Comment(0)
B
0

Dowie Sorry for the confusion, there are two sets of keys going on. I have the self-signed .crt and .key files which I used in the Godot project (and which didn't work for clients on HTML5), and I have the four .pem files I generated (with certbot) for the website I am using to serve the client.
What I tried in my last post was to use the .pem files in the Godot project (which didn't work either).
I think as you say I'm not using the LE cert correctly. I've checked that the cert was valid (the website is served on https correctly and https://www.digicert.com/help/ finds a valid cert). But I'm not sure how to use it in Godot.
The TLSOptions.server function takes in a key, is that not the private key? If not, what should it be?

Also, do I need to convert the .pem file to another format?

Bono answered 19/10, 2023 at 3:33 Comment(0)
B
0

I found this github thread which seems to do something similar to me. https://github.com/godotengine/godot/issues/37739#issuecomment-814929503
I'm not sure what exactly my FQDN would be.

Bono answered 19/10, 2023 at 3:53 Comment(0)
B
0

I think a problem may be that the LE cert was generated for a given IP, but the Godot server is running on a different IP. I am going to generate another LE cert for the IP the Godot server is running on, and use this in the TLSOptions.

From what I read in the github thread above I'm pretty sure I want to use the fullchain.pem and privkey.pem files, but I'm still not sure what's the correct procedure to convert them to the format desired by Godot, the second openssl rsa -outform command doesn't seem to work on my private key file.

Bono answered 19/10, 2023 at 19:41 Comment(0)
B
0

Alright, seems like I figured it out. For posterity: the server where the godot server is running needs a certification generated explicitly for it, which I generated with sudo certbot certonly --standalone. The files do not need to be modified in any way, you can just rename the .pem to .crt and .key so that the files are recognized by the Godot editor. Make sure to exclude the .key file from your client exports.

Bono answered 19/10, 2023 at 21:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.