feat(ausrollen): Private Key mit ssh-config und known_hosts (#017)
Der Kern-Anwendungsfall im Worker: Private Key auf Host A, Public Key auf Host B, dazu ein Block in ~/.ssh/config von A und der vertraute Host-Key von B in known_hosts - danach meldet sich A per Alias bei B an, ohne Rueckfrage zum Host-Key (Integrationstest gegen zwei echte sshd). Gleiches Muster wie bei Public Keys: Plan je Datei mit Hashes, dann genau dieser Plan. Der Inhalt eines Private Keys steht nie im Plan oder Protokoll, eine fremde Datei am Zielpfad wird nie ueberschrieben, und von einem alten Private Key bleibt keine Sicherungskopie liegen. Der config-Block steht am Anfang, weil ssh den ersten Treffer nimmt. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -24,7 +24,7 @@ beforeEach(async () => {
|
||||
await deploymentKeySicherstellen();
|
||||
await befehlAlsRoot(
|
||||
zielA,
|
||||
"userdel -r sshkv 2>/dev/null; rm -f /etc/sudoers.d/sshkv /root/.ssh/authorized_keys* /home/test/.ssh/authorized_keys*; true",
|
||||
"userdel -r sshkv 2>/dev/null; rm -f /etc/sudoers.d/sshkv /home/test/.ssh/authorized_keys*; rm -rf /root/.ssh; true",
|
||||
);
|
||||
});
|
||||
|
||||
@@ -101,7 +101,9 @@ describe("Public Key ausrollen", () => {
|
||||
expect((await prisma.publicVerwendung.findUniqueOrThrow({ where: { id: verwendungId } })).zustand).toBe(
|
||||
"AUSGEROLLT",
|
||||
);
|
||||
expect((await befehlAlsRoot(zielA, "ls /root/.ssh | grep -c sshkv.bak")).stdout.trim()).toBe("1");
|
||||
expect(
|
||||
(await befehlAlsRoot(zielA, "ls /root/.ssh | grep -c authorized_keys.sshkv.bak")).stdout.trim(),
|
||||
).toBe("1");
|
||||
expect((await befehlAlsRoot(zielA, "stat -c %a /root/.ssh/authorized_keys")).stdout.trim()).toBe("600");
|
||||
const eintrag = await prisma.protokoll.findFirst({ where: { aktion: "authorized_keys.geschrieben" } });
|
||||
expect(eintrag?.diff).toContain("+ restrict");
|
||||
|
||||
Reference in New Issue
Block a user