[Modul] Password Vault – Schluss mit Klartext-Passwörtern in IP-Symcon

Hallo zusammen,

wer kennt es nicht? Man schreibt ein Modul oder ein Skript für eine API, eine Datenbank oder den Router und landet früher oder später bei der Frage: Wohin mit den Zugangsdaten?

Die strukturelle Schwäche

Bisher bietet IP-Symcon keine native, verschlüsselte Tresor-Lösung für sensible Daten. Gemäß der offiziellen Dokumentation werden Instanz-Eigenschaften (Properties) persistent gespeichert. Das führt in der Praxis zu einem erheblichen Sicherheitsrisiko:

  • Klartext in der settings.json: Selbst wenn man eine PasswordTextBox im Formular nutzt (die nur optisch maskiert), werden die Passwörter unverschlüsselt in der zentralen settings.json gespeichert.

  • Sichtbarkeit: Wer Zugriff auf ein Backup oder das Dateisystem hat, kann alle API-Keys, Router-Passwörter und Datenbank-Logins im Klartext auslesen.

Die Lösung: Password Vault (Standalone)

Dieses Modul führt einen dedizierten Verschlüsselungs-Tresor (AES-128-GCM) ein. In der Standalone-Variante werden alle Geheimnisse in einer verschlüsselten Datei auf Betriebssystem-Ebene abgelegt. Der Clou: Der für die Entschlüsselung notwendige Master-Key wird physisch getrennt vom Symcon-Datenverzeichnis gespeichert.

  • Grafischer Tresor-Explorer: Direkt in der Instanz-Konfiguration können Ordnerstrukturen angelegt und Geheimnisse verwaltet werden.

  • Key-Rotation: Der Master-Key kann jederzeit neu generiert werden, wobei der Tresor automatisch umgeschlüsselt wird.

  • JSON-Import: Ein schneller Umstieg ist durch die Import-Funktion für bestehende Datensammlungen problemlos möglich.

Sicherheit in verteilten Systemen (Master/Slave)

Die Herausforderung wächst bei mehreren Symcon Installationen (z.B. Hauptwerk, Gartenhaus, Ferienwohnung). Bisher mussten Passwörter händisch synchronisiert werden – oft über unsichere Kanäle.

Hier setzt die Master/Slave-Architektur an:

  • Zentrale Verwaltung: Ein Master dient als „Source of Truth“.

  • Sicherer Transport: Änderungen werden per WebHook an die Slaves gepusht. Die Übertragung erfolgt verschlüsselt und kann zusätzlich durch Certificate Pinning (TLS) gegen Man-in-the-Middle-Angriffe abgesichert werden.

  • Autarkie: Die Slaves speichern eine lokale, verschlüsselte Kopie. Fällt der Master oder die Internetverbindung aus, arbeiten alle Slaves mit ihren vorhandenen Daten ganz normal weiter.


Praxis-Beispiel: Datensatz & Anwendung

Stellen wir uns vor, ihr habt im Tresor einen Datensatz für ein Remote-System angelegt. So sieht die Struktur innerhalb des Tresors aus:

Hierarchische Darstellung (Baumstruktur):

    📦 GESAMT-TRESOR (Root-Array)
 ├── 📂 Folder_Kameras
 │    └── 🔑 Haustür-Kamera
 ├── 📂 RemoteSystem           <-- Dies ist der Ident (Key)
 │    ├── 🔑 User: "admin"
 │    ├── 🔑 Pass: "geheim123"
 │    └── 🔑 URL:  "http://192.168.1.50:3777/api/"
 └── 📂 SmartHome_Cloud
  

PHP-Syntax für einen RPC-Aufruf:
Statt das Passwort im Skript zu hartcodieren, ruft ihr es sicher ab. Da das Array RemoteSystem mehrere Felder hat, liefert das Modul diese als JSON-kodiertes Array zurück:

    // 1. Das Geheimnis aus dem Tresor laden (Ident: "RemoteSystem")
$jsonSecret = SEC_GetSecret($vaultID, "RemoteSystem");
$credentials = json_decode($jsonSecret, true);

if (!$credentials) die("Zugangsdaten nicht gefunden.");

