Upload via GUI (202 Dateien)
This commit is contained in:
@@ -19,9 +19,14 @@ HOST=0.0.0.0
|
|||||||
# weiterlaufen, bis alle das Update haben – danach das alte streichen.
|
# weiterlaufen, bis alle das Update haben – danach das alte streichen.
|
||||||
# CF_PROXY_TOKEN=neues-token,altes-token
|
# CF_PROXY_TOKEN=neues-token,altes-token
|
||||||
#
|
#
|
||||||
# Leer lassen = keine Tokenprüfung.
|
# Pflicht: Ohne Token startet der Dienst nicht – sonst könnte jeder, der die
|
||||||
|
# Adresse kennt, deinen API-Key und dein Download-Kontingent benutzen.
|
||||||
|
# Ein langes Zufalls-Token erzeugen, z. B.: openssl rand -hex 32
|
||||||
CF_PROXY_TOKEN=
|
CF_PROXY_TOKEN=
|
||||||
|
|
||||||
|
# Nur für ein abgeschottetes Netz: Dienst bewusst OHNE Token betreiben.
|
||||||
|
# CF_PROXY_OFFEN=1
|
||||||
|
|
||||||
# Anfragen je Minute und Absender. 0 = keine Begrenzung.
|
# Anfragen je Minute und Absender. 0 = keine Begrenzung.
|
||||||
RATE_LIMIT_PER_MIN=60
|
RATE_LIMIT_PER_MIN=60
|
||||||
|
|
||||||
|
|||||||
@@ -101,7 +101,8 @@ Der Dienst steht offen im Netz. Eingebaut ist:
|
|||||||
die Host-Liste geprüft, höchstens vier Sprünge.
|
die Host-Liste geprüft, höchstens vier Sprünge.
|
||||||
- **Ratenbegrenzung** je Absender, einstellbar über `RATE_LIMIT_PER_MIN`.
|
- **Ratenbegrenzung** je Absender, einstellbar über `RATE_LIMIT_PER_MIN`.
|
||||||
- **Größengrenze** für durchgereichte Dateien über `MAX_DOWNLOAD_MB`.
|
- **Größengrenze** für durchgereichte Dateien über `MAX_DOWNLOAD_MB`.
|
||||||
- **Optionales Token** über `CF_PROXY_TOKEN`.
|
- **Token** über `CF_PROXY_TOKEN` – Pflicht: ohne Token startet der Dienst nicht
|
||||||
|
(bewusst offen nur mit `CF_PROXY_OFFEN=1`, z. B. im abgeschotteten Netz).
|
||||||
|
|
||||||
Zum Token eine ehrliche Einordnung: Es steckt dann auch im Launcher und ist
|
Zum Token eine ehrliche Einordnung: Es steckt dann auch im Launcher und ist
|
||||||
dort auslesbar. Es hält Gelegenheitsnutzer ab, keine entschlossenen. Die
|
dort auslesbar. Es hält Gelegenheitsnutzer ab, keine entschlossenen. Die
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const http = require('http');
|
const http = require('http');
|
||||||
|
const crypto = require('crypto');
|
||||||
const { Readable } = require('stream');
|
const { Readable } = require('stream');
|
||||||
|
|
||||||
const KEY = (process.env.CF_API_KEY || '').trim();
|
const KEY = (process.env.CF_API_KEY || '').trim();
|
||||||
@@ -35,6 +36,17 @@ if (!KEY) {
|
|||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ohne Token wäre der Dienst für jeden offen, der die Adresse kennt – und damit
|
||||||
|
// auch der API-Key und das Download-Kontingent dahinter. Deshalb startet er
|
||||||
|
// ohne CF_PROXY_TOKEN gar nicht erst. Wer ihn bewusst offen betreiben will
|
||||||
|
// (z. B. nur im eigenen Netz), muss das ausdrücklich sagen: CF_PROXY_OFFEN=1.
|
||||||
|
const OFFEN_ERLAUBT = process.env.CF_PROXY_OFFEN === '1';
|
||||||
|
if (!TOKENS.size && !OFFEN_ERLAUBT) {
|
||||||
|
console.error('CF_PROXY_TOKEN fehlt. Ohne Token könnte jeder den Dienst (und deinen API-Key) benutzen.');
|
||||||
|
console.error('Token setzen (siehe .env.example) – oder, nur für ein abgeschottetes Netz, CF_PROXY_OFFEN=1.');
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// Ratenbegrenzung: einfaches Zeitfenster je Absender
|
// Ratenbegrenzung: einfaches Zeitfenster je Absender
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
@@ -88,9 +100,21 @@ function sendeJson(res, code, daten) {
|
|||||||
res.end(koerper);
|
res.end(koerper);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Vergleich in gleichbleibender Zeit, damit sich ein Token nicht Zeichen für
|
||||||
|
// Zeichen über die Antwortdauer erraten lässt
|
||||||
|
function gleich(a, b) {
|
||||||
|
const x = crypto.createHash('sha256').update(a).digest();
|
||||||
|
const y = crypto.createHash('sha256').update(b).digest();
|
||||||
|
return crypto.timingSafeEqual(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
function tokenOk(req) {
|
function tokenOk(req) {
|
||||||
if (!TOKENS.size) return true;
|
if (!TOKENS.size) return OFFEN_ERLAUBT; // ohne Token nur mit ausdrücklicher Freigabe
|
||||||
return TOKENS.has(String(req.headers['x-aeromc-token'] || '').trim());
|
const erhalten = String(req.headers['x-aeromc-token'] || '').trim();
|
||||||
|
if (!erhalten) return false;
|
||||||
|
let ok = false;
|
||||||
|
for (const t of TOKENS) if (gleich(t, erhalten)) ok = true;
|
||||||
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
function leseKoerper(req, maxBytes = 1_000_000) {
|
function leseKoerper(req, maxBytes = 1_000_000) {
|
||||||
@@ -308,7 +332,7 @@ server.listen(PORT, HOST, () => {
|
|||||||
console.log(`AeroMC CurseForge-Weiterleitung läuft auf ${HOST}:${PORT}`);
|
console.log(`AeroMC CurseForge-Weiterleitung läuft auf ${HOST}:${PORT}`);
|
||||||
console.log(` Ratenbegrenzung: ${LIMIT_PRO_MIN > 0 ? LIMIT_PRO_MIN + '/Minute je Absender' : 'aus'}`);
|
console.log(` Ratenbegrenzung: ${LIMIT_PRO_MIN > 0 ? LIMIT_PRO_MIN + '/Minute je Absender' : 'aus'}`);
|
||||||
// niemals die Token selbst ausgeben – Protokolle wandern schnell woanders hin
|
// niemals die Token selbst ausgeben – Protokolle wandern schnell woanders hin
|
||||||
console.log(` Token verlangt : ${TOKENS.size ? 'ja (' + TOKENS.size + ' gültige)' : 'nein'}`);
|
console.log(` Token verlangt : ${TOKENS.size ? 'ja (' + TOKENS.size + ' gültige)' : 'NEIN – offen für jeden (CF_PROXY_OFFEN=1)'}`);
|
||||||
console.log(` Proxy-Stufen : ${PROXY_STUFEN} (${PROXY_STUFEN ? 'Absender aus X-Forwarded-For' : 'Absender aus der Verbindung'})`);
|
console.log(` Proxy-Stufen : ${PROXY_STUFEN} (${PROXY_STUFEN ? 'Absender aus X-Forwarded-For' : 'Absender aus der Verbindung'})`);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 164 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 183 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 169 KiB |
Reference in New Issue
Block a user