5.2 KiB
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.netundmedia.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.