// 2. RPC-Aufruf mit Basic-Auth ausführen (Kein Passwort im Klartext im Skript!)
$context = stream_context_create([
    'http' => [
        'method'  => 'POST',
        'header'  => [
            'Content-Type: application/json',
            'Authorization: Basic ' . base64_encode($credentials['User'] . ':' . $credentials['Pass'])
        ],
        'content' => json_encode([
            'jsonrpc' => '2.0', 
            'method'  => 'GetValue', 
            'params'  => [54321], 
            'id'      => 1
        ])
    ]
]);

$response = file_get_contents($credentials['URL'], false, $context);
  

:warning: Wichtige Hinweise zu Backup & Sicherheit

  • Das Backup-Dilemma: Da der master.key bewusst außerhalb des Symcon-Pfades liegt, wird er NICHT vom Standard-Symcon-Backup erfasst. Ihr müsst diesen Key unbedingt separat sichern (z.B. in einem physischen Tresor oder eurem privaten Passwort-Manager). Ohne diesen Key ist der Tresor bei einem Server-Crash verloren!

  • Pfad-Empfehlung: Wählt für den Key-Ordner einen Pfad, der nicht im Symcon-Verzeichnis liegt (z.B. ein anderer Mount-Point oder ein USB-Stick), um die physische Trennung von Schlüssel und Tresor zu gewährleisten.

  • Voraussetzungen: Das Modul nutzt die PHP-Extension OpenSSL (in fast allen IPS-Installationen standardmäßig enthalten) und ist für moderne PHP-Versionen (8.x) optimiert.

Installation

Das Modul ist ab sofort im Module Store unter dem Namen „Password Vault“ zu finden.

Ich freue mich auf euer Feedback und hoffe, dass wir damit gemeinsam die Sicherheit unserer IP-Symcon Installationen ein Stück professioneller machen können!


3 „Gefällt mir“

Hallo. Das klingt schon super. Um ehrlich zu sein bin ich aber enttäuscht, dass DU das herausbringen musstest.

Was mir bisher ein großer Dorn im Auge war: jeder mit Zugriff auf Symcon PHP kommt an die Passwörter. Das ist auch hier so?

Wie wird das Userinterface für ein Endmodul in Symcon aussehen? Hier trägt man dann analog deines Beispiels RemoteSystem in ein selbst zu definierendes Feld ‚Schlüsselbund Wert‘ sowie in ein ‚SelectInstance‘ Feld die ID ein?

Wie werden die Indizies im o.g. (User, Pass, URL) zugeordnet und befüllt?

Hallo @tobiasr ,

Du triffst damit genau den Punkt, wie Sicherheit in einem System wie IP-Symcon funktioniert. Hier sind die Antworten dazu:

1. Zugriff über PHP: Wer darf die Passwörter lesen?

Hier muss man ehrlich sein: Ja, das ist in IP-Symcon systembedingt weiterhin so.
Wer in IP-Symcon das Recht hat, PHP-Skripte auszuführen, kann grundsätzlich jede öffentliche Funktion jedes Moduls aufrufen – und damit auch SEC_GetSecret.

Warum ist das Modul trotzdem ein Gewinn?
Der Fokus liegt auf der „Security at Rest“ (Sicherheit der gespeicherten Daten):

  • Schutz vor passiven Leaks: Bei einem Standard-Modul stehen Passwörter im Klartext in der settings.json. Wer ein Backup entwendet oder Zugriff auf das Dateisystem hat (z. B. per FTP oder SSH), hat alle Passwörter. Beim Password Vault findet er dort nur Datenmüll. Ohne den physisch getrennten master.key sind die Daten wertlos.

  • Schutz der Backup-Kette: Da der Schlüssel nicht im Symcon-Backup landet, ist dein Passwort-Tresor auch dann geschützt, wenn dein Cloud-Backup oder dein USB-Stick mit den Symcon-Sicherungen in falsche Hände gerät.

  • Laufzeit-Sicherheit: Passwörter tauchen nicht mehr in der Konsole oder im Objektbaum auf. Sie existieren nur für Millisekunden als Variable im Arbeitsspeicher während der Skriptausführung.

2. Integration in andere Module (User Interface)

Genau so, wie du es vermutet hast, ist der „Best Practice“ Weg. Wenn du ein Modul entwickelst, das den Tresor nutzen soll, fügst du in deiner form.json zwei Felder hinzu:

  1. SelectInstance: Zur Auswahl der „Password Vault“-Instanz.

  2. ValidationTextBox: Zur Eingabe des Namens (Idents) im Tresor (z. B. „MeinCloudDienst“).

