Transport security: TLS end-to-end (https + wss) before public exposure #133
Labels
No labels
alpha:wave-0
alpha:wave-1
alpha:wave-2
alpha:wave-3
area:assets
area:combat
area:ecology
area:infra
area:render
area:scripting
area:ui
area:world
enhancement
epic
migration
post-alpha
roadmap
tech-debt
type:bug
type:chore
type:design
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
marco/IsoMmo#133
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem. Today the client talks to Auth over
http://and to the GameServer overws://. The JWT (which fully authenticates a player) travels in the clear: anyone on the network path can sniff it and impersonate that player, or MITM/alter traffic. The wire format (JSON) is not the issue — a custom client can forge any protocol; our defense is server-authoritative validation. The real gap is transport confidentiality/integrity.Decision (from a protocol-security discussion). Do NOT invest in gRPC / a binary protocol / client attestation / mTLS-cert-pinning: none add trust for a client the user runs, and they are the wrong scale for a friends server. The one concrete, worthwhile hardening is TLS end-to-end.
Scope
https://and the GameServer WebSocket overwss://.config.jsonuseshttps/wssURLs; keepws/httpallowed for local dev.docs/deploy.md.Out of scope
Definition of Done
docs/deploy.mddocuments the TLS setup (proxy or Kestrel cert).Priority: before any public/non-LAN exposure (pairs with the open-registration tech debt).
mTLS / client certificate — considered and rejected. A client-side certificate authenticates the TLS peer ("a build of our client"), not the player, and the cert must ship inside a client the user controls → extractable, so it does not prove "our client" against a determined user. A shared embedded cert is security-through-obscurity (the "keep random scanners out" role is better served by the planned invite/allow-list); a per-player cert merely duplicates the JWT with PKI/rotation/revocation overhead. Correct stack: server-side TLS (wss) + the signed JWT over it. Client certs are an enterprise/public-scale tool for a threat model that is not ours (friends-scale).
Already satisfied in production — closing as done.
The substantive requirement (TLS end-to-end so the JWT/password never travel in cleartext) is already live via the homelab Traefik setup (
home-infra-ngroles/isommo):isommo-authandisommo-gameserverrun behind Traefik on theproxynetwork, entrypointwebsecure(:443). Routerisommo-authservesHost(mmo.homelab.devncode.it); routerisommo-wsservesPathPrefix(/ws)→ gameserver:5100 with the WebSocket Upgrade proxied transparently.:80redirects → websecure,:443usescertResolver: letsencrypt+ ACME (auto-renew), same mechanism as Forgejo.config.jsonwithhttps://mmo.homelab.devncode.it+wss://mmo.homelab.devncode.it/ws.Verification (just now):
So Auth is served over https and the GameServer over wss with a valid Lets Encrypt cert, and local dev still uses ws/http (Debug config). DoD met.
Deferred (rejected here, see thread): gRPC / binary protocol / client mTLS / attestation — wrong scale for a friends server.
Follow-up (optional, not blocking): sync
docs/deploy.md(currently a generic Caddy example) to the real Traefik setup, and addUseForwardedHeadersin the two servers so they log the real client IP behind the proxy.