Zielbenutzer wie deploy legt sshkv bei Bedarf an, mit ~/.ssh und optional einer sudoers-Datei: keine Rechte, bestimmte Befehle oder voll. Die Datei entsteht unter einem Namen, den sudo ignoriert, und wird erst nach visudo -c aktiv. Eine fremde Datei gleichen Namens ueberschreibt sshkv nie, Systemkonten wie root oder sshkv fasst es nicht an. Befehle muessen absolute Pfade sein; Zeichen mit Sonderbedeutung in sudoers sind ausgeschlossen, damit die Liste so wirkt, wie sie aussieht. Vorgang und Oberflaeche folgen mit #019/#020. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
66 lines
2.4 KiB
TypeScript
66 lines
2.4 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import {
|
|
ZielkontoFehler,
|
|
befehlPruefen,
|
|
sudoersInhalt,
|
|
zielkontoEntfernenSkript,
|
|
zielkontoSkript,
|
|
} from "@/lib/ssh/zielkonto";
|
|
|
|
/** Zielkonten und sudoers (#018), als Text; ausgefuehrt im Integrationstest. */
|
|
|
|
describe("sudoers-Inhalt", () => {
|
|
it("gibt vollen Zugriff nur ausdruecklich", () => {
|
|
expect(sudoersInhalt("deploy", "VOLL")).toContain("deploy ALL=(ALL:ALL) NOPASSWD: ALL");
|
|
expect(sudoersInhalt("deploy", "KEINER")).toBeNull();
|
|
});
|
|
|
|
it("listet bestimmte Befehle", () => {
|
|
expect(
|
|
sudoersInhalt("deploy", "BEFEHLE", [
|
|
"/usr/bin/systemctl restart app",
|
|
" /usr/bin/docker compose up -d ",
|
|
]),
|
|
).toBe(
|
|
"# Verwaltet von SSHKeyVault (sshkv) - nicht manuell bearbeiten\n" +
|
|
"deploy ALL=(root) NOPASSWD: /usr/bin/systemctl restart app, /usr/bin/docker compose up -d\n",
|
|
);
|
|
expect(() => sudoersInhalt("deploy", "BEFEHLE", [])).toThrow(ZielkontoFehler);
|
|
});
|
|
|
|
it.each([
|
|
["relativer Pfad", "systemctl restart app"],
|
|
["Komma", "/bin/a, ALL"],
|
|
["Doppelpunkt", "/bin/a:b"],
|
|
["Gleichheitszeichen", "/bin/a x=y"],
|
|
["Wildcard", "/bin/rm *"],
|
|
["Backslash", "/bin/a \\,"],
|
|
["Zeilenumbruch", "/bin/a\nALL ALL=(ALL) ALL"],
|
|
["Shell-Zeichen", "/bin/sh -c id;id"],
|
|
])("weist ab: %s", (_, befehl) => {
|
|
expect(() => befehlPruefen(befehl)).toThrow(ZielkontoFehler);
|
|
});
|
|
});
|
|
|
|
describe("Skripte", () => {
|
|
it("schuetzt Systemkonten", () => {
|
|
for (const benutzer of ["root", "sshkv", "nobody"]) {
|
|
expect(() => zielkontoSkript(benutzer, "VOLL")).toThrow(ZielkontoFehler);
|
|
expect(() => zielkontoEntfernenSkript(benutzer, true)).toThrow(ZielkontoFehler);
|
|
}
|
|
expect(() => zielkontoSkript("Root;id", "KEINER")).toThrow(ZielkontoFehler);
|
|
});
|
|
|
|
it("prueft sudoers vor dem Aktivieren und ueberschreibt keine fremde Datei", () => {
|
|
const skript = zielkontoSkript("deploy", "VOLL");
|
|
expect(skript.indexOf("visudo -cf")).toBeLessThan(skript.indexOf('mv "$NEU" "$DATEI"'));
|
|
expect(skript).toContain("SSHKV-SUDOERS-FREMD");
|
|
expect(zielkontoSkript("deploy", "KEINER")).toContain('rm -f "$DATEI"');
|
|
});
|
|
|
|
it("loescht den Benutzer nur, wenn gewuenscht", () => {
|
|
expect(zielkontoEntfernenSkript("deploy", true)).toContain("userdel");
|
|
expect(zielkontoEntfernenSkript("deploy", false)).not.toContain("userdel");
|
|
});
|
|
});
|