Absicherung: Socket-Eingaben, Geheimnisse in Fehlern, Logparser, Start/Stopp, RCON, Stream-Zugang
- Socket-Nachrichten werden geprüft, Handlerfehler abgefangen, Abfragen pro Verbindung begrenzt (vorher beendete stream:subscribe mit null ohne Anmeldung das Backend). - Fehlermeldungen von Prozessen ohne Befehlszeile und mit geschwärzten Passwörtern/Tokens. - Logparser wertet nur ganze Systemzeilen nach dem Zeitstempel aus; Chat kann keine Map beenden. - Verspätet ankommende Starts nach Stopp, Neuanforderung oder Löschen bauen ihren Container ab. - RCON: kaputte Pakete trennen nur die Verbindung, Befehle ohne Antwort gelten als Fehler. - Organisatoren bekommen einen Stream-Schlüssel nur für ihr Match statt des globalen STREAM_KEY. - Rate-Limiter mit regelmäßiger Bereinigung und Obergrenze, alte Admin-Sitzungen werden entfernt.
This commit is contained in:
1 parent
35bdfc1f67
commit
e18b8b4430
13 files changed
+409
-49
No files matched your search
@@ -3,7 +3,7 @@ import { buildKnifeCommands, KNIFE_UNDO_COMMANDS } from './knifeServers.js';
|
||||
import { DemoMatchSimulator } from './demoMatchSimulator.js';
|
||||
import { backupPrefix, describeBackup, isValidBackupFile, pointsForMap } from '../rounds.js';
|
||||
import { HttpError, CLOSED_STATUSES } from '../matchService.js';
|
||||
import { randomPassword } from '../security.js';
|
||||
import { randomPassword, safeErrorMessage } from '../security.js';
|
||||
|
||||
export const SERVER_STATUS = {
|
||||
starting: 'Server startet',
|
||||
@@ -343,6 +343,7 @@ export class ServerManager {
|
||||
this.service.log(matchId, 'server', this.adapter.simulated ? 'Demo-Server (Simulation) wird vorbereitet' : 'Server wird gestartet');
|
||||
|
||||
const match = this.service.getMatch(matchId);
|
||||
const attempt = (previous?.attempts ?? 0) + 1;
|
||||
try {
|
||||
const result = await this.adapter.start({
|
||||
matchId,
|
||||
@@ -350,6 +351,14 @@ export class ServerManager {
|
||||
secrets,
|
||||
teamNames: { A: match.team_a_name, B: match.team_b_name },
|
||||
});
|
||||
// Während des (oft langen) Starts gestoppt, neu angefordert oder gelöscht: den neuen Container
|
||||
// gleich wieder abbauen, sonst liefe er ohne Überwachung weiter
|
||||
const current = this.row(matchId);
|
||||
if (!current || current.status !== 'starting' || current.attempts !== attempt) {
|
||||
this.logger.warn?.(`[server] ${matchId}: Start kam nach dem Stopp an, Container wird wieder entfernt`);
|
||||
await this.adapter.stop(result.handle, { resetPassword: randomPassword(16) }).catch(() => {});
|
||||
return;
|
||||
}
|
||||
this.update(matchId, {
|
||||
handle: JSON.stringify(result.handle),
|
||||
host: result.host,
|
||||
@@ -358,8 +367,9 @@ export class ServerManager {
|
||||
message: this.adapter.simulated ? 'Simulierter Start läuft' : 'Server fährt hoch',
|
||||
});
|
||||
} catch (err) {
|
||||
this.update(matchId, { status: 'start_failed', message: err.message });
|
||||
this.service.log(matchId, 'server', `Serverstart fehlgeschlagen: ${err.message}`);
|
||||
const message = safeErrorMessage(err, Object.values(secrets));
|
||||
if (this.row(matchId)?.status === 'starting') this.update(matchId, { status: 'start_failed', message });
|
||||
if (this.row(matchId)) this.service.log(matchId, 'server', `Serverstart fehlgeschlagen: ${message}`);
|
||||
}
|
||||
} finally {
|
||||
this.busy.delete(matchId);
|
||||
@@ -536,8 +546,9 @@ export class ServerManager {
|
||||
try {
|
||||
await this.adapter.configure(JSON.parse(row.handle), { map: seriesMap.map, ...plan });
|
||||
} catch (err) {
|
||||
this.update(matchId, { status: 'config_failed', message: err.message });
|
||||
this.service.log(matchId, 'server', `Konfiguration fehlgeschlagen: ${err.message}`);
|
||||
const message = safeErrorMessage(err, [row.rcon_password, row.server_password, row.tv_password]);
|
||||
this.update(matchId, { status: 'config_failed', message });
|
||||
this.service.log(matchId, 'server', `Konfiguration fehlgeschlagen: ${message}`);
|
||||
return;
|
||||
}
|
||||
this.update(matchId, {
|
||||
|
||||
Reference in new issue
Block a user