Upload via GUI (39 Dateien)

This commit is contained in:
Git Manager GUI
2026-08-02 17:01:18 +02:00
parent a803f297ea
commit eff6403dd5
26 changed files with 3536 additions and 134 deletions
+160
View File
@@ -0,0 +1,160 @@
# 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
```bash
cp .env.example .env
# CF_API_KEY eintragen
```
### Ohne Docker
Braucht nur Node 18 oder neuer, keine Pakete.
```bash
node index.js
```
Dauerhaft über systemd: `aeromc-cf-proxy.service` nach
`/etc/systemd/system/` kopieren, Pfade und Benutzer darin anpassen, dann
```bash
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.
```bash
pm2 start ecosystem.config.js
pm2 save
pm2 startup # einmalig, für den Start nach einem Neustart
```
Nach jeder Änderung an der `.env`:
```bash
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:
```bash
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
```bash
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:
```nginx
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.