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.
|
||||
# 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=
|
||||
|
||||
# Nur für ein abgeschottetes Netz: Dienst bewusst OHNE Token betreiben.
|
||||
# CF_PROXY_OFFEN=1
|
||||
|
||||
# Anfragen je Minute und Absender. 0 = keine Begrenzung.
|
||||
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.
|
||||
- **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`.
|
||||
- **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
|
||||
dort auslesbar. Es hält Gelegenheitsnutzer ab, keine entschlossenen. Die
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
const http = require('http');
|
||||
const crypto = require('crypto');
|
||||
const { Readable } = require('stream');
|
||||
|
||||
const KEY = (process.env.CF_API_KEY || '').trim();
|
||||
@@ -35,6 +36,17 @@ if (!KEY) {
|
||||
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
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -88,9 +100,21 @@ function sendeJson(res, code, daten) {
|
||||
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) {
|
||||
if (!TOKENS.size) return true;
|
||||
return TOKENS.has(String(req.headers['x-aeromc-token'] || '').trim());
|
||||
if (!TOKENS.size) return OFFEN_ERLAUBT; // ohne Token nur mit ausdrücklicher Freigabe
|
||||
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) {
|
||||
@@ -308,7 +332,7 @@ server.listen(PORT, HOST, () => {
|
||||
console.log(`AeroMC CurseForge-Weiterleitung läuft auf ${HOST}:${PORT}`);
|
||||
console.log(` Ratenbegrenzung: ${LIMIT_PRO_MIN > 0 ? LIMIT_PRO_MIN + '/Minute je Absender' : 'aus'}`);
|
||||
// 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'})`);
|
||||
});
|
||||
|
||||
|
||||
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