Files
sshkeyvault/tests/integration/hilfen/host.ts
T
florian.wildeandClaude Opus 5.5 61a52d4538 feat(ausrollen): Verbindungstest von Host A nach Host B (#020)
Auf A als Zielbenutzer ssh mit BatchMode und StrictHostKeyChecking:
keine Rueckfrage, keine stille Annahme eines Host-Keys. Der Test
beweist damit genau das, was ein Cronjob auf A spaeter braucht. Die
letzte Meldung von ssh landet in Vorgang und Protokoll; ein Erfolg
setzt die letzte Verwendung des Schluessels.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 10:50:43 +02:00

61 lines
2.3 KiB
TypeScript

import { mkdtempSync, rmSync, writeFileSync } from "node:fs";
import { randomBytes } from "node:crypto";
import { tmpdir } from "node:os";
import path from "node:path";
import { prisma } from "@/lib/db";
import { verschluesseln } from "@/lib/geheimnisse";
import { vorgangAusfuehren } from "@/worker/ausfuehren";
import { masterKeyVergessen } from "@/worker/geheimnisse";
import { HANDLER } from "@/worker/handler";
import { rootPasswort, type Ziel } from "./ziele";
/** Gemeinsame Vorbereitung fuer Integrationstests: Master-Key, Host mit Bootstrap (#016). */
export function masterKeyAnlegen(): () => void {
const verzeichnis = mkdtempSync(path.join(tmpdir(), "sshkv-master-"));
const datei = path.join(verzeichnis, "master.key");
writeFileSync(datei, randomBytes(32), { mode: 0o600 });
process.env["SSHKV_MASTER_KEY_FILE"] = datei;
masterKeyVergessen();
return () => rmSync(verzeichnis, { recursive: true, force: true });
}
export async function vorgangLaufen(
art: "HOSTKEY_ABRUFEN" | "BOOTSTRAP" | "TROCKENLAUF" | "AUSROLLEN" | "VERBINDUNGSTEST",
daten: {
hostId?: string;
eingabe?: object;
geheim?: string;
angefordertVonId?: string;
},
) {
const vorgang = await prisma.vorgang.create({
data: {
art,
hostId: daten.hostId ?? null,
eingabe: daten.eingabe ?? {},
angefordertVonId: daten.angefordertVonId ?? null,
},
});
await vorgangAusfuehren(vorgang.id, HANDLER, daten.geheim);
return prisma.vorgang.findUniqueOrThrow({ where: { id: vorgang.id } });
}
/** Host anlegen, Host-Key vertrauen, Bootstrap per root-Passwort. */
export async function eingerichteterHost(
ziel: Ziel,
name: string,
anmeldeart: "DIENSTBENUTZER" | "ROOT" = "DIENSTBENUTZER",
) {
const host = await prisma.host.create({ data: { name, adresse: ziel.host, port: ziel.port, anmeldeart } });
await vorgangLaufen("HOSTKEY_ABRUFEN", { hostId: host.id });
await prisma.hostSchluessel.updateMany({ where: { hostId: host.id }, data: { status: "VERTRAUT" } });
const bootstrap = await vorgangLaufen("BOOTSTRAP", {
hostId: host.id,
eingabe: { modus: "passwort", benutzer: "root" },
geheim: verschluesseln(rootPasswort()),
});
if (bootstrap.status !== "ERLEDIGT") throw new Error(`Bootstrap fehlgeschlagen: ${bootstrap.fehler}`);
return prisma.host.findUniqueOrThrow({ where: { id: host.id } });
}