Read-only Host-Forensik über Butler #26

Merged
sascha merged 2 commits from feat/read-only-host-forensics-20260814 into main 2026-08-14 09:52:54 +02:00
Showing only changes of commit a5d3b0c7ce - Show all commits

View file

@ -174,6 +174,33 @@ def test_sysctl_audit_rejects_unknown_host_without_ssh(monkeypatch):
assert response.status_code == 404 assert response.status_code == 404
def test_host_forensics_is_read_only_and_uses_inventory(monkeypatch):
payload = {"docker_binary": {"rc": 0, "stdout": "/usr/bin/docker", "stderr": ""}}
calls = []
monkeypatch.setattr(app, "_find_inventory_host", lambda name: {"name": name, "user": "root", "ip": "10.5.85.13"})
monkeypatch.setattr(app, "_ssh", lambda host, command, timeout=600: (calls.append((host, command, timeout)) or (0, __import__("json").dumps(payload), "")))
with TestClient(app.app) as client:
response = client.get("/system/forensics/node3?since_hours=24", headers={"Authorization": "Bearer test-token"})
assert response.status_code == 200
assert response.json()["checks"] == payload
assert calls[0][0] == "root@10.5.85.13"
assert calls[0][2] == 60
assert "base64.b64decode" in calls[0][1]
command = app._host_forensics_command(24)
for destructive in ("systemctl restart", "systemctl stop", "systemctl disable", "docker rm", "docker system prune", "iptables -F", "rm -rf"):
assert destructive not in command
def test_host_forensics_rejects_unknown_host_and_invalid_window(monkeypatch):
monkeypatch.setattr(app, "_find_inventory_host", lambda _name: None)
monkeypatch.setattr(app, "_ssh", lambda *_args, **_kwargs: (_ for _ in ()).throw(AssertionError("must not SSH")))
with TestClient(app.app) as client:
missing = client.get("/system/forensics/not-there", headers={"Authorization": "Bearer test-token"})
bad_window = client.get("/system/forensics/node3?since_hours=999", headers={"Authorization": "Bearer test-token"})
assert missing.status_code == 404
assert bad_window.status_code == 422
def test_invalid_log_target_is_rejected_before_ssh(): def test_invalid_log_target_is_rejected_before_ssh():
with TestClient(app.app) as client: with TestClient(app.app) as client:
response = client.get( response = client.get(