Follow-up with measured results, now that I've moved three Cloudron servers to Ubuntu 26.04, for anyone finding this post and wondering...
Short version: upgrading the host OS to Ubuntu 26.04 makes Cloudron's own port-443 nginx negotiate hybrid post-quantum key exchange (X25519MLKEM768) by default. Cloudron needs no config change, and classic clients still connect.
What I measured (openssl s_client -groups <group> against each dashboard and app domain on 443, before and after the upgrade):
Host OS
OpenSSL
nginx
X25519MLKEM768
SecP256r1MLKEM768
X25519
P-256
Ubuntu 24.04
3.0.x
1.24
refused
refused
accepted
accepted
Ubuntu 26.04
3.5.5
1.28.3
accepted (negotiated by default)
refused
accepted
accepted
Same result on Cloudron 10.0.5 and 10.1.5.
Cloudron's generated nginx config has no ssl_ecdh_curve directive, so it inherits OpenSSL 3.5's default group list. That list prefers X25519MLKEM768.
With no group forced, a modern client now negotiates X25519MLKEM768. Older clients fall back to X25519/P-256 as before.
So for anyone asking how to get PQ TLS on the Cloudron dashboard and apps, the answer today is to upgrade the host to 26.04 following the official guide (https://docs.cloudron.io/guides/upgrade-ubuntu-26). This needs no packaging or app changes.
Upgrade notes from doing three servers (Hetzner Cloud, 22.04/24.04 → 26.04), in case they save someone time:
Take a fresh Cloudron backup and a provider snapshot first. Hetzner snapshots do not include attached Volumes, so the Cloudron backup is what covers data stored on them.
If an earlier dpkg run hung in shim-signed/GRUB configuration, compare debconf-show grub-pc grub-efi-amd64 with /dev/disk/by-id/. Stale device IDs make the GRUB prompt loop even in noninteractive mode.
Hetzner Cloud x86 guests boot via BIOS. Before each reboot, I ran grub-install --target=i386-pc /dev/sda && update-grub.
Older Hetzner images can have both a cloud-init ifupdown config and netplan defining the same interface. After the upgrade, networking.service failed with "address already assigned". The netplan config was correct, so I backed up and disabled the duplicate ifupdown file.
On 26.04, follow the guide's MySQL 8.4 step (stop box, install mysql-server, re-run the box setup script, start box). After that, cloudron-support --troubleshoot passed cleanly and every app came back with the same state and health as my pre-upgrade baseline, including four Nextcloud instances.
Check whether sudo-rs was installed and switch back to classic sudo if needed (the guide covers this).
During the package phase, SSH may be unreachable for a while, but apps kept serving. On the server where I watched, Nextcloud still returned 200 the whole time.
Port 443 is the host's nginx, so this is the only way an app package can get PQ there. App-specific listeners on their own ports (for example a NetBird native gRPC port) still need their own TLS config.