Verwaltungsspeicher und Hauptschlüssel
Mit einem Verwaltungsspeicher hält der Dienst seine Betriebsdaten – Datenquellen, Regeln, Zuordnungen, Personen, Schlüssel, Anmelderichtlinie – in einer eigenen Datei statt in der Konfigurationsdatei. Die Geheimnisse darin sind versiegelt; Namen, Regeln und Protokoll stehen lesbar darin. Änderungen wirken ohne Neustart. Diese Seite erklärt, was wo liegt, wie Änderungen wirken und was der Hauptschlüssel schützt.
Wichtige Funktionen
- Änderungen ohne Neustart; eine ungültige Fassung wird nie übernommen.
- Verbindungszeichenfolgen und zweite Faktoren versiegelt; eine Kopie der Datei allein öffnet nichts.
- Hauptschlüssel wechselbar ohne Datenverlust, mit zwei kurzen Neustarts.
- Anmelde- und Lastprotokoll in einer eigenen Protokolldatei mit fester Größengrenze.
Grundkonzepte
Warum eine Datei mit Datenbank
Die Konfiguration soll die Vorteile einer Datei und die einer Datenbank zugleich haben. SQLite liefert beides in einem:
| Von der Datei | Von der Datenbank |
|---|---|
| Eine einzige Datei neben dem Dienst; kein Datenbankserver, keine Anmeldung, kein Netz | Transaktionen: eine Änderung gilt ganz oder gar nicht, auch wenn der Dienst mittendrin endet |
Sichern und Umziehen durch Kopieren (über backup-store, siehe unten) | Zeilen statt eines Dokuments: jede Liste ist eine Tabelle und damit eine Menge der Verwaltungsschnittstelle, die Access wie eine Tabelle verknüpft |
| Läuft ohne die Datenbanken, die der Dienst anbietet – die Verwaltung bleibt erreichbar, wenn eine Datenquelle ausfällt | Prüfung vor Übernahme: Eine Änderung wird mit dem ganzen Betriebsstand geprüft und sonst zurückgenommen |
| Geheimnisse liegen getrennt von den Fachdaten und versiegelt | Lesen während Schreiben (WAL): Neu laden sieht immer einen abgeschlossenen Stand |
Daraus folgen die Grenzen weiter unten: eine Instanz je Datei, nur lokale Platte, und kein fälschungssicheres Protokoll.
Verwaltungsspeicher
Mit Gateway:Store hält der Dienst seine Betriebsdaten in einer eigenen SQLite-Datei statt
in der Konfigurationsdatei. Eine Änderung dort wirkt ohne Neustart.
| Schicht | Ort | Inhalt |
|---|---|---|
| Start | Konfigurationsdatei, Umgebung | Lauschadresse, Anmeldemodi, Dienstschlüssel, Grenzen, Proxys, Gateway:Store |
| Betrieb | Verwaltungsspeicher | Datenquellen (Databases), Regeln (Clients), Zuordnungen von Windows-Konten (WindowsAccounts) und SQL-Anmeldungen (SqlLogins), Personen und ihre persönlichen Schlüssel |
{
"Gateway": {
"Store": {
"Path": "store/gateway.db",
"MasterKey": "env:WKL_GW_MASTER_KEY",
"PollSeconds": 5
}
}
}
Erster Start. Ist der Speicher neu, übernimmt der Dienst einmalig die Betriebsdaten der
Konfigurationsdatei – mit den Werten, die dort tatsächlich gelten, also auch einer
Verbindungszeichenfolge aus einer Umgebungsvariablen. Danach entscheidet der Speicher. Stehen in
der Datei weiter Betriebsdaten, nennt der Start sie in einer Warnung und verwendet sie nicht. Für
Security:SignInRules warnt er nicht, obwohl auch sie dann nur noch aus dem Speicher gelten: Wer
dort Anmelderegeln ändert, sieht deshalb keine Wirkung. Ein Speicher,
in dem später alle Datenquellen gelöscht wurden, holt sich die Einträge der Datei nicht
zurück.
Änderung im Betrieb. Der Dienst fragt SQLite im Abstand PollSeconds, ob eine andere
Verbindung in die Datei geschrieben hat (PRAGMA data_version); das liest keine Daten. Nur nach
einer Änderung lädt er neu und prüft das Ergebnis mit derselben Prüfung wie beim Start.
Besteht es die Prüfung nicht, bleibt die bisherige Fassung in Kraft, und das Protokoll nennt
jeden Fehler. Eine geladene Fassung wird nicht verändert, sondern als Ganzes ersetzt. Eine
Datenquelle, deren Einstellungen gleich blieben, behält ihren Ressourcenkatalog; nur eine
geänderte liest ihn neu.
Datenquellen nach Namen und mit Schalter. Im Speicher ist der Name der Schlüssel, nicht die
Position. Jede Datenquelle hat den Schalter Enabled (auch in der Konfigurationsdatei
nutzbar, Vorgabe true): Eine abgeschaltete Datenquelle bleibt mit allen Regeln stehen, die sie
nennen, ihr Alias wird aber nicht gefunden – eine Anfrage erhält dieselbe Antwort wie für einen
unbekannten Alias, und keine Liste der Aliasse nennt ihn. Gedacht für Wartung oder Umzug
einer Datenbank, ohne Einträge zu löschen.
Verbindungszeichenfolgen und zweite Faktoren sind versiegelt. Authentisierte Verschlüsselung
mit XChaCha20-Poly1305 – ein Teilschlüssel nach HChaCha20 aus den ersten 16 Byte der 24-Byte-Nonce,
damit ChaCha20-Poly1305 der .NET-Laufzeit – aus der
Identitätsbibliothek des Hauses (Wkl.Identity, CredentialProtection). Der Schlüssel wird je Zweck
(DataSourceConnection, TotpSecret) mit HKDF aus MasterKey abgeleitet, der Zweck geht zusätzlich
in die authentifizierten Daten ein; ein versiegelter Wert lässt sich so nur für seinen Zweck öffnen.
Der Hauptschlüssel steht nie in der Datei. Folgen:
- Eine Kopie der Datei allein – Sicherung, Anhang an eine Anfrage – öffnet keine Verbindung. Lesbar bleiben die Namen der Datenquellen, die Regeln und die Zuordnungen.
- Mit demselben Hauptschlüssel läuft die Datei auf jedem Rechner (Umzug = Datei und Schlüssel getrennt übertragen). Bewusst keine DPAPI: Sie bindet an Rechner oder Konto und machte genau diesen Umzug unmöglich.
- Passt der Schlüssel nicht oder wurde ein Wert in der Datei verändert, nennt die Prüfung jede betroffene Datenquelle; beide Ursachen sind nach Art der Verschlüsselung nicht unterscheidbar.
- Geht der Hauptschlüssel verloren, sind die Verbindungszeichenfolgen verloren. Ihn getrennt von den Sicherungen der Datei aufbewahren.
- Jeder Wert nennt die Kennung des Schlüssels, mit dem er versiegelt wurde (Umschlagformat 2 der Identitätsbibliothek). Kennung und Format sind mitbeglaubigt: Eine veränderte Kennung führt zur Ablehnung, nie zum Öffnen mit einem anderen Schlüssel.
Ein geeigneter Schlüssel sind 32 Zufallsbytes als Base64:
[Convert]::ToBase64String([Security.Cryptography.RandomNumberGenerator]::GetBytes(32))
Datei und Zugriff. SQLite im WAL-Modus: Neu laden liest, während geschrieben wird, und sieht
immer den Stand des letzten Abschlusses; ein Lesen umfasst alle Tabellen in einer Transaktion.
Ein Verzeichnis und eine Datei, die der Dienst anlegt, dürfen nur das Dienstkonto und die
Administratoren des Rechners lesen (Windows: Zugriffsliste ohne Vererbung mit diesen Einträgen;
sonst Modus 700/600). Die Administratoren brauchen den Zugriff für die
Befehle am Server; ohne ihn könnte
init-admin den Speicher eines als NetworkService laufenden Dienstes nicht öffnen. Legt init-admin den Speicher an,
bevor der Dienst je lief, nennt --service-account das Konto, unter dem der Dienst laufen wird. SQLite schreibt
neben die Datei -wal und -shm; sie erben die Rechte des Verzeichnisses – deshalb ein eigenes
Verzeichnis. Darf eine bestehende Datei auch ein anderes Konto lesen, nennt der Start es in einer
Warnung und ändert nichts. Eine Datei je Instanz und nur auf einer lokalen Platte: Die Sperren
von SQLite sind auf Netzfreigaben nicht verlässlich.
Protokolldatei
Anmelde- und Lastprotokoll liegen in einer zweiten SQLite-Datei neben dem Speicher, der
Protokolldatei. Sie wächst mit der Nutzung; der Speicher selbst bleibt klein, schnell neu
geladen und schnell gesichert. Ohne Angabe heißt sie wie der Speicher mit angehängtem -logs und
liegt im selben Verzeichnis – für store/gateway.db also store/gateway-logs.db. Einen anderen Ort
nennt `Gateway:Store:LogPath`.
| Inhalt | Gelesen über |
|---|---|
| Einzelne Anmeldeereignisse mit Herkunft | SignInEvents, SignInOrigins |
| Tageswerte je Person: Länder, Netze, Netzbetreiber, Programme, Verfahren, Stunden | `sign-in-profile` |
| Befunde der Anmelderegeln | `SignInFindings` |
| Stundenwerte der Anmeldungen ohne Person und Adresse | SignInHours |
| Lastprotokoll und gespeicherte Lasthinweise | LoadShapes, LoadHours, LoadPersons, SlowRequests, LoadFindings |
Personen über ihre Kennung. Die Protokolldatei nennt eine Person über die Kennung ihrer Zeile im
Speicher, nicht über ihren Namen: Eine umbenannte Person behält ihre Geschichte. Die Mengen zeigen
den aktuellen Namen; gibt es die Person nicht mehr, zeigen sie # und die Kennung.
Größe statt Alter. Die Datei bleibt innerhalb von
`Gateway:Store:LogMaxMegabytes` (Vorgabe 4 096 MB). Wird
die Grenze überschritten, entfernt der Dienst einmal in der Stunde die ältesten Einträge in dieser
Reihenfolge: einzelne langsame Anfragen, einzelne Anmeldeereignisse, Tageswerte der Profile,
Befunde, zuletzt die ältesten Tage der Stundenwerte und der Last je Person. Formen und gespeicherte
Lasthinweise bleiben stehen; sie sind wenige und nennen keine Person. Die Fristen von
Gateway:SignInLog:HourDays und Gateway:LoadLog gelten zusätzlich.
Zugriff und Sicherung. Für die Protokolldatei gelten dieselben Zugriffsrechte wie für den
Speicher. Sie enthält personenbezogene Daten (Adressen, Personen, Zeiten) und keine Geheimnisse.
backup-store sichert sie mit; beide Kopien nebeneinander zurückgelegt öffnen sich wie das Original.
Umzug aus einer früheren Fassung. Hielt der Speicher die Protokolle noch selbst, zieht der Dienst sie beim ersten Start einmal in die Protokolldatei um und entfernt sie danach aus dem Speicher. Die Befunde der Anmelderegeln beginnen mit den Ereignissen nach dem Umzug; frühere Ereignisse werden nicht nachträglich bewertet.
Eine Instanz je Speicher
Ein Verwaltungsspeicher gehört zu genau einer Instanz des Dienstes. Zwei Instanzen auf verschiedenen Rechnern können sich keine Datei teilen (keine Netzfreigabe, siehe oben), und zwei Instanzen auf demselben Rechner mit derselben Datei werden nicht unterstützt. Laufen mehrere Instanzen – etwa für Ausfallsicherheit –, hat jede ihren eigenen Speicher und damit eigene Personen, Schlüssel und Sitzungen; einen Abgleich zwischen ihnen gibt es nicht. Ausfallsicherheit erreichen Sie mit einer Instanz und einer wiederherstellbaren Sicherung (siehe So sichern Sie den Verwaltungsspeicher, stellen ihn wieder her und ziehen um).
Änderungsprotokoll und Nachweis
Jede Änderung über die Verwaltungsschnittstelle schreibt in derselben Transaktion eine Zeile ins
Änderungsprotokoll (Menge ChangeLog: Zeitpunkt, wer, Aktion, Menge, Zeile, Werte vorher und
nachher; ein Geheimnis wie eine Verbindungszeichenfolge nur als Vermerk „(neu gesetzt)“, weder
Wert noch Umschlag). Über die Schnittstelle lässt sich das
Protokoll nur lesen. Fälschungssicher ist es bewusst nicht: Wer die Datei schreiben darf –
das Dienstkonto und die Administratoren des Rechners –, kann auch das Protokoll ändern; eine
Hash-Kette oder Signatur führt es nicht. Wer einen Nachweis braucht, den der Betreiber des
Rechners nicht verändern kann, liest ChangeLog fortlaufend aus (die Nummer steigt streng) und
schreibt es in ein Protokoll außerhalb dieses Rechners. Eine solche Weitergabe bietet der
Dienst nicht.
Aufbewahrung und Löschen
Für ein Löschkonzept nach der Datenschutz-Grundverordnung (Speicherbegrenzung, Art. 5 Abs. 1 lit. e; Recht auf Löschung, Art. 17) gilt im Speicher dieses tatsächliche Verhalten:
| Daten | Wie lange | Löschen |
|---|---|---|
| Person (Name, Windows-Konto, SQL-Anmeldung, Mail-Adresse, zweiter Faktor) | bis sie gelöscht wird | Löschen über die Verwaltung nur, solange die Person keine Spuren hinterlassen hat (siehe unten); es entfernt ihre Zeile und mit ihr ihre Regelzuordnungen, Identitätszuordnungen und offenen Einmal-Links per Mail. Hat sie Spuren hinterlassen, lehnt der Dienst mit 422 ab, und die Person lässt sich nur sperren (Enabled = false) |
| Persönliche Schlüssel | bis sie oder ihre Person gelöscht werden; gesperrte und abgelaufene bleiben als Zeile stehen | über die Verwaltung |
Änderungsprotokoll (ChangeLog) | unbegrenzt | kein Weg im Dienst. Die Menge ist über die Schnittstelle nur lesbar; der Dienst kürzt sie nie |
| Anmelde- und Lastprotokoll, Profile und Befunde (Protokolldatei) | bis die Datei ihre Größe erreicht, die ältesten zuerst; Stundenwerte und Lastprotokoll zusätzlich nach ihren Fristen | der Dienst entfernt sie selbst; einzelne Einträge lassen sich nicht löschen |
| Protokoll der Zugriffe (Audit) | im Speicher des Dienstes die letzten 10 000 Einträge bis zum Neustart; im Protokollziel des Dienstes (Ereignisprotokoll, Journal) nach dessen Aufbewahrung | Aufbewahrung des Protokollziels, vom Betreiber eingestellt |
| Sicherungen | wie der Betreiber sie aufbewahrt | Aufräumen des Sicherungsordners |
Personen mit Spuren werden gesperrt, nicht gelöscht. Anmelde- und Lastprotokoll nennen eine
Person über die Kennung ihrer Zeile, das Änderungsprotokoll über ihren Namen. Würde die Person
gelöscht, verwiesen diese Einträge auf niemanden mehr – oder auf eine spätere Person gleichen
Namens. Der Dienst lehnt das Löschen deshalb mit 422 ab, sobald zu der Person mindestens eines
davon besteht:
- ein persönlicher Schlüssel oder eine Sitzung, auch gesperrt oder abgelaufen;
- ein einzelnes Ereignis im Anmeldeprotokoll oder ein Eintrag im Lastprotokoll zu ihr;
- ein Eintrag im Änderungsprotokoll, den sie selbst geschrieben hat – als Akteur steht dort ihr Name, ihr Name mit Schlüssel oder „(Selbstbedienung)“, ihr Windows-Konto oder ihre SQL-Anmeldung.
Keine Spur sind Einträge, die andere über die Person geschrieben haben, etwa ihr Anlegen oder ihre
Regelzuordnungen. Eine Person, die angelegt, aber nie benutzt wurde, lässt sich also löschen.
Personen, die Einträge im Anmelde- oder Lastprotokoll hinterlassen haben, lassen sich löschen,
sobald diese Einträge aus der Protokolldatei entfernt wurden und sie keine anderen Spuren mehr
haben. Tageswerte ihres Profils und Befunde zu ihr können dann noch stehen; sie zeigen die Person
als # mit Kennung.
Folge für gelöschte Personen. Jede Änderung an einer Person steht mit den Werten vorher und nachher im Änderungsprotokoll – Name, Windows-Konto und Mail-Adresse eingeschlossen. Nach dem Löschen der Person bleiben diese Zeilen stehen, ebenso ihre Kennung als Akteur der Änderungen, die sie selbst vorgenommen hat. Eine Frist, nach der der Dienst Einträge entfernt oder pseudonymisiert, gibt es nicht. Das ist eine Grenze des Dienstes: Ein Löschkonzept, das das verlangt, lässt sich mit dem Dienst allein nicht umsetzen. Möglich ist es nur von außen, mit angehaltenem Dienst und einem SQLite-Werkzeug auf der Datei; dabei gehen der Beweiswert des Protokolls und die Vergleichbarkeit mit älteren Sicherungen verloren, und Sicherungen enthalten die Einträge weiter.
Den Wechsel des Hauptschlüssels beschreibt So wechseln Sie den Hauptschlüssel, Sicherung, Umzug und Wiederherstellung beschreibt So sichern Sie den Verwaltungsspeicher, stellen ihn wieder her und ziehen um.