How to load .pem files generated by certbot for TLS?

Godot Version

4.2.1

Question

I am developing a multiplayer game, with a server-side Godot app running on Ubuntu, and a browser-based client-side app served as HTML5 by Apache. To get HTML5 working, Apache must server the HTML5 over HTTPS, and thus Godot must use wss for communication, not ws.

I am using Certbot to generate two different TLS certificates, one for Apache, and one for Godot.

The server app will not be running 24/7, so I would like to be able to be able load the Godot certificate when I start the app, so I don’t have to worry about when the certificate renews. However, I have three problems, so it feels like I’m going about this the wrong way:


  1. I can’t get Godot to load the .pem files generated by Certbot without first renaming them as .crt and .key
tls_cert = ResourceLoader.load("/home/tobyjones/Godot 4 Dev/certificates/cert.pem","X509Certificate")`
tls_key = ResourceLoader.load("/home/tobyjones/Godot 4 Dev/certificates/privkey.pem","CryptoKey")

Gives me an error:

E 0:00:00:0878   WebSocketServer.gd:21 @ _ready(): No loader found for resource: /home/tobyjones/Godot 4 Dev/certificates/cert.pem (expected type: X509Certificate)

  1. The privkey.pem file generated by certbot is in directory owned by root, and it has permission 600, so as well as copying the file to an accessible directory, and renaming it, I had to change it’s permission to 644 for Godot to be able to read it. I could probably do that via cron, but it seems clunky.

  1. I believe I have to bundle the cert.crt file with my HTML5 export to get the WebSocket Multiplayer Demo working with wss (a whole other question), so does that mean I have to re-export the game every time the certificate changes?

Honestly, I feel like I’m going about this completely the wrong way, so any help would be appreciated, thank you.

  1. You will have to load using the singleton’s load function for each
X509Certificate.load("/home/tobyjones/Godot 4 Dev/certificates/cert.pem")
CryptoKey.load("/home/tobyjones/Godot 4 Dev/certificates/privkey.pem")
  1. I believe letsencrypt creates an accessable /etc/letsencrypt/live/example.com/, I could’ve changed this folders permissions myself though it’s been a while.

  2. Only res:// paths will be packed for the executable.

1 Like

Thanks @gertkeno

  1. In case anyone finds this on a search, I got the load working with this code:
var tls_cert := X509Certificate.new()
var tls_key := CryptoKey.new()

func _ready():
    tls_cert.load("/etc/letsencrypt/live/<domain>/cert.pem")
    tls_key.load("/etc/letsencrypt/live/<domain>/privkey.pem")
  1. But I did have to change the permissions - I followed the guide on certbot docs.

  2. Yes, I guess I will have to copy the cert.prm file to res:// if I need to pack it in the executable. We will see!

1 Like