fix(uhd): 4K-UHD geloest - makemkvcon holt Schluessel unter Linux nie
Ampel / ampel (push) Successful in 28s

Richtigstellung des Vortags-Befunds. Dort stand, MakeMKVs Schluessel-Kanal
sei abgeschaltet. Das war FALSCH: die Herleitung stuetzte sich auf zwei
Hostnamen aus alten Forumsbeitraegen (hkdata.fairuse.org,
hkdata.crabdance.com), die zwar wirklich nicht mehr aufloesen, von MakeMKV
aber laengst nicht mehr benutzt werden. Aufgedeckt durch den Einwand des
Commanders, unter Windows ginge es sofort.

Gegenprobe mit demselben Laufwerk und derselben Disc (Akira UHD, MKB v76):

                        Linux (Worker)      Windows
  Verbindungen          KEINE EINZIGE       185.84.108.20:443
  Meldung 3338          nie                 "Downloading latest HK"
  _private_data.tar     2048 B, 0 Keys      6,4 MB, 604 Keys
  Disc                  volume key unknown  TCOUNT:5, geht auf

Gegengeprueft mit leerem UND gefuelltem Speicher, mit und ohne --noscan,
mit dev:/dev/sr0 und disc:0, mit geloeschter update.conf. Linux fragt nie.
Die Meldungsvorlage "Downloading latest %1 to %2 ..." steckt sehr wohl im
Linux-Binary - sie loest nur nicht aus. Gleiches Symptom im MakeMKV-Forum,
seit Jahren offen (t=25782, t=34022). Der Dienst lebt; der Worker erreicht
185.84.108.20:443 sogar problemlos.

BEWIESEN: Nach Uebernahme des Windows-Schluesselspeichers oeffnet
makemkvcon auf der VM die Akira-UHD - "Operation successfully completed",
TCOUNT:5, fuenf Titel, identisch zum Windows-Ergebnis. Erster belegter
UHD-Disc-Zugriff auf der Rippy-Maschine.

- makemkv_daten.py (beide Zwillinge): zaehle_schluessel,
  private_data_pruefen, schluesselspeicher_status, private_data_schreiben.
  Die Pruefung lehnt einen Speicher OHNE hkd_*.bin ab - sonst laedt jemand
  den leeren Vorrat einer frischen Installation hoch, nichts aendert sich,
  und niemand versteht warum. Modulkopf komplett neu, inkl. der
  Fehldiagnose als Warnung fuer spaeter.
- API: GET/POST /system/keystore. Der Rohkoerper der Anfrage IST die Datei
  (binaer - JSON/Base64 waere Ballast, Multipart kann die API nicht).
  Groessengrenze 64 MB = client_max_body_size in nginx.conf.
- UI: neuer Block "Disc-Schluessel fuer 4K-UHD" UEBER dem KEYDB-Block, mit
  Schluessel-Anzahl, Upload und Anleitung fuer den Windows-Weg. KEYDB.cfg
  ist jetzt als Notnagel beschriftet. Worker-Plakette zeigt die Anzahl;
  0 heisst sichtbar "4K-UHD scheitert".
- tasks.py: UHD-Fehlertext sagt den Windows-Weg an und nennt die Anzahl
  bekannter Schluessel dieses Workers.
