Files
2026-08-02 17:01:18 +02:00

5.2 KiB
Raw Permalink Blame History

AeroMC CurseForge-Weiterleitung

Kleiner Dienst, der den CurseForge-API-Schlüssel hält und die Anfragen stellvertretend für den Launcher stellt.

Wozu das Ganze

CurseForge erlaubt es nicht, den API-Schlüssel weiterzugeben. In einer verteilten .exe wäre er für jeden auslesbar das Entpacken einer Electron-Anwendung dauert keine Minute. Deshalb bleibt der Schlüssel hier auf dem Server, und der Launcher kennt nur die Adresse dieses Dienstes.

Wege

Weg Zweck
GET /health Lebenszeichen, verrät nichts über den Schlüssel
POST /v1/mods/files Dateiliste auflösen, Rumpf { "fileIds": [...] }, höchstens 100 je Anfrage
GET /v1/download?url=… Mod-Datei durchreichen; das CurseForge-CDN verlangt seit Juli 2026 ebenfalls einen Schlüssel

Einrichten

cp .env.example .env
# CF_API_KEY eintragen

Ohne Docker

Braucht nur Node 18 oder neuer, keine Pakete.

node index.js

Dauerhaft über systemd: aeromc-cf-proxy.service nach /etc/systemd/system/ kopieren, Pfade und Benutzer darin anpassen, dann

systemctl daemon-reload
systemctl enable --now aeromc-cf-proxy

Mit pm2

ecosystem.config.js liegt bei und liest die .env selbst ein pm2 tut das von sich aus nämlich nicht.

pm2 start ecosystem.config.js
pm2 save
pm2 startup     # einmalig, für den Start nach einem Neustart

Nach jeder Änderung an der .env:

pm2 restart aeromc-cf-proxy --update-env

Ohne --update-env behält pm2 die alten Werte, und du suchst lange nach dem Grund, warum der neue Schlüssel nicht greift.

Nachsehen, ob er läuft:

pm2 logs aeromc-cf-proxy --lines 20

Nicht auf Cluster-Betrieb umstellen. Die Konfiguration steht bewusst auf exec_mode: 'fork' mit einem Prozess. Die Ratenbegrenzung zählt im Arbeitsspeicher bei vier Arbeitern hätte jeder seine eigene Zählung, und die Grenze wäre in Wahrheit viermal so hoch wie eingestellt.

Mit Docker

docker compose up -d

Launcher einstellen

In den Launcher-Einstellungen unter Netzwerk → CurseForge die Adresse eintragen, zum Beispiel https://cf.example.de. Das Feld „Eigener API-Key" bleibt leer wer dort einen Schlüssel einträgt, geht direkt zu CurseForge und nutzt diesen Dienst nicht.

Soll die Adresse für alle Nutzer voreingestellt sein, trage sie in src/services.js bei STANDARD_WEITERLEITUNG ein. Die Adresse ist kein Geheimnis, nur der Schlüssel ist eines.

Absicherung

Der Dienst steht offen im Netz. Eingebaut ist:

  • Host-Liste durchgereicht wird nur an edge.forgecdn.net, mediafilez.forgecdn.net und media.forgecdn.net. Ohne diese Prüfung könnte jemand den Dienst Adressen in deinem Heimnetz abrufen lassen und die Antwort mitlesen.
  • Umleitungen werden selbst verfolgt und bei jedem Sprung erneut gegen die Host-Liste geprüft, höchstens vier Sprünge.
  • Ratenbegrenzung je Absender, einstellbar über RATE_LIMIT_PER_MIN.
  • Größengrenze für durchgereichte Dateien über MAX_DOWNLOAD_MB.
  • Optionales Token über CF_PROXY_TOKEN.

Zum Token eine ehrliche Einordnung: Es steckt dann auch im Launcher und ist dort auslesbar. Es hält Gelegenheitsnutzer ab, keine entschlossenen. Die Ratenbegrenzung ist der wirksamere Schutz für dein Kontingent.

Reverse-Proxy: TRUST_PROXY richtig setzen

TRUST_PROXY ist keine Ja/Nein-Angabe, sondern die Anzahl der Stufen vor dem Dienst: 0 ohne Proxy, 1 mit Nginx Proxy Manager, 2 mit Cloudflare davor.

Der Grund: nginx ergänzt X-Forwarded-For, statt es zu ersetzen. Schickt ein Aufrufer selbst X-Forwarded-For: 1.2.3.4, steht hinterher 1.2.3.4, <echte-IP> darin. Deshalb wird von rechts gezählt die eigenen Proxy-Stufen sind die einzigen Einträge, die niemand von außen setzen kann.

Zu hoch angesetzt, greift der Dienst auf einen Eintrag zu, den der Aufrufer selbst erfunden hat: Dann kann sich jeder mit jeder Anfrage eine neue Adresse ausdenken und die Ratenbegrenzung ins Leere laufen lassen. Im Zweifel 0.

Nginx Proxy Manager

Im Proxy Host eintragen:

Feld Wert
Scheme http
Forward Hostname / IP Containername oder LAN-Adresse des Dienstes
Forward Port 8420
Block Common Exploits an
Websockets Support nicht nötig

Im Reiter SSL: Let's-Encrypt-Zertifikat anfordern, „Force SSL" und HTTP/2 aktivieren. Ohne HTTPS ginge das Token im Klartext über die Leitung.

Im Reiter Advanced empfiehlt sich für die durchgereichten Mod-Dateien:

proxy_buffering off;
proxy_read_timeout 300s;

Ohne proxy_buffering off schreibt nginx große Dateien erst vollständig in eine temporäre Datei, bevor der Launcher das erste Byte sieht bei mehreren hundert MB fühlt sich das wie ein Hänger an.

Läuft der Nginx Proxy Manager selbst in Docker, gehören beide ins gleiche Docker-Netz und der Port muss gar nicht nach außen gebunden werden: In der docker-compose.yml dann den ports-Block weglassen. Sonst wenigstens auf 127.0.0.1:8420:8420 einschränken, damit der Dienst nicht an der Absicherung des Proxys vorbei erreichbar ist.

Was der Dienst nicht tut

Er speichert nichts, protokolliert keine Adressen der Nutzer und gibt Schlüsselfehler von CurseForge nicht im Wortlaut nach außen weiter.