Server 2.10.4: HTTPS for the web panel and hostile client hardening
- Panel over HTTPS on the game port (TLS handshake detected like HTTP); self-signed certificate in data/panel_cert.pfx (fingerprint in the log) or an own PFX (PanelCertificatePath); remote HTTP is redirected to HTTPS (not locally / behind a proxy); cookie Secure over HTTPS; PanelHttps=false turns it off - Panel login: also locked per user name (16 failures / 15 min), failure lists bounded, user names in the log without control characters - panel_users.json, panel_sessions.json, server.json, certificate: owner-only on Linux - Players: names/chat without control or direction characters (no fake log lines), no '<' '>' in names; '* ' system-style chat, msco.* messages (time/weather) and MSCO_INSTALL only from admins; NaN/absurd money changes dropped (could break the shared money for good) - Extra headers: Permissions-Policy, Cross-Origin-Opener-Policy - 11 new tests (165 pass) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+18
-1
@@ -54,6 +54,16 @@ public sealed class ServerConfig
|
||||
public bool PanelTrustProxy { get; set; } = false;
|
||||
/// <summary>Unterpfad, unter dem das Panel läuft, z.B. "/panel" (leer = direkt unter /).</summary>
|
||||
public string PanelBasePath { get; set; } = "";
|
||||
/// <summary>
|
||||
/// HTTPS im Panel. Auf dem Spiel-Port immer verfügbar (https://<server>:<port>/); true = Browser, die von
|
||||
/// außen per HTTP kommen, werden auf HTTPS umgeleitet (Passwörter nie unverschlüsselt). Bei eigenem PanelPort spricht
|
||||
/// dieser nur mit eigenem Zertifikat (PanelCertificatePath) HTTPS. Hinter einem Reverse-Proxy (PanelTrustProxy) macht
|
||||
/// der Proxy HTTPS.
|
||||
/// </summary>
|
||||
public bool PanelHttps { get; set; } = true;
|
||||
/// <summary>Eigenes Zertifikat (PFX, Pfad absolut oder relativ zu data/) - leer = selbst signiertes in data/panel_cert.pfx.</summary>
|
||||
public string PanelCertificatePath { get; set; } = "";
|
||||
public string PanelCertificatePassword { get; set; } = "";
|
||||
|
||||
static readonly JsonSerializerOptions Options = new() { WriteIndented = true };
|
||||
|
||||
@@ -72,7 +82,11 @@ public sealed class ServerConfig
|
||||
return config;
|
||||
}
|
||||
|
||||
public void Save(string path) => File.WriteAllText(path, JsonSerializer.Serialize(this, Options));
|
||||
public void Save(string path)
|
||||
{
|
||||
File.WriteAllText(path, JsonSerializer.Serialize(this, Options));
|
||||
PanelTls.Restrict(path); // enthält den Lizenzschlüssel und Passwörter (Linux: nur der Server-Benutzer)
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Umgebungsvariablen überschreiben server.json (praktisch für Docker/systemd):
|
||||
@@ -111,6 +125,9 @@ public sealed class ServerConfig
|
||||
if (bool.TryParse(Env("MSCO_PANEL_TRUST_PROXY"), out bool trustProxy)) { PanelTrustProxy = trustProxy; used.Add("MSCO_PANEL_TRUST_PROXY"); }
|
||||
PanelBindAddress = Take("MSCO_PANEL_BIND", PanelBindAddress);
|
||||
PanelBasePath = Take("MSCO_PANEL_BASE_PATH", PanelBasePath);
|
||||
if (bool.TryParse(Env("MSCO_PANEL_HTTPS"), out bool panelHttps)) { PanelHttps = panelHttps; used.Add("MSCO_PANEL_HTTPS"); }
|
||||
PanelCertificatePath = Take("MSCO_PANEL_CERT", PanelCertificatePath);
|
||||
PanelCertificatePassword = Take("MSCO_PANEL_CERT_PASSWORD", PanelCertificatePassword);
|
||||
return used;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user