- caps.py meldet schluessel je Worker.
- Alle Falschaussagen korrigiert: UI (3), Anleitung (2), README (3),
  KONZEPT §8 + §10, Worker-Dockerfile, makemkv_key.py (dort stand "Den
  AACS-Schluessel zieht MakeMKV via LibreDrive ohnehin selbst aus dem
  Laufwerk" - gilt fuer Blu-ray, NICHT fuer UHD).
- SAVEPOINT v3.11, ROADMAP Etappe 18 (Etappe 17 mit Nachtrag), AGENTS.

Offen: voller UHD-Rip inkl. Transcode-E2E; und ob sich der Abruf unter
Linux doch anstossen laesst.

Quellen (AGENTS Regel D):
- Linux laedt keine Hashed Keys, gleiches Symptom:
  https://forum.makemkv.com/forum/viewtopic.php?t=25782
  https://forum.makemkv.com/forum/viewtopic.php?t=34022
- Schluessel als hkd_*.bin in _private_data.tar:
  https://forum.makemkv.com/forum/viewtopic.php?t=32675
- Meldungsformat: https://www.makemkv.com/developers/usage.txt

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Hitonabi
2026-07-25 11:18:09 +02:00
parent 0935766f61
commit f449c4ee34
14 changed files with 828 additions and 163 deletions
+157 -24
View File
@@ -1,35 +1,51 @@
"""MakeMKV-Datenverzeichnis: KEYDB.cfg, AACS-Dumps, settings.conf.
"""MakeMKV-Datenverzeichnis: Schluesselspeicher, KEYDB.cfg, AACS-Dumps.
WARUM ES DIESE DATEI GIBT (Befund 25.07.2026, live im Worker nachgemessen):
Bei 4K-UHD-Discs meldet MakeMKV "The volume key is unknown for this disc".
Das Laufwerk ist dabei in Ordnung — makemkvcon meldet "Using LibreDrive mode
(v06.3)" und liest die Disc — MakeMKV kennt nur den Schluessel DIESER Pressung
nicht. Und es holt ihn NICHT mehr online nach:
WARUM ES DIESE DATEI GIBT (Befund 25.07.2026, auf BEIDEN Maschinen gemessen):
4K-UHD-Discs scheiterten mit "The volume key is unknown for this disc". Die
Ursache ist weder die Disc noch das Laufwerk — LibreDrive v06.3 laeuft und
MakeMKV liest die Disc — sondern:
* /root/.MakeMKV/_private_data.tar enthielt ausser der Index-Datei keine
einzige hkd_*.bin, also nie einen heruntergeladenen Schluessel;
* auch mit erzwungener frischer Pruefung (update.conf geloescht, Meldung
5074 belegt den Web-Kontakt) und mit app_UpdateEnable = "1" kam keiner;
* die im MakeMKV-Forum dokumentierten Schluessel-Server hkdata.fairuse.org
und hkdata.crabdance.com loesen weltweit nicht mehr auf (gegen Fritz!Box,
8.8.8.8 und 1.1.1.1 geprueft: NXDOMAIN).
makemkvcon unter LINUX ruft die Disc-Schluessel nie ab.
Die Windows-Version tut es.
Betroffen war Akira UHD (MKB v76, Pressung von Dezember 2020) — also gerade
KEINE Neuerscheinung. Die bisherige Fehlermeldung ("Disc neuer als die
Schluessel-Datenbank, mit einem der naechsten Updates rippbar") war damit
schlicht falsch.
Gemessen, nicht vermutet:
* Linux: in KEINEM Lauf auch nur eine Verbindung nach draussen. Geprueft mit
leerem UND mit gefuelltem Schluesselspeicher, mit und ohne --noscan, mit
dev:/dev/sr0 und mit disc:0, und mit erzwungener frischer Pruefung
(update.conf geloescht, Meldung 5074 belegt den Web-Kontakt). Immer:
keine Verbindung, kein Schluessel.
* Windows, dieselbe Disc, dasselbe Laufwerk: Meldung 3338 "Downloading
latest HK to ...", Verbindung nach 185.84.108.20:443
(web33.majordomo.ru), _private_data.tar waechst — und die Disc geht auf
(TCOUNT:5, "Operation successfully completed").
* Der Code dafuer steckt auch im Linux-Binary: die Meldungsvorlage
"Downloading latest %1 to %2 ..." steht in makemkvcon. Sie loest nur nie
aus. Gleiches Symptom im Forum, seit Jahren offen und unbeantwortet.
Der einzige heute funktionierende Weg ist eine KEYDB.cfg im
MakeMKV-Datenverzeichnis. Rippy liefert KEINE Schluessel mit, laedt keine
herunter und verteilt keine — es stellt nur den Platz dafuer bereit und zeigt
ehrlich an, was dort liegt. Die Datei bringt der Nutzer selbst mit.
FRUEHERE FEHLDIAGNOSE, bewusst festgehalten: An dieser Stelle stand zuerst,
MakeMKVs Schluessel-Kanal sei abgeschaltet. Das war FALSCH. Die Herleitung
stuetzte sich auf zwei Hostnamen aus alten Forumsbeitraegen
(hkdata.fairuse.org, hkdata.crabdance.com), die tatsaechlich nicht mehr
aufloesen — MakeMKV benutzt sie aber laengst nicht mehr. Der Dienst lebt, der
Worker erreicht ihn sogar; er wird unter Linux nur nie gefragt.
WAS DARAUS FOLGT: Der Schluesselspeicher (_private_data.tar) muss von einer
MakeMKV-Installation kommen, die ihn wirklich abruft — praktisch von Windows.
Rippy nimmt ihn unter Einstellungen -> System entgegen. Die KEYDB.cfg bleibt
der Notnagel fuer Pressungen, die auch MakeMKV selbst nicht kennt.
Rippy liefert KEINE Schluessel mit, laedt keine herunter und verteilt keine.
Es verwaltet nur, was der Nutzer selbst mitbringt.
QUELLEN (AGENTS Regel D — externe Schnittstellen nie aus dem Kopf):
* Datenverzeichnis und Dateiname GROSS geschrieben (unter Linux
* Linux laedt keine Hashed Keys — dasselbe Symptom, mehrfach berichtet:
https://forum.makemkv.com/forum/viewtopic.php?t=25782
https://forum.makemkv.com/forum/viewtopic.php?t=34022
* Schluessel liegen als hkd_*.bin in _private_data.tar:
https://forum.makemkv.com/forum/viewtopic.php?t=32675
* Datenverzeichnis und Dateiname KEYDB.cfg GROSS geschrieben (unter Linux
case-sensitiv), dort geloest mit "cp KEYDB.cfg ~/.MakeMKV/":
https://forum.makemkv.com/forum/viewtopic.php?t=30636
* Heruntergeladene Schluessel liegen als hkd_*.bin in _private_data.tar:
https://forum.makemkv.com/forum/viewtopic.php?t=32675
* Zeilenformat der KEYDB.cfg (libaacs): Disc-Kennung = 40 Hex-Zeichen,
optional mit 0x-Praefix, dann "= Titel", danach optionale Felder wie
"| V | <32 Hex>"; Zeilen ab ";" sind Kommentare:
@@ -42,8 +58,10 @@ Images brauchen sie, ein gemeinsames Paket gibt es in diesem Projekt nicht
(gleiche Lage wie bei db.py). Aenderungen IMMER in BEIDEN Dateien nachziehen.
"""
import io
import os
import re
import tarfile
from datetime import datetime, timezone
# Container-Pfad aus der Umgebung: /root/.MakeMKV im Worker (nur dort sucht
@@ -226,6 +244,121 @@ def dumps_auflisten(daten_dir: str = None) -> list:
return liste
# --- Schluesselspeicher (_private_data.tar) -------------------------------
#
# Das ist MakeMKVs eigener Speicher fuer die "Hashed Keys": ein tar-Archiv mit
# hkd_*.bin-Eintraegen. Unter Windows fuellt MakeMKV es selbst (Meldung 3338),
# unter Linux nie — siehe Modul-Kopf. Rippy nimmt die Datei deshalb entgegen
# und legt sie ins Datenverzeichnis; MakeMKV liest sie beim naechsten Start.
PRIVATE_DATA_NAME = "_private_data.tar"
# Der Speicher lag am 25.07.2026 bei rund 6 MB und waechst mit jeder neuen
# Pressung. 64 MB sind reichlich Luft — und derselbe Wert wie
# client_max_body_size in docker/ui/nginx.conf: waere die Grenze hier hoeher,
# wuerde nginx den Upload abweisen, bevor die API ihn ueberhaupt sieht.
MAX_PRIVATE_DATA_BYTES = 64 * 1024 * 1024
def private_data_pfad(daten_dir: str = None) -> str:
"""Voller Pfad zum Schluesselspeicher im Datenverzeichnis."""
return os.path.join(daten_dir or DATEN_DIR, PRIVATE_DATA_NAME)
def zaehle_schluessel(rohdaten: bytes) -> int:
"""Anzahl der hkd_*.bin-Eintraege im Archiv (pure Funktion, testbar).
Das ist die ehrliche Kennzahl fuer "wie viele Disc-Schluessel kennt diese
Installation". Ein frischer, leerer Speicher enthaelt nur eine
Index-Datei und kommt hier auf 0 — genau der Zustand, in dem jede
unbekannte UHD-Disc scheitert.
"""
try:
with tarfile.open(fileobj=io.BytesIO(rohdaten)) as archiv:
return sum(1 for name in archiv.getnames() if name.startswith("hkd_"))
except (tarfile.TarError, OSError, EOFError):
return 0
def private_data_pruefen(rohdaten: bytes) -> str:
"""Prueft hochgeladene Rohdaten; deutscher Fehlertext oder "".
Faengt die beiden Bedienfehler ab, die sonst still danebengehen: eine
voellig andere Datei hochladen, oder den Speicher einer Installation, die
selbst noch keine Schluessel geholt hat (dann aendert sich nichts, und
niemand versteht warum).
"""
if not rohdaten:
return "Die Datei ist leer."
if len(rohdaten) > MAX_PRIVATE_DATA_BYTES:
return (
"Die Datei ist groesser als "
f"{MAX_PRIVATE_DATA_BYTES // (1024 * 1024)} MB — das ist kein "
"MakeMKV-Schluesselspeicher."
)
try:
with tarfile.open(fileobj=io.BytesIO(rohdaten)) as archiv:
namen = archiv.getnames()
except (tarfile.TarError, OSError, EOFError):
return (
"Das ist kein tar-Archiv. Erwartet wird die Datei "
f"{PRIVATE_DATA_NAME} aus dem MakeMKV-Datenverzeichnis."
)
if not any(name.startswith("hkd_") for name in namen):
return (
"In dieser Datei steckt kein einziger Schluessel (kein hkd_*.bin). "
"Sie stammt vermutlich von einer MakeMKV-Installation, die selbst "
"noch keine geholt hat — oeffne dort erst einmal eine Disc."
)
return ""
def schluesselspeicher_status(daten_dir: str = None) -> dict:
"""Zustand des Schluesselspeichers. Fehlt er, ist das kein Fehler."""
pfad = private_data_pfad(daten_dir)
try:
angaben = os.stat(pfad)
with open(pfad, "rb") as datei:
schluessel = zaehle_schluessel(datei.read())
except OSError:
return {
"vorhanden": False,
"pfad": pfad,
"groesse_bytes": 0,
"schluessel": 0,
"geaendert": "",
}
return {
"vorhanden": True,
"pfad": pfad,
"groesse_bytes": angaben.st_size,
"schluessel": schluessel,
"geaendert": _iso(angaben.st_mtime),
}
def private_data_schreiben(rohdaten: bytes, daten_dir: str = None) -> dict:
"""Legt den Schluesselspeicher atomar ab und meldet den neuen Zustand.
Atomar aus demselben Grund wie bei der KEYDB.cfg: waehrend ein Rip laeuft,
darf makemkvcon nie ein halb geschriebenes Archiv sehen.
"""
pfad = private_data_pfad(daten_dir)
os.makedirs(os.path.dirname(pfad), exist_ok=True)
neben = pfad + ".neu"
try:
with open(neben, "wb") as datei:
datei.write(rohdaten)
os.replace(neben, pfad)
except OSError:
try:
os.remove(neben)
except OSError:
pass
raise
return schluesselspeicher_status(daten_dir)
def settings_conf_zusammenfuehren(inhalt: str, key: str) -> str:
"""app_Key setzen, ohne den Rest der settings.conf zu verlieren (pure).