fix(mc): ONLINE_MODE=true — authlib-injector needs online handshake for skins
online-mode=false made the server skip the online-auth handshake entirely, so authlib-injector never validated sessions against Drasl: players got offline-hash UUIDs and no skin textures (everyone Steve). authlib-injector's whole purpose is to redirect the *online* handshake from Mojang to Drasl, so online-mode must be true; only the 1.21+ secure profile stays off (ENFORCE_SECURE_PROFILE=false + Drasl SignPublicKeys=false). Correct the conflation in CLAUDE.md and plan/05-minecraft.md. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
10
CLAUDE.md
10
CLAUDE.md
@@ -35,7 +35,7 @@ Internet ── host nginx (TLS, LE certs, HSTS) ──► caddy (127.0.0.1:8880
|
|||||||
distribution.${BASE} ─► static site from ANOTHER repo (DISTRIBUTION_WEB_ROOT)
|
distribution.${BASE} ─► static site from ANOTHER repo (DISTRIBUTION_WEB_ROOT)
|
||||||
|
|
||||||
minecraft :25565 (+ 24454/udp Simple Voice Chat)
|
minecraft :25565 (+ 24454/udp Simple Voice Chat)
|
||||||
└ ONLINE_MODE=false, -javaagent authlib-injector → http://auth.${BASE_DOMAIN}/authlib-injector
|
└ ONLINE_MODE=true (validated against Drasl, NOT offline), -javaagent authlib-injector → http://auth.${BASE_DOMAIN}/authlib-injector
|
||||||
└ mods from ./server-mods volume (/mods, REMOVE_OLD_MODS) — see plan/04-mods.md
|
└ mods from ./server-mods volume (/mods, REMOVE_OLD_MODS) — see plan/04-mods.md
|
||||||
mc-backup ── RCON → minecraft (6h interval, prune 14d, world-only)
|
mc-backup ── RCON → minecraft (6h interval, prune 14d, world-only)
|
||||||
```
|
```
|
||||||
@@ -67,6 +67,14 @@ via the `deploy` skill.
|
|||||||
- Drasl: `SignPublicKeys = false`
|
- Drasl: `SignPublicKeys = false`
|
||||||
- Linked. Drasl docs: *"Mixed authentication does not work with
|
- Linked. Drasl docs: *"Mixed authentication does not work with
|
||||||
`SignPublicKeys = true` on Minecraft 1.21+."*
|
`SignPublicKeys = true` on Minecraft 1.21+."*
|
||||||
|
- **This is the ONLY auth flag that goes off. `ONLINE_MODE` stays TRUE** — see
|
||||||
|
next gotcha. Do not conflate "secure profile off" with "offline mode".
|
||||||
|
|
||||||
|
### ONLINE_MODE must be TRUE (authlib-injector ≠ offline)
|
||||||
|
authlib-injector redirects the server's normal **online**-auth handshake from
|
||||||
|
Mojang to Drasl. `ONLINE_MODE=FALSE` skips that handshake → offline-hash UUIDs,
|
||||||
|
no Drasl session validation, and **no skins** (everyone joins but everyone is
|
||||||
|
Steve; `usercache.json` shows offline-hash UUIDs). Keep `ONLINE_MODE=TRUE`.
|
||||||
|
|
||||||
### authlib-injector JVM agent
|
### authlib-injector JVM agent
|
||||||
- Syntax: `-javaagent:/extras/authlib-injector.jar=<yggdrasil-api-url>`
|
- Syntax: `-javaagent:/extras/authlib-injector.jar=<yggdrasil-api-url>`
|
||||||
|
|||||||
@@ -58,8 +58,13 @@ services:
|
|||||||
USE_AIKAR_FLAGS: "TRUE"
|
USE_AIKAR_FLAGS: "TRUE"
|
||||||
JVM_XX_OPTS: "-XX:+UseG1GC"
|
JVM_XX_OPTS: "-XX:+UseG1GC"
|
||||||
|
|
||||||
# ── Auth: offline mode + authlib-injector pointing at Drasl ─
|
# ── Auth: ONLINE mode validated against Drasl via authlib-injector ─
|
||||||
ONLINE_MODE: "FALSE"
|
# MUST be true: authlib-injector redirects the normal online-auth
|
||||||
|
# handshake from Mojang to Drasl. online-mode=false skips the handshake
|
||||||
|
# entirely -> offline UUIDs, no session validation, NO SKINS for anyone.
|
||||||
|
# Secure-profile is the part that must stay off on 1.21+ (see
|
||||||
|
# ENFORCE_SECURE_PROFILE + Drasl SignPublicKeys=false), NOT online-mode.
|
||||||
|
ONLINE_MODE: "TRUE"
|
||||||
# Resolves over mcnet to caddy (alias auth.${BASE_DOMAIN}) -> drasl.
|
# Resolves over mcnet to caddy (alias auth.${BASE_DOMAIN}) -> drasl.
|
||||||
JVM_OPTS: "-javaagent:/extras/authlib-injector.jar=https://auth.${BASE_DOMAIN}/authlib-injector"
|
JVM_OPTS: "-javaagent:/extras/authlib-injector.jar=https://auth.${BASE_DOMAIN}/authlib-injector"
|
||||||
|
|
||||||
|
|||||||
@@ -25,21 +25,30 @@ mirrors `/mods` into `/data/mods` and prunes removed ones (`REMOVE_OLD_MODS`).
|
|||||||
## Auth / config
|
## Auth / config
|
||||||
|
|
||||||
```
|
```
|
||||||
ONLINE_MODE=FALSE
|
ONLINE_MODE=TRUE
|
||||||
ENFORCE_SECURE_PROFILE=FALSE # pairs with drasl SignPublicKeys=false
|
ENFORCE_SECURE_PROFILE=FALSE # pairs with drasl SignPublicKeys=false
|
||||||
JVM_OPTS=-javaagent:/extras/authlib-injector.jar=http://auth.${BASE_DOMAIN}/authlib-injector
|
JVM_OPTS=-javaagent:/extras/authlib-injector.jar=http://auth.${BASE_DOMAIN}/authlib-injector
|
||||||
```
|
```
|
||||||
authlib URL uses the `auth` subdomain; resolves internally via the caddy alias.
|
authlib URL uses the `auth` subdomain; resolves internally via the caddy alias.
|
||||||
(Server still needs the agent even though Fjord clients have it built in.)
|
(Server still needs the agent even though Fjord clients have it built in.)
|
||||||
|
|
||||||
|
**`ONLINE_MODE` MUST be true.** authlib-injector works by redirecting the
|
||||||
|
server's normal online-auth handshake from Mojang to Drasl. With
|
||||||
|
`ONLINE_MODE=FALSE` the server skips that handshake entirely → players get
|
||||||
|
offline-hash UUIDs, no session validation, and **no skins** (the server never
|
||||||
|
fetches textures from Drasl). The thing that must stay *off* for 1.21+ is the
|
||||||
|
**secure profile** (`ENFORCE_SECURE_PROFILE=FALSE` + Drasl `SignPublicKeys=false`),
|
||||||
|
not online-mode. Symptom of getting this wrong: everyone can join but everyone is
|
||||||
|
Steve, and `usercache.json` shows offline-hash UUIDs.
|
||||||
|
|
||||||
Memory: `INIT_MEMORY 4G`, `MAX_MEMORY 10G`, `USE_AIKAR_FLAGS TRUE`.
|
Memory: `INIT_MEMORY 4G`, `MAX_MEMORY 10G`, `USE_AIKAR_FLAGS TRUE`.
|
||||||
RCON enabled for mc-backup.
|
RCON enabled for mc-backup.
|
||||||
|
|
||||||
## Server operators (OP)
|
## Server operators (OP)
|
||||||
|
|
||||||
**Do NOT use the itzg `OPS` env var.** It resolves usernames to UUIDs via a
|
**Do NOT use the itzg `OPS` env var.** It resolves usernames to UUIDs via a
|
||||||
Mojang lookup, but this server is `ONLINE_MODE=FALSE` with Drasl auth — Drasl
|
Mojang lookup, but this server is `ONLINE_MODE=TRUE` validated against Drasl —
|
||||||
assigns its own UUIDs (not Mojang, not the offline-hash). A Mojang-resolved UUID
|
Drasl assigns its own UUIDs (not Mojang, not the offline-hash). A Mojang-resolved UUID
|
||||||
would not match the player's real session UUID, so the op entry would be inert
|
would not match the player's real session UUID, so the op entry would be inert
|
||||||
(and could clobber a correct `ops.json` on reboot).
|
(and could clobber a correct `ops.json` on reboot).
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user