Files
ssh-jumphost/app/db/migrations/0010_credential_usernames.sql
2026-08-21 06:14:10 +02:00

56 lines
2.9 KiB
SQL

-- Phase 12: Benutzernamen gehoeren zu den ZUGANGSDATEN, nicht zum Host.
--
-- Bisher standen ssh_username bzw. rdp_username/rdp_domain in der Tabelle
-- hosts -- also beim "Server". Fachlich falsch: der Benutzername ist Teil der
-- Anmeldung (er gehoert zum Schluessel bzw. zum Passwort), nicht zur
-- Beschreibung des Zielsystems. Ab jetzt:
-- * SSH: ssh_keys.username (ein Benutzername je Schluessel)
-- * RDP: rdp_credentials.username / .domain (je Host-Passwortsatz)
-- Die alten hosts-Spalten bleiben im Schema (SQLite-Spalten zu entfernen
-- erzwingt einen Tabellen-Rebuild, siehe die ausfuehrliche Begruendung in
-- 0006_tenants.sql) und werden nur noch als Fallback fuer Datensaetze
-- gelesen, die vor dieser Migration angelegt und noch nicht umgestellt
-- wurden. Neue Schreibpfade fassen sie nicht mehr an, die Admin-Oberflaeche
-- zeigt sie nicht mehr an.
ALTER TABLE ssh_keys ADD COLUMN username TEXT;
ALTER TABLE rdp_credentials ADD COLUMN username TEXT;
ALTER TABLE rdp_credentials ADD COLUMN domain TEXT;
-- Uebernahme der bestehenden Werte:
--
-- SSH: nur wenn ALLE Hosts, denen der Schluessel zugeordnet ist, denselben
-- Benutzernamen tragen (COUNT(DISTINCT ...) = 1). Waeren es mehrere, waere
-- jede automatische Wahl geraten -- solche Schluessel bleiben leer und
-- greifen weiter auf den Host-Fallback zurueck, bis ein Admin den
-- Benutzernamen am Schluessel setzt (die Oberflaeche weist darauf hin).
UPDATE ssh_keys
SET username = (
SELECT h.ssh_username
FROM host_ssh_key_map m JOIN hosts h ON h.id = m.host_id
WHERE m.ssh_key_id = ssh_keys.id
AND h.ssh_username IS NOT NULL AND TRIM(h.ssh_username) <> ''
ORDER BY h.id LIMIT 1)
WHERE username IS NULL
AND (SELECT COUNT(DISTINCT h.ssh_username)
FROM host_ssh_key_map m JOIN hosts h ON h.id = m.host_id
WHERE m.ssh_key_id = ssh_keys.id
AND h.ssh_username IS NOT NULL AND TRIM(h.ssh_username) <> '') = 1;
-- RDP: eindeutig, weil rdp_credentials ohnehin genau einen Datensatz pro Host
-- haelt (host_id ist Primaerschluessel).
UPDATE rdp_credentials
SET username = (SELECT h.rdp_username FROM hosts h WHERE h.id = rdp_credentials.host_id),
domain = (SELECT h.rdp_domain FROM hosts h WHERE h.id = rdp_credentials.host_id)
WHERE username IS NULL;
-- hosts.ssh_host_key: der VOLLSTAENDIGE Host-Key im OpenSSH-Format, nicht nur
-- sein Fingerprint. Grund: mit dem Fingerprint allein laesst sich eine
-- Verbindung nicht vorab pinnen -- man sieht den Schluessel erst, wenn der
-- Server ihn praesentiert hat. Mit dem gespeicherten Schluessel kann der
-- Jumphost den vom Ziel angebotenen Schluessel VOR der Anmeldung byteweise
-- vergleichen (siehe app/ssh_proxy/proxy.py). Wird beim "Host-Key ermitteln"
-- mitgeschrieben und fuer Altbestand beim naechsten erfolgreichen
-- Verbindungsaufbau nachgetragen.
ALTER TABLE hosts ADD COLUMN ssh_host_key TEXT;