Files
4server/app/sbin/audit
T
oliver 43d2a16ac4 works
2026-06-19 13:06:18 -03:00

150 lines
3.5 KiB
Python
Executable File

#!/usr/bin/env python3
"""Docker system audit: collect container diagnostics and return as JSON."""
import json
import os
import subprocess
def cmd(args, parse_json=False):
try:
result = subprocess.run(
args,
capture_output=True,
text=True,
timeout=30,
)
out = (result.stdout + result.stderr).strip()
if parse_json:
try:
return json.loads(out) if out else None
except json.JSONDecodeError:
return out
return out
except Exception as e:
return f"ERROR: {e}"
def read_file(path):
try:
with open(path) as f:
return f.read().strip().splitlines()
except FileNotFoundError:
return None
def main():
audit = {}
# Container identity
audit["container_id"] = os.environ.get("HOSTNAME")
# OS information inside container
audit["os_release"] = read_file("/etc/os-release")
audit["uname"] = cmd(["uname", "-a"])
# Installed packages (works for Debian/Ubuntu, Alpine, etc.)
audit["packages"] = {}
if os.path.exists("/etc/alpine-release"):
audit["packages"]["manager"] = "apk"
audit["packages"]["installed"] = cmd(["apk", "info", "-v"]).splitlines()
audit["packages"]["upgradeable"] = cmd(
["apk", "version", "-l", "<"]
).splitlines()
elif os.path.exists("/etc/debian_version"):
audit["packages"]["manager"] = "dpkg"
audit["packages"]["installed"] = cmd(
["dpkg-query", "-W", "-f=${Package}-${Version}\n"]
).splitlines()
elif os.path.exists("/etc/redhat-release"):
audit["packages"]["manager"] = "rpm"
audit["packages"]["installed"] = cmd(["rpm", "-qa"]).splitlines()
# Docker engine information
audit["docker_version"] = cmd(
["docker", "version", "--format", "{{json .}}"],
parse_json=True,
)
audit["docker_info"] = cmd(
["docker", "info", "--format", "{{json .}}"],
parse_json=True,
)
# Containers
containers = cmd(
["docker", "ps", "-a", "--format", "{{json .}}"],
parse_json=True,
)
if isinstance(containers, list):
audit["docker_containers"] = containers
else:
audit["docker_containers"] = []
# Images
audit["docker_images"] = cmd(
["docker", "images", "--format", "{{json .}}"],
parse_json=True,
)
# Runtime stats
audit["docker_stats"] = cmd(
[
"docker",
"stats",
"--no-stream",
"--format",
"table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.NetIO}}",
]
)
# Container logs
logs = {}
for c in audit["docker_containers"]:
name = c.get("Names") or c.get("ID")
if not name:
continue
logs[name] = cmd(
[
"docker",
"logs",
"--tail",
"100",
name,
]
)
audit["docker_logs"] = logs
# SSH config if present
audit["sshd_config"] = cmd(["sshd", "-T"]).splitlines()
# Users
audit["passwd"] = read_file("/etc/passwd")
# Runtime info
audit["uptime"] = cmd(["uptime"])
audit["top"] = cmd(["top", "-b", "-n", "1"]).splitlines()
# cgroups (useful in Docker)
audit["cgroup"] = read_file("/proc/self/cgroup")
# Mounted filesystems
audit["mounts"] = cmd(["mount"]).splitlines()
print(json.dumps(audit, indent=2))
if __name__ == "__main__":
main()