feat(rcon): add admin server console
This commit is contained in:
@@ -8,6 +8,10 @@ The Next.js application owns user onboarding, account management, admin configur
|
||||
|
||||
User authentication begins with an opaque, short-lived, single-use token created for a Discord user. Only a cryptographic hash of the token is persisted. Admin authentication is a separate Keycloak OIDC flow and requires the `minecraft-account-manager-admin` role.
|
||||
|
||||
### RCON administration
|
||||
|
||||
The administrator console stores one or more internal Minecraft RCON endpoints with write-only AES-GCM-encrypted passwords. Browser requests invoke authenticated server actions; only the Next.js runtime opens RCON TCP connections. Exact deployment-managed endpoint allowlisting prevents the connection registry from becoming an arbitrary internal network proxy. Commands and responses are bounded and ephemeral, while credential-safe audit events retain the operator, server, command verb, keyed digest, outcome, and duration. RCON is exposed only through internal cluster services and never through public ingress.
|
||||
|
||||
### Discord bot
|
||||
|
||||
The bot creates private login links in response to `/register` and `/account`. Discord user IDs are the canonical Discord identity; mutable usernames are snapshots only. Nickname updates target the deployment guild configured by `DISCORD_GUILD_ID`; the public join button uses `DISCORD_INVITE_URL`.
|
||||
@@ -26,6 +30,8 @@ The admission decision is fail closed. Unknown players, disabled effective group
|
||||
- Velocity requests use hashed per-server bearer credentials, timestamps, and database-unique request IDs for authentication and replay prevention.
|
||||
- Session and one-time-code values are random and stored only as hashes.
|
||||
- Exact IP addresses are sensitive data and require an explicit retention policy before production deployment.
|
||||
- RCON hostnames and ports must match the deployment allowlist on save and use; passwords never cross the browser trust boundary.
|
||||
- RCON commands and responses are untrusted, bounded, rendered only as text, and excluded from persistent history and logs.
|
||||
|
||||
## Database invariants
|
||||
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
# RCON administration
|
||||
|
||||
The administrator RCON console proxies commands through the Next.js server runtime. Browsers never receive RCON credentials and never open RCON sockets.
|
||||
|
||||
## Application configuration
|
||||
|
||||
Set `RCON_ALLOWED_ENDPOINTS` to a comma-separated allowlist of exact internal `host:port` pairs:
|
||||
|
||||
```text
|
||||
RCON_ALLOWED_ENDPOINTS=season4.somc.svc.cluster.local:25575
|
||||
```
|
||||
|
||||
IP literals, trailing-dot hostnames, malformed DNS names, and endpoints absent from the allowlist are rejected whenever a connection is saved, tested, or used.
|
||||
|
||||
Saved passwords are encrypted with AES-256-GCM and connection-bound authenticated data. By default, domain-separated credential and audit keys are derived from `AUTH_SECRET`. Deployments may instead provide independent 32-byte base64 values through `RCON_CREDENTIAL_KEY` and `RCON_AUDIT_KEY`. Rotating the credential key requires replacing saved RCON passwords.
|
||||
|
||||
## Minecraft server configuration
|
||||
|
||||
Enable RCON with a high-entropy password supplied through the deployment secret. Expose its port only on an internal `ClusterIP` service. Do not add RCON to an Ingress, NodePort, or public LoadBalancer.
|
||||
|
||||
The password entered in the administrator connection form must match the server password. Existing passwords are write-only; leave the replacement field blank when editing unrelated connection settings.
|
||||
|
||||
## Security behavior
|
||||
|
||||
- Existing account-manager administrator authorization is rechecked for every connection mutation, test, and command.
|
||||
- Commands are limited to 1,024 UTF-8 bytes and reject control characters.
|
||||
- Each web process allows one operation per connection and at most eight RCON operations total. Size replica counts with that aggregate ceiling in mind.
|
||||
- Each complete connect-and-response operation times out after five seconds and tears down the socket; cleanup is independently capped at one second.
|
||||
- Responses are sanitized and limited to 64 KiB.
|
||||
- Full commands and responses are not persisted or logged. Audit events contain the command verb and a domain-separated HMAC digest.
|
||||
- Connection passwords are never selected by page queries or returned to the browser.
|
||||
|
||||
RCON is plaintext TCP. Keep it on the cluster network and use network policy or an encrypted tunnel when the network trust model requires stronger isolation.
|
||||
|
||||
## Migration
|
||||
|
||||
Apply the generated Drizzle migration before deploying the web image:
|
||||
|
||||
```bash
|
||||
npx drizzle-kit migrate
|
||||
```
|
||||
|
||||
Never use `drizzle push` for this schema change.
|
||||
Reference in New Issue
Block a user