In deinem Modul-Code rufst du dann einfach auf:
$json = SEC_GetSecret($VaultID, $Ident);

3. Zuordnung der Indizes (User, Pass, URL)

Der Tresor-Explorer im Modul ist frei definierbar. Wenn du im Explorer einen neuen „Record“ (Eintrag) anlegst, kannst du darin beliebig viele Felder hinzufügen.

  • Befüllung: Du klickst im Explorer auf „Neu → Record“, gibst ihm den Namen „RemoteSystem“ und fügst über ein Plus-Icon die Zeilen für „User“, „Pass“ etc. hinzu.

  • Zuordnung: Das Modul gibt dir einfach das zurück, was du dort eingetragen hast. Wenn du als Entwickler eines Drittmoduls erwartest, dass dort ein Feld namens Pass existiert, dann dokumentierst du das für deine Nutzer („Bitte legen Sie im Password Vault einen Eintrag mit dem Feld ‚Pass‘ an“).

Der Vorteil dieser losen Kopplung ist, dass der Tresor extrem flexibel ist. Ein Record für eine Datenbank braucht vielleicht Host, Port, User, Pass, während ein API-Key-Eintrag nur ein einziges Feld namens Token benötigt.

Ich hoffe, das klärt die Funktionsweise! Das Modul schließt nicht die Lücke der PHP-Berechtigungen (das müsste das Symcon-Kernsystem tun), aber es riegelt die „Hintertür“ über die Konfigurationsdateien und Backups massiv ab.

1 „Gefällt mir“

IP-Symcon schützt die Perimeter (wer kommt ins System?) hervorragend durch Benutzerverwaltung, IP-Filter und TLS-Verschlüsselung. Aber: IP-Symcon ist intern als offenes Framework konzipiert. Wer ‚drinnen‘ ist (also PHP-Skripte bearbeiten darf), ist quasi System-Administrator.

Mein Modul Password Vault schützt daher nicht vor dem legitimen Administrator, der absichtlich ein Skript schreibt, um Daten auszulesen. Es schützt vor passiven Sicherheitslücken:

  1. Diebstahl von Backups (settings.json).

  2. Einsicht in Konfigurationsdateien durch unbefugte OS-Nutzer.

  3. Unbeabsichtigtes Preisgeben von Passwörtern bei der Fehlersuche oder beim Teilen von Skripten.

Um das Problem der PHP-Einsicht zu lösen, müsste Symcon ein Role-Based Access Control (RBAC) auf Objekt-Ebene einführen. Da das aber die Kompatibilität zu fast allen bestehenden Skripten brechen würde, ist es unwahrscheinlich, dass dies kurzfristig passiert.

Mein Modul schließt daher die Lücke, die wir heute schließen können: Den Schutz der Daten in der Dateiablage und im Backup (Data at Rest).

Puhh, lässt du inzwischen alles durch AI machen? Module schreiben, Forum Posts schreiben und beantworten lassen? Diese seitenweisen Abhandlungen sind echt eine lesehemmung.

Aber das soll nicht dein Problem sein, ich werde in Zukunft einfach diese Posts ignorieren.

Gruß BlackOrca

6 „Gefällt mir“

Hallo @BlackOrca ,

Ich kann verstehen, dass die Menge an Text erst mal abschreckend wirkt.

Um es kurz zu machen: Ja, ich nutze KI als Werkzeug – sowohl beim Programmieren als auch beim Aufbereiten der Dokumentation und lerne dabei eine ganze Menge. Mein Ziel ist es, ein technisch absolut sauberes und vor allem sicherheitsrelevantes Modul abzuliefern. Die KI hilft mir dabei, komplexe Sachverhalte wie AES-Verschlüsselung so zu erklären, dass sie auch für Nicht-Kryptographen nachvollziehbar sind.

Ich nehme deinen Punkt mit der „Lesehemmung“ aber ernst: Ich werde versuchen, künftige Erklärungen kompakter zu fassen oder technische Details in Spoiler-Tags zu packen, damit der Lesefluss im Forum nicht leidet.

Beste Grüße,
Artur/BestEx

2 „Gefällt mir“

