diff --git a/app/sbin/audit b/app/sbin/audit new file mode 100755 index 0000000..aaecb2d --- /dev/null +++ b/app/sbin/audit @@ -0,0 +1,155 @@ +#!/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") + audit["environment"] = dict(os.environ) + + # 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"]) + + # 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() diff --git a/app/sbin/upgrade_alpine_version b/app/sbin/upgrade_alpine_version new file mode 100755 index 0000000..24f766d --- /dev/null +++ b/app/sbin/upgrade_alpine_version @@ -0,0 +1,42 @@ +#!/bin/sh +# Set target Alpine version here +TARGET_VERSION="3.24" + +echo "Current Alpine:" +cat /etc/alpine-release + +echo "Upgrading to Alpine ${TARGET_VERSION}..." + +# Safety backup +BACKUP="/etc/apk/repositories.backup.$(date +%Y%m%d-%H%M%S)" +cp /etc/apk/repositories "$BACKUP" +echo "Repository backup saved: $BACKUP" + +# Update repositories +sed -i "s/v[0-9]\+\.[0-9]\+/v${TARGET_VERSION}/g" /etc/apk/repositories + +echo "New repositories:" +cat /etc/apk/repositories + +# Refresh indexes +apk update + +# Upgrade apk tooling first +apk add --upgrade apk-tools + +# Upgrade all packages to target branch +apk upgrade --available + +# Clean cache +apk cache clean + +echo +echo "Upgrade finished." +echo "New Alpine version:" +cat /etc/alpine-release + +echo +echo "Kernel:" +uname -r + + diff --git a/app/update_alpine b/app/update_alpine new file mode 100755 index 0000000..2d1ba24 --- /dev/null +++ b/app/update_alpine @@ -0,0 +1,4 @@ +rex doas apk update +rex doas apk fix +rex doas apk upgrade +rex doas reboot diff --git a/app/vault/host_vars.img b/app/vault/host_vars.img index 4e024bd..50d725d 100644 Binary files a/app/vault/host_vars.img and b/app/vault/host_vars.img differ