From de1ac2ee17eed6b116efd847c0a05aff1aebe580 Mon Sep 17 00:00:00 2001 From: Oier Bravo Urtasun Date: Wed, 10 Jun 2026 21:12:59 +0200 Subject: [PATCH] =?UTF-8?q?fix(nmsr):=20render=20real=20skins,=20not=20def?= =?UTF-8?q?ault=20=E2=80=94=20pin=20auth.=20to=20host=20over=20https?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Every avatar rendered the default skin. NMSR fetched the player profile from Drasl fine, but the profile embeds an absolute HTTPS skin URL (Drasl BaseURL is https), and NMSR could not connect to auth.${BASE_DOMAIN}:443: the mcnet alias resolves auth. -> caddy, which only listens on :80 internally. Logs showed `fetch_texture_from_mojang … client error (Connect)` for the skin URL, so NMSR fell back to the default skin. Mirror what the minecraft service already does: pin auth.${BASE_DOMAIN} to the host via extra_hosts so NMSR reaches the host nginx on :443 (real LE cert, publicly trusted — no private CA needed), and switch the nmsr mojank endpoints from http:// to https:// so the profile/texture scheme matches the embedded skin URLs. Co-Authored-By: Claude Opus 4.8 --- docker-compose.yml | 7 +++++++ nmsr/config.toml.tmpl | 21 +++++++++++++-------- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index c768f49..a142df0 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -158,6 +158,13 @@ services: restart: unless-stopped volumes: - ./nmsr/config.toml:/nmsr/config.toml:ro + # Drasl embeds absolute HTTPS skin URLs (BaseURL is https) in the profile. + # The mcnet alias resolves auth. -> caddy (http :80 only), so NMSR's https + # skin fetch to auth.:443 finds no listener and every avatar falls back to + # the default skin. Pin auth. to the host (same as the minecraft service) so + # NMSR reaches the host nginx on :443 with the real LE cert. + extra_hosts: + - "auth.${BASE_DOMAIN}:host-gateway" networks: - mcnet diff --git a/nmsr/config.toml.tmpl b/nmsr/config.toml.tmpl index 203e416..dfaecd8 100644 --- a/nmsr/config.toml.tmpl +++ b/nmsr/config.toml.tmpl @@ -5,10 +5,13 @@ # the bare BaseURL: # session_server -> {url}/session/minecraft/profile/{uuid} # mojang_api_server -> {url}/users/profiles/minecraft/{name} -# and embeds absolute skin URLs (http://auth.${BASE_DOMAIN}/web/texture/skin/…) -# in the profile, which NMSR fetches directly (textures_server is only a -# fallback). NMSR resolves auth.${BASE_DOMAIN} internally over the docker -# network (caddy holds the mcnet alias → drasl), so no public round-trip. +# and embeds absolute skin URLs (https://auth.${BASE_DOMAIN}/web/texture/skin/…) +# in the profile — Drasl's BaseURL is https, so these are https and NMSR must +# fetch them over :443. The mcnet alias only resolves auth. -> caddy on :80, so +# the nmsr service pins auth.${BASE_DOMAIN} to the host (extra_hosts in +# docker-compose.yml) and talks to the host nginx on :443 (real LE cert). Hence +# the https:// endpoints below — they must match the scheme of the embedded +# skin URLs, or the skin fetch Connect-fails and avatars render the default skin. [server] address = "0.0.0.0" @@ -31,10 +34,12 @@ texture_cache_duration = "48h" [caching.cache_biases] [mojank] -# Point every Mojang endpoint at Drasl (internal, plain http via the caddy alias). -session_server = "http://auth.${BASE_DOMAIN}" -textures_server = "http://auth.${BASE_DOMAIN}" -mojang_api_server = "http://auth.${BASE_DOMAIN}" +# Point every Mojang endpoint at Drasl over https — auth. is pinned to the host +# (extra_hosts), so this reaches the host nginx on :443 with the real LE cert. +# Must stay https to match the https skin URLs Drasl embeds in the profile. +session_server = "https://auth.${BASE_DOMAIN}" +textures_server = "https://auth.${BASE_DOMAIN}" +mojang_api_server = "https://auth.${BASE_DOMAIN}" session_server_rate_limit = 10 # This is an offline-mode (authlib-injector) server — Drasl issues v3 offline # UUIDs, so they must be accepted.