Ich finde obige Dokumentation hervorragend strukturiert und gut lesbar.

1 „Gefällt mir“

Ja, dem muss ich zustimmen … die Doku ist auf den ersten Blick gut lesbar und verständlich.

1 „Gefällt mir“

Biometrische Authentifizierung für WebHooks – Passkeys (WebAuthn) im Password Vault (BETA Version)

Hallo zusammen,

bevor ich ins Detail gehe, ein wichtiger Hinweis vorab: Dieses Modul, die gesamte Code-Logik sowie dieser Beitrag wurden unter intensiver Nutzung von Gemini 3.5 Pro entwickelt. Wer KI-generierte Inhalte oder mit KI entwickelte Module ablehnt, braucht an dieser Stelle nicht weiterzulesen.

Für alle anderen: Ich möchte euch heute eine weitreichende Erweiterung meines SecretsManager (Password Vault) vorstellen.

Das Ziel: Schluss mit Passwörtern im Browser

Bisher war der Zugriff auf geschützte WebHook-Skripte oder Dashboards in IP-Symcon oft mit lästigen Basic-Auth-Popups oder (unsicheren) Passwörtern in der URL verbunden. Mein Ziel war es, den Zugriff so sicher wie möglich, aber gleichzeitig so komfortabel wie den Login am Smartphone zu machen.

Die Lösung: Passkey-Integration (FIDO2/WebAuthn)

Ich habe den SecretsManager um eine vollwertige Passkey-Unterstützung erweitert. Damit ist es nun möglich, WebHook-Aufrufe direkt per Fingerabdruck, Gesichtserkennung oder Windows Hello zu autorisieren.

Die Highlights der neuen Version 3.0:

  1. Biometrischer Gatekeeper: Eigene Skripte können mit einer einfachen Abfrage (SEC_IsPortalAuthenticated) geschützt werden. Ist man nicht eingeloggt, leitet das Modul automatisch zum biometrischen Portal um und nach dem Scan direkt wieder zurück zum Skript.

  2. Zero-Knowledge & Stateless: Wie gewohnt landen keine Passwörter in der settings.json. Die biometrische Sitzung wird kryptografisch verifiziert und nur im flüchtigen RAM-Buffer gehalten.

  3. Intelligentes Master-Slave-Merging: Passkeys sind strikt an Domains gebunden. Damit ein Setup mit Master und mehreren Slaves funktioniert, erkennt das Modul bei der Synchronisation lokale Geräte-Registrierungen und führt diese zusammen, anstatt sie zu überschreiben.

  4. Zentrales Admin-Dashboard: Über einen speziell gesicherten Bereich (?admin=1) lassen sich Registrierungs-Links für alle verbundenen Systeme generieren. Der Erstzugriff erfolgt per Passwort, danach übernimmt auch hier der Passkey.

  5. Zero-Convention Handling: Der Tresor erkennt Ordnerstrukturen nun automatisch anhand der JSON-Hierarchie. Manuelle Flags wie __folder sind für den Import nicht mehr nötig.

Ein Beispiel aus der Praxis

So sieht der Schutz eines eigenen WebHook-Skripts nun aus:

codePHP

<?php
$instanceID = 12345; // SecretsManager

if (isset($_IPS['SENDER']) && $_IPS['SENDER'] === 'WebHook') {
    if (!SEC_IsPortalAuthenticated($instanceID)) {
        $currentUrl = $_SERVER['REQUEST_URI'] ?? '';
        $loginUrl = "/hook/secrets_" . $instanceID . "?portal=1&return=" . urlencode($currentUrl);
        header("Location: " . $loginUrl);
        exit;
    }
}

echo "Willkommen im biometrisch geschützten Bereich!";

Sicherheit

Die Verschlüsselung basiert weiterhin auf AES-128-GCM mit physischer Trennung des Master-Keys vom Symcon-System. Die Passkeys nutzen den FIDO2-Standard, bei dem der private Schlüssel niemals das Endgerät verlässt.

Ich nutze das System mittlerweile auf allen meinen Geräten (Windows 11, Android Tablet/Phone) und der Komfortgewinn ist enorm – einmal kurz den Finger auf den Sensor, und alle Dashboards sind offen.

Das Modul findet ihr im Modul Store im Beta Kanal. Ich freue mich auf euer Feedback