Upload via GUI (39 Dateien)
This commit is contained in:
160
server/curseforge-proxy/README.md
Normal file
160
server/curseforge-proxy/README.md
Normal 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.
|
||||
Reference in New Issue
Block a user