{"id":"09e57aec-2073-4d3e-a308-9316d8a6514f","entityType":"agent","slug":"clawhub-cyber-bye-linux-security-guardian","name":"Linux Security Guardian","canonicalUrl":"https://www.xpersona.co/agent/clawhub-cyber-bye-linux-security-guardian","canonicalPath":"/agent/clawhub-cyber-bye-linux-security-guardian","generatedAt":"2026-10-10T21:42:16.458Z","source":"CLAWHUB","claimStatus":"UNCLAIMED","verificationTier":"NONE","summary":{"evidence":{"source":"editorial-content","verified":true,"confidence":"high","updatedAt":"2026-10-10T17:55:01.674Z","emptyReason":null},"description":"Autonomous multi-client Linux server security management via SSH MCP. Runs full audit at 1 AM IST nightly via cron. Iterates over all clients and their serve... Skill: Linux Security Guardian Owner: cyber-bye Summary: Autonomous multi-client Linux server security management via SSH MCP. Runs full audit at 1 AM IST nightly via cron. Iterates over all clients and their serve... Tags: latest:1.6.0 Version history: v1.6.0 | 2026-07-14T10:06:54.523Z | user v1.6.0 — 8 new audit modules (19-26), 5 enhanced modules, backup-restore hook - New: 19-cis-scoring (CIS benchmark alignment","descriptionLabel":"Technical summary","evidenceSummary":"Capability contract not published. No trust telemetry is available yet. 1.3K downloads reported by the source. Last updated 10/10/2026.","installCommand":"clawhub skill install s176ths3s2f0frn4xsrfq480h584nvaj:linux-security-guardian","sourceUrl":"https://clawhub.ai/cyber-bye/linux-security-guardian","homepage":"https://clawhub.ai/cyber-bye/skills/linux-security-guardian","primaryLinks":[{"label":"View on ClawHub","url":"https://clawhub.ai/cyber-bye/linux-security-guardian","kind":"source"},{"label":"Homepage","url":"https://clawhub.ai/cyber-bye/skills/linux-security-guardian","kind":"homepage"}],"safetyScore":84,"overallRank":62,"popularityScore":62,"trustScore":null,"claimedByName":null,"isOwner":false,"seoDescription":"Autonomous multi-client Linux server security management via SSH MCP. Runs full audit at 1 AM IST nightly via cron. Iterates over all clients and their serve..."},"coverage":{"evidence":{"source":"public-profile","verified":false,"confidence":"medium","updatedAt":"2026-10-10T17:55:01.674Z","emptyReason":null},"protocols":[{"protocol":"OPENCLEW","label":"OpenClaw","status":"self-declared","notes":"Declared in the public agent profile."}],"capabilities":[],"verifiedCount":0,"selfDeclaredCount":1,"capabilityMatrix":{"rows":[{"key":"OPENCLEW","type":"protocol","support":"unknown","confidenceSource":"profile","notes":"Listed on profile"}],"flattenedTokens":"protocol:OPENCLEW|unknown|profile"}},"adoption":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-10T17:55:01.674Z","emptyReason":null},"stars":null,"forks":null,"downloads":1308,"packageName":null,"latestVersion":"1.6.0","tractionLabel":"1.3K downloads"},"release":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-10T17:55:01.674Z","emptyReason":null},"lastUpdatedAt":"2026-10-10T17:55:01.674Z","lastCrawledAt":"2026-10-10T17:55:01.674Z","lastIndexedAt":null,"nextCrawlAt":"2026-10-11T17:55:01.674Z","lastVerifiedAt":null,"highlights":[{"version":"1.6.0","createdAt":"2026-07-14T10:06:54.523Z","changelog":"v1.6.0 — 8 new audit modules (19-26), 5 enhanced modules, backup-restore hook - New: 19-cis-scoring (CIS benchmark alignment %) - New: 20-systemd-analyze (per-service sandboxing, exposure scoring) - New: 21-mount-hardening (noexec/nosuid/nodev enforcement) - New: 22-apparmor-selinux (MAC enforcement, process confinement) - New: 23-proc-hidepid (/proc visibility isolation) - New: 24-swap-encryption (LUKS/dm-crypt verification) - New: 25-usbguard (USB device authorization) - New: 26-ipv6-audit (RA/redirect/NDP hardening) - Enhanced: 03-ssh (weak ciphers/MACs/Kex CIS checks) - Enhanced: 04-auth (fail2ban auto-install, password policy) - Enhanced: 06-packages (unattended-upgrades auto-enable) - Enhanced: 11-kernel (BPF restrictions) - Enhanced: 15-docker (daemon.json security defaults) - Added: hooks/backup-restore.sh - Preserved: core-extra config system intact","fileCount":50,"zipByteSize":80513},{"version":"1.4.2","createdAt":"2026-06-18T05:20:45.562Z","changelog":"v1.4.2 — Extracted all hardcoded owner data into core-extra/config/profile.md. Removed hardcoded name (Vk), domain (durbhasigurukulam), and email from hooks/SOUL. Added core-extra/ structure for pluggable config (config/, hooks/, templates/). Added Core-Extra Config System section in SKILL.md.","fileCount":41,"zipByteSize":57991},{"version":"1.4.1","createdAt":"2026-06-08T06:28:52.942Z","changelog":"Update dependencies: remove hardcoded local/legacy paths and decouple SSH MCP tool documentation into a dedicated skill.","fileCount":40,"zipByteSize":56819},{"version":"1.4.0","createdAt":"2026-05-29T09:17:53.975Z","changelog":"v1.4.0 — Multi-client architecture: restructured all paths to <client>/<server>/ prefix, SERVER_PROFILE.md supports multiple ## Client: sections, audit-runner iterates all clients→servers, cve-scan.sh accepts --client --server, added AGENT.md rules (SSH MCP hard dep + email + onboarding), SOUL.md placeholders filled, added errors/ + high/ dirs","fileCount":40,"zipByteSize":57617},{"version":"1.3.0","createdAt":"2026-05-29T07:51:07.561Z","changelog":"v1.3.0: SSH MCP API restructured — consolidated to 2 tools (ssh_conn + ssh_exec). ssh_conn: list/test/save connections. ssh_exec: open/run/logs/status/close/list. Array commands support for reduced channel overhead. Self-healing concurrency queue handles MaxSessions limits. audit-runner.md, SKILL.md, 07-cve.md, SERVER_PROFILE.md all updated to new op-based API.","fileCount":40,"zipByteSize":55300},{"version":"1.2.0","createdAt":"2026-05-29T05:18:54.992Z","changelog":"v1.2.0: Removed inline email implementation (Python smtplib, Himalaya CLI, sendmail). Replaced with email plugin/skill redirect — mail-sender.md now delegates to available email skill. Removed mail/ directory with templates. SERVER_PROFILE.md email config simplified. Critical alerts also go through email plugin. SKILL.md, AGENT.md, audit-runner.md updated to reflect no bundled email.","fileCount":40,"zipByteSize":54499},{"version":"1.1.0","createdAt":"2026-05-29T05:11:49.802Z","changelog":"v1.1.0: SSH MCP hard dependency integration — all 18 audit modules now execute via ssh_execute/ssh_get_logs. SERVER_PROFILE.md updated with REQUIRED ssh_mcp connection fields. audit-runner.md: SSH MCP connect/disconnect lifecycle, ABORT on failure (no local fallback). CVE module: API calls routed through SSH MCP. SKILL.md: full SSH MCP usage patterns, tools mapping, connection lifecycle documented.","fileCount":40,"zipByteSize":54755},{"version":"1.0.0","createdAt":"2026-05-29T03:02:51.952Z","changelog":"Initial release: full 18-module Linux security audit — CVE scanning, auto-fix safe issues, confirm-required for critical/firewall/patches, 1AM IST cron, email report via Himalaya/SMTP, action decision matrix, security scoring, baseline tracking","fileCount":38,"zipByteSize":37458}]},"execution":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No published capability contract is available yet."},"installCommand":"clawhub skill install s176ths3s2f0frn4xsrfq480h584nvaj:linux-security-guardian","setupComplexity":"low","setupSteps":["Setup complexity is classified as HIGH. You must provision dedicated cloud infrastructure or an isolated VM. Do not run this directly on your local workstation.","Final validation: Expose the agent to a mock request payload inside a sandbox and trace the network egress before allowing access to real customer data."],"contract":{"contractStatus":"missing","authModes":[],"requires":[],"forbidden":[],"supportsMcp":false,"supportsA2a":false,"supportsStreaming":false,"inputSchemaRef":null,"outputSchemaRef":null,"dataRegion":null,"contractUpdatedAt":null,"sourceUpdatedAt":null,"freshnessSeconds":null},"invocationGuide":{"preferredApi":{"snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-cyber-bye-linux-security-guardian/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-cyber-bye-linux-security-guardian/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-cyber-bye-linux-security-guardian/trust"},"curlExamples":["curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-cyber-bye-linux-security-guardian/snapshot\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-cyber-bye-linux-security-guardian/contract\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-cyber-bye-linux-security-guardian/trust\""],"jsonRequestTemplate":{"query":"summarize this repo","constraints":{"maxLatencyMs":2000,"protocolPreference":["OPENCLEW"]}},"jsonResponseTemplate":{"ok":true,"result":{"summary":"...","confidence":0.9},"meta":{"source":"CLAWHUB","generatedAt":"2026-10-10T21:42:16.455Z"}},"retryPolicy":{"maxAttempts":3,"backoffMs":[500,1500,3500],"retryableConditions":["HTTP_429","HTTP_503","NETWORK_TIMEOUT"]}},"endpoints":{"dossierUrl":"https://www.xpersona.co/api/v1/agents/clawhub-cyber-bye-linux-security-guardian/dossier","snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-cyber-bye-linux-security-guardian/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-cyber-bye-linux-security-guardian/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-cyber-bye-linux-security-guardian/trust"}},"reliability":{"evidence":{"source":"runtime-metrics","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No trust, reliability, or runtime telemetry is available."},"trust":{"status":"unavailable","handshakeStatus":"UNKNOWN","verificationFreshnessHours":null,"reputationScore":null,"p95LatencyMs":null,"successRate30d":null,"fallbackRate":null,"attempts30d":null,"trustUpdatedAt":null,"trustConfidence":"unknown","sourceUpdatedAt":null,"freshnessSeconds":null},"decisionGuardrails":{"doNotUseIf":["Contract metadata is missing or unavailable for deterministic execution."],"safeUseWhen":[],"riskFlags":["missing_or_unavailable_contract","trust_data_unavailable","schema_references_missing"],"operationalConfidence":"low"},"executionMetrics":{"observedLatencyMsP50":null,"observedLatencyMsP95":null,"estimatedCostUsd":null,"uptime30d":null,"rateLimitRpm":null,"rateLimitBurst":null,"lastVerifiedAt":null,"verificationSource":null},"runtimeMetrics":{"successRate":null,"avgLatencyMs":null,"avgCostUsd":null,"hallucinationRate":null,"retryRate":null,"disputeRate":null,"p50Latency":null,"p95Latency":null,"lastUpdated":null}},"benchmarks":{"evidence":{"source":"no-benchmark-data","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No benchmark suites or observed failure patterns are available."},"suites":[],"failurePatterns":[]},"artifacts":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"high","updatedAt":"2026-10-10T17:55:01.674Z","emptyReason":null},"readme":"Skill: Linux Security Guardian\n\nOwner: cyber-bye\n\nSummary: Autonomous multi-client Linux server security management via SSH MCP. Runs full audit at 1 AM IST nightly via cron. Iterates over all clients and their serve...\n\nTags: latest:1.6.0\n\nVersion history:\n\nv1.6.0 | 2026-07-14T10:06:54.523Z | user\n\nv1.6.0 — 8 new audit modules (19-26), 5 enhanced modules, backup-restore hook\n- New: 19-cis-scoring (CIS benchmark alignment %)\n- New: 20-systemd-analyze (per-service sandboxing, exposure scoring)\n- New: 21-mount-hardening (noexec/nosuid/nodev enforcement)\n- New: 22-apparmor-selinux (MAC enforcement, process confinement)\n- New: 23-proc-hidepid (/proc visibility isolation)\n- New: 24-swap-encryption (LUKS/dm-crypt verification)\n- New: 25-usbguard (USB device authorization)\n- New: 26-ipv6-audit (RA/redirect/NDP hardening)\n- Enhanced: 03-ssh (weak ciphers/MACs/Kex CIS checks)\n- Enhanced: 04-auth (fail2ban auto-install, password policy)\n- Enhanced: 06-packages (unattended-upgrades auto-enable)\n- Enhanced: 11-kernel (BPF restrictions)\n- Enhanced: 15-docker (daemon.json security defaults)\n- Added: hooks/backup-restore.sh\n- Preserved: core-extra config system intact\n\nv1.4.2 | 2026-06-18T05:20:45.562Z | user\n\nv1.4.2 — Extracted all hardcoded owner data into core-extra/config/profile.md. Removed hardcoded name (Vk), domain (durbhasigurukulam), and email from hooks/SOUL. Added core-extra/ structure for pluggable config (config/, hooks/, templates/). Added Core-Extra Config System section in SKILL.md.\n\nv1.4.1 | 2026-06-08T06:28:52.942Z | user\n\nUpdate dependencies: remove hardcoded local/legacy paths and decouple SSH MCP tool documentation into a dedicated skill.\n\nv1.4.0 | 2026-05-29T09:17:53.975Z | user\n\nv1.4.0 — Multi-client architecture: restructured all paths to <client>/<server>/ prefix, SERVER_PROFILE.md supports multiple ## Client: sections, audit-runner iterates all clients→servers, cve-scan.sh accepts --client --server, added AGENT.md rules (SSH MCP hard dep + email + onboarding), SOUL.md placeholders filled, added errors/ + high/ dirs\n\nv1.3.0 | 2026-05-29T07:51:07.561Z | user\n\nv1.3.0: SSH MCP API restructured — consolidated to 2 tools (ssh_conn + ssh_exec). ssh_conn: list/test/save connections. ssh_exec: open/run/logs/status/close/list. Array commands support for reduced channel overhead. Self-healing concurrency queue handles MaxSessions limits. audit-runner.md, SKILL.md, 07-cve.md, SERVER_PROFILE.md all updated to new op-based API.\n\nv1.2.0 | 2026-05-29T05:18:54.992Z | user\n\nv1.2.0: Removed inline email implementation (Python smtplib, Himalaya CLI, sendmail). Replaced with email plugin/skill redirect — mail-sender.md now delegates to available email skill. Removed mail/ directory with templates. SERVER_PROFILE.md email config simplified. Critical alerts also go through email plugin. SKILL.md, AGENT.md, audit-runner.md updated to reflect no bundled email.\n\nv1.1.0 | 2026-05-29T05:11:49.802Z | user\n\nv1.1.0: SSH MCP hard dependency integration — all 18 audit modules now execute via ssh_execute/ssh_get_logs. SERVER_PROFILE.md updated with REQUIRED ssh_mcp connection fields. audit-runner.md: SSH MCP connect/disconnect lifecycle, ABORT on failure (no local fallback). CVE module: API calls routed through SSH MCP. SKILL.md: full SSH MCP usage patterns, tools mapping, connection lifecycle documented.\n\nv1.0.0 | 2026-05-29T03:02:51.952Z | user\n\nInitial release: full 18-module Linux security audit — CVE scanning, auto-fix safe issues, confirm-required for critical/firewall/patches, 1AM IST cron, email report via Himalaya/SMTP, action decision matrix, security scoring, baseline tracking\n\nArchive index:\n\nArchive v1.6.0: 50 files, 80513 bytes\n\nFiles: AGENT.md (7263b), AUDIT_LOG.md (56b), audit/modules/01-system.md (1500b), audit/modules/02-users.md (1781b), audit/modules/03-ssh.md (4403b), audit/modules/04-auth.md (5762b), audit/modules/05-services.md (1826b), audit/modules/06-packages.md (3476b), audit/modules/07-cve.md (10288b), audit/modules/08-network.md (1438b), audit/modules/09-firewall.md (1972b), audit/modules/10-filesystem.md (1958b), audit/modules/11-kernel.md (3585b), audit/modules/12-logs.md (1867b), audit/modules/13-crons.md (1225b), audit/modules/14-ssl.md (1473b), audit/modules/15-docker.md (4318b), audit/modules/16-disk.md (790b), audit/modules/17-integrity.md (1096b), audit/modules/18-rootkit.md (1549b), audit/modules/19-cis-scoring.md (4574b), audit/modules/20-systemd-analyze.md (5544b), audit/modules/21-mount-hardening.md (3548b), audit/modules/22-apparmor-selinux.md (4228b), audit/modules/23-proc-hidepid.md (4156b), audit/modules/24-swap-encryption.md (4319b), audit/modules/25-usbguard.md (4463b), audit/modules/26-ipv6-audit.md (6768b), BASELINE.md (964b), core-extra/config/profile.md (516b), crons/active/nightly-audit.md (1696b), cve/cve-scan.sh (25326b), cve/external-sources.md (10102b), hooks/audit-runner.md (8419b), hooks/backup-restore.sh (3296b), hooks/mail-sender.md (2068b), hooks/on-confirm-reply.md (1910b), hooks/on-critical.md (2054b), hooks/post-action.md (993b), hooks/pre-action.md (1636b), memory/schema.json (3449b), SERVER_PROFILE.md (2707b), skill-card.md (2633b), SKILL.md (16761b), SOUL.md (3208b), STATS.md (460b), templates/finding.md (902b), templates/firewall-change.md (739b), templates/pending-action.md (940b), _meta.json (142b)\n\nFile v1.6.0:SKILL.md\n\n---\nname: linux-security-guardian\ndescription: Autonomous multi-client Linux server security management via SSH MCP. Runs full audit at 1 AM IST nightly via cron. Iterates over all clients and their server fleets. Covers system hardening, CVE scanning (CISA KEV + OSV.dev + NVD API), user auditing, SSH config (incl. weak ciphers/MACs/Kex), firewall rules, running services, file permissions, log analysis, SSL certs, kernel parameters (incl. BPF restrictions), Docker daemon security defaults (userns-remap, no-new-privileges, seccomp), fail2ban auto-install, unattended-upgrades auto-enable, CIS benchmark scoring, systemd sandbox analysis, AppArmor/SELinux audit, and swap encryption check. Non-breaking actions auto-applied. Critical patches and network/firewall changes require owner confirmation. Report sent per-server and per-client via email plugin/skill (not bundled). All owner-specific config lives in core-extra/config/ — no hardcoded names, domains, or emails.\nversion: 1.6.0\nmetadata: {\"openclaw\": {\"emoji\": \"🛡️\", \"requires\": {\"bins\": [\"bash\",\"python3\",\"ss\",\"iptables\",\"systemctl\",\"grep\",\"awk\",\"sed\",\"find\",\"curl\"], \"mcp\": [\"ssh_conn\",\"ssh_exec\"]}}}\n---\n\n# Linux Security Guardian\n\n## ⚡ SSH MCP — REQUIRED DEPENDENCY\n\n> **SSH MCP is a hard dependency. The agent MUST have SSH MCP tools available to operate.**\n> No local/legacy fallback. All operations go through SSH MCP.\n\n### Prerequisite\n\n```yaml\n# SSH MCP server must be running and accessible\ndependency: ssh_mcp\nstatus: required    # if unavailable → ABORT, alert owner\n```\n\n### Server Profile Config\n\nEach target server needs a saved connection in SSH MCP database. Configure in `SERVER_PROFILE.md`:\n\n```yaml\nssh_mcp:\n  connection_id: \"<id-name-or-alias-from-ssh-conn-list>\"   # Saved connection ID, Name, or Alias\n  # OR inline config:\n  # host: \"<server-ip>\"\n  # port: 22\n  # username: \"<user>\"\n  # key_path: \"</path/to/key>\"\n```\n\n### Audit Modules\n\nAll 26 modules execute commands via SSH MCP. Each module file lists commands that get wrapped with `ssh_exec(op=\"run\", sessionId, command)`:\n\n```\nmodule command → ssh_exec(op=\"run\", sessionId, command=\"module command\")\n              → ssh_exec(op=\"logs\", commandId=cmdId)\n              → parse output\n```\n\n### CVE Scan\n\nThe external CVE scan runs locally (on the guardian host) using curl to CISA KEV, OSV.dev, and NVD API.\nUsage requires `--client` and `--server` to write results to per-server paths:\n\n```bash\nbash cve/cve-scan.sh --client \"client-1\" --server \"server-01\"\n\n# Writes results to:\n#   cve/<client>/<server>/scan-results/YYYY-MM-DD.md\n#   cve/<client>/<server>/advisories/<CVE-ID>.md\n```\n\nSteps:\n```bash\n# 1. SSH MCP: ssh_exec(op=\"run\", sessionId, command=\"dpkg-query -W ...\") → save locally\n# 2. Read from cve/<client>/<server>/scan-results/installed-packages.txt\n# 3. curl CISA KEV → filter Linux entries → write advisories\n# 4. curl POST OSV.dev batch → match packages → write advisories\n# 5. curl NVD API (optional) → cross-check → write advisories\n```\n\n---\n\n## Core-Extra Config System\n\nAll owner-specific data lives in `core-extra/config/` — **never hardcoded** in hooks or modules.\n\n### Profile\n| File | Contains | Fields |\n|------|----------|--------|\n| `core-extra/config/profile.md` | Owner identity + domain + email | `Owner.name`, `Domain.primary`, `Email.noreply` |\n\n### How Agents Use It\n```\nAt session start → load core-extra/config/profile.md\n→ Owner.name  → used in SOUL.md [WORKSPACE OWNER]\n→ Email.noreply → used as from: in mail-sender.md\n→ Domain.primary → used in config generation\n\nTo change: edit core-extra/config/profile.md only.\n```\n\n### Rule\n- NO hardcoded names, domains, or emails in hooks/, modules/, or root files\n- All personal/owner data comes from `core-extra/config/profile.md`\n- The core-extra directory is part of the skill (published to ClawHub with placeholders)\n- Owner fills profile.md ONCE after install\n\n---\n\n## Multi-Client Architecture\n\nThe guardian manages **multiple clients**, each with their own server fleet.\nSERVER_PROFILE.md defines `## Client:` sections. The audit iterates ALL.\n\n```\nSERVER_PROFILE.md\n├── ## Client: client-1 (7 servers)\n│   ├── server-01\n│   ├── server-02\n│   └── ... server-07\n├── ## Client: client-2 (N servers) ← add as needed\n│   └── ...\n└── ## Client: [NEXT-CLIENT]\n```\n\nAll paths use `<client>/<server>/` prefix:\n- Findings: `audit/results/<client>/<server>/<severity>/`\n- Actions:  `actions/<client>/<server>/auto-done/`\n- CVEs:     `cve/<client>/<server>/advisories/`\n- Reports:  `reports/<client>/<server>/daily/`\n\n---\n\n## Purpose\n\nAgent manages complete Linux server security autonomously via SSH MCP.\nEvery night at 1 AM IST:\n- Iterates all clients → all servers\n- Full security audit runs via SSH MCP\n- CVEs scanned against installed packages\n- Auto-fixes applied for safe issues\n- Critical issues queued for owner confirmation\n- Per-server, per-client, and master email reports delivered\n\n---\n\n## Action Decision Matrix\n\nThe most important thing — what agent does vs what it asks first:\n\n| Finding Type | CVSS / Severity | Action |\n|---|---|---|\n| CVE — Critical | ≥ 9.0 | EMAIL ALERT immediately + queue for confirm |\n| CVE — High | 7.0–8.9 | Queue for confirm + include in report |\n| CVE — Medium | 4.0–6.9 | Include in report + advisory |\n| CVE — Low | < 4.0 | Info in report only |\n| CVE — KEV (CISA) | any | **Treated as CRITICAL** — immediate alert + confirm within due date |\n| CVE — KEV + Ransomware | any | **🔥 HIGHEST PRIORITY** — immediate alert, confirm ASAP |\n| Kernel update available | any | Confirm required before patch |\n| Security-only pkg update | any | Confirm required |\n| SSH: PermitRootLogin yes | critical | Alert + confirm to fix |\n| SSH: PasswordAuth yes | high | Alert + confirm to fix |\n| SSH: Port 22 | medium | Advisory only |\n| Empty password account | critical | AUTO-LOCK immediately |\n| Unknown root-uid account | critical | Alert + confirm to lock |\n| Inactive account > 90d | medium | Alert + confirm to lock |\n| World-writable /tmp | medium | AUTO-FIX chmod |\n| World-writable system dir | high | Alert + confirm to fix |\n| Unexpected SUID binary | high | Alert only (owner decides) |\n| Failed login spike > 20/hr | high | Alert immediately |\n| New unknown cron job | high | Alert immediately |\n| Firewall rule change needed | any | CONFIRM REQUIRED always |\n| Open unexpected port | high | Alert + confirm to close |\n| Service: unnecessary running | medium | Alert + confirm to stop |\n| SSL cert expiring < 30d | warning | Alert |\n| SSL cert expired | critical | Alert immediately |\n| Disk > 85% full | warning | Alert |\n| Disk > 95% full | critical | Alert immediately |\n| Auditd not running | high | AUTO-START + alert |\n| fail2ban not running | high | AUTO-START + alert |\n| Log file suspicious entry | high | Alert with extract |\n\n---\n\n## Audit Modules\n\n| Module | What it checks | SSH MCP Command |\n|--------|---------------|-----------------|\n| `01-system` | OS, kernel, uptime, last reboot, hardware | `ssh_exec(op=\"run\", sessionId, command=\"uname -a; cat /etc/*release\")` |\n| `02-users` | Accounts, root access, sudo, empty passwords, inactive | `ssh_exec(op=\"run\", sessionId, command=\"cat /etc/passwd; cat /etc/shadow; ...\")` |\n| `03-ssh` | sshd_config full audit — 20+ checks + weak ciphers/MACs/KexAlgorithms (CIS) | `ssh_exec(op=\"run\", sessionId, command=\"cat /etc/ssh/sshd_config; sshd -T 2>/dev/null | grep -iE 'ciphers|macs|kex'\")` |\n| `04-auth` | Login history, failed logins, PAM config, fail2ban auto-install + SSH jail config, password policy enforcement | `ssh_exec(op=\"run\", sessionId, command=\"last; cat /var/log/auth.log\")` |\n| `05-services` | Running services, unnecessary ones, failed units | `ssh_exec(op=\"run\", sessionId, command=\"systemctl list-units ...\")` |\n| `06-packages` | Pending updates, security updates count, unattended-upgrades auto-enable (security-only) | `ssh_exec(op=\"run\", sessionId, command=\"apt list --upgradable 2>/dev/null\")` |\n| `07-cve` | CVE scan — remote via SSH MCP + API-based | `ssh_exec(op=\"run\", sessionId, command=\"dpkg-query -W ...; curl ...\")` |\n| `08-network` | Open ports, listening services, active connections | `ssh_exec(op=\"run\", sessionId, command=\"ss -tulpn; netstat -tulpn\")` |\n| `09-firewall` | iptables/nftables/ufw rules audit | `ssh_exec(op=\"run\", sessionId, command=\"iptables-save 2>/dev/null\")` |\n| `10-filesystem` | SUID/SGID, world-writable, /tmp, sticky bits | `ssh_exec(op=\"run\", sessionId, command=\"find / -perm -4000 ...\")` |\n| `11-kernel` | sysctl security params — 15+ checks + BPF restrictions (unprivileged_bpf_disabled, bpf_jit_enable) | `ssh_exec(op=\"run\", sessionId, command=\"sysctl -a 2>/dev/null\")` |\n| `12-logs` | auth.log, syslog, kern.log — anomaly scan | `ssh_exec(op=\"run\", sessionId, command=\"tail -100 /var/log/syslog\")` |\n| `13-crons` | System + user cron jobs — unknown jobs flagged | `ssh_exec(op=\"run\", sessionId, command=\"cat /etc/crontab; ls -la /var/spool/cron/\")` |\n| `14-ssl` | Cert expiry check for all domains/services | `ssh_exec(op=\"run\", sessionId, command=\"openssl x509 -in ... -noout -dates\")` |\n| `15-docker` | If running — image vulns, container config, daemon.json security defaults (userns-remap, no-new-privileges, seccomp) | `ssh_exec(op=\"run\", sessionId, command=\"docker ps; docker images; cat /etc/docker/daemon.json\")` |\n| `16-disk` | Disk usage, inode usage | `ssh_exec(op=\"run\", sessionId, command=\"df -h; df -i\")` |\n| `17-integrity` | AIDE/tripwire check if installed | `ssh_exec(op=\"run\", sessionId, command=\"aide --check\")` |\n| `18-rootkit` | rkhunter/chkrootkit if installed | `ssh_exec(op=\"run\", sessionId, command=\"rkhunter --check --skip-keypress\")` |\n| `19-cis-scoring` | CIS benchmark alignment score across all modules | `(aggregated from all modules)` |\n| `20-systemd-analyze` | systemd service sandboxing — 80+ security directives per service | `ssh_exec(op=\"run\", sessionId, command=\"systemd-analyze security --json=short 2>/dev/null\")` |\n| `21-mount-hardening` | Mount point security — noexec, nosuid, nodev on /tmp, /dev/shm, /var/tmp | `ssh_exec(op=\"run\", sessionId, command=\"mount | grep -E '^/'\")` |\n| `22-apparmor-selinux` | AppArmor/SELinux MAC status — enforcement mode, confined processes | `ssh_exec(op=\"run\", sessionId, command=\"aa-status 2>/dev/null || sestatus 2>/dev/null\")` |\n| `23-proc-hidepid` | /proc hidepid enforcement — process visibility isolation | `ssh_exec(op=\"run\", sessionId, command=\"mount | grep 'proc on /proc'\")` |\n| `24-swap-encryption` | Swap partition encryption — LUKS/dm-crypt check | `ssh_exec(op=\"run\", sessionId, command=\"swapon --show 2>/dev/null\")` |\n| `25-usbguard` | USB device authorization — USBGuard policy and daemon status | `ssh_exec(op=\"run\", sessionId, command=\"systemctl is-active usbguard\")` |\n| `26-ipv6-audit` | IPv6 security — RA acceptance, redirects, privacy extensions, NDP hardening | `ssh_exec(op=\"run\", sessionId, command=\"sysctl net.ipv6.conf.all.disable_ipv6\")` |\n\n**Execution rule**: All commands go through `ssh_exec(op=\"run\", sessionId, command=\"<command>\")` → `ssh_exec(op=\"logs\", commandId=cmdId)`. No local execution.\n\n---\n\n## Finding Severity Levels\n\n| Level | Color | Meaning |\n|---|---|---|\n| `CRITICAL` | 🔴 | Immediate risk, action required now |\n| `HIGH` | 🟠 | Significant risk, fix this week |\n| `MEDIUM` | 🟡 | Moderate risk, fix this month |\n| `LOW` | 🔵 | Minor issue, fix when possible |\n| `INFO` | ⚪ | Informational, no action needed |\n| `PASS` | 🟢 | Check passed, all good |\n\n---\n\n## Confirmation Flow\n\nWhen owner confirmation is needed:\n\n```\nFinding detected (requires confirm) on <client>/<server>\n    ↓\nWrite to actions/<client>/<server>/pending-confirm/<client>-<server>-<id>-<slug>.md\n    ↓\nInclude in email report under \"NEEDS YOUR DECISION\" with <client>/<server> context\n    ↓\nOwner replies with: APPROVE <id> / DENY <id> / SKIP <id>\n(Full ID format: <client>-<server>-<type>-<NNN>, e.g. client-1-server-01-ACT-20260529-001)\n    ↓\nSearch all actions/*/*/pending-confirm/ for the ID\n    ↓\nAPPROVE → agent connects to <client>/<server> via SSH MCP → executes action → logs to history/\nDENY    → action skipped, noted\nSKIP    → deferred to next audit\n```\n\n---\n\n## Email Report Structure\n\nReports are sent per-server, per-client (summary), and master. All via email plugin/skill.\n\n### Per-Server Report\n```\nSubject: [Linux Guardian] <client>/<server> — YYYY-MM-DD | Score: N/100 | CRITICAL:N HIGH:N\n\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\nLINUX SECURITY GUARDIAN — NIGHTLY REPORT\nClient: <client> | Server: <server> | <IP> | YYYY-MM-DD 01:00 IST\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\nEXECUTIVE SUMMARY\nSecurity Score: N/100 | Grade: X\nCritical: N | High: N | Medium: N | Low: N\nAuto-fixed: N | Pending confirm: N | Passed: N\n\n━━ 🔴 CRITICAL (immediate action needed)\n[Finding details]\n\n━━ 🟠 HIGH\n[Finding details]\n\n━━ ⚡ AUTO-ACTIONS TAKEN (safe, non-breaking)\n[What was auto-fixed]\n\n━━ 🔑 NEEDS YOUR DECISION (reply APPROVE/DENY/SKIP <id>)\n[Pending confirmations with IDs — includes <client>/<server> prefix]\n\n━━ 📦 CVE REPORT\n[CVEs found by severity]\n\n━━ 🌐 NETWORK & FIREWALL\n[Port/firewall status]\n\n━━ 🟡 MEDIUM / LOW\n[Less urgent findings]\n\n━━ 🟢 ALL PASSING\n[Checks that passed]\n\n━━ NEXT AUDIT: Tomorrow 01:00 IST\n```\n\n### Per-Client Summary Report\n```\nSubject: [Linux Guardian] <client> Summary — YYYY-MM-DD | Servers: N/N | CRITICAL:N HIGH:N\n\nClient: <client>\nServers audited: N of N total\nAverage score: N/100\n\n| Server | Score | Critical | High | Score Grade |\n|--------|-------|----------|------|-------------|\n| ...    | ...   | ...      | ...  | ...         |\n\nCross-server patterns: [same vuln found on multiple servers]\n```\n\n\n---\n\n## Security Score Formula\n\n```\nscore = 100\nscore -= (critical_count × 20)\nscore -= (high_count × 10)\nscore -= (medium_count × 3)\nscore -= (low_count × 1)\nscore = max(0, score)\n\nGrade: 90-100 = A | 75-89 = B | 60-74 = C | < 60 = F\n```\n\n---\n\n## Folder Structure\n\n```\nlinux-security-guardian/\n  audit/\n    modules/                     ← 01-system.md ... 26-ipv6-audit.md\n    results/\n      <client>/<server>/\n        critical/  high/  warning/  info/  pass/\n          YYYY-MM-DD-<check>.md  ← per-client/per-server findings\n\n  actions/\n    <client>/<server>/\n      auto-done/                 ← auto-fixed actions (logged)\n        YYYY-MM-DD-<slug>.md\n      pending-confirm/           ← waiting for owner\n        <id>-<slug>.md\n      history/                   ← all approved/denied actions\n\n  cve/\n    cve-scan.sh                  ← external CVE scanner (takes --client --server)\n    external-sources.md          ← all API URLs, query params, working examples\n    .cache/                      ← shared cached API responses (6h TTL)\n    <client>/<server>/\n      scan-results/              ← YYYY-MM-DD.md\n      advisories/                ← <cve-id>.md\n\n  reports/\n    <client>/<server>/\n      daily/YYYY-MM-DD.md\n      weekly/YYYY-WNN.md\n\n  network/\n    <client>/<server>/\n      firewall-snapshots/        ← YYYY-MM-DD-rules.txt\n      port-scans/                ← YYYY-MM-DD.md\n      proposed-changes/          ← <id>-<change>.md\n\n  hooks/\n    audit-runner.md              ← main 1 AM audit orchestrator (multi-client loop)\n    on-critical.md               ← fires on any critical finding (with client/server)\n    on-confirm-reply.md          ← processes owner APPROVE/DENY/SKIP\n    pre-action.md                ← safety check before any action\n    post-action.md               ← verify action succeeded\n    mail-sender.md               ← uses email plugin/skill to send report\n\n  crons/\n    active/\n      nightly-audit.md           ← 1 AM IST permanent\n    completed/\n\n  core-extra/\n    config/\n      profile.md                 ← owner name, domain, email (fill ONCE, no hardcode)\n    hooks/                       ← shared hooks (mirrors hooks/ structure)\n    templates/                   ← shared templates\n\n  errors/\n    raw/                         ← raw error logs\n\n  memory/\n    schema.json\n    index.json\n\n  SOUL.md                        ← soul context (multi-client aware)\n  AGENT.md                       ← behavioral rules (multi-client, SSH MCP hard dep)\n  SERVER_PROFILE.md               ← multi-client server details\n  AUDIT_LOG.md                    ← append-only master log\n  BASELINE.md                     ← expected state snapshot\n  STATS.md\n```\n\nFile v1.6.0:_meta.json\n\n{\n  \"ownerId\": \"kn79djxt41q03wtr3nth5h8y8184mgcm\",\n  \"slug\": \"linux-security-guardian\",\n  \"version\": \"1.6.0\",\n  \"publishedAt\": 1784023614523\n}\n\nFile v1.6.0:AGENT.md\n\n---\nname: linux-security-guardian-agent\ndescription: Behavioral rules for linux-security-guardian. Multi-client, SSH MCP hard dependency, safe-first actions, mandatory confirmations for critical changes, complete audit coverage.\n---\n\n# Agent Rules — Linux Security Guardian\n\n## THE PRIME RULE — SAFE FIRST\n\nWhen in doubt about whether an action is safe: DON'T DO IT.\nLog it. Alert owner. Wait for explicit approval.\nA delayed fix is always better than an accidental outage.\n\n---\n\n## Rule 1 — SSH MCP Hard Dependency\n\nSSH MCP is a hard dependency. The agent MUST have SSH MCP tools available to operate.\n\n```yaml\nrequired_tools: [ssh_conn, ssh_exec]\nversion: v2  # 13 tools: ssh_conn, ssh_exec, ssh_bulk_exec, ssh_bulk_audit, ssh_client, etc.\n```\n\nIf SSH MCP tools are unavailable → ABORT audit, alert owner: \"SSH MCP not available\".\nNo local/legacy fallback. All operations go through SSH MCP.\n\n---\n\n## Rule 2 — Multi-Client Audit Flow\n\nSERVER_PROFILE.md contains one or more `## Client:` sections.\nThe audit MUST iterate over ALL clients and ALL servers:\n\n```\nfor each client in SERVER_PROFILE.md:\n  for each server in client.server_fleet:\n    ssh_conn → test/save connection if needed\n    ssh_exec(op=\"open\", connectionId) → sessionId\n    Run all 26 modules via ssh_exec(op=\"run\", sessionId, ...)\n    Compile per-server findings → audit/results/<client>/<server>/<severity>/\n    Compile per-server report → reports/<client>/<server>/daily/YYYY-MM-DD.md\n    ssh_exec(op=\"close\", sessionId)\n  Compile per-client summary\nAppend master report\nSend via default email account\n```\n\n---\n\n## Rule 3 — Email Account Selection\n\n- **Default account**: Used for ALL outgoing reports and alerts.\n- **Admin account**: Personal account. NEVER use for automated reports.\n- Rule: Always use default account. Never specify `--account admin`.\n- Check available accounts: `himalaya account list` (identify default vs admin).\n- If no email plugin available → log to AUDIT_LOG.md, report is on disk. Non-fatal.\n\n---\n\n## Rule 4 — Read SERVER_PROFILE.md Before Every Audit\n\nLoad SERVER_PROFILE.md at audit start.\nParse each `## Client:` section. Extract server fleet table.\nExpected ports, services, users, SUID list — all per-server from this file.\nDeviation from profile = finding.\nProfile not filled = abort audit, alert owner.\n\n---\n\n## Rule 5 — Auto-Actions Whitelist Only\n\nAgent can ONLY auto-execute actions listed in SERVER_PROFILE.md under `Auto-Actions Allowed`.\nAnything not explicitly whitelisted → queue for confirmation.\nNo exceptions. Owner preference > agent judgment.\n\nAuto-action execution:\n1. Run pre-action safety check (hooks/pre-action.md)\n2. Execute action via SSH MCP\n3. Verify result (hooks/post-action.md)\n4. Log to actions/<client>/<server>/auto-done/\n5. Include in email report\n\n---\n\n## Rule 6 — Confirmation Queue Protocol\n\nWhen action requires confirmation:\n1. Generate unique ID: `ACT-YYYYMMDD-NNN`\n2. Write to actions/<client>/<server>/pending-confirm/<id>-<slug>.md\n3. Include in email report under \"NEEDS YOUR DECISION\"\n4. Wait. Do not execute until owner says APPROVE.\n5. Confirmation expires after 7 days → re-queue next audit\n\n---\n\n## Rule 7 — Critical Finding = Immediate Alert\n\nAny CRITICAL finding triggers hooks/on-critical.md immediately.\nDo not wait for report compilation.\nSend alert via default email account NOW.\nContinue audit in parallel.\n\nCritical findings:\n- CVSS ≥ 9.0 CVE\n- KEV entry (any CVSS — treated as CRITICAL)\n- KEV + Ransomware (🔥 highest priority)\n- Empty password account found\n- Unknown UID 0 account\n- Root login via SSH successful (from logs)\n- SSL cert expired\n- Disk > 95%\n- Rootkit detected\n- Unexpected kernel module loaded\n- /etc/passwd or /etc/shadow modified unexpectedly\n\n---\n\n## Rule 8 — Firewall Rules — Always Confirm\n\nFirewall is ALWAYS confirm-required. No exceptions.\nEven \"obviously safe\" rules need owner approval.\nFormat for proposed change:\n\n```\nID: FW-YYYYMMDD-NNN\nClient: <client>\nServer: <server>\nCurrent rule: [exact current state]\nProposed change: [exact proposed command]\nReason: [why this change is needed]\nRisk: [what could break if wrong]\nRollback: [exact command to undo]\n```\n\nAgent writes this to network/<client>/<server>/proposed-changes/ and includes in report.\nAgent NEVER runs iptables/nftables/ufw commands without explicit APPROVE.\n\n---\n\n## Rule 9 — CVE Scan — Complete Coverage\n\nCVE scan must cover ALL installed packages per server.\nDetect package manager automatically (apt/yum/dnf/pacman).\nUse best available tool per OS via SSH MCP.\n\nCVE results saved to cve/<client>/<server>/scan-results/YYYY-MM-DD.md.\nAny CVSS ≥ 7.0 or KEV entry → also save individual advisory to cve/<client>/<server>/advisories/<CVE-ID>.md.\n\nExternal sources (CISA KEV, OSV.dev, NVD API) queried via ssh_exec from remote server.\nSource override flags: KEV → CRITICAL, RANSOMWARE → 🔥 immediate alert, OSV_MATCH → per CVSS, NVD_CORROBORATED → +1 severity.\n\n---\n\n## Rule 10 — Snapshot Before Any Action\n\nBefore any auto-action or approved action that modifies config:\n1. Snapshot current state of the relevant file/config\n2. Save to actions/<client>/<server>/history/<id>-BEFORE.txt\n3. Execute action\n4. Save new state to actions/<client>/<server>/history/<id>-AFTER.txt\n5. Save rollback command to actions/<client>/<server>/history/<id>-ROLLBACK.sh\n\n---\n\n## Rule 11 — Audit Must Be Complete\n\nAll 26 modules must run per server.\nIf a module fails (command not found, permission error):\nLog failure: `[MODULE FAILED] <client>/<server> 07-cve: ...`\nNever silently skip a module.\nReport module failures in email.\nContinue to next server. Do not abort entire audit on single server failure.\n\n---\n\n## Rule 12 — Audit Log is Append-Only\n\nEvery audit run appended to AUDIT_LOG.md:\n```\nYYYY-MM-DD 01:00 IST | audit_start | clients:N | servers:N\nYYYY-MM-DD 01:XX IST | audit_complete | clients:N | servers_total:N | critical:N high:N | score:N/100\n```\nNever edit, never delete.\n\n---\n\n## Rule 13 — New Client Onboarding\n\nWhen adding a new client:\n1. Add `## Client: <name>` section to SERVER_PROFILE.md\n2. Fill server fleet table (host, port, username, key_path)\n3. Save connections via SSH MCP: `ssh_conn(op=\"save\", name, host, port, username, key_path)`\n4. Verify each server reachable: `ssh_conn(op=\"test\", ...)`\n5. Create per-client directories: `audit/results/<client>/<server>/`, `actions/`, `cve/`, `network/`, `reports/`\n6. Set notification email for the client\n7. Run first audit to establish baseline\n8. Verify report delivery reaches client's notification email\n\n---\n\n## Rule 14 — Baseline Management\n\nFirst run per server: create baseline in `audit/results/<client>/<server>/baseline/`.\nSubsequent runs: compare against baseline.\nDeviations from baseline = findings (even if not a security issue).\n\nBaseline updated only when:\n- Owner explicitly says \"update baseline\"\n- After an approved action changes system state\n\n---\n\n## Rule 15 — Session Start Check\n\nAt session start (if during day):\n- Any pending-confirm actions across any client/server? → surface: \"N actions await your approval\"\n- Any CRITICAL findings from last audit? → surface immediately with client/server context\n- Any CVE CRITICAL from last scan? → surface\n\nFile v1.6.0:AUDIT_LOG.md\n\n# Audit Log\n*Append-only. One entry per audit run.*\n---\n\nFile v1.6.0:audit/modules/01-system.md\n\n# Module 01 — System Info\n\n## Commands\n```bash\nuname -r                           # kernel version\nuname -a                           # full kernel info\nlsb_release -a 2>/dev/null        # OS info\ncat /etc/os-release                # OS info fallback\nuptime -p                          # uptime\nlast reboot | head -5              # reboot history\ndf -h                              # disk usage\nfree -h                            # memory\nnproc                              # CPU count\ncat /proc/cpuinfo | grep \"model name\" | head -1\ntimedatectl                        # NTP sync status\n```\n\n## Checks & Findings\n\n### OS EOL Check\n- Ubuntu 20.04 LTS → EOL April 2025 → if still running: HIGH finding\n- Ubuntu 22.04 LTS → EOL April 2027 → OK\n- Ubuntu 24.04 LTS → EOL April 2029 → OK\n- Debian 11 → EOL June 2026 → OK\n- Debian 10 → EOL June 2024 → HIGH if still running\n\n### Kernel Version Check\n- Compare against latest stable for the distro\n- More than 2 major versions behind → HIGH\n- Security patch available → MEDIUM\n\n### NTP Sync\n- timedatectl | grep \"NTP service: active\" → PASS\n- NTP not synced → MEDIUM (time drift breaks certs/logs)\n\n### Disk Usage\n- < 80% → PASS\n- 80-85% → LOW\n- 85-95% → WARNING\n- > 95% → CRITICAL (auto-alert)\n\n### Last Reboot\n- No reboot in > 90 days with kernel updates pending → MEDIUM\n- Server rebooted unexpectedly (not matching known maintenance) → HIGH\n\n## Output Format\n```\n[PASS/FINDING] 01-system: <check> | <result>\n```\n\nFile v1.6.0:audit/modules/02-users.md\n\n# Module 02 — User Accounts\n\n## Commands\n```bash\n# All users with login shell\ngrep -v \"nologin\\|false\\|sync\\|halt\\|shutdown\" /etc/passwd | cut -d: -f1,3,6,7\n\n# UID 0 accounts (should only be root)\nawk -F: '($3 == 0) { print $1 }' /etc/passwd\n\n# Sudo users\ngetent group sudo 2>/dev/null || getent group wheel 2>/dev/null\ncat /etc/sudoers | grep -v \"^#\" | grep -v \"^$\"\nls /etc/sudoers.d/\n\n# Empty passwords (CRITICAL)\nawk -F: '($2 == \"\" || $2 == \"!!\" ) { print $1 }' /etc/shadow 2>/dev/null\n\n# Password age\nawk -F: '{print $1, $5}' /etc/shadow 2>/dev/null | grep \"^[^:]*:[0-9]\"\n\n# Last login for all users\nlastlog | grep -v \"Never\\|Username\"\n\n# Users logged in right now\nwho\nw\n\n# Recently created accounts (last 30 days)\nfind /home -maxdepth 1 -type d -newer /tmp -mtime -30 2>/dev/null\n```\n\n## Checks & Findings\n\n### UID 0 Accounts\n- Only 'root' should have UID 0\n- Any other UID 0 account → CRITICAL immediate alert\n\n### Unknown Sudo Users\n- Compare against SERVER_PROFILE.md expected sudo users\n- Unknown sudo user → CRITICAL\n\n### Empty Passwords\n- Any account with empty password → CRITICAL\n- AUTO-ACTION if whitelisted: `passwd -l <username>`\n\n### Inactive Accounts (> 90 days no login)\n- Check lastlog, find accounts with login > 90 days ago\n- Still active login shell → MEDIUM\n- Queue confirm to lock: `usermod -L <username>`\n\n### Password Policy\n- Check /etc/login.defs for PASS_MAX_DAYS, PASS_MIN_DAYS\n- PASS_MAX_DAYS > 90 → LOW\n- No password expiry → MEDIUM\n\n### Root Account Direct Login\n- Check if anyone logged in as root via SSH recently\n- grep \"Accepted.*root\" /var/log/auth.log → HIGH if found\n\n## Output Format\n```\n[CRITICAL] 02-users: empty_password | account: <name> | action: auto-lock-queued\n[PASS] 02-users: uid0_check | only root has uid 0\n```\n\nFile v1.6.0:audit/modules/03-ssh.md\n\n# Module 03 — SSH Configuration\n\n## Commands\n```bash\nsshd -T 2>/dev/null          # full effective SSH config (best method)\ncat /etc/ssh/sshd_config     # raw config file\ngrep -v \"^#\\|^$\" /etc/ssh/sshd_config\n```\n\n## Checks — 20+ SSH Security Parameters\n\n| Parameter | Secure Value | Finding if Wrong |\n|---|---|---|\n| PermitRootLogin | no | HIGH → confirm to set no |\n| PasswordAuthentication | no | HIGH → confirm to set no |\n| PubkeyAuthentication | yes | HIGH |\n| PermitEmptyPasswords | no | CRITICAL → auto-fix |\n| X11Forwarding | no | MEDIUM |\n| MaxAuthTries | ≤ 4 | MEDIUM |\n| LoginGraceTime | ≤ 60 | LOW |\n| AllowAgentForwarding | no | LOW |\n| AllowTcpForwarding | no | MEDIUM |\n| ClientAliveInterval | 300 | LOW |\n| ClientAliveCountMax | 2 | LOW |\n| Protocol | 2 (implicit modern) | CRITICAL if 1 |\n| Port | not 22 | INFO (advisory) |\n| UsePAM | yes | MEDIUM if no |\n| IgnoreRhosts | yes | HIGH if no |\n| HostbasedAuthentication | no | HIGH |\n| PermitUserEnvironment | no | MEDIUM |\n| StrictModes | yes | HIGH if no |\n| MaxSessions | ≤ 4 | LOW |\n| Banner | set | INFO |\n| LogLevel | VERBOSE or INFO | MEDIUM if silent |\n| AllowUsers/AllowGroups | set | INFO (advisory) |\n\n## Auto-Fix Eligible (from whitelist only)\n- PermitEmptyPasswords no → AUTO-FIX (sed in place)\n\n## Confirm Required\n- PermitRootLogin no → confirm (could lock out if no key auth)\n- PasswordAuthentication no → confirm (MUST have key auth working first)\n- All others → queue confirm\n\n## Checks — SSH Ciphers, MACs, and Key Exchange Algorithms (CIS)\n\n### Commands\n```bash\n# Check configured ciphers\nsshd -T 2>/dev/null | grep -i ciphers\n\n# Check configured MACs\nsshd -T 2>/dev/null | grep -i macs\n\n# Check configured KexAlgorithms\nsshd -T 2>/dev/null | grep -i kexalgorithms\n\n# Check for weak ciphers in current config\ngrep -i ciphers /etc/ssh/sshd_config 2>/dev/null\n```\n\n### Weak Ciphers (CBC mode — vulnerable to padding oracle attacks)\n| Cipher | Status | Severity |\n|--------|--------|----------|\n| 3des-cbc | WEAK | HIGH |\n| aes128-cbc | WEAK | MEDIUM |\n| aes192-cbc | WEAK | MEDIUM |\n| aes256-cbc | WEAK | MEDIUM |\n| blowfish-cbc | WEAK | HIGH |\n| cast128-cbc | WEAK | MEDIUM |\n| arcfour/arcfour128/arcfour256 | WEAK (RC4) | CRITICAL |\n| rijndael-cbc@lysator.liu.se | WEAK | MEDIUM |\n\n### Weak MACs (vulnerable to hash collision)\n| MAC | Status | Severity |\n|-----|--------|----------|\n| hmac-md5 | WEAK | HIGH |\n| hmac-md5-96 | WEAK | HIGH |\n| hmac-ripemd160 | WEAK | MEDIUM |\n| hmac-sha1 | WEAK | MEDIUM |\n| hmac-sha1-96 | WEAK | MEDIUM |\n| umac-64@openssh.com | WEAK | MEDIUM |\n| hmac-sha2-256-96 | WEAK | MEDIUM |\n| hmac-sha2-512-96 | WEAK | MEDIUM |\n\n### Weak Kex Algorithms (vulnerable to man-in-the-middle)\n| Algorithm | Status | Severity |\n|-----------|--------|----------|\n| diffie-hellman-group1-sha1 | WEAK | HIGH |\n| diffie-hellman-group14-sha1 | WEAK | MEDIUM |\n| diffie-hellman-group-exchange-sha1 | WEAK | HIGH |\n| diffie-hellman-group-exchange-sha256 (small moduli) | WEAK | MEDIUM |\n| ecdh-sha2-nistp256/384/521 | WEAK (NIST curves) | LOW |\n| curve25519-sha256 | STRONG | PASS |\n| curve25519-sha256@libssh.org | STRONG | PASS |\n| diffie-hellman-group16-sha512 | STRONG | PASS |\n| diffie-hellman-group18-sha512 | STRONG | PASS |\n| sntrup761x25519-sha512@openssh.com | STRONG (post-quantum) | PASS |\n\n### Recommended Secure Config\n```\n# /etc/ssh/sshd_config.d/99-hardening.conf\nCiphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr\nMACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512,hmac-sha2-256\nKexAlgorithms sntrup761x25519-sha512@openssh.com,curve25519-sha256,curve25519-sha256@libssh.org,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512\n```\n\n### Auto-Fix Eligible\n- Weak ciphers/MACs/Kex detected → write hardening config to /etc/ssh/sshd_config.d/99-hardening.conf (confirm required — could break legacy clients)\n\n### Output Format (Ciphers/MACs/Kex)\n```\n[HIGH] 03-ssh: weak_cipher | cipher: 3des-cbc | in use: yes | action_id: ACT-YYYYMMDD-XXX\n[MEDIUM] 03-ssh: weak_mac | mac: hmac-sha1 | in use: yes | action_id: ACT-YYYYMMDD-XXX\n[PASS] 03-ssh: kex_algorithm | kex: curve25519-sha256 | strong ✓\n```\n\n## Output Format\n```\n[HIGH] 03-ssh: PermitRootLogin | value: yes | expected: no | action_id: ACT-YYYYMMDD-001\n[PASS] 03-ssh: MaxAuthTries | value: 3 ≤ 4\n```\n\nFile v1.6.0:audit/modules/04-auth.md\n\n# Module 04 — Authentication & Login Audit\n\n## Commands\n```bash\n# Failed login attempts\ngrep \"Failed password\" /var/log/auth.log | tail -100\ngrep \"Failed password\" /var/log/auth.log | awk '{print $11}' | sort | uniq -c | sort -rn | head -20  # top source IPs\n\n# Successful logins\ngrep \"Accepted\" /var/log/auth.log | tail -50\n\n# Sudo usage\ngrep \"sudo:\" /var/log/auth.log | tail -50\n\n# Failed sudo\ngrep \"sudo:.*NOT in sudoers\" /var/log/auth.log\n\n# Login from unexpected locations\nlast | head -30\n\n# Brute force threshold check\nFAILED=$(grep \"Failed password\" /var/log/auth.log | grep \"$(date '+%b %e')\" | wc -l)\necho \"Failed logins today: $FAILED\"\n\n# PAM configuration\ncat /etc/pam.d/sshd | grep -v \"^#\"\ncat /etc/pam.d/login | grep -v \"^#\"\n\n# fail2ban status\nsystemctl is-active fail2ban 2>/dev/null\nfail2ban-client status sshd 2>/dev/null\n```\n\n## Checks & Findings\n\n### Failed Login Spike\n- > 20 failed logins in last hour → HIGH alert\n- > 100 failed logins in last hour → CRITICAL alert\n- Single IP with > 10 failures → HIGH (may not be in fail2ban)\n\n### Successful Root SSH Login\n- Any \"Accepted.*root\" in auth.log → HIGH (if PermitRootLogin is yes)\n\n### Unauthorized Sudo Usage\n- \"NOT in sudoers\" entries → HIGH\n\n### fail2ban Status\n- Not running → HIGH → AUTO-START (if whitelisted)\n- Not configured for SSH → MEDIUM\n\n### fail2ban Auto-Install & Config\nIf fail2ban not installed:\n```bash\n# Check if installable\nwhich apt >/dev/null 2>&1 && echo \"apt available\"\nwhich yum >/dev/null 2>&1 && echo \"yum available\"\n\n# Auto-install command (confirm required)\n# apt install -y fail2ban  # Debian/Ubuntu\n# yum install -y fail2ban   # RHEL/CentOS\n```\n\nIf fail2ban installed but SSH jail not active:\n```bash\n# Check SSH jail status\nfail2ban-client status sshd 2>/dev/null || echo \"sshd jail not configured\"\n\n# Check jail.local config\ncat /etc/fail2ban/jail.local 2>/dev/null | grep -A10 \"\\[sshd\\]\"\n\n# Default SSH jail config to write (confirm required):\n# [sshd]\n# enabled = true\n# port = ssh\n# filter = sshd\n# logpath = /var/log/auth.log\n# maxretry = 5\n# bantime = 3600\n# findtime = 600\n```\n\n### fail2ban Auto-Install Flow\n1. Check if fail2ban installed → if not, queue install to confirm\n2. Check if SSH jail enabled → if not, queue config to confirm\n3. After install + config → restart fail2ban → verify active\n4. Log action to actions/auto-done/<client>/<server>/\n\n### Output Format (fail2ban auto-install)\n```\n[HIGH] 04-auth: fail2ban_not_installed | action: install_queued | action_id: ACT-YYYYMMDD-XXX\n[MEDIUM] 04-auth: fail2ban_ssh_jail_disabled | action: config_queued | action_id: ACT-YYYYMMDD-XXX\n[PASS] 04-auth: fail2ban_ssh_jail | status: active | banned: 3 IPs\n```\n\n### PAM Configuration\n- pam_tally2 or pam_faillock not configured → MEDIUM\n- No account lockout policy → MEDIUM\n\n### Login from Unknown IPs\n- Compare login IPs against SERVER_PROFILE.md management IPs\n- Unknown IP logged in successfully → HIGH\n\n### Password Policy Enforcement\nCheck current password policy:\n```bash\n# Check PASS_MIN_LEN, PASS_MAX_DAYS, PASS_WARN_AGE\ncat /etc/login.defs | grep -E \"^PASS_|^#PASS_\" | head -10\n\n# Check password quality requirements\ncat /etc/pam.d/common-password 2>/dev/null | grep -v \"^#\" | grep -E \"pam_pwquality|pam_cracklib|pam_unix\"\n\n# Check if pwquality is installed\ndpkg -l libpam-pwquality 2>/dev/null | grep \"^ii\" || echo \"pwquality_not_installed\"\n\n# Check user password aging\nfor u in $(awk -F: '$3>=1000 && $3!=65534 {print $1}' /etc/passwd); do\n  echo \"$u: $(chage -l $u 2>/dev/null | grep 'Maximum' | cut -d: -f2)\"\ndone\n```\n\n### Recommended Password Policy (confirm required)\n\n**/etc/login.defs settings:**\n```\nPASS_MAX_DAYS   90\nPASS_MIN_DAYS   7\nPASS_MIN_LEN    12\nPASS_WARN_AGE   14\n```\n\n**/etc/pam.d/common-password (pwquality):**\n```\npassword requisite pam_pwquality.so retry=3 minlen=12 difok=3 ucredit=-1 lcredit=-1 dcredit=-1 ocredit=-1 enforce_for_root\n```\n\nIf libpam-pwquality not installed:\n```bash\n# Auto-install command (confirm required)\n# apt install -y libpam-pwquality  # Debian/Ubuntu\n# yum install -y pam_pwquality     # RHEL/CentOS\n```\n\n### Auto-Install Flow\n1. Check if libpam-pwquality installed → if not, queue install (confirm required)\n2. Check PASS_MIN_LEN >= 12 → if not, queue login.defs update (confirm required)\n3. Check PASS_MAX_DAYS <= 90 → if not, queue login.defs update (confirm required)\n4. Check pwquality configured in common-password → if not, queue PAM config (confirm required)\n5. After changes → verify with: `chage -l <user> | grep Maximum`\n6. Log action to actions/auto-done/<client>/<server>/\n\n### Password Policy Notes\n- **Existing users are NOT affected** by login.defs changes — only new users\n- **chage** can update existing users: `chage -M 90 <user>`\n- **pwquality** affects all password changes (root + users)\n- **enforce_for_root** applies quality checks to root too (optional — remove if risky)\n- **retry=3** allows 3 attempts before failure\n- **minlen=12** = minimum 12 characters\n- **difok=3** = at least 3 characters different from old password\n- **ucredit/lcredit/dcredit/ocredit=-1** = at least 1 upper/lower/digit/other character\n\n## Output Format\n```\n[HIGH] 04-auth: brute_force | failed_logins_1hr: 47 | top_source: 1.2.3.4 (23 attempts)\n[HIGH] 04-auth: fail2ban_down | status: inactive | action: auto-start queued\n[MEDIUM] 04-auth: pwquality_not_installed | action: install_queued | action_id: ACT-YYYYMMDD-XXX\n[MEDIUM] 04-auth: password_minlen | current: 6 | recommended: 12 | action: config_queued | action_id: ACT-YYYYMMDD-XXX\n[MEDIUM] 04-auth: password_maxdays | current: 99999 | recommended: 90 | action: config_queued | action_id: ACT-YYYYMMDD-XXX\n[PASS] 04-auth: password_policy | minlen: 12 | maxdays: 90 | pwquality: yes\n```\n\nFile v1.6.0:audit/modules/05-services.md\n\n# Module 05 — Services Audit\n\n## Commands\n```bash\n# All running services\nsystemctl list-units --type=service --state=running --no-pager\n\n# Failed services\nsystemctl list-units --type=service --state=failed --no-pager\n\n# Services enabled at boot\nsystemctl list-unit-files --type=service --state=enabled --no-pager\n\n# Listening processes\nss -tulpn\n# or: netstat -tulpn\n\n# Processes listening on all interfaces (0.0.0.0 or :::)\nss -tulpn | grep -E \"0\\.0\\.0\\.0|:::\"\n\n# Check for suspicious processes\nps aux --sort=-%cpu | head -20\nps aux | awk '{if ($3 > 50.0) print $0}'  # high CPU\n\n# Docker if running\ndocker ps 2>/dev/null\ndocker ps -a 2>/dev/null\n```\n\n## Checks & Findings\n\n### Unknown Running Services\n- Compare against SERVER_PROFILE.md expected services\n- Any unlisted service running → MEDIUM (queue confirm to investigate/stop)\n\n### Failed Services\n- Any failed service → HIGH (could indicate attack or config issue)\n- Check if service was recently working: journalctl -u <service> --since \"1 hour ago\"\n\n### Services Listening on All Interfaces\n- Services bound to 0.0.0.0 that should be internal only → HIGH\n- Cross-check with expected open ports in SERVER_PROFILE.md\n\n### Unnecessary Services Running\nCommon unnecessary services to flag:\n- telnet → CRITICAL (plaintext)\n- rsh, rlogin, rexec → CRITICAL\n- finger → MEDIUM\n- rpcbind (if not NFS server) → LOW\n- avahi-daemon (if not needed) → LOW\n- cups (if not print server) → LOW\n\n### Auditd Status\n- Not running → HIGH → AUTO-START (if whitelisted)\n- systemctl enable auditd + systemctl start auditd\n\n## Output Format\n```\n[CRITICAL] 05-services: telnet_running | service: telnet | action: confirm-to-stop ACT-XXX\n[HIGH] 05-services: auditd_down | action: auto-starting\n[PASS] 05-services: expected_services | all 5 expected services running\n```\n\nFile v1.6.0:audit/modules/06-packages.md\n\n# Module 06 — Package Updates\n\n## Commands\n\n### Debian/Ubuntu\n```bash\napt update -qq 2>/dev/null\n\n# Total pending updates\napt list --upgradable 2>/dev/null | grep -v \"Listing...\" | wc -l\n\n# Security updates specifically\napt list --upgradable 2>/dev/null | grep -i security | wc -l\n\n# List security updates\napt-get --just-print upgrade 2>/dev/null | grep \"^Inst\" | grep -i security\n\n# Held packages\napt-mark showhold\n```\n\n### RHEL/CentOS/Rocky\n```bash\nyum check-update --security -q 2>/dev/null\nyum updateinfo list security 2>/dev/null | tail -20\ndnf check-update --security 2>/dev/null\n```\n\n## Checks & Findings\n\n### Pending Security Updates\n- 0 security updates → PASS\n- 1-5 security updates → MEDIUM\n- > 5 security updates → HIGH\n- Any kernel security update → HIGH + confirm required\n\n### Total Update Lag\n- 0-10 packages behind → LOW\n- 10-50 packages behind → MEDIUM\n- > 50 packages behind → HIGH (neglected system)\n\n### Held Packages\n- Any held package with known CVE → HIGH\n\n### Auto-Update Config\n- Check if unattended-upgrades is configured\n- Not configured → MEDIUM advisory\n\n### Unattended-Upgrades Auto-Enable\nIf unattended-upgrades not installed:\n```bash\n# Check if installable\nwhich apt >/dev/null 2>&1 || { echo \"Not Debian/Ubuntu — skip\"; exit 0; }\n\n# Check if installed\ndpkg -l unattended-upgrades 2>/dev/null | grep -q \"^ii\" || echo \"not installed\"\n```\n\nIf not installed → queue install (confirm required):\n```bash\n# apt install -y unattended-upgrades\n```\n\nIf installed but not configured for security-only updates:\n```bash\n# Check current config\ncat /etc/apt/apt.conf.d/50unattended-upgrades 2>/dev/null | grep -E \"Allowed-Origins|Automatic-Reboot|Remove-Unused\"\n\n# Check if enabled\ncat /etc/apt/apt.conf.d/20auto-upgrades 2>/dev/null\n```\n\n### Recommended Config (security-only)\nWrite to /etc/apt/apt.conf.d/20auto-upgrades (confirm required):\n```\nAPT::Periodic::Update-Package-Lists \"1\";\nAPT::Periodic::Download-Upgradeable-Packages \"1\";\nAPT::Periodic::AutocleanInterval \"7\";\nAPT::Periodic::Unattended-Upgrade \"1\";\n```\n\nWrite to /etc/apt/apt.conf.d/50unattended-upgrades (confirm required):\n```\nUnattended-Upgrade::Allowed-Origins {\n    \"${distro_id}:${distro_codename}-security\";\n};\nUnattended-Upgrade::AutoFixInterruptedDpkg \"true\";\nUnattended-Upgrade::MinimalSteps \"true\";\nUnattended-Upgrade::Remove-Unused-Kernel-Packages \"true\";\nUnattended-Upgrade::Remove-Unused-Dependencies \"true\";\nUnattended-Upgrade::Automatic-Reboot \"false\";\nUnattended-Upgrade::Automatic-Reboot-Time \"03:00\";\n```\n\n### Auto-Enable Flow\n1. Check if unattended-upgrades installed → if not, queue install\n2. Check if 20auto-upgrades has Unattended-Upgrade \"1\" → if not, queue config\n3. Check if 50unattended-upgrades restricts to security-only → if not, queue config\n4. After config → verify with: `unattended-upgrades --dry-run --debug 2>&1 | head -20`\n5. Log action to actions/auto-done/<client>/<server>/\n\n### Output Format (unattended-upgrades)\n```\n[MEDIUM] 06-packages: unattended_upgrades_not_installed | action: install_queued | action_id: ACT-YYYYMMDD-XXX\n[MEDIUM] 06-packages: unattended_upgrades_not_enabled | action: config_queued | action_id: ACT-YYYYMMDD-XXX\n[PASS] 06-packages: unattended_upgrades | security-only updates enabled ✓\n```\n\n## Output Format\n```\n[HIGH] 06-packages: security_updates_pending | count: 12 | kernel_update: yes | action_id: ACT-XXX\n[MEDIUM] 06-packages: no_auto_updates | unattended-upgrades not configured\n```\n\nFile v1.6.0:audit/modules/07-cve.md\n\n# Module 07 — CVE Scan\n\n## Detection Strategy (tries in order)\n\n### EXECUTION NOTE\nAll commands run via `ssh_exec(op=\"run\", sessionId, command=\"<command>\")` on the remote server. Output retrieved via `ssh_exec(op=\"logs\", commandId=cmdId)`. API calls (CISA KEV, OSV.dev, NVD) execute via `ssh_exec` on the remote server using `curl`. No local command execution.\n\n### LOCAL METHODS (local tools, no network needed)\n\n```bash\n# Method 1: debsecan (Debian/Ubuntu — most accurate)\nwhich debsecan >/dev/null 2>&1 && debsecan --suite $(lsb_release -cs) --only-fixed --format=detail\n\n# Method 2: Ubuntu CVEScan\nwhich cvescan >/dev/null 2>&1 && cvescan\n\n# Method 3: apt security info (fallback)\napt-get --just-print upgrade 2>/dev/null | grep \"^Inst\" | grep -i \"security\\|CVE\"\n\n# Method 4: RHEL/CentOS yum security\nwhich yum >/dev/null 2>&1 && yum updateinfo list security 2>/dev/null\n\n# Method 5: Installed package list (for external source cross-ref)\ndpkg-query -W -f='${Package}\\t${Version}\\n' 2>/dev/null\n# Or: rpm -qa --queryformat '%{NAME}\\t%{VERSION}\\n' 2>/dev/null\n```\n\n### EXTERNAL METHODS (requires internet — enrich local findings)\n\n```bash\n# ═══════════════════════════════════════════════════════════════\n# METHOD 6: CISA KEV Catalog [CURL] ✅\n# ═══════════════════════════════════════════════════════════════\n# URL: https://www.cisa.gov/sites/default/files/feeds/known_exploited_vulnerabilities.json\n# No API key needed. No rate limits. Always works with curl.\n# Cross-ref against installed packages. KEV match → auto-CRITICAL.\n#\n# curl -s \"https://www.cisa.gov/sites/default/files/feeds/known_exploited_vulnerabilities.json\" \\\n#   | jq '[.vulnerabilities[] | select(.vendorProject == \"Linux\")]'\n\n# ═══════════════════════════════════════════════════════════════\n# METHOD 7: OSV.dev — open source vuln DB [CURL] ✅\n# ═══════════════════════════════════════════════════════════════\n# POST https://api.osv.dev/v1/query (single)\n# POST https://api.osv.dev/v1/querybatch (batch — up to 1000)\n# No API key. No rate limits. Always works with curl.\n# Best method: matches by package + ecosystem + version.\n#\n# curl -s -X POST \"https://api.osv.dev/v1/querybatch\" \\\n#   -H \"Content-Type: application/json\" \\\n#   -d '{\"queries\":[\n#     {\"package\":{\"name\":\"openssl\",\"ecosystem\":\"Debian\"},\"version\":\"3.0.2\"},\n#     {\"package\":{\"name\":\"nginx\",\"ecosystem\":\"Debian\"},\"version\":\"1.22.0\"}\n#   ]}'\n\n# ═══════════════════════════════════════════════════════════════\n# METHOD 8: NVD API 2.0 [CURL] ⚠️ rate limited\n# ═══════════════════════════════════════════════════════════════\n# URL: https://services.nvd.nist.gov/rest/json/cves/2.0\n# Rate limit: 5 req/30s (no key), 50 req/30s (with key)\n# API key (free): https://nvd.nist.gov/developers/request-an-api-key [BROWSER]\n# ⚠️ API endpoint works with curl. Web portal (nvd.nist.gov) is CLOUDFLARE BLOCKED.\n#\n# Without key (sleep 6s between calls):\n#   curl -s \"https://services.nvd.nist.gov/rest/json/cves/2.0?keywordSearch=linux&resultsPerPage=5\"\n# With key:\n#   curl -s -H \"apiKey:NVD_API_KEY\" \"https://services.nvd.nist.gov/rest/json/cves/2.0?cveId=CVE-2024-1086\"\n#\n# ⚠️ Skip if blocked: if curl returns Cloudflare \"Attention Required\" → SKIP immediately\n#    Do NOT retry. OSV.dev and CISA KEV already cover what NVD would tell you.\n\n# ═══════════════════════════════════════════════════════════════\n# METHOD 9: Web portal URLs [BROWSER] ❌ Cloudflare blocks curl\n# ═══════════════════════════════════════════════════════════════\n# Only use with browser tool. DO NOT use curl on these URLs.\n#\n# CISA KEV (Linux filter):\n#   https://www.cisa.gov/known-exploited-vulnerabilities-catalog?f%5B0%5D=vendor_project%3ALinux\n#\n# NVD Search — Linux:\n#   https://nvd.nist.gov/vuln/search/results?query=linux&search_type=all&queryType=phrase\n#\n# NVD Search — Critical Linux:\n#   https://nvd.nist.gov/vuln/search/results?query=linux&cvssSeverity=CRITICAL&queryType=phrase\n#\n# OSV.dev — Linux kernel:\n#   https://osv.dev/list?ecosystem=Linux\n```\n\n### Skip Logic (— every method runs independently)\n\n```\nEACH external method follows this rule:\n\n1. curl --max-time 15 --connect-timeout 10 $URL\n2. if curl exit code != 0:\n     → Log \"[SKIP] $SOURCE unavailable (network)\"\n     → Move to next source. Not fatal.\n3. if response contains \"Attention Required\" OR \"Cloudflare\" OR \"cf-wrapper\":\n     → Log \"[SKIP] $SOURCE blocked by Cloudflare — use browser tool only\"\n     → Skip permanently this session. Don't retry. Ever.\n4. if HTTP 429 (rate limit):\n     → Sleep 6s, retry once\n     → Still 429? Log \"[SKIP] $SOURCE rate limited — too many requests\"\n     → Skip.\n5. Success → parse results, write advisories, continue next method.\n\nNEVER let one blocked/failed source fail the entire scan.\nEach source is independent.\n```\n\n### URL Working Status Quick Reference\n\n| URL | curl | Browser | Notes |\n|-----|------|---------|-------|\n| `cisa.gov/.../known_exploited_vulnerabilities.json` | ✅ Works | ✅ Works | No key needed |\n| `services.nvd.nist.gov/rest/json/cves/2.0` | ✅ Works | ❌ API only | Rate limited |\n| `nvd.nist.gov/vuln/search` | ❌ **Cloudflare** | ✅ Works | Do NOT use curl |\n| `nvd.nist.gov/vuln/detail/CVE-XXXX` | ❌ **Cloudflare** | ✅ Works | Do NOT use curl |\n| `api.osv.dev/v1/querybatch` | ✅ Works | ❌ API only | No key needed |\n| `osv.dev/list` | ✅ Works | ✅ Works | Web UI |\n\n### Priority Chain\n\n```\n1. cve/cve-scan.sh (external: CISA KEV + OSV.dev batch + NVD API)\n   → Run first if internet available via: cve/cve-scan.sh --client <name> --server <name>\n   → Each source independent — if one fails, others still run\n   → Writes to cve/<client>/<server>/scan-results/YYYY-MM-DD.md\n   → Advisories to cve/<client>/<server>/advisories/<CVE-ID>.md\n   → Matches against installed packages from dpkg-query\n\n2. Local methods 1-5 (debsecan / cvescan / apt / yum)\n   → Always run as baseline (no network dependency)\n   → Catch what external methods miss\n\n3. Web portal URLs [BROWSER]\n   → Agent opens in browser for manual verification\n   → Use when API calls are blocked or for deep investigation\n   → NVD portal blocked by Cloudflare — only works in browser\n```\n\n## CVE Severity Classification (CVSS v3)\n\n| CVSS Score | Severity | Action |\n|---|---|---|\n| 9.0 – 10.0 | CRITICAL | Immediate alert + confirm to patch |\n| 7.0 – 8.9 | HIGH | Queue confirm to patch |\n| 4.0 – 6.9 | MEDIUM | Report + advisory |\n| 0.1 – 3.9 | LOW | Report only |\n\n## External Source Override Flags\n\n| Flag | Source | Impact |\n|---|---|---|\n| `KEV` | CISA Known Exploited Vulnerabilities | ⚡ Any CVE in KEV → treat as CRITICAL regardless of CVSS |\n| `RANSOMWARE` | CISA KEV (knownRansomwareCampaignUse) | 🔥 Highest priority — immediate alert + confirm within due date |\n| `OSV_MATCH` | OSV.dev (version match) | Confirmed vulnerable version installed — treat per CVSS |\n| `NVD_CORROBORATED` | NVD API cross-check | Dual-source confirmed — increase severity by one level |\n\n## Output to cve/<client>/<server>/scan-results/YYYY-MM-DD.md\n\n```markdown\n# CVE Scan — YYYY-MM-DD\n\n## Summary\n- Method used: debsecan / cvescan / apt-fallback\n- Total CVEs found: N\n- Critical: N | High: N | Medium: N | Low: N\n\n## Critical CVEs\n| CVE ID | Package | CVSS | Description | Patch Available |\n|---|---|---|---|---|\n\n## High CVEs\n...\n\n## Patch Commands\n# For each patchable CVE:\n# apt-get install --only-upgrade <package>\n```\n\n## Individual Advisory (for CVSS ≥ 7.0 OR KEV entry)\nWrite to cve/<client>/<server>/advisories/<CVE-ID>.md with full detail including source attribution.\n\n### Advisory Format\n```markdown\n# CVE-2024-XXXXX — <package>\n\n**Severity:** CRITICAL | HIGH\n**CVSS:** 9.8\n**Source:** CISA KEV | OSV.dev | NVD API\n**Flags:** KEV | RANSOMWARE | OSV_MATCH | NVD_CORROBORATED\n**Package:** openssh-server\n**Installed Version:** 8.9p1\n**Patch Available:** yes / no\n**Due Date:** YYYY-MM-DD (if from KEV)\n**Scan Date:** YYYY-MM-DD\n\n## Description\n...\n\n## References\n- https://nvd.nist.gov/vuln/detail/<CVE-ID>\n- https://www.cve.org/CVERecord?id=<CVE-ID>\n- https://osv.dev/vulnerability/<CVE-ID> (if OSV match)\n```\n\n## Output Format\n```\n[CRITICAL][KEV] 07-cve: CVE-2024-XXXXX | package: openssh-server | cvss: 9.8 | patch: available | action_id: ACT-XXX\n[HIGH][OSV_MATCH] 07-cve: CVE-2024-YYYYY | package: sudo | cvss: 7.8 | patch: available | action_id: ACT-YYY\n[CRITICAL][RANSOMWARE] 07-cve: CVE-2024-ZZZZZ | package: nginx | cvss: 7.5 | kev: ransomware_known | due: 2024-06-15 | action_id: ACT-ZZZ\n[INFO] 07-cve: scan_complete | total: 23 | critical: 1 | high: 3 | medium: 12 | low: 7\n[INFO] 07-cve: external_sources | cisa_kev: 2_matches | osv_dev: 5_matches | nvd_api: 10_findings\n```\n\n## External Script\nCVE scan commands run via `ssh_exec(op=\"run\", sessionId, command=\"...\")` on the remote server:\n- `dpkg-query -W -f='${Package}\\t${Version}\\n'` → installed packages\n- `curl -s 'https://www.cisa.gov/...'` → CISA KEV fetch\n- `curl -s -X POST 'https://api.osv.dev/v1/querybatch'` → OSV.dev query\n- `curl -s 'https://services.nvd.nist.gov/rest/json/cves/2.0?...'` → NVD query\nResults parsed locally, advisories written to `cve/<client>/<server>/advisories/<CVE-ID>.md`.\nScan report to `cve/<client>/<server>/scan-results/YYYY-MM-DD.md`.\n\nFile v1.6.0:audit/modules/08-network.md\n\n# Module 08 — Network Audit\n\n## Commands\n```bash\n# All listening ports and which process\nss -tulpn\n# Alternative: netstat -tulpn\n\n# Active connections\nss -tnp | grep ESTABLISHED | head -20\n\n# Network interfaces\nip addr show\nip link show\n\n# Routing table\nip route\n\n# ARP table (unexpected entries?)\narp -n\n\n# DNS config\ncat /resolv.conf 2>/dev/null || cat /etc/resolv.conf\n\n# Check for promiscuous mode (sniffing)\nip link | grep PROMISC\n\n# Network sockets stats\nss -s\n```\n\n## Checks & Findings\n\n### Unexpected Open Ports\n- Compare ss output against SERVER_PROFILE.md expected ports\n- Any unlisted port open on 0.0.0.0 or :: → HIGH\n- Queue firewall rule to close: FW-YYYYMMDD-NNN\n\n### Management Ports on Public Interface\n- SSH (22) or database ports (3306, 5432, 27017) on 0.0.0.0 → HIGH\n- Should be bound to 127.0.0.1 or private IP\n\n### Promiscuous Mode\n- Any interface in promiscuous mode → HIGH (possible packet sniffing)\n\n### Unexpected Active Connections\n- Outbound connections to unknown external IPs → MEDIUM\n- Long-lived connections to suspicious IPs → HIGH\n\n### IP Forwarding\n- cat /proc/sys/net/ipv4/ip_forward\n- Enabled when not expected → MEDIUM\n\n### IPv6 Management\n- IPv6 enabled but not managed → MEDIUM advisory\n\n## Output Format\n```\n[HIGH] 08-network: unexpected_port | port: 8080 | process: python3 | bound: 0.0.0.0 | action: FW-XXX confirm\n[PASS] 08-network: expected_ports | all ports match profile\n```\n\nArchive v1.4.2: 41 files, 57991 bytes\n\nFiles: AGENT.md (7263b), AUDIT_LOG.md (56b), audit/modules/01-system.md (1500b), audit/modules/02-users.md (1781b), audit/modules/03-ssh.md (1646b), audit/modules/04-auth.md (1780b), audit/modules/05-services.md (1826b), audit/modules/06-packages.md (1304b), audit/modules/07-cve.md (10288b), audit/modules/08-network.md (1438b), audit/modules/09-firewall.md (1972b), audit/modules/10-filesystem.md (1958b), audit/modules/11-kernel.md (1882b), audit/modules/12-logs.md (1867b), audit/modules/13-crons.md (1225b), audit/modules/14-ssl.md (1473b), audit/modules/15-docker.md (2152b), audit/modules/16-disk.md (790b), audit/modules/17-integrity.md (1096b), audit/modules/18-rootkit.md (1549b), BASELINE.md (964b), core-extra/config/profile.md (516b), crons/active/nightly-audit.md (1696b), cve/cve-scan.sh (25326b), cve/external-sources.md (10102b), hooks/audit-runner.md (8419b), hooks/mail-sender.md (2068b), hooks/on-confirm-reply.md (1910b), hooks/on-critical.md (2054b), hooks/post-action.md (993b), hooks/pre-action.md (1636b), memory/schema.json (3449b), SERVER_PROFILE.md (2707b), skill-card.md (3255b), SKILL.md (14803b), SOUL.md (3208b), STATS.md (460b), templates/finding.md (902b), templates/firewall-change.md (739b), templates/pending-action.md (940b), _meta.json (142b)\n\nFile v1.4.2:SKILL.md\n\n---\nname: linux-security-guardian\ndescription: Autonomous multi-client Linux server security management via SSH MCP. Runs full audit at 1 AM IST nightly via cron. Iterates over all clients and their server fleets. Covers system hardening, CVE scanning (CISA KEV + OSV.dev + NVD API), user auditing, SSH config, firewall rules, running services, file permissions, log analysis, SSL certs, and kernel parameters. Non-breaking actions auto-applied. Critical patches and network/firewall changes require owner confirmation. Report sent per-server and per-client via email plugin/skill (not bundled). All owner-specific config lives in core-extra/config/ — no hardcoded names, domains, or emails.\nversion: 1.4.2\nmetadata: {\"openclaw\": {\"emoji\": \"🛡️\", \"requires\": {\"bins\": [\"bash\",\"python3\",\"ss\",\"iptables\",\"systemctl\",\"grep\",\"awk\",\"sed\",\"find\",\"curl\"], \"mcp\": [\"ssh_conn\",\"ssh_exec\"]}}}\n---\n\n# Linux Security Guardian\n\n## ⚡ SSH MCP — REQUIRED DEPENDENCY\n\n> **SSH MCP is a hard dependency. The agent MUST have SSH MCP tools available to operate.**\n> No local/legacy fallback. All operations go through SSH MCP.\n\n### Prerequisite\n\n```yaml\n# SSH MCP server must be running and accessible\ndependency: ssh_mcp\nstatus: required    # if unavailable → ABORT, alert owner\n```\n\n### Server Profile Config\n\nEach target server needs a saved connection in SSH MCP database. Configure in `SERVER_PROFILE.md`:\n\n```yaml\nssh_mcp:\n  connection_id: \"<id-name-or-alias-from-ssh-conn-list>\"   # Saved connection ID, Name, or Alias\n  # OR inline config:\n  # host: \"<server-ip>\"\n  # port: 22\n  # username: \"<user>\"\n  # key_path: \"</path/to/key>\"\n```\n\n### Audit Modules\n\nAll 18 modules execute commands via SSH MCP. Each module file lists commands that get wrapped with `ssh_exec(op=\"run\", sessionId, command)`:\n\n```\nmodule command → ssh_exec(op=\"run\", sessionId, command=\"module command\")\n              → ssh_exec(op=\"logs\", commandId=cmdId)\n              → parse output\n```\n\n### CVE Scan\n\nThe external CVE scan runs locally (on the guardian host) using curl to CISA KEV, OSV.dev, and NVD API.\nUsage requires `--client` and `--server` to write results to per-server paths:\n\n```bash\nbash cve/cve-scan.sh --client \"client-1\" --server \"server-01\"\n\n# Writes results to:\n#   cve/<client>/<server>/scan-results/YYYY-MM-DD.md\n#   cve/<client>/<server>/advisories/<CVE-ID>.md\n```\n\nSteps:\n```bash\n# 1. SSH MCP: ssh_exec(op=\"run\", sessionId, command=\"dpkg-query -W ...\") → save locally\n# 2. Read from cve/<client>/<server>/scan-results/installed-packages.txt\n# 3. curl CISA KEV → filter Linux entries → write advisories\n# 4. curl POST OSV.dev batch → match packages → write advisories\n# 5. curl NVD API (optional) → cross-check → write advisories\n```\n\n---\n\n## Core-Extra Config System\n\nAll owner-specific data lives in `core-extra/config/` — **never hardcoded** in hooks or modules.\n\n### Profile\n| File | Contains | Fields |\n|------|----------|--------|\n| `core-extra/config/profile.md` | Owner identity + domain + email | `Owner.name`, `Domain.primary`, `Email.noreply` |\n\n### How Agents Use It\n```\nAt session start → load core-extra/config/profile.md\n→ Owner.name  → used in SOUL.md [WORKSPACE OWNER]\n→ Email.noreply → used as from: in mail-sender.md\n→ Domain.primary → used in config generation\n\nTo change: edit core-extra/config/profile.md only.\n```\n\n### Rule\n- NO hardcoded names, domains, or emails in hooks/, modules/, or root files\n- All personal/owner data comes from `core-extra/config/profile.md`\n- The core-extra directory is part of the skill (published to ClawHub with placeholders)\n- Owner fills profile.md ONCE after install\n\n---\n\n## Multi-Client Architecture\n\nThe guardian manages **multiple clients**, each with their own server fleet.\nSERVER_PROFILE.md defines `## Client:` sections. The audit iterates ALL.\n\n```\nSERVER_PROFILE.md\n├── ## Client: client-1 (7 servers)\n│   ├── server-01\n│   ├── server-02\n│   └── ... server-07\n├── ## Client: client-2 (N servers) ← add as needed\n│   └── ...\n└── ## Client: [NEXT-CLIENT]\n```\n\nAll paths use `<client>/<server>/` prefix:\n- Findings: `audit/results/<client>/<server>/<severity>/`\n- Actions:  `actions/<client>/<server>/auto-done/`\n- CVEs:     `cve/<client>/<server>/advisories/`\n- Reports:  `reports/<client>/<server>/daily/`\n\n---\n\n## Purpose\n\nAgent manages complete Linux server security autonomously via SSH MCP.\nEvery night at 1 AM IST:\n- Iterates all clients → all servers\n- Full security audit runs via SSH MCP\n- CVEs scanned against installed packages\n- Auto-fixes applied for safe issues\n- Critical issues queued for owner confirmation\n- Per-server, per-client, and master email reports delivered\n\n---\n\n## Action Decision Matrix\n\nThe most important thing — what agent does vs what it asks first:\n\n| Finding Type | CVSS / Severity | Action |\n|---|---|---|\n| CVE — Critical | ≥ 9.0 | EMAIL ALERT immediately + queue for confirm |\n| CVE — High | 7.0–8.9 | Queue for confirm + include in report |\n| CVE — Medium | 4.0–6.9 | Include in report + advisory |\n| CVE — Low | < 4.0 | Info in report only |\n| CVE — KEV (CISA) | any | **Treated as CRITICAL** — immediate alert + confirm within due date |\n| CVE — KEV + Ransomware | any | **🔥 HIGHEST PRIORITY** — immediate alert, confirm ASAP |\n| Kernel update available | any | Confirm required before patch |\n| Security-only pkg update | any | Confirm required |\n| SSH: PermitRootLogin yes | critical | Alert + confirm to fix |\n| SSH: PasswordAuth yes | high | Alert + confirm to fix |\n| SSH: Port 22 | medium | Advisory only |\n| Empty password account | critical | AUTO-LOCK immediately |\n| Unknown root-uid account | critical | Alert + confirm to lock |\n| Inactive account > 90d | medium | Alert + confirm to lock |\n| World-writable /tmp | medium | AUTO-FIX chmod |\n| World-writable system dir | high | Alert + confirm to fix |\n| Unexpected SUID binary | high | Alert only (owner decides) |\n| Failed login spike > 20/hr | high | Alert immediately |\n| New unknown cron job | high | Alert immediately |\n| Firewall rule change needed | any | CONFIRM REQUIRED always |\n| Open unexpected port | high | Alert + confirm to close |\n| Service: unnecessary running | medium | Alert + confirm to stop |\n| SSL cert expiring < 30d | warning | Alert |\n| SSL cert expired | critical | Alert immediately |\n| Disk > 85% full | warning | Alert |\n| Disk > 95% full | critical | Alert immediately |\n| Auditd not running | high | AUTO-START + alert |\n| fail2ban not running | high | AUTO-START + alert |\n| Log file suspicious entry | high | Alert with extract |\n\n---\n\n## Audit Modules\n\n| Module | What it checks | SSH MCP Command |\n|--------|---------------|-----------------|\n| `01-system` | OS, kernel, uptime, last reboot, hardware | `ssh_exec(op=\"run\", sessionId, command=\"uname -a; cat /etc/*release\")` |\n| `02-users` | Accounts, root access, sudo, empty passwords, inactive | `ssh_exec(op=\"run\", sessionId, command=\"cat /etc/passwd; cat /etc/shadow; ...\")` |\n| `03-ssh` | sshd_config full audit — 20+ checks | `ssh_exec(op=\"run\", sessionId, command=\"cat /etc/ssh/sshd_config\")` |\n| `04-auth` | Login history, failed logins, PAM config | `ssh_exec(op=\"run\", sessionId, command=\"last; cat /var/log/auth.log\")` |\n| `05-services` | Running services, unnecessary ones, failed units | `ssh_exec(op=\"run\", sessionId, command=\"systemctl list-units ...\")` |\n| `06-packages` | Pending updates, security updates count | `ssh_exec(op=\"run\", sessionId, command=\"apt list --upgradable 2>/dev/null\")` |\n| `07-cve` | CVE scan — remote via SSH MCP + API-based | `ssh_exec(op=\"run\", sessionId, command=\"dpkg-query -W ...; curl ...\")` |\n| `08-network` | Open ports, listening services, active connections | `ssh_exec(op=\"run\", sessionId, command=\"ss -tulpn; netstat -tulpn\")` |\n| `09-firewall` | iptables/nftables/ufw rules audit | `ssh_exec(op=\"run\", sessionId, command=\"iptables-save 2>/dev/null\")` |\n| `10-filesystem` | SUID/SGID, world-writable, /tmp, sticky bits | `ssh_exec(op=\"run\", sessionId, command=\"find / -perm -4000 ...\")` |\n| `11-kernel` | sysctl security params — 15+ checks | `ssh_exec(op=\"run\", sessionId, command=\"sysctl -a 2>/dev/null\")` |\n| `12-logs` | auth.log, syslog, kern.log — anomaly scan | `ssh_exec(op=\"run\", sessionId, command=\"tail -100 /var/log/syslog\")` |\n| `13-crons` | System + user cron jobs — unknown jobs flagged | `ssh_exec(op=\"run\", sessionId, command=\"cat /etc/crontab; ls -la /var/spool/cron/\")` |\n| `14-ssl` | Cert expiry check for all domains/services | `ssh_exec(op=\"run\", sessionId, command=\"openssl x509 -in ... -noout -dates\")` |\n| `15-docker` | If running — image vulns, container config | `ssh_exec(op=\"run\", sessionId, command=\"docker ps; docker images\")` |\n| `16-disk` | Disk usage, inode usage | `ssh_exec(op=\"run\", sessionId, command=\"df -h; df -i\")` |\n| `17-integrity` | AIDE/tripwire check if installed | `ssh_exec(op=\"run\", sessionId, command=\"aide --check\")` |\n| `18-rootkit` | rkhunter/chkrootkit if installed | `ssh_exec(op=\"run\", sessionId, command=\"rkhunter --check --skip-keypress\")` |\n\n**Execution rule**: All commands go through `ssh_exec(op=\"run\", sessionId, command=\"<command>\")` → `ssh_exec(op=\"logs\", commandId=cmdId)`. No local execution.\n\n---\n\n## Finding Severity Levels\n\n| Level | Color | Meaning |\n|---|---|---|\n| `CRITICAL` | 🔴 | Immediate risk, action required now |\n| `HIGH` | 🟠 | Significant risk, fix this week |\n| `MEDIUM` | 🟡 | Moderate risk, fix this month |\n| `LOW` | 🔵 | Minor issue, fix when possible |\n| `INFO` | ⚪ | Informational, no action needed |\n| `PASS` | 🟢 | Check passed, all good |\n\n---\n\n## Confirmation Flow\n\nWhen owner confirmation is needed:\n\n```\nFinding detected (requires confirm) on <client>/<server>\n    ↓\nWrite to actions/<client>/<server>/pending-confirm/<client>-<server>-<id>-<slug>.md\n    ↓\nInclude in email report under \"NEEDS YOUR DECISION\" with <client>/<server> context\n    ↓\nOwner replies with: APPROVE <id> / DENY <id> / SKIP <id>\n(Full ID format: <client>-<server>-<type>-<NNN>, e.g. client-1-server-01-ACT-20260529-001)\n    ↓\nSearch all actions/*/*/pending-confirm/ for the ID\n    ↓\nAPPROVE → agent connects to <client>/<server> via SSH MCP → executes action → logs to history/\nDENY    → action skipped, noted\nSKIP    → deferred to next audit\n```\n\n---\n\n## Email Report Structure\n\nReports are sent per-server, per-client (summary), and master. All via email plugin/skill.\n\n### Per-Server Report\n```\nSubject: [Linux Guardian] <client>/<server> — YYYY-MM-DD | Score: N/100 | CRITICAL:N HIGH:N\n\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\nLINUX SECURITY GUARDIAN — NIGHTLY REPORT\nClient: <client> | Server: <server> | <IP> | YYYY-MM-DD 01:00 IST\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\nEXECUTIVE SUMMARY\nSecurity Score: N/100 | Grade: X\nCritical: N | High: N | Medium: N | Low: N\nAuto-fixed: N | Pending confirm: N | Passed: N\n\n━━ 🔴 CRITICAL (immediate action needed)\n[Finding details]\n\n━━ 🟠 HIGH\n[Finding details]\n\n━━ ⚡ AUTO-ACTIONS TAKEN (safe, non-breaking)\n[What was auto-fixed]\n\n━━ 🔑 NEEDS YOUR DECISION (reply APPROVE/DENY/SKIP <id>)\n[Pending confirmations with IDs — includes <client>/<server> prefix]\n\n━━ 📦 CVE REPORT\n[CVEs found by severity]\n\n━━ 🌐 NETWORK & FIREWALL\n[Port/firewall status]\n\n━━ 🟡 MEDIUM / LOW\n[Less urgent findings]\n\n━━ 🟢 ALL PASSING\n[Checks that passed]\n\n━━ NEXT AUDIT: Tomorrow 01:00 IST\n```\n\n### Per-Client Summary Report\n```\nSubject: [Linux Guardian] <client> Summary — YYYY-MM-DD | Servers: N/N | CRITICAL:N HIGH:N\n\nClient: <client>\nServers audited: N of N total\nAverage score: N/100\n\n| Server | Score | Critical | High | Score Grade |\n|--------|-------|----------|------|-------------|\n| ...    | ...   | ...      | ...  | ...         |\n\nCross-server patterns: [same vuln found on multiple servers]\n```\n\n\n---\n\n## Security Score Formula\n\n```\nscore = 100\nscore -= (critical_count × 20)\nscore -= (high_count × 10)\nscore -= (medium_count × 3)\nscore -= (low_count × 1)\nscore = max(0, score)\n\nGrade: 90-100 = A | 75-89 = B | 60-74 = C | < 60 = F\n```\n\n---\n\n## Folder Structure\n\n```\nlinux-security-guardian/\n  audit/\n    modules/                     ← 01-system.md ... 18-rootkit.md\n    results/\n      <client>/<server>/\n        critical/  high/  warning/  info/  pass/\n          YYYY-MM-DD-<check>.md  ← per-client/per-server findings\n\n  actions/\n    <client>/<server>/\n      auto-done/                 ← auto-fixed actions (logged)\n        YYYY-MM-DD-<slug>.md\n      pending-confirm/           ← waiting for owner\n        <id>-<slug>.md\n      history/                   ← all approved/denied actions\n\n  cve/\n    cve-scan.sh                  ← external CVE scanner (takes --client --server)\n    external-sources.md          ← all API URLs, query params, working examples\n    .cache/                      ← shared cached API responses (6h TTL)\n    <client>/<server>/\n      scan-results/              ← YYYY-MM-DD.md\n      advisories/                ← <cve-id>.md\n\n  reports/\n    <client>/<server>/\n      daily/YYYY-MM-DD.md\n      weekly/YYYY-WNN.md\n\n  network/\n    <client>/<server>/\n      firewall-snapshots/        ← YYYY-MM-DD-rules.txt\n      port-scans/                ← YYYY-MM-DD.md\n      proposed-changes/          ← <id>-<change>.md\n\n  hooks/\n    audit-runner.md              ← main 1 AM audit orchestrator (multi-client loop)\n    on-critical.md               ← fires on any critical finding (with client/server)\n    on-confirm-reply.md          ← processes owner APPROVE/DENY/SKIP\n    pre-action.md                ← safety check before any action\n    post-action.md               ← verify action succeeded\n    mail-sender.md               ← uses email plugin/skill to send report\n\n  crons/\n    active/\n      nightly-audit.md           ← 1 AM IST permanent\n    completed/\n\n  core-extra/\n    config/\n      profile.md                 ← owner name, domain, email (fill ONCE, no hardcode)\n    hooks/                       ← shared hooks (mirrors hooks/ structure)\n    templates/                   ← shared templates\n\n  errors/\n    raw/                         ← raw error logs\n\n  memory/\n    schema.json\n    index.json\n\n  SOUL.md                        ← soul context (multi-client aware)\n  AGENT.md                       ← behavioral rules (multi-client, SSH MCP hard dep)\n  SERVER_PROFILE.md               ← multi-client server details\n  AUDIT_LOG.md                    ← append-only master log\n  BASELINE.md                     ← expected state snapshot\n  STATS.md\n```\n\nFile v1.4.2:_meta.json\n\n{\n  \"ownerId\": \"kn79djxt41q03wtr3nth5h8y8184mgcm\",\n  \"slug\": \"linux-security-guardian\",\n  \"version\": \"1.4.2\",\n  \"publishedAt\": 1781760045562\n}\n\nFile v1.4.2:AGENT.md\n\n---\nname: linux-security-guardian-agent\ndescription: Behavioral rules for linux-security-guardian. Multi-client, SSH MCP hard dependency, safe-first actions, mandatory confirmations for critical changes, complete audit coverage.\n---\n\n# Agent Rules — Linux Security Guardian\n\n## THE PRIME RULE — SAFE FIRST\n\nWhen in doubt about whether an action is safe: DON'T DO IT.\nLog it. Alert owner. Wait for explicit approval.\nA delayed fix is always better than an accidental outage.\n\n---\n\n## Rule 1 — SSH MCP Hard Dependency\n\nSSH MCP is a hard dependency. The agent MUST have SSH MCP tools available to operate.\n\n```yaml\nrequired_tools: [ssh_conn, ssh_exec]\nversion: v2  # 13 tools: ssh_conn, ssh_exec, ssh_bulk_exec, ssh_bulk_audit, ssh_client, etc.\n```\n\nIf SSH MCP tools are unavailable → ABORT audit, alert owner: \"SSH MCP not available\".\nNo local/legacy fallback. All operations go through SSH MCP.\n\n---\n\n## Rule 2 — Multi-Client Audit Flow\n\nSERVER_PROFILE.md contains one or more `## Client:` sections.\nThe audit MUST iterate over ALL clients and ALL servers:\n\n```\nfor each client in SERVER_PROFILE.md:\n  for each server in client.server_fleet:\n    ssh_conn → test/save connection if needed\n    ssh_exec(op=\"open\", connectionId) → sessionId\n    Run all 18 modules via ssh_exec(op=\"run\", sessionId, ...)\n    Compile per-server findings → audit/results/<client>/<server>/<severity>/\n    Compile per-server report → reports/<client>/<server>/daily/YYYY-MM-DD.md\n    ssh_exec(op=\"close\", sessionId)\n  Compile per-client summary\nAppend master report\nSend via default email account\n```\n\n---\n\n## Rule 3 — Email Account Selection\n\n- **Default account**: Used for ALL outgoing reports and alerts.\n- **Admin account**: Personal account. NEVER use for automated reports.\n- Rule: Always use default account. Never specify `--account admin`.\n- Check available accounts: `himalaya account list` (identify default vs admin).\n- If no email plugin available → log to AUDIT_LOG.md, report is on disk. Non-fatal.\n\n---\n\n## Rule 4 — Read SERVER_PROFILE.md Before Every Audit\n\nLoad SERVER_PROFILE.md at audit start.\nParse each `## Client:` section. Extract server fleet table.\nExpected ports, services, users, SUID list — all per-server from this file.\nDeviation from profile = finding.\nProfile not filled = abort audit, alert owner.\n\n---\n\n## Rule 5 — Auto-Actions Whitelist Only\n\nAgent can ONLY auto-execute actions listed in SERVER_PROFILE.md under `Auto-Actions Allowed`.\nAnything not explicitly whitelisted → queue for confirmation.\nNo exceptions. Owner preference > agent judgment.\n\nAuto-action execution:\n1. Run pre-action safety check (hooks/pre-action.md)\n2. Execute action via SSH MCP\n3. Verify result (hooks/post-action.md)\n4. Log to actions/<client>/<server>/auto-done/\n5. Include in email report\n\n---\n\n## Rule 6 — Confirmation Queue Protocol\n\nWhen action requires confirmation:\n1. Generate unique ID: `ACT-YYYYMMDD-NNN`\n2. Write to actions/<client>/<server>/pending-confirm/<id>-<slug>.md\n3. Include in email report under \"NEEDS YOUR DECISION\"\n4. Wait. Do not execute until owner says APPROVE.\n5. Confirmation expires after 7 days → re-queue next audit\n\n---\n\n## Rule 7 — Critical Finding = Immediate Alert\n\nAny CRITICAL finding triggers hooks/on-critical.md immediately.\nDo not wait for report compilation.\nSend alert via default email account NOW.\nContinue audit in parallel.\n\nCritical findings:\n- CVSS ≥ 9.0 CVE\n- KEV entry (any CVSS — treated as CRITICAL)\n- KEV + Ransomware (🔥 highest priority)\n- Empty password account found\n- Unknown UID 0 account\n- Root login via SSH successful (from logs)\n- SSL cert expired\n- Disk > 95%\n- Rootkit detected\n- Unexpected kernel module loaded\n- /etc/passwd or /etc/shadow modified unexpectedly\n\n---\n\n## Rule 8 — Firewall Rules — Always Confirm\n\nFirewall is ALWAYS confirm-required. No exceptions.\nEven \"obviously safe\" rules need owner approval.\nFormat for proposed change:\n\n```\nID: FW-YYYYMMDD-NNN\nClient: <client>\nServer: <server>\nCurrent rule: [exact current state]\nProposed change: [exact proposed command]\nReason: [why this change is needed]\nRisk: [what could break if wrong]\nRollback: [exact command to undo]\n```\n\nAgent writes this to network/<client>/<server>/proposed-changes/ and includes in report.\nAgent NEVER runs iptables/nftables/ufw commands without explicit APPROVE.\n\n---\n\n## Rule 9 — CVE Scan — Complete Coverage\n\nCVE scan must cover ALL installed packages per server.\nDetect package manager automatically (apt/yum/dnf/pacman).\nUse best available tool per OS via SSH MCP.\n\nCVE results saved to cve/<client>/<server>/scan-results/YYYY-MM-DD.md.\nAny CVSS ≥ 7.0 or KEV entry → also save individual advisory to cve/<client>/<server>/advisories/<CVE-ID>.md.\n\nExternal sources (CISA KEV, OSV.dev, NVD API) queried via ssh_exec from remote server.\nSource override flags: KEV → CRITICAL, RANSOMWARE → 🔥 immediate alert, OSV_MATCH → per CVSS, NVD_CORROBORATED → +1 severity.\n\n---\n\n## Rule 10 — Snapshot Before Any Action\n\nBefore any auto-action or approved action that modifies config:\n1. Snapshot current state of the relevant file/config\n2. Save to actions/<client>/<server>/history/<id>-BEFORE.txt\n3. Execute action\n4. Save new state to actions/<client>/<server>/history/<id>-AFTER.txt\n5. Save rollback command to actions/<client>/<server>/history/<id>-ROLLBACK.sh\n\n---\n\n## Rule 11 — Audit Must Be Complete\n\nAll 18 modules must run per server.\nIf a module fails (command not found, permission error):\nLog failure: `[MODULE FAILED] <client>/<server> 07-cve: ...`\nNever silently skip a module.\nReport module failures in email.\nContinue to next server. Do not abort entire audit on single server failure.\n\n---\n\n## Rule 12 — Audit Log is Append-Only\n\nEvery audit run appended to AUDIT_LOG.md:\n```\nYYYY-MM-DD 01:00 IST | audit_start | clients:N | servers:N\nYYYY-MM-DD 01:XX IST | audit_complete | clients:N | servers_total:N | critical:N high:N | score:N/100\n```\nNever edit, never delete.\n\n---\n\n## Rule 13 — New Client Onboarding\n\nWhen adding a new client:\n1. Add `## Client: <name>` section to SERVER_PROFILE.md\n2. Fill server fleet table (host, port, username, key_path)\n3. Save connections via SSH MCP: `ssh_conn(op=\"save\", name, host, port, username, key_path)`\n4. Verify each server reachable: `ssh_conn(op=\"test\", ...)`\n5. Create per-client directories: `audit/results/<client>/<server>/`, `actions/`, `cve/`, `network/`, `reports/`\n6. Set notification email for the client\n7. Run first audit to establish baseline\n8. Verify report delivery reaches client's notification email\n\n---\n\n## Rule 14 — Baseline Management\n\nFirst run per server: create baseline in `audit/results/<client>/<server>/baseline/`.\nSubsequent runs: compare against baseline.\nDeviations from baseline = findings (even if not a security issue).\n\nBaseline updated only when:\n- Owner explicitly says \"update baseline\"\n- After an approved action changes system state\n\n---\n\n## Rule 15 — Session Start Check\n\nAt session start (if during day):\n- Any pending-confirm actions across any client/server? → surface: \"N actions await your approval\"\n- Any CRITICAL findings from last audit? → surface immediately with client/server context\n- Any CVE CRITICAL from last scan? → surface\n\nFile v1.4.2:AUDIT_LOG.md\n\n# Audit Log\n*Append-only. One entry per audit run.*\n---\n\nFile v1.4.2:audit/modules/01-system.md\n\n# Module 01 — System Info\n\n## Commands\n```bash\nuname -r                           # kernel version\nuname -a                           # full kernel info\nlsb_release -a 2>/dev/null        # OS info\ncat /etc/os-release                # OS info fallback\nuptime -p                          # uptime\nlast reboot | head -5              # reboot history\ndf -h                              # disk usage\nfree -h                            # memory\nnproc                              # CPU count\ncat /proc/cpuinfo | grep \"model name\" | head -1\ntimedatectl                        # NTP sync status\n```\n\n## Checks & Findings\n\n### OS EOL Check\n- Ubuntu 20.04 LTS → EOL April 2025 → if still running: HIGH finding\n- Ubuntu 22.04 LTS → EOL April 2027 → OK\n- Ubuntu 24.04 LTS → EOL April 2029 → OK\n- Debian 11 → EOL June 2026 → OK\n- Debian 10 → EOL June 2024 → HIGH if still running\n\n### Kernel Version Check\n- Compare against latest stable for the distro\n- More than 2 major versions behind → HIGH\n- Security patch available → MEDIUM\n\n### NTP Sync\n- timedatectl | grep \"NTP service: active\" → PASS\n- NTP not synced → MEDIUM (time drift breaks certs/logs)\n\n### Disk Usage\n- < 80% → PASS\n- 80-85% → LOW\n- 85-95% → WARNING\n- > 95% → CRITICAL (auto-alert)\n\n### Last Reboot\n- No reboot in > 90 days with kernel updates pending → MEDIUM\n- Server rebooted unexpectedly (not matching known maintenance) → HIGH\n\n## Output Format\n```\n[PASS/FINDING] 01-system: <check> | <result>\n```\n\nFile v1.4.2:audit/modules/02-users.md\n\n# Module 02 — User Accounts\n\n## Commands\n```bash\n# All users with login shell\ngrep -v \"nologin\\|false\\|sync\\|halt\\|shutdown\" /etc/passwd | cut -d: -f1,3,6,7\n\n# UID 0 accounts (should only be root)\nawk -F: '($3 == 0) { print $1 }' /etc/passwd\n\n# Sudo users\ngetent group sudo 2>/dev/null || getent group wheel 2>/dev/null\ncat /etc/sudoers | grep -v \"^#\" | grep -v \"^$\"\nls /etc/sudoers.d/\n\n# Empty passwords (CRITICAL)\nawk -F: '($2 == \"\" || $2 == \"!!\" ) { print $1 }' /etc/shadow 2>/dev/null\n\n# Password age\nawk -F: '{print $1, $5}' /etc/shadow 2>/dev/null | grep \"^[^:]*:[0-9]\"\n\n# Last login for all users\nlastlog | grep -v \"Never\\|Username\"\n\n# Users logged in right now\nwho\nw\n\n# Recently created accounts (last 30 days)\nfind /home -maxdepth 1 -type d -newer /tmp -mtime -30 2>/dev/null\n```\n\n## Checks & Findings\n\n### UID 0 Accounts\n- Only 'root' should have UID 0\n- Any other UID 0 account → CRITICAL immediate alert\n\n### Unknown Sudo Users\n- Compare against SERVER_PROFILE.md expected sudo users\n- Unknown sudo user → CRITICAL\n\n### Empty Passwords\n- Any account with empty password → CRITICAL\n- AUTO-ACTION if whitelisted: `passwd -l <username>`\n\n### Inactive Accounts (> 90 days no login)\n- Check lastlog, find accounts with login > 90 days ago\n- Still active login shell → MEDIUM\n- Queue confirm to lock: `usermod -L <username>`\n\n### Password Policy\n- Check /etc/login.defs for PASS_MAX_DAYS, PASS_MIN_DAYS\n- PASS_MAX_DAYS > 90 → LOW\n- No password expiry → MEDIUM\n\n### Root Account Direct Login\n- Check if anyone logged in as root via SSH recently\n- grep \"Accepted.*root\" /var/log/auth.log → HIGH if found\n\n## Output Format\n```\n[CRITICAL] 02-users: empty_password | account: <name> | action: auto-lock-queued\n[PASS] 02-users: uid0_check | only root has uid 0\n```\n\nFile v1.4.2:audit/modules/03-ssh.md\n\n# Module 03 — SSH Configuration\n\n## Commands\n```bash\nsshd -T 2>/dev/null          # full effective SSH config (best method)\ncat /etc/ssh/sshd_config     # raw config file\ngrep -v \"^#\\|^$\" /etc/ssh/sshd_config\n```\n\n## Checks — 20+ SSH Security Parameters\n\n| Parameter | Secure Value | Finding if Wrong |\n|---|---|---|\n| PermitRootLogin | no | HIGH → confirm to set no |\n| PasswordAuthentication | no | HIGH → confirm to set no |\n| PubkeyAuthentication | yes | HIGH |\n| PermitEmptyPasswords | no | CRITICAL → auto-fix |\n| X11Forwarding | no | MEDIUM |\n| MaxAuthTries | ≤ 4 | MEDIUM |\n| LoginGraceTime | ≤ 60 | LOW |\n| AllowAgentForwarding | no | LOW |\n| AllowTcpForwarding | no | MEDIUM |\n| ClientAliveInterval | 300 | LOW |\n| ClientAliveCountMax | 2 | LOW |\n| Protocol | 2 (implicit modern) | CRITICAL if 1 |\n| Port | not 22 | INFO (advisory) |\n| UsePAM | yes | MEDIUM if no |\n| IgnoreRhosts | yes | HIGH if no |\n| HostbasedAuthentication | no | HIGH |\n| PermitUserEnvironment | no | MEDIUM |\n| StrictModes | yes | HIGH if no |\n| MaxSessions | ≤ 4 | LOW |\n| Banner | set | INFO |\n| LogLevel | VERBOSE or INFO | MEDIUM if silent |\n| AllowUsers/AllowGroups | set | INFO (advisory) |\n\n## Auto-Fix Eligible (from whitelist only)\n- PermitEmptyPasswords no → AUTO-FIX (sed in place)\n\n## Confirm Required\n- PermitRootLogin no → confirm (could lock out if no key auth)\n- PasswordAuthentication no → confirm (MUST have key auth working first)\n- All others → queue confirm\n\n## Output Format\n```\n[HIGH] 03-ssh: PermitRootLogin | value: yes | expected: no | action_id: ACT-YYYYMMDD-001\n[PASS] 03-ssh: MaxAuthTries | value: 3 ≤ 4\n```\n\nFile v1.4.2:audit/modules/04-auth.md\n\n# Module 04 — Authentication & Login Audit\n\n## Commands\n```bash\n# Failed login attempts\ngrep \"Failed password\" /var/log/auth.log | tail -100\ngrep \"Failed password\" /var/log/auth.log | awk '{print $11}' | sort | uniq -c | sort -rn | head -20  # top source IPs\n\n# Successful logins\ngrep \"Accepted\" /var/log/auth.log | tail -50\n\n# Sudo usage\ngrep \"sudo:\" /var/log/auth.log | tail -50\n\n# Failed sudo\ngrep \"sudo:.*NOT in sudoers\" /var/log/auth.log\n\n# Login from unexpected locations\nlast | head -30\n\n# Brute force threshold check\nFAILED=$(grep \"Failed password\" /var/log/auth.log | grep \"$(date '+%b %e')\" | wc -l)\necho \"Failed logins today: $FAILED\"\n\n# PAM configuration\ncat /etc/pam.d/sshd | grep -v \"^#\"\ncat /etc/pam.d/login | grep -v \"^#\"\n\n# fail2ban status\nsystemctl is-active fail2ban 2>/dev/null\nfail2ban-client status sshd 2>/dev/null\n```\n\n## Checks & Findings\n\n### Failed Login Spike\n- > 20 failed logins in last hour → HIGH alert\n- > 100 failed logins in last hour → CRITICAL alert\n- Single IP with > 10 failures → HIGH (may not be in fail2ban)\n\n### Successful Root SSH Login\n- Any \"Accepted.*root\" in auth.log → HIGH (if PermitRootLogin is yes)\n\n### Unauthorized Sudo Usage\n- \"NOT in sudoers\" entries → HIGH\n\n### fail2ban Status\n- Not running → HIGH → AUTO-START (if whitelisted)\n- Not configured for SSH → MEDIUM\n\n### PAM Configuration\n- pam_tally2 or pam_faillock not configured → MEDIUM\n- No account lockout policy → MEDIUM\n\n### Login from Unknown IPs\n- Compare login IPs against SERVER_PROFILE.md management IPs\n- Unknown IP logged in successfully → HIGH\n\n## Output Format\n```\n[HIGH] 04-auth: brute_force | failed_logins_1hr: 47 | top_source: 1.2.3.4 (23 attempts)\n[HIGH] 04-auth: fail2ban_down | status: inactive | action: auto-start queued\n```\n\nFile v1.4.2:audit/modules/05-services.md\n\n# Module 05 — Services Audit\n\n## Commands\n```bash\n# All running services\nsystemctl list-units --type=service --state=running --no-pager\n\n# Failed services\nsystemctl list-units --type=service --state=failed --no-pager\n\n# Services enabled at boot\nsystemctl list-unit-files --type=service --state=enabled --no-pager\n\n# Listening processes\nss -tulpn\n# or: netstat -tulpn\n\n# Processes listening on all interfaces (0.0.0.0 or :::)\nss -tulpn | grep -E \"0\\.0\\.0\\.0|:::\"\n\n# Check for suspicious processes\nps aux --sort=-%cpu | head -20\nps aux | awk '{if ($3 > 50.0) print $0}'  # high CPU\n\n# Docker if running\ndocker ps 2>/dev/null\ndocker ps -a 2>/dev/null\n```\n\n## Checks & Findings\n\n### Unknown Running Services\n- Compare against SERVER_PROFILE.md expected services\n- Any unlisted service running → MEDIUM (queue confirm to investigate/stop)\n\n### Failed Services\n- Any failed service → HIGH (could indicate attack or config issue)\n- Check if service was recently working: journalctl -u <service> --since \"1 hour ago\"\n\n### Services Listening on All Interfaces\n- Services bound to 0.0.0.0 that should be internal only → HIGH\n- Cross-check with expected open ports in SERVER_PROFILE.md\n\n### Unnecessary Services Running\nCommon unnecessary services to flag:\n- telnet → CRITICAL (plaintext)\n- rsh, rlogin, rexec → CRITICAL\n- finger → MEDIUM\n- rpcbind (if not NFS server) → LOW\n- avahi-daemon (if not needed) → LOW\n- cups (if not print server) → LOW\n\n### Auditd Status\n- Not running → HIGH → AUTO-START (if whitelisted)\n- systemctl enable auditd + systemctl start auditd\n\n## Output Format\n```\n[CRITICAL] 05-services: telnet_running | service: telnet | action: confirm-to-stop ACT-XXX\n[HIGH] 05-services: auditd_down | action: auto-starting\n[PASS] 05-services: expected_services | all 5 expected services running\n```\n\nFile v1.4.2:audit/modules/06-packages.md\n\n# Module 06 — Package Updates\n\n## Commands\n\n### Debian/Ubuntu\n```bash\napt update -qq 2>/dev/null\n\n# Total pending updates\napt list --upgradable 2>/dev/null | grep -v \"Listing...\" | wc -l\n\n# Security updates specifically\napt list --upgradable 2>/dev/null | grep -i security | wc -l\n\n# List security updates\napt-get --just-print upgrade 2>/dev/null | grep \"^Inst\" | grep -i security\n\n# Held packages\napt-mark showhold\n```\n\n### RHEL/CentOS/Rocky\n```bash\nyum check-update --security -q 2>/dev/null\nyum updateinfo list security 2>/dev/null | tail -20\ndnf check-update --security 2>/dev/null\n```\n\n## Checks & Findings\n\n### Pending Security Updates\n- 0 security updates → PASS\n- 1-5 security updates → MEDIUM\n- > 5 security updates → HIGH\n- Any kernel security update → HIGH + confirm required\n\n### Total Update Lag\n- 0-10 packages behind → LOW\n- 10-50 packages behind → MEDIUM\n- > 50 packages behind → HIGH (neglected system)\n\n### Held Packages\n- Any held package with known CVE → HIGH\n\n### Auto-Update Config\n- Check if unattended-upgrades is configured\n- Not configured → MEDIUM advisory\n\n## Output Format\n```\n[HIGH] 06-packages: security_updates_pending | count: 12 | kernel_update: yes | action_id: ACT-XXX\n[MEDIUM] 06-packages: no_auto_updates | unattended-upgrades not configured\n```\n\nFile v1.4.2:audit/modules/07-cve.md\n\n# Module 07 — CVE Scan\n\n## Detection Strategy (tries in order)\n\n### EXECUTION NOTE\nAll commands run via `ssh_exec(op=\"run\", sessionId, command=\"<command>\")` on the remote server. Output retrieved via `ssh_exec(op=\"logs\", commandId=cmdId)`. API calls (CISA KEV, OSV.dev, NVD) execute via `ssh_exec` on the remote server using `curl`. No local command execution.\n\n### LOCAL METHODS (local tools, no network needed)\n\n```bash\n# Method 1: debsecan (Debian/Ubuntu — most accurate)\nwhich debsecan >/dev/null 2>&1 && debsecan --suite $(lsb_release -cs) --only-fixed --format=detail\n\n# Method 2: Ubuntu CVEScan\nwhich cvescan >/dev/null 2>&1 && cvescan\n\n# Method 3: apt security info (fallback)\napt-get --just-print upgrade 2>/dev/null | grep \"^Inst\" | grep -i \"security\\|CVE\"\n\n# Method 4: RHEL/CentOS yum security\nwhich yum >/dev/null 2>&1 && yum updateinfo list security 2>/dev/null\n\n# Method 5: Installed package list (for external source cross-ref)\ndpkg-query -W -f='${Package}\\t${Version}\\n' 2>/dev/null\n# Or: rpm -qa --queryformat '%{NAME}\\t%{VERSION}\\n' 2>/dev/null\n```\n\n### EXTERNAL METHODS (requires internet — enrich local findings)\n\n```bash\n# ═══════════════════════════════════════════════════════════════\n# METHOD 6: CISA KEV Catalog [CURL] ✅\n# ═══════════════════════════════════════════════════════════════\n# URL: https://www.cisa.gov/sites/default/files/feeds/known_exploited_vulnerabilities.json\n# No API key needed. No rate limits. Always works with curl.\n# Cross-ref against installed packages. KEV match → auto-CRITICAL.\n#\n# curl -s \"https://www.cisa.gov/sites/default/files/feeds/known_exploited_vulnerabilities.json\" \\\n#   | jq '[.vulnerabilities[] | select(.vendorProject == \"Linux\")]'\n\n# ═══════════════════════════════════════════════════════════════\n# METHOD 7: OSV.dev — open source vuln DB [CURL] ✅\n# ═══════════════════════════════════════════════════════════════\n# POST https://api.osv.dev/v1/query (single)\n# POST https://api.osv.dev/v1/querybatch (batch — up to 1000)\n# No API key. No rate limits. Always works with curl.\n# Best method: matches by package + ecosystem + version.\n#\n# curl -s -X POST \"https://api.osv.dev/v1/querybatch\" \\\n#   -H \"Content-Type: application/json\" \\\n#   -d '{\"queries\":[\n#     {\"package\":{\"name\":\"openssl\",\"ecosystem\":\"Debian\"},\"version\":\"3.0.2\"},\n#     {\"package\":{\"name\":\"nginx\",\"ecosystem\":\"Debian\"},\"version\":\"1.22.0\"}\n#   ]}'\n\n# ═══════════════════════════════════════════════════════════════\n# METHOD 8: NVD API 2.0 [CURL] ⚠️ rate limited\n# ═══════════════════════════════════════════════════════════════\n# URL: https://services.nvd.nist.gov/rest/json/cves/2.0\n# Rate limit: 5 req/30s (no key), 50 req/30s (with key)\n# API key (free): https://nvd.nist.gov/developers/request-an-api-key [BROWSER]\n# ⚠️ API endpoint works with curl. Web portal (nvd.nist.gov) is CLOUDFLARE BLOCKED.\n#\n# Without key (sleep 6s between calls):\n#   curl -s \"https://services.nvd.nist.gov/rest/json/cves/2.0?keywordSearch=linux&resultsPerPage=5\"\n# With key:\n#   curl -s -H \"apiKey:NVD_API_KEY\" \"https://services.nvd.nist.gov/rest/json/cves/2.0?cveId=CVE-2024-1086\"\n#\n# ⚠️ Skip if blocked: if curl returns Cloudflare \"Attention Required\" → SKIP immediately\n#    Do NOT retry. OSV.dev and CISA KEV already cover what NVD would tell you.\n\n# ═══════════════════════════════════════════════════════════════\n# METHOD 9: Web portal URLs [BROWSER] ❌ Cloudflare blocks curl\n# ═══════════════════════════════════════════════════════════════\n# Only use with browser tool. DO NOT use curl on these URLs.\n#\n# CISA KEV (Linux filter):\n#   https://www.cisa.gov/known-exploited-vulnerabilities-catalog?f%5B0%5D=vendor_project%3ALinux\n#\n# NVD Search — Linux:\n#   https://nvd.nist.gov/vuln/search/results?query=linux&search_type=all&queryType=phrase\n#\n# NVD Search — Critical Linux:\n#   https://nvd.nist.gov/vuln/search/results?query=linux&cvssSeverity=CRITICAL&queryType=phrase\n#\n# OSV.dev — Linux kernel:\n#   https://osv.dev/list?ecosystem=Linux\n```\n\n### Skip Logic (— every method runs independently)\n\n```\nEACH external method follows this rule:\n\n1. curl --max-time 15 --connect-timeout 10 $URL\n2. if curl exit code != 0:\n     → Log \"[SKIP] $SOURCE unavailable (network)\"\n     → Move to next source. Not fatal.\n3. if response contains \"Attention Required\" OR \"Cloudflare\" OR \"cf-wrapper\":\n     → Log \"[SKIP] $SOURCE blocked by Cloudflare — use browser tool only\"\n     → Skip permanently this session. Don't retry. Ever.\n4. if HTTP 429 (rate limit):\n     → Sleep 6s, retry once\n     → Still 429? Log \"[SKIP] $SOURCE rate limited — too many requests\"\n     → Skip.\n5. Success → parse results, write advisories, continue next method.\n\nNEVER let one blocked/failed source fail the entire scan.\nEach source is independent.\n```\n\n### URL Working Status Quick Reference\n\n| URL | curl | Browser | Notes |\n|-----|------|---------|-------|\n| `cisa.gov/.../known_exploited_vulnerabilities.json` | ✅ Works | ✅ Works | No key needed |\n| `services.nvd.nist.gov/rest/json/cves/2.0` | ✅ Works | ❌ API only | Rate limited |\n| `nvd.nist.gov/vuln/search` | ❌ **Cloudflare** | ✅ Works | Do NOT use curl |\n| `nvd.nist.gov/vuln/detail/CVE-XXXX` | ❌ **Cloudflare** | ✅ Works | Do NOT use curl |\n| `api.osv.dev/v1/querybatch` | ✅ Works | ❌ API only | No key needed |\n| `osv.dev/list` | ✅ Works | ✅ Works | Web UI |\n\n### Priority Chain\n\n```\n1. cve/cve-scan.sh (external: CISA KEV + OSV.dev batch + NVD API)\n   → Run first if internet available via: cve/cve-scan.sh --client <name> --server <name>\n   → Each source independent — if one fails, others still run\n   → Writes to cve/<client>/<server>/scan-results/YYYY-MM-DD.md\n   → Advisories to cve/<client>/<server>/advisories/<CVE-ID>.md\n   → Matches against installed packages from dpkg-query\n\n2. Local methods 1-5 (debsecan / cvescan / apt / yum)\n   → Always run as baseline (no network dependency)\n   → Catch what external methods miss\n\n3. Web portal URLs [BROWSER]\n   → Agent opens in browser for manual verification\n   → Use when API calls are blocked or for deep investigation\n   → NVD portal blocked by Cloudflare — only works in browser\n```\n\n## CVE Severity Classification (CVSS v3)\n\n| CVSS Score | Severity | Action |\n|---|---|---|\n| 9.0 – 10.0 | CRITICAL | Immediate alert + confirm to patch |\n| 7.0 – 8.9 | HIGH | Queue confirm to patch |\n| 4.0 – 6.9 | MEDIUM | Report + advisory |\n| 0.1 – 3.9 | LOW | Report only |\n\n## External Source Override Flags\n\n| Flag | Source | Impact |\n|---|---|---|\n| `KEV` | CISA Known Exploited Vulnerabilities | ⚡ Any CVE in KEV → treat as CRITICAL regardless of CVSS |\n| `RANSOMWARE` | CISA KEV (knownRansomwareCampaignUse) | 🔥 Highest priority — immediate alert + confirm within due date |\n| `OSV_MATCH` | OSV.dev (version match) | Confirmed vulnerable version installed — treat per CVSS |\n| `NVD_CORROBORATED` | NVD API cross-check | Dual-source confirmed — increase severity by one level |\n\n## Output to cve/<client>/<server>/scan-results/YYYY-MM-DD.md\n\n```markdown\n# CVE Scan — YYYY-MM-DD\n\n## Summary\n- Method used: debsecan / cvescan / apt-fallback\n- Total CVEs found: N\n- Critical: N | High: N | Medium: N | Low: N\n\n## Critical CVEs\n| CVE ID | Package | CVSS | Description | Patch Available |\n|---|---|---|---|---|\n\n## High CVEs\n...\n\n## Patch Commands\n# For each patchable CVE:\n# apt-get install --only-upgrade <package>\n```\n\n## Individual Advisory (for CVSS ≥ 7.0 OR KEV entry)\nWrite to cve/<client>/<server>/advisories/<CVE-ID>.md with full detail including source attribution.\n\n### Advisory Format\n```markdown\n# CVE-2024-XXXXX — <package>\n\n**Severity:** CRITICAL | HIGH\n**CVSS:** 9.8\n**Source:** CISA KEV | OSV.dev | NVD API\n**Flags:** KEV | RANSOMWARE | OSV_MATCH | NVD_CORROBORATED\n**Package:** openssh-server\n**Installed Version:** 8.9p1\n**Patch Available:** yes / no\n**Due Date:** YYYY-MM-DD (if from KEV)\n**Scan Date:** YYYY-MM-DD\n\n## Description\n...\n\n## References\n- https://nvd.nist.gov/vuln/detail/<CVE-ID>\n- https://www.cve.org/CVERecord?id=<CVE-ID>\n- https://osv.dev/vulnerability/<CVE-ID> (if OSV match)\n```\n\n## Output Format\n```\n[CRITICAL][KEV] 07-cve: CVE-2024-XXXXX | package: openssh-server | cvss: 9.8 | patch: available | action_id: ACT-XXX\n[HIGH][OSV_MATCH] 07-cve: CVE-2024-YYYYY | package: sudo | cvss: 7.8 | patch: available | action_id: ACT-YYY\n[CRITICAL][RANSOMWARE] 07-cve: CVE-2024-ZZZZZ | package: nginx | cvss: 7.5 | kev: ransomware_known | due: 2024-06-15 | action_id: ACT-ZZZ\n[INFO] 07-cve: scan_complete | total: 23 | critical: 1 | high: 3 | medium: 12 | low: 7\n[INFO] 07-cve: external_sources | cisa_kev: 2_matches | osv_dev: 5_matches | nvd_api: 10_findings\n```\n\n## External Script\nCVE scan commands run via `ssh_exec(op=\"run\", sessionId, command=\"...\")` on the remote server:\n- `dpkg-query -W -f='${Package}\\t${Version}\\n'` → installed packages\n- `curl -s 'https://www.cisa.gov/...'` → CISA KEV fetch\n- `curl -s -X POST 'https://api.osv.dev/v1/querybatch'` → OSV.dev query\n- `curl -s 'https://services.nvd.nist.gov/rest/json/cves/2.0?...'` → NVD query\nResults parsed locally, advisories written to `cve/<client>/<server>/advisories/<CVE-ID>.md`.\nScan report to `cve/<client>/<server>/scan-results/YYYY-MM-DD.md`.\n\nFile v1.4.2:audit/modules/08-network.md\n\n# Module 08 — Network Audit\n\n## Commands\n```bash\n# All listening ports and which process\nss -tulpn\n# Alternative: netstat -tulpn\n\n# Active connections\nss -tnp | grep ESTABLISHED | head -20\n\n# Network interfaces\nip addr show\nip link show\n\n# Routing table\nip route\n\n# ARP table (unexpected entries?)\narp -n\n\n# DNS config\ncat /resolv.conf 2>/dev/null || cat /etc/resolv.conf\n\n# Check for promiscuous mode (sniffing)\nip link | grep PROMISC\n\n# Network sockets stats\nss -s\n```\n\n## Checks & Findings\n\n### Unexpected Open Ports\n- Compare ss output against SERVER_PROFILE.md expected ports\n- Any unlisted port open on 0.0.0.0 or :: → HIGH\n- Queue firewall rule to close: FW-YYYYMMDD-NNN\n\n### Management Ports on Public Interface\n- SSH (22) or database ports (3306, 5432, 27017) on 0.0.0.0 → HIGH\n- Should be bound to 127.0.0.1 or private IP\n\n### Promiscuous Mode\n- Any interface in promiscuous mode → HIGH (possible packet sniffing)\n\n### Unexpected Active Connections\n- Outbound connections to unknown external IPs → MEDIUM\n- Long-lived connections to suspicious IPs → HIGH\n\n### IP Forwarding\n- cat /proc/sys/net/ipv4/ip_forward\n- Enabled when not expected → MEDIUM\n\n### IPv6 Management\n- IPv6 enabled but not managed → MEDIUM advisory\n\n## Output Format\n```\n[HIGH] 08-network: unexpected_port | port: 8080 | process: python3 | bound: 0.0.0.0 | action: FW-XXX confirm\n[PASS] 08-network: expected_ports | all ports match profile\n```\n\nArchive v1.4.1: 40 files, 56819 bytes\n\nFiles: AGENT.md (7263b), AUDIT_LOG.md (56b), audit/modules/01-system.md (1500b), audit/modules/02-users.md (1781b), audit/modules/03-ssh.md (1646b), audit/modules/04-auth.md (1780b), audit/modules/05-services.md (1826b), audit/modules/06-packages.md (1304b), audit/modules/07-cve.md (10288b), audit/modules/08-network.md (1438b), audit/modules/09-firewall.md (1972b), audit/modules/10-filesystem.md (1958b), audit/modules/11-kernel.md (1882b), audit/modules/12-logs.md (1867b), audit/modules/13-crons.md (1225b), audit/modules/14-ssl.md (1473b), audit/modules/15-docker.md (2152b), audit/modules/16-disk.md (790b), audit/modules/17-integrity.md (1096b), audit/modules/18-rootkit.md (1549b), BASELINE.md (964b), crons/active/nightly-audit.md (1696b), cve/cve-scan.sh (25326b), cve/external-sources.md (10102b), hooks/audit-runner.md (8419b), hooks/mail-sender.md (1490b), hooks/on-confirm-reply.md (1910b), hooks/on-critical.md (2054b), hooks/post-action.md (993b), hooks/pre-action.md (1636b), memory/schema.json (3449b), SERVER_PROFILE.md (2707b), skill-card.md (3050b), SKILL.md (13597b), SOUL.md (3102b), STATS.md (460b), templates/finding.md (902b), templates/firewall-change.md (739b), templates/pending-action.md (940b), _meta.json (142b)\n\nFile v1.4.1:SKILL.md\n\n---\nname: linux-security-guardian\ndescription: Autonomous multi-client Linux server security management via SSH MCP. Runs full audit at 1 AM IST nightly via cron. Iterates over all clients and their server fleets. Covers system hardening, CVE scanning (CISA KEV + OSV.dev + NVD API), user auditing, SSH config, firewall rules, running services, file permissions, log analysis, SSL certs, and kernel parameters. Non-breaking actions auto-applied. Critical patches and network/firewall changes require owner confirmation. Report sent per-server and per-client via email plugin/skill (not bundled). Dependency: SSH MCP server must be running.\nversion: 1.4.1\nmetadata: {\"openclaw\": {\"emoji\": \"🛡️\", \"requires\": {\"bins\": [\"bash\",\"python3\",\"ss\",\"iptables\",\"systemctl\",\"grep\",\"awk\",\"sed\",\"find\",\"curl\"], \"mcp\": [\"ssh_conn\",\"ssh_exec\"]}}}\n---\n\n# Linux Security Guardian\n\n## ⚡ SSH MCP — REQUIRED DEPENDENCY\n\n> **SSH MCP is a hard dependency. The agent MUST have SSH MCP tools available to operate.**\n> No local/legacy fallback. All operations go through SSH MCP.\n\n### Prerequisite\n\n```yaml\n# SSH MCP server must be running and accessible\ndependency: ssh_mcp\nstatus: required    # if unavailable → ABORT, alert owner\n```\n\n### Server Profile Config\n\nEach target server needs a saved connection in SSH MCP database. Configure in `SERVER_PROFILE.md`:\n\n```yaml\nssh_mcp:\n  connection_id: \"<id-name-or-alias-from-ssh-conn-list>\"   # Saved connection ID, Name, or Alias\n  # OR inline config:\n  # host: \"<server-ip>\"\n  # port: 22\n  # username: \"<user>\"\n  # key_path: \"</path/to/key>\"\n```\n\n### Audit Modules\n\nAll 18 modules execute commands via SSH MCP. Each module file lists commands that get wrapped with `ssh_exec(op=\"run\", sessionId, command)`:\n\n```\nmodule command → ssh_exec(op=\"run\", sessionId, command=\"module command\")\n              → ssh_exec(op=\"logs\", commandId=cmdId)\n              → parse output\n```\n\n### CVE Scan\n\nThe external CVE scan runs locally (on the guardian host) using curl to CISA KEV, OSV.dev, and NVD API.\nUsage requires `--client` and `--server` to write results to per-server paths:\n\n```bash\nbash cve/cve-scan.sh --client \"client-1\" --server \"server-01\"\n\n# Writes results to:\n#   cve/<client>/<server>/scan-results/YYYY-MM-DD.md\n#   cve/<client>/<server>/advisories/<CVE-ID>.md\n```\n\nSteps:\n```bash\n# 1. SSH MCP: ssh_exec(op=\"run\", sessionId, command=\"dpkg-query -W ...\") → save locally\n# 2. Read from cve/<client>/<server>/scan-results/installed-packages.txt\n# 3. curl CISA KEV → filter Linux entries → write advisories\n# 4. curl POST OSV.dev batch → match packages → write advisories\n# 5. curl NVD API (optional) → cross-check → write advisories\n```\n\n---\n\n## Multi-Client Architecture\n\nThe guardian manages **multiple clients**, each with their own server fleet.\nSERVER_PROFILE.md defines `## Client:` sections. The audit iterates ALL.\n\n```\nSERVER_PROFILE.md\n├── ## Client: client-1 (7 servers)\n│   ├── server-01\n│   ├── server-02\n│   └── ... server-07\n├── ## Client: client-2 (N servers) ← add as needed\n│   └── ...\n└── ## Client: [NEXT-CLIENT]\n```\n\nAll paths use `<client>/<server>/` prefix:\n- Findings: `audit/results/<client>/<server>/<severity>/`\n- Actions:  `actions/<client>/<server>/auto-done/`\n- CVEs:     `cve/<client>/<server>/advisories/`\n- Reports:  `reports/<client>/<server>/daily/`\n\n---\n\n## Purpose\n\nAgent manages complete Linux server security autonomously via SSH MCP.\nEvery night at 1 AM IST:\n- Iterates all clients → all servers\n- Full security audit runs via SSH MCP\n- CVEs scanned against installed packages\n- Auto-fixes applied for safe issues\n- Critical issues queued for owner confirmation\n- Per-server, per-client, and master email reports delivered\n\n---\n\n## Action Decision Matrix\n\nThe most important thing — what agent does vs what it asks first:\n\n| Finding Type | CVSS / Severity | Action |\n|---|---|---|\n| CVE — Critical | ≥ 9.0 | EMAIL ALERT immediately + queue for confirm |\n| CVE — High | 7.0–8.9 | Queue for confirm + include in report |\n| CVE — Medium | 4.0–6.9 | Include in report + advisory |\n| CVE — Low | < 4.0 | Info in report only |\n| CVE — KEV (CISA) | any | **Treated as CRITICAL** — immediate alert + confirm within due date |\n| CVE — KEV + Ransomware | any | **🔥 HIGHEST PRIORITY** — immediate alert, confirm ASAP |\n| Kernel update available | any | Confirm required before patch |\n| Security-only pkg update | any | Confirm required |\n| SSH: PermitRootLogin yes | critical | Alert + confirm to fix |\n| SSH: PasswordAuth yes | high | Alert + confirm to fix |\n| SSH: Port 22 | medium | Advisory only |\n| Empty password account | critical | AUTO-LOCK immediately |\n| Unknown root-uid account | critical | Alert + confirm to lock |\n| Inactive account > 90d | medium | Alert + confirm to lock |\n| World-writable /tmp | medium | AUTO-FIX chmod |\n| World-writable system dir | high | Alert + confirm to fix |\n| Unexpected SUID binary | high | Alert only (owner decides) |\n| Failed login spike > 20/hr | high | Alert immediately |\n| New unknown cron job | high | Alert immediately |\n| Firewall rule change needed | any | CONFIRM REQUIRED always |\n| Open unexpected port | high | Alert + confirm to close |\n| Service: unnecessary running | medium | Alert + confirm to stop |\n| SSL cert expiring < 30d | warning | Alert |\n| SSL cert expired | critical | Alert immediately |\n| Disk > 85% full | warning | Alert |\n| Disk > 95% full | critical | Alert immediately |\n| Auditd not running | high | AUTO-START + alert |\n| fail2ban not running | high | AUTO-START + alert |\n| Log file suspicious entry | high | Alert with extract |\n\n---\n\n## Audit Modules\n\n| Module | What it checks | SSH MCP Command |\n|--------|---------------|-----------------|\n| `01-system` | OS, kernel, uptime, last reboot, hardware | `ssh_exec(op=\"run\", sessionId, command=\"uname -a; cat /etc/*release\")` |\n| `02-users` | Accounts, root access, sudo, empty passwords, inactive | `ssh_exec(op=\"run\", sessionId, command=\"cat /etc/passwd; cat /etc/shadow; ...\")` |\n| `03-ssh` | sshd_config full audit — 20+ checks | `ssh_exec(op=\"run\", sessionId, command=\"cat /etc/ssh/sshd_config\")` |\n| `04-auth` | Login history, failed logins, PAM config | `ssh_exec(op=\"run\", sessionId, command=\"last; cat /var/log/auth.log\")` |\n| `05-services` | Running services, unnecessary ones, failed units | `ssh_exec(op=\"run\", sessionId, command=\"systemctl list-units ...\")` |\n| `06-packages` | Pending updates, security updates count | `ssh_exec(op=\"run\", sessionId, command=\"apt list --upgradable 2>/dev/null\")` |\n| `07-cve` | CVE scan — remote via SSH MCP + API-based | `ssh_exec(op=\"run\", sessionId, command=\"dpkg-query -W ...; curl ...\")` |\n| `08-network` | Open ports, listening services, active connections | `ssh_exec(op=\"run\", sessionId, command=\"ss -tulpn; netstat -tulpn\")` |\n| `09-firewall` | iptables/nftables/ufw rules audit | `ssh_exec(op=\"run\", sessionId, command=\"iptables-save 2>/dev/null\")` |\n| `10-filesystem` | SUID/SGID, world-writable, /tmp, sticky bits | `ssh_exec(op=\"run\", sessionId, command=\"find / -perm -4000 ...\")` |\n| `11-kernel` | sysctl security params — 15+ checks | `ssh_exec(op=\"run\", sessionId, command=\"sysctl -a 2>/dev/null\")` |\n| `12-logs` | auth.log, syslog, kern.log — anomaly scan | `ssh_exec(op=\"run\", sessionId, command=\"tail -100 /var/log/syslog\")` |\n| `13-crons` | System + user cron jobs — unknown jobs flagged | `ssh_exec(op=\"run\", sessionId, command=\"cat /etc/crontab; ls -la /var/spool/cron/\")` |\n| `14-ssl` | Cert expiry check for all domains/services | `ssh_exec(op=\"run\", sessionId, command=\"openssl x509 -in ... -noout -dates\")` |\n| `15-docker` | If running — image vulns, container config | `ssh_exec(op=\"run\", sessionId, command=\"docker ps; docker images\")` |\n| `16-disk` | Disk usage, inode usage | `ssh_exec(op=\"run\", sessionId, command=\"df -h; df -i\")` |\n| `17-integrity` | AIDE/tripwire check if installed | `ssh_exec(op=\"run\", sessionId, command=\"aide --check\")` |\n| `18-rootkit` | rkhunter/chkrootkit if installed | `ssh_exec(op=\"run\", sessionId, command=\"rkhunter --check --skip-keypress\")` |\n\n**Execution rule**: All commands go through `ssh_exec(op=\"run\", sessionId, command=\"<command>\")` → `ssh_exec(op=\"logs\", commandId=cmdId)`. No local execution.\n\n---\n\n## Finding Severity Levels\n\n| Level | Color | Meaning |\n|---|---|---|\n| `CRITICAL` | 🔴 | Immediate risk, action required now |\n| `HIGH` | 🟠 | Significant risk, fix this week |\n| `MEDIUM` | 🟡 | Moderate risk, fix this month |\n| `LOW` | 🔵 | Minor issue, fix when possible |\n| `INFO` | ⚪ | Informational, no action needed |\n| `PASS` | 🟢 | Check passed, all good |\n\n---\n\n## Confirmation Flow\n\nWhen owner confirmation is needed:\n\n```\nFinding detected (requires confirm) on <client>/<server>\n    ↓\nWrite to actions/<client>/<server>/pending-confirm/<client>-<server>-<id>-<slug>.md\n    ↓\nInclude in email report under \"NEEDS YOUR DECISION\" with <client>/<server> context\n    ↓\nOwner replies with: APPROVE <id> / DENY <id> / SKIP <id>\n(Full ID format: <client>-<server>-<type>-<NNN>, e.g. client-1-server-01-ACT-20260529-001)\n    ↓\nSearch all actions/*/*/pending-confirm/ for the ID\n    ↓\nAPPROVE → agent connects to <client>/<server> via SSH MCP → executes action → logs to history/\nDENY    → action skipped, noted\nSKIP    → deferred to next audit\n```\n\n---\n\n## Email Report Structure\n\nReports are sent per-server, per-client (summary), and master. All via email plugin/skill.\n\n### Per-Server Report\n```\nSubject: [Linux Guardian] <client>/<server> — YYYY-MM-DD | Score: N/100 | CRITICAL:N HIGH:N\n\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\nLINUX SECURITY GUARDIAN — NIGHTLY REPORT\nClient: <client> | Server: <server> | <IP> | YYYY-MM-DD 01:00 IST\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\nEXECUTIVE SUMMARY\nSecurity Score: N/100 | Grade: X\nCritical: N | High: N | Medium: N | Low: N\nAuto-fixed: N | Pending confirm: N | Passed: N\n\n━━ 🔴 CRITICAL (immediate action needed)\n[Finding details]\n\n━━ 🟠 HIGH\n[Finding details]\n\n━━ ⚡ AUTO-ACTIONS TAKEN (safe, non-breaking)\n[What was auto-fixed]\n\n━━ 🔑 NEEDS YOUR DECISION (reply APPROVE/DENY/SKIP <id>)\n[Pending confirmations with IDs — includes <client>/<server> prefix]\n\n━━ 📦 CVE REPORT\n[CVEs found by severity]\n\n━━ 🌐 NETWORK & FIREWALL\n[Port/firewall status]\n\n━━ 🟡 MEDIUM / LOW\n[Less urgent findings]\n\n━━ 🟢 ALL PASSING\n[Checks that passed]\n\n━━ NEXT AUDIT: Tomorrow 01:00 IST\n```\n\n### Per-Client Summary Report\n```\nSubject: [Linux Guardian] <client> Summary — YYYY-MM-DD | Servers: N/N | CRITICAL:N HIGH:N\n\nClient: <client>\nServers audited: N of N total\nAverage score: N/100\n\n| Server | Score | Critical | High | Score Grade |\n|--------|-------|----------|------|-------------|\n| ...    | ...   | ...      | ...  | ...         |\n\nCross-server patterns: [same vuln found on multiple servers]\n```\n\n\n---\n\n## Security Score Formula\n\n```\nscore = 100\nscore -= (critical_count × 20)\nscore -= (high_count × 10)\nscore -= (medium_count × 3)\nscore -= (low_count × 1)\nscore = max(0, score)\n\nGrade: 90-100 = A | 75-89 = B | 60-74 = C | < 60 = F\n```\n\n---\n\n## Folder Structure\n\n```\nlinux-security-guardian/\n  audit/\n    modules/                     ← 01-system.md ... 18-rootkit.md\n    results/\n      <client>/<server>/\n        critical/  high/  warning/  info/  pass/\n          YYYY-MM-DD-<check>.md  ← per-client/per-server findings\n\n  actions/\n    <client>/<server>/\n      auto-done/                 ← auto-fixed actions (logged)\n        YYYY-MM-DD-<slug>.md\n      pending-confirm/           ← waiting for owner\n        <id>-<slug>.md\n      history/                   ← all approved/denied actions\n\n  cve/\n    cve-scan.sh                  ← external CVE scanner (takes --client --server)\n    external-sources.md          ← all API URLs, query params, working examples\n    .cache/                      ← shared cached API responses (6h TTL)\n    <client>/<server>/\n      scan-results/              ← YYYY-MM-DD.md\n      advisories/                ← <cve-id>.md\n\n  reports/\n    <client>/<server>/\n      daily/YYYY-MM-DD.md\n      weekly/YYYY-WNN.md\n\n  network/\n    <client>/<server>/\n      firewall-snapshots/        ← YYYY-MM-DD-rules.txt\n      port-scans/                ← YYYY-MM-DD.md\n      proposed-changes/          ← <id>-<change>.md\n\n  hooks/\n    audit-runner.md              ← main 1 AM audit orchestrator (multi-client loop)\n    on-critical.md               ← fires on any critical finding (with client/server)\n    on-confirm-reply.md          ← processes owner APPROVE/DENY/SKIP\n    pre-action.md                ← safety check before any action\n    post-action.md               ← verify action succeeded\n    mail-sender.md               ← uses email plugin/skill to send report\n\n  crons/\n    active/\n      nightly-audit.md           ← 1 AM IST permanent\n    completed/\n\n  errors/\n    raw/                         ← raw error logs\n\n  memory/\n    schema.json\n    index.json\n\n  SOUL.md                        ← soul context (multi-client aware)\n  AGENT.md                       ← behavioral rules (multi-client, SSH MCP hard dep)\n  SERVER_PROFILE.md               ← multi-client server details\n  AUDIT_LOG.md                    ← append-only master log\n  BASELINE.md                     ← expected state snapshot\n  STATS.md\n```\n\nFile v1.4.1:_meta.json\n\n{\n  \"ownerId\": \"kn79djxt41q03wtr3nth5h8y8184mgcm\",\n  \"slug\": \"linux-security-guardian\",\n  \"version\": \"1.4.1\",\n  \"publishedAt\": 1780900132942\n}\n\nFile v1.4.1:AGENT.md\n\n---\nname: linux-security-guardian-agent\ndescription: Behavioral rules for linux-security-guardian. Multi-client, SSH MCP hard dependency, safe-first actions, mandatory confirmations for critical changes, complete audit coverage.\n---\n\n# Agent Rules — Linux Security Guardian\n\n## THE PRIME RULE — SAFE FIRST\n\nWhen in doubt about whether an action is safe: DON'T DO IT.\nLog it. Alert owner. Wait for explicit approval.\nA delayed fix is always better than an accidental outage.\n\n---\n\n## Rule 1 — SSH MCP Hard Dependency\n\nSSH MCP is a hard dependency. The agent MUST have SSH MCP tools available to operate.\n\n```yaml\nrequired_tools: [ssh_conn, ssh_exec]\nversion: v2  # 13 tools: ssh_conn, ssh_exec, ssh_bulk_exec, ssh_bulk_audit, ssh_client, etc.\n```\n\nIf SSH MCP tools are unavailable → ABORT audit, alert owner: \"SSH MCP not available\".\nNo local/legacy fallback. All operations go through SSH MCP.\n\n---\n\n## Rule 2 — Multi-Client Audit Flow\n\nSERVER_PROFILE.md contains one or more `## Client:` sections.\nThe audit MUST iterate over ALL clients and ALL servers:\n\n```\nfor each client in SERVER_PROFILE.md:\n  for each server in client.server_fleet:\n    ssh_conn → test/save connection if needed\n    ssh_exec(op=\"open\", connectionId) → sessionId\n    Run all 18 modules via ssh_exec(op=\"run\", sessionId, ...)\n    Compile per-server findings → audit/results/<client>/<server>/<severity>/\n    Compile per-server report → reports/<client>/<server>/daily/YYYY-MM-DD.md\n    ssh_exec(op=\"close\", sessionId)\n  Compile per-client summary\nAppend master report\nSend via default email account\n```\n\n---\n\n## Rule 3 — Email Account Selection\n\n- **Default account**: Used for ALL outgoing reports and alerts.\n- **Admin account**: Personal account. NEVER use for automated reports.\n- Rule: Always use default account. Never specify `--account admin`.\n- Check available accounts: `himalaya account list` (identify default vs admin).\n- If no email plugin available → log to AUDIT_LOG.md, report is on disk. Non-fatal.\n\n---\n\n## Rule 4 — Read SERVER_PROFILE.md Before Every Audit\n\nLoad SERVER_PROFILE.md at audit start.\nParse each `## Client:` section. Extract server fleet table.\nExpected ports, services, users, SUID list — all per-server from this file.\nDeviation from profile = finding.\nProfile not filled = abort audit, alert owner.\n\n---\n\n## Rule 5 — Auto-Actions Whitelist Only\n\nAgent can ONLY auto-execute actions listed in SERVER_PROFILE.md under `Auto-Actions Allowed`.\nAnything not explicitly whitelisted → queue for confirmation.\nNo exceptions. Owner preference > agent judgment.\n\nAuto-action execution:\n1. Run pre-action safety check (hooks/pre-action.md)\n2. Execute action via SSH MCP\n3. Verify result (hooks/post-action.md)\n4. Log to actions/<client>/<server>/auto-done/\n5. Include in email report\n\n---\n\n## Rule 6 — Confirmation Queue Protocol\n\nWhen action requires confirmation:\n1. Generate unique ID: `ACT-YYYYMMDD-NNN`\n2. Write to actions/<client>/<server>/pending-confirm/<id>-<slug>.md\n3. Include in email report under \"NEEDS YOUR DECISION\"\n4. Wait. Do not execute until owner says APPROVE.\n5. Confirmation expires after 7 days → re-queue next audit\n\n---\n\n## Rule 7 — Critical Finding = Immediate Alert\n\nAny CRITICAL finding triggers hooks/on-critical.md immediately.\nDo not wait for report compilation.\nSend alert via default email account NOW.\nContinue audit in parallel.\n\nCritical findings:\n- CVSS ≥ 9.0 CVE\n- KEV entry (any CVSS — treated as CRITICAL)\n- KEV + Ransomware (🔥 highest priority)\n- Empty password account found\n- Unknown UID 0 account\n- Root login via SSH successful (from logs)\n- SSL cert expired\n- Disk > 95%\n- Rootkit detected\n- Unexpected kernel module loaded\n- /etc/passwd or /etc/shadow modified unexpectedly\n\n---\n\n## Rule 8 — Firewall Rules — Always Confirm\n\nFirewall is ALWAYS confirm-required. No exceptions.\nEven \"obviously safe\" rules need owner approval.\nFormat for proposed change:\n\n```\nID: FW-YYYYMMDD-NNN\nClient: <client>\nServer: <server>\nCurrent rule: [exact current state]\nProposed change: [exact proposed command]\nReason: [why this change is needed]\nRisk: [what could break if wrong]\nRollback: [exact command to undo]\n```\n\nAgent writes this to network/<client>/<server>/proposed-changes/ and includes in report.\nAgent NEVER runs iptables/nftables/ufw commands without explicit APPROVE.\n\n---\n\n## Rule 9 — CVE Scan — Complete Coverage\n\nCVE scan must cover ALL installed packages per server.\nDetect package manager automatically (apt/yum/dnf/pacman).\nUse best available tool per OS via SSH MCP.\n\nCVE results saved to cve/<client>/<server>/scan-results/YYYY-MM-DD.md.\nAny CVSS ≥ 7.0 or KEV entry → also save individual advisory to cve/<client>/<server>/advisories/<CVE-ID>.md.\n\nExternal sources (CISA KEV, OSV.dev, NVD API) queried via ssh_exec from remote server.\nSource override flags: KEV → CRITICAL, RANSOMWARE → 🔥 immediate alert, OSV_MATCH → per CVSS, NVD_CORROBORATED → +1 severity.\n\n---\n\n## Rule 10 — Snapshot Before Any Action\n\nBefore any auto-action or approved action that modifies config:\n1. Snapshot current state of the relevant file/config\n2. Save to actions/<client>/<server>/history/<id>-BEFORE.txt\n3. Execute action\n4. Save new state to actions/<client>/<server>/history/<id>-AFTER.txt\n5. Save rollback command to actions/<client>/<server>/history/<id>-ROLLBACK.sh\n\n---\n\n## Rule 11 — Audit Must Be Complete\n\nAll 18 modules must run per server.\nIf a module fails (command not found, permission error):\nLog failure: `[MODULE FAILED] <client>/<server> 07-cve: ...`\nNever silently skip a module.\nReport module failures in email.\nContinue to next server. Do not abort entire audit on single server failure.\n\n---\n\n## Rule 12 — Audit Log is Append-Only\n\nEvery audit run appended to AUDIT_LOG.md:\n```\nYYYY-MM-DD 01:00 IST | audit_start | clients:N | servers:N\nYYYY-MM-DD 01:XX IST | audit_complete | clients:N | servers_total:N | critical:N high:N | score:N/100\n```\nNever edit, never delete.\n\n---\n\n## Rule 13 — New Client Onboarding\n\nWhen adding a new client:\n1. Add `## Client: <name>` section to SERVER_PROFILE.md\n2. Fill server fleet table (host, port, username, key_path)\n3. Save connections via SSH MCP: `ssh_conn(op=\"save\", name, host, port, username, key_path)`\n4. Verify each server reachable: `ssh_conn(op=\"test\", ...)`\n5. Create per-client directories: `audit/results/<client>/<server>/`, `actions/`, `cve/`, `network/`, `reports/`\n6. Set notification email for the client\n7. Run first audit to establish baseline\n8. Verify report delivery reaches client's notification email\n\n---\n\n## Rule 14 — Baseline Management\n\nFirst run per server: create baseline in `audit/results/<client>/<server>/baseline/`.\nSubsequent runs: compare against baseline.\nDeviations from baseline = findings (even if not a security issue).\n\nBaseline updated only when:\n- Owner explicitly says \"update baseline\"\n- After an approved action changes system state\n\n---\n\n## Rule 15 — Session Start Check\n\nAt session start (if during day):\n- Any pending-confirm actions across any client/server? → surface: \"N actions await your approval\"\n- Any CRITICAL findings from last audit? → surface immediately with client/server context\n- Any CVE CRITICAL from last scan? → surface\n\nFile v1.4.1:AUDIT_LOG.md\n\n# Audit Log\n*Append-only. One entry per audit run.*\n---\n\nFile v1.4.1:audit/modules/01-system.md\n\n# Module 01 — System Info\n\n## Commands\n```bash\nuname -r                           # kernel version\nuname -a                           # full kernel info\nlsb_release -a 2>/dev/null        # OS info\ncat /etc/os-release                # OS info fallback\nuptime -p                          # uptime\nlast reboot | head -5              # reboot history\ndf -h                              # disk usage\nfree -h                            # memory\nnproc                              # CPU count\ncat /proc/cpuinfo | grep \"model name\" | head -1\ntimedatectl                        # NTP sync status\n```\n\n## Checks & Findings\n\n### OS EOL Check\n- Ubuntu 20.04 LTS → EOL April 2025 → if still running: HIGH finding\n- Ubuntu 22.04 LTS → EOL April 2027 → OK\n- Ubuntu 24.04 LTS → EOL April 2029 → OK\n- Debian 11 → EOL June 2026 → OK\n- Debian 10 → EOL June 2024 → HIGH if still running\n\n### Kernel Version Check\n- Compare against latest stable for the distro\n- More than 2 major versions behind → HIGH\n- Security patch available → MEDIUM\n\n### NTP Sync\n- timedatectl | grep \"NTP service: active\" → PASS\n- NTP not synced → MEDIUM (time drift breaks certs/logs)\n\n### Disk Usage\n- < 80% → PASS\n- 80-85% → LOW\n- 85-95% → WARNING\n- > 95% → CRITICAL (auto-alert)\n\n### Last Reboot\n- No reboot in > 90 days with kernel updates pending → MEDIUM\n- Server rebooted unexpectedly (not matching known maintenance) → HIGH\n\n## Output Format\n```\n[PASS/FINDING] 01-system: <check> | <result>\n```\n\nFile v1.4.1:audit/modules/02-users.md\n\n# Module 02 — User Accounts\n\n## Commands\n```bash\n# All users with login shell\ngrep -v \"nologin\\|false\\|sync\\|halt\\|shutdown\" /etc/passwd | cut -d: -f1,3,6,7\n\n# UID 0 accounts (should only be root)\nawk -F: '($3 == 0) { print $1 }' /etc/passwd\n\n# Sudo users\ngetent group sudo 2>/dev/null || getent group wheel 2>/dev/null\ncat /etc/sudoers | grep -v \"^#\" | grep -v \"^$\"\nls /etc/sudoers.d/\n\n# Empty passwords (CRITICAL)\nawk -F: '($2 == \"\" || $2 == \"!!\" ) { print $1 }' /etc/shadow 2>/dev/null\n\n# Password age\nawk -F: '{print $1, $5}' /etc/shadow 2>/dev/null | grep \"^[^:]*:[0-9]\"\n\n# Last login for all users\nlastlog | grep -v \"Never\\|Username\"\n\n# Users logged in right now\nwho\nw\n\n# Recently created accounts (last 30 days)\nfind /home -maxdepth 1 -type d -newer /tmp -mtime -30 2>/dev/null\n```\n\n## Checks & Findings\n\n### UID 0 Accounts\n- Only 'root' should have UID 0\n- Any other UID 0 account → CRITICAL immediate alert\n\n### Unknown Sudo Users\n- Compare against SERVER_PROFILE.md expected sudo users\n- Unknown sudo user → CRITICAL\n\n### Empty Passwords\n- Any account with empty password → CRITICAL\n- AUTO-ACTION if whitelisted: `passwd -l <username>`\n\n### Inactive Accounts (> 90 days no login)\n- Check lastlog, find accounts with login > 90 days ago\n- Still active login shell → MEDIUM\n- Queue confirm to lock: `usermod -L <username>`\n\n### Password Policy\n- Check /etc/login.defs for PASS_MAX_DAYS, PASS_MIN_DAYS\n- PASS_MAX_DAYS > 90 → LOW\n- No password expiry → MEDIUM\n\n### Root Account Direct Login\n- Check if anyone logged in as root via SSH recently\n- grep \"Accepted.*root\" /var/log/auth.log → HIGH if found\n\n## Output Format\n```\n[CRITICAL] 02-users: empty_password | account: <name> | action: auto-lock-queued\n[PASS] 02-users: uid0_check | only root has uid 0\n```\n\nFile v1.4.1:audit/modules/03-ssh.md\n\n# Module 03 — SSH Configuration\n\n## Commands\n```bash\nsshd -T 2>/dev/null          # full effective SSH config (best method)\ncat /etc/ssh/sshd_config     # raw config file\ngrep -v \"^#\\|^$\" /etc/ssh/sshd_config\n```\n\n## Checks — 20+ SSH Security Parameters\n\n| Parameter | Secure Value | Finding if Wrong |\n|---|---|---|\n| PermitRootLogin | no | HIGH → confirm to set no |\n| PasswordAuthentication | no | HIGH → confirm to set no |\n| PubkeyAuthentication | yes | HIGH |\n| PermitEmptyPasswords | no | CRITICAL → auto-fix |\n| X11Forwarding | no | MEDIUM |\n| MaxAuthTries | ≤ 4 | MEDIUM |\n| LoginGraceTime | ≤ 60 | LOW |\n| AllowAgentForwarding | no | LOW |\n| AllowTcpForwarding | no | MEDIUM |\n| ClientAliveInterval | 300 | LOW |\n| ClientAliveCountMax | 2 | LOW |\n| Protocol | 2 (implicit modern) | CRITICAL if 1 |\n| Port | not 22 | INFO (advisory) |\n| UsePAM | yes | MEDIUM if no |\n| IgnoreRhosts | yes | HIGH if no |\n| HostbasedAuthentication | no | HIGH |\n| PermitUserEnvironment | no | MEDIUM |\n| StrictModes | yes | HIGH if no |\n| MaxSessions | ≤ 4 | LOW |\n| Banner | set | INFO |\n| LogLevel | VERBOSE or INFO | MEDIUM if silent |\n| AllowUsers/AllowGroups | set | INFO (advisory) |\n\n## Auto-Fix Eligible (from whitelist only)\n- PermitEmptyPasswords no → AUTO-FIX (sed in place)\n\n## Confirm Required\n- PermitRootLogin no → confirm (could lock out if no key auth)\n- PasswordAuthentication no → confirm (MUST have key auth working first)\n- All others → queue confirm\n\n## Output Format\n```\n[HIGH] 03-ssh: PermitRootLogin | value: yes | expected: no | action_id: ACT-YYYYMMDD-001\n[PASS] 03-ssh: MaxAuthTries | value: 3 ≤ 4\n```\n\nFile v1.4.1:audit/modules/04-auth.md\n\n# Module 04 — Authentication & Login Audit\n\n## Commands\n```bash\n# Failed login attempts\ngrep \"Failed password\" /var/log/auth.log | tail -100\ngrep \"Failed password\" /var/log/auth.log | awk '{print $11}' | sort | uniq -c | sort -rn | head -20  # top source IPs\n\n# Successful logins\ngrep \"Accepted\" /var/log/auth.log | tail -50\n\n# Sudo usage\ngrep \"sudo:\" /var/log/auth.log | tail -50\n\n# Failed sudo\ngrep \"sudo:.*NOT in sudoers\" /var/log/auth.log\n\n# Login from unexpected locations\nlast | head -30\n\n# Brute force threshold check\nFAILED=$(grep \"Failed password\" /var/log/auth.log | grep \"$(date '+%b %e')\" | wc -l)\necho \"Failed logins today: $FAILED\"\n\n# PAM configuration\ncat /etc/pam.d/sshd | grep -v \"^#\"\ncat /etc/pam.d/login | grep -v \"^#\"\n\n# fail2ban status\nsystemctl is-active fail2ban 2>/dev/null\nfail2ban-client status sshd 2>/dev/null\n```\n\n## Checks & Findings\n\n### Failed Login Spike\n- > 20 failed logins in last hour → HIGH alert\n- > 100 failed logins in last hour → CRITICAL alert\n- Single IP with > 10 failures → HIGH (may not be in fail2ban)\n\n### Successful Root SSH Login\n- Any \"Accepted.*root\" in auth.log → HIGH (if PermitRootLogin is yes)\n\n### Unauthorized Sudo Usage\n- \"NOT in sudoers\" entries → HIGH\n\n### fail2ban Status\n- Not running → HIGH → AUTO-START (if whitelisted)\n- Not configured for SSH → MEDIUM\n\n### PAM Configuration\n- pam_tally2 or pam_faillock not configured → MEDIUM\n- No account lockout policy → MEDIUM\n\n### Login from Unknown IPs\n- Compare login IPs against SERVER_PROFILE.md management IPs\n- Unknown IP logged in successfully → HIGH\n\n## Output Format\n```\n[HIGH] 04-auth: brute_force | failed_logins_1hr: 47 | top_source: 1.2.3.4 (23 attempts)\n[HIGH] 04-auth: fail2ban_down | status: inactive | action: auto-start queued\n```\n\nFile v1.4.1:audit/modules/05-services.md\n\n# Module 05 — Services Audit\n\n## Commands\n```bash\n# All running services\nsystemctl list-units --type=service --state=running --no-pager\n\n# Failed services\nsystemctl list-units --type=service --state=failed --no-pager\n\n# Services enabled at boot\nsystemctl list-unit-files --type=service --state=enabled --no-pager\n\n# Listening processes\nss -tulpn\n# or: netstat -tulpn\n\n# Processes listening on all interfaces (0.0.0.0 or :::)\nss -tulpn | grep -E \"0\\.0\\.0\\.0|:::\"\n\n# Check for suspicious processes\nps aux --sort=-%cpu | head -20\nps aux | awk '{if ($3 > 50.0) print $0}'  # high CPU\n\n# Docker if running\ndocker ps 2>/dev/null\ndocker ps -a 2>/dev/null\n```\n\n## Checks & Findings\n\n### Unknown Running Services\n- Compare against SERVER_PROFILE.md expected services\n- Any unlisted service running → MEDIUM (queue confirm to investigate/stop)\n\n### Failed Services\n- Any failed service → HIGH (could indicate attack or config issue)\n- Check if service was recently working: journalctl -u <service> --since \"1 hour ago\"\n\n### Services Listening on All Interfaces\n- Services bound to 0.0.0.0 that should be internal only → HIGH\n- Cross-check with expected open ports in SERVER_PROFILE.md\n\n### Unnecessary Services Running\nCommon unnecessary services to flag:\n- telnet → CRITICAL (plaintext)\n- rsh, rlogin, rexec → CRITICAL\n- finger → MEDIUM\n- rpcbind (if not NFS server) → LOW\n- avahi-daemon (if not needed) → LOW\n- cups (if not print server) → LOW\n\n### Auditd Status\n- Not running → HIGH → AUTO-START (if whitelisted)\n- systemctl enable auditd + systemctl start auditd\n\n## Output Format\n```\n[CRITICAL] 05-services: telnet_running | service: telnet | action: confirm-to-stop ACT-XXX\n[HIGH] 05-services: auditd_down | action: auto-starting\n[PASS] 05-services: expected_services | all 5 expected services running\n```\n\nFile v1.4.1:audit/modules/06-packages.md\n\n# Module 06 — Package Updates\n\n## Commands\n\n### Debian/Ubuntu\n```bash\napt update -qq 2>/dev/null\n\n# Total pending updates\napt list --upgradable 2>/dev/null | grep -v \"Listing...\" | wc -l\n\n# Security updates specifically\napt list --upgradable 2>/dev/null | grep -i security | wc -l\n\n# List security updates\napt-get --just-print upgrade 2>/dev/null | grep \"^Inst\" | grep -i security\n\n# Held packages\napt-mark showhold\n```\n\n### RHEL/CentOS/Rocky\n```bash\nyum check-update --security -q 2>/dev/null\nyum updateinfo list security 2>/dev/null | tail -20\ndnf check-update --security 2>/dev/null\n```\n\n## Checks & Findings\n\n### Pending Security Updates\n- 0 security updates → PASS\n- 1-5 security updates → MEDIUM\n- > 5 security updates → HIGH\n- Any kernel security update → HIGH + confirm required\n\n### Total Update Lag\n- 0-10 packages behind → LOW\n- 10-50 packages behind → MEDIUM\n- > 50 packages behind → HIGH (neglected system)\n\n### Held Packages\n- Any held package with known CVE → HIGH\n\n### Auto-Update Config\n- Check if unattended-upgrades is configured\n- Not configured → MEDIUM advisory\n\n## Output Format\n```\n[HIGH] 06-packages: security_updates_pending | count: 12 | kernel_update: yes | action_id: ACT-XXX\n[MEDIUM] 06-packages: no_auto_updates | unattended-upgrades not configured\n```\n\nFile v1.4.1:audit/modules/07-cve.md\n\n# Module 07 — CVE Scan\n\n## Detection Strategy (tries in order)\n\n### EXECUTION NOTE\nAll commands run via `ssh_exec(op=\"run\", sessionId, command=\"<command>\")` on the remote server. Output retrieved via `ssh_exec(op=\"logs\", commandId=cmdId)`. API calls (CISA KEV, OSV.dev, NVD) execute via `ssh_exec` on the remote server using `curl`. No local command execution.\n\n### LOCAL METHODS (local tools, no network needed)\n\n```bash\n# Method 1: debsecan (Debian/Ubuntu — most accurate)\nwhich debsecan >/dev/null 2>&1 && debsecan --suite $(lsb_release -cs) --only-fixed --format=detail\n\n# Method 2: Ubuntu CVEScan\nwhich cvescan >/dev/null 2>&1 && cvescan\n\n# Method 3: apt security info (fallback)\napt-get --just-print upgrade 2>/dev/null | grep \"^Inst\" | grep -i \"security\\|CVE\"\n\n# Method 4: RHEL/CentOS yum security\nwhich yum >/dev/null 2>&1 && yum updateinfo list security 2>/dev/null\n\n# Method 5: Installed package list (for external source cross-ref)\ndpkg-query -W -f='${Package}\\t${Version}\\n' 2>/dev/null\n# Or: rpm -qa --queryformat '%{NAME}\\t%{VERSION}\\n' 2>/dev/null\n```\n\n### EXTERNAL METHODS (requires internet — enrich local findings)\n\n```bash\n# ═══════════════════════════════════════════════════════════════\n# METHOD 6: CISA KEV Catalog [CURL] ✅\n# ═══════════════════════════════════════════════════════════════\n# URL: https://www.cisa.gov/sites/default/files/feeds/known_exploited_vulnerabilities.json\n# No API key needed. No rate limits. Always works with curl.\n# Cross-ref against installed packages. KEV match → auto-CRITICAL.\n#\n# curl -s \"https://www.cisa.gov/sites/default/files/feeds/known_exploited_vulnerabilities.json\" \\\n#   | jq '[.vulnerabilities[] | select(.vendorProject == \"Linux\")]'\n\n# ═══════════════════════════════════════════════════════════════\n# METHOD 7: OSV.dev — open source vuln DB [CURL] ✅\n# ═══════════════════════════════════════════════════════════════\n# POST https://api.osv.dev/v1/query (single)\n# POST https://api.osv.dev/v1/querybatch (batch — up to 1000)\n# No API key. No rate limits. Always works with curl.\n# Best method: matches by package + ecosystem + version.\n#\n# curl -s -X POST \"https://api.osv.dev/v1/querybatch\" \\\n#   -H \"Content-Type: application/json\" \\\n#   -d '{\"queries\":[\n#     {\"package\":{\"name\":\"openssl\",\"ecosystem\":\"Debian\"},\"version\":\"3.0.2\"},\n#     {\"package\":{\"name\":\"nginx\",\"ecosystem\":\"Debian\"},\"version\":\"1.22.0\"}\n#   ]}'\n\n# ═══════════════════════════════════════════════════════════════\n# METHOD 8: NVD API 2.0 [CURL] ⚠️ rate limited\n# ═══════════════════════════════════════════════════════════════\n# URL: https://services.nvd.nist.gov/rest/json/cves/2.0\n# Rate limit: 5 req/30s (no key), 50 req/30s (with key)\n# API key (free): https://nvd.nist.gov/developers/request-an-api-key [BROWSER]\n# ⚠️ API endpoint works with curl. Web portal (nvd.nist.gov) is CLOUDFLARE BLOCKED.\n#\n# Without key (sleep 6s between calls):\n#   curl -s \"https://services.nvd.nist.gov/rest/json/cves/2.0?keywordSearch=linux&resultsPerPage=5\"\n# With key:\n#   curl -s -H \"apiKey:NVD_API_KEY\" \"https://services.nvd.nist.gov/rest/json/cves/2.0?cveId=CVE-2024-1086\"\n#\n# ⚠️ Skip if blocked: if curl returns Cloudflare \"Attention Required\" → SKIP immediately\n#    Do NOT retry. OSV.dev and CISA KEV already cover what NVD would tell you.\n\n# ═══════════════════════════════════════════════════════════════\n# METHOD 9: Web portal URLs [BROWSER] ❌ Cloudflare blocks curl\n# ═══════════════════════════════════════════════════════════════\n# Only use with browser tool. DO NOT use curl on these URLs.\n#\n# CISA KEV (Linux filter):\n#   https://www.cisa.gov/known-exploited-vulnerabilities-catalog?f%5B0%5D=vendor_project%3ALinux\n#\n# NVD Search — Linux:\n#   https://nvd.nist.gov/vuln/search/results?query=linux&search_type=all&queryType=phrase\n#\n# NVD Search — Critical Linux:\n#   https://nvd.nist.gov/vuln/search/results?query=linux&cvssSeverity=CRITICAL&queryType=phrase\n#\n# OSV.dev — Linux kernel:\n#   https://osv.dev/list?ecosystem=Linux\n```\n\n### Skip Logic (— every method runs independently)\n\n```\nEACH external method follows this rule:\n\n1. curl --max-time 15 --connect-timeout 10 $URL\n2. if curl exit code != 0:\n     → Log \"[SKIP] $SOURCE unavailable (network)\"\n     → Move to next source. Not fatal.\n3. if response contains \"Attention Required\" OR \"Cloudflare\" OR \"cf-wrapper\":\n     → Log \"[SKIP] $SOURCE blocked by Cloudflare — use browser tool only\"\n     → Skip permanently this session. Don't retry. Ever.\n4. if HTTP 429 (rate limit):\n     → Sleep 6s, retry once\n     → Still 429? Log \"[SKIP] $SOURCE rate limited — too many requests\"\n     → Skip.\n5. Success → parse results, write advisories, continue next method.\n\nNEVER let one blocked/failed source fail the entire scan.\nEach source is independent.\n```\n\n### URL Working Status Quick Reference\n\n| URL | curl | Browser | Notes |\n|-----|------|---------|-------|\n| `cisa.gov/.../known_exploited_vulnerabilities.json` | ✅ Works | ✅ Works | No key needed |\n| `services.nvd.nist.gov/rest/json/cves/2.0` | ✅ Works | ❌ API only | Rate limited |\n| `nvd.nist.gov/vuln/search` | ❌ **Cloudflare** | ✅ Works | Do NOT use curl |\n| `nvd.nist.gov/vuln/detail/CVE-XXXX` | ❌ **Cloudflare** | ✅ Works | Do NOT use curl |\n| `api.osv.dev/v1/querybatch` | ✅ Works | ❌ API only | No key needed |\n| `osv.dev/list` | ✅ Works | ✅ Works | Web UI |\n\n### Priority Chain\n\n```\n1. cve/cve-scan.sh (external: CISA KEV + OSV.dev batch + NVD API)\n   → Run first if internet available via: cve/cve-scan.sh --client <name> --server <name>\n   → Each source independent — if one fails, others still run\n   → Writes to cve/<client>/<server>/scan-results/YYYY-MM-DD.md\n   → Advisories to cve/<client>/<server>/advisories/<CVE-ID>.md\n   → Matches against installed packages from dpkg-query\n\n2. Local methods 1-5 (debsecan / cvescan / apt / yum)\n   → Always run as baseline (no network dependency)\n   → Catch what external methods miss\n\n3. Web portal URLs [BROWSER]\n   → Agent opens in browser for manual verification\n   → Use when API calls are blocked or for deep investigation\n   → NVD portal blocked by Cloudflare — only works in browser\n```\n\n## CVE Severity Classification (CVSS v3)\n\n| CVSS Score | Severity | Action |\n|---|---|---|\n| 9.0 – 10.0 | CRITICAL | Immediate alert + confirm to patch |\n| 7.0 – 8.9 | HIGH | Queue confirm to patch |\n| 4.0 – 6.9 | MEDIUM | Report + advisory |\n| 0.1 – 3.9 | LOW | Report only |\n\n## External Source Override Flags\n\n| Flag | Source | Impact |\n|---|---|---|\n| `KEV` | CISA Known Exploited Vulnerabilities | ⚡ Any CVE in KEV → treat as CRITICAL regardless of CVSS |\n| `RANSOMWARE` | CISA KEV (knownRansomwareCampaignUse) | 🔥 Highest priority — immediate alert + confirm within due date |\n| `OSV_MATCH` | OSV.dev (version match) | Confirmed vulnerable version installed — treat per CVSS |\n| `NVD_CORROBORATED` | NVD API cross-check | Dual-source confirmed — increase severity by one level |\n\n## Output to cve/<client>/<server>/scan-results/YYYY-MM-DD.md\n\n```markdown\n# CVE Scan — YYYY-MM-DD\n\n## Summary\n- Method used: debsecan / cvescan / apt-fallback\n- Total CVEs found: N\n- Critical: N | High: N | Medium: N | Low: N\n\n## Critical CVEs\n| CVE ID | Package | CVSS | Description | Patch Available |\n|---|---|---|---|---|\n\n## High CVEs\n...\n\n## Patch Commands\n# For each patchable CVE:\n# apt-get install --only-upgrade <package>\n```\n\n## Individual Advisory (for CVSS ≥ 7.0 OR KEV entry)\nWrite to cve/<client>/<server>/advisories/<CVE-ID>.md with full detail including source attribution.\n\n### Advisory Format\n```markdown\n# CVE-2024-XXXXX — <package>\n\n**Severity:** CRITICAL | HIGH\n**CVSS:** 9.8\n**Source:** CISA KEV | OSV.dev | NVD API\n**Flags:** KEV | RANSOMWARE | OSV_MATCH | NVD_CORROBORATED\n**Package:** openssh-server\n**Installed Version:** 8.9p1\n**Patch Available:** yes / no\n**Due Date:** YYYY-MM-DD (if from KEV)\n**Scan Date:** YYYY-MM-DD\n\n## Description\n...\n\n## References\n- https://nvd.nist.gov/vuln/detail/<CVE-ID>\n- https://www.cve.org/CVERecord?id=<CVE-ID>\n- https://osv.dev/vulnerability/<CVE-ID> (if OSV match)\n```\n\n## Output Format\n```\n[CRITICAL][KEV] 07-cve: CVE-2024-XXXXX | package: openssh-server | cvss: 9.8 | patch: available | action_id: ACT-XXX\n[HIGH][OSV_MATCH] 07-cve: CVE-2024-YYYYY | package: sudo | cvss: 7.8 | patch: available | action_id: ACT-YYY\n[CRITICAL][RANSOMWARE] 07-cve: CVE-2024-ZZZZZ | package: nginx | cvss: 7.5 | kev: ransomware_known | due: 2024-06-15 | action_id: ACT-ZZZ\n[INFO] 07-cve: scan_complete | total: 23 | critical: 1 | high: 3 | medium: 12 | low: 7\n[INFO] 07-cve: external_sources | cisa_kev: 2_matches | osv_dev: 5_matches | nvd_api: 10_findings\n```\n\n## External Script\nCVE scan commands run via `ssh_exec(op=\"run\", sessionId, command=\"...\")` on the remote server:\n- `dpkg-query -W -f='${Package}\\t${Version}\\n'` → installed packages\n- `curl -s 'https://www.cisa.gov/...'` → CISA KEV fetch\n- `curl -s -X POST 'https://api.osv.dev/v1/querybatch'` → OSV.dev query\n- `curl -s 'https://services.nvd.nist.gov/rest/json/cves/2.0?...'` → NVD query\nResults parsed locally, advisories written to `cve/<client>/<server>/advisories/<CVE-ID>.md`.\nScan report to `cve/<client>/<server>/scan-results/YYYY-MM-DD.md`.\n\nFile v1.4.1:audit/modules/08-network.md\n\n# Module 08 — Network Audit\n\n## Commands\n```bash\n# All listening ports and which process\nss -tulpn\n# Alternative: netstat -tulpn\n\n# Active connections\nss -tnp | grep ESTABLISHED | head -20\n\n# Network interfaces\nip addr show\nip link show\n\n# Routing table\nip route\n\n# ARP table (unexpected entries?)\narp -n\n\n# DNS config\ncat /resolv.conf 2>/dev/null || cat /etc/resolv.conf\n\n# Check for promiscuous mode (sniffing)\nip link | grep PROMISC\n\n# Network sockets stats\nss -s\n```\n\n## Checks & Findings\n\n### Unexpected Open Ports\n- Compare ss output against SERVER_PROFILE.md expected ports\n- Any unlisted port open on 0.0.0.0 or :: → HIGH\n- Queue firewall rule to close: FW-YYYYMMDD-NNN\n\n### Management Ports on Public Interface\n- SSH (22) or database ports (3306, 5432, 27017) on 0.0.0.0 → HIGH\n- Should be bound to 127.0.0.1 or private IP\n\n### Promiscuous Mode\n- Any interface in promiscuous mode → HIGH (possible packet sniffing)\n\n### Unexpected Active Connections\n- Outbound connections to unknown external IPs → MEDIUM\n- Long-lived connections to suspicious IPs → HIGH\n\n### IP Forwarding\n- cat /proc/sys/net/ipv4/ip_forward\n- Enabled when not expected → MEDIUM\n\n### IPv6 Management\n- IPv6 enabled but not managed → MEDIUM advisory\n\n## Output Format\n```\n[HIGH] 08-network: unexpected_port | port: 8080 | process: python3 | bound: 0.0.0.0 | action: FW-XXX confirm\n[PASS] 08-network: expected_ports | all ports match profile\n```\n\nArchive v1.4.0: 40 files, 57617 bytes\n\nFiles: AGENT.md (7307b), AUDIT_LOG.md (56b), audit/modules/01-system.md (1500b), audit/modules/02-users.md (1781b), audit/modules/03-ssh.md (1646b), audit/modules/04-auth.md (1780b), audit/modules/05-services.md (1826b), audit/modules/06-packages.md (1304b), audit/modules/07-cve.md (10288b), audit/modules/08-network.md (1438b), audit/modules/09-firewall.md (1972b), audit/modules/10-filesystem.md (1958b), audit/modules/11-kernel.md (1882b), audit/modules/12-logs.md (1867b), audit/modules/13-crons.md (1225b), audit/modules/14-ssl.md (1473b), audit/modules/15-docker.md (2152b), audit/modules/16-disk.md (790b), audit/modules/17-integrity.md (1096b), audit/modules/18-rootkit.md (1549b), BASELINE.md (964b), crons/active/nightly-audit.md (1696b), cve/cve-scan.sh (25326b), cve/external-sources.md (10102b), hooks/audit-runner.md (8419b), hooks/mail-sender.md (1490b), hooks/on-confirm-reply.md (1910b), hooks/on-critical.md (2054b), hooks/post-action.md (993b), hooks/pre-action.md (1636b), memory/schema.json (3449b), SERVER_PROFILE.md (2754b), skill-card.md (2938b), SKILL.md (15756b), SOUL.md (3102b), STATS.md (460b), templates/finding.md (902b), templates/firewall-change.md (739b), templates/pending-action.md (940b), _meta.json (142b)\n\nFile v1.4.0:SKILL.md\n\n---\nname: linux-security-guardian\ndescription: Autonomous multi-client Linux server security management via SSH MCP. Runs full audit at 1 AM IST nightly via cron. Iterates over all clients and their server fleets. Covers system hardening, CVE scanning (CISA KEV + OSV.dev + NVD API), user auditing, SSH config, firewall rules, running services, file permissions, log analysis, SSL certs, and kernel parameters. Non-breaking actions auto-applied. Critical patches and network/firewall changes require owner confirmation. Report sent per-server and per-client via email plugin/skill (not bundled). Dependency: SSH MCP server must be running.\nversion: 1.4.0\nmetadata: {\"openclaw\": {\"emoji\": \"🛡️\", \"requires\": {\"bins\": [\"bash\",\"python3\",\"ss\",\"iptables\",\"systemctl\",\"grep\",\"awk\",\"sed\",\"find\",\"curl\"], \"mcp\": [\"ssh_conn\",\"ssh_exec\"]}}}\n---\n\n# Linux Security Guardian\n\n## ⚡ SSH MCP — REQUIRED DEPENDENCY\n\n> **SSH MCP is a hard dependency. The agent MUST have SSH MCP tools available to operate.**\n> No local/legacy fallback. All operations go through SSH MCP.\n\n### Prerequisite\n\n```yaml\n# SSH MCP server must be running and accessible\n# Tools required: ssh_conn, ssh_exec\n# Config reference: /save_data/projects/ssh_mcp/\ndependency: ssh_mcp\nstatus: required    # if unavailable → ABORT, alert owner\n```\n\n### Server Profile Config\n\nEach target server needs a saved connection in SSH MCP database. Configure in `SERVER_PROFILE.md`:\n\n```yaml\nssh_mcp:\n  connection_id: \"<id-name-or-alias-from-ssh-conn-list>\"   # Saved connection ID, Name, or Alias\n  # OR inline config:\n  # host: \"<server-ip>\"\n  # port: 22\n  # username: \"<user>\"\n  # key_path: \"</path/to/key>\"\n```\n\n### Connection Lifecycle\n\n```\n1. ssh_conn(op=\"list\") → find target server connection_id\n   → If not found → log error, ABORT audit (no fallback)\n\n2. ssh_exec(op=\"open\", connectionId) → returns sessionId\n   → If fails → log error, ABORT audit\n   → sessionId used for ALL subsequent commands\n\n3. Run commands in audit modules:\n   → Prefer passing multiple commands in a module as a sequential array to reduce overhead: `ssh_exec(op=\"run\", sessionId, command=[\"cmd1\", \"cmd2\", ...])` → returns a single commandId.\n   → Alternatively, run individually: `ssh_exec(op=\"run\", sessionId, command=\"<command>\")`.\n   → If multiple command runs are triggered concurrently, the SSH MCP server's self-healing queue handles concurrency. If the target server rejects channel opens (due to low `MaxSessions`), the MCP server dynamically drops the concurrency limit, unshifts the task, and retries with backoff.\n   → Retrieve output: `ssh_exec(op=\"logs\", commandId=commandId, stream=\"stdout\")`.\n\n4. ssh_exec(op=\"close\", sessionId) after audit complete\n```\n\n### SSH MCP Tool Usage\n\n| Operation | SSH MCP Tool | Notes |\n|-----------|-------------|-------|\n| List/Manage connections | `ssh_conn(op=\"list\")` | Find target server by name/IP |\n| Connect to server | `ssh_exec(op=\"open\", connectionId)` | Returns sessionId |\n| Execute command | `ssh_exec(op=\"run\", sessionId, command)` | Returns commandId (non-blocking) |\n| Get command output | `ssh_exec(op=\"logs\", commandId)` | Can filter: grep, head, tail, fromLine, toLine |\n| Get command status | `ssh_exec(op=\"status\", commandId)` | Check if still running |\n| Disconnect | `ssh_exec(op=\"close\", sessionId)` | Always disconnect after audit |\n| List active sessions | `ssh_exec(op=\"list\")` | Monitor active connections |\n| Bulk execution | `ssh_bulk_exec(commands, connectionIds)` | Run command(s) in bulk across servers |\n| Bulk audit checks | `ssh_bulk_audit(op, client)` | Run health/sysinfo/security checks in bulk |\n| Client CRUD management | `ssh_client(op=\"list\")` | Manage client groups and servers ownership |\n\n### Audit Modules\n\nAll 18 modules execute commands via SSH MCP. Each module file lists commands that get wrapped with `ssh_exec(op=\"run\", sessionId, command)`:\n\n```\nmodule command → ssh_exec(op=\"run\", sessionId, command=\"module command\")\n              → ssh_exec(op=\"logs\", commandId=cmdId)\n              → parse output\n```\n\n### CVE Scan\n\nThe external CVE scan runs locally (on the guardian host) using curl to CISA KEV, OSV.dev, and NVD API.\nUsage requires `--client` and `--server` to write results to per-server paths:\n\n```bash\nbash cve/cve-scan.sh --client \"client-1\" --server \"server-01\"\n\n# Writes results to:\n#   cve/<client>/<server>/scan-results/YYYY-MM-DD.md\n#   cve/<client>/<server>/advisories/<CVE-ID>.md\n```\n\nSteps:\n```bash\n# 1. SSH MCP: ssh_exec(op=\n\nArchive v1.3.0: 40 files, 55300 bytes\n\nFiles: AGENT.md (4862b), AUDIT_LOG.md (56b), audit/modules/01-system.md (1500b), audit/modules/02-users.md (1781b), audit/modules/03-ssh.md (1646b), audit/modules/04-auth.md (1780b), audit/modules/05-services.md (1826b), audit/modules/06-packages.md (1304b), audit/modules/07-cve.md (10079b), audit/modules/08-network.md (1438b), audit/modules/09-firewall.md (1972b), audit/modules/10-filesystem.md (1958b), audit/modules/11-kernel.md (1882b), audit/modules/12-logs.md (1867b), audit/modules/13-crons.md (1225b), audit/modules/14-ssl.md (1473b), audit/modules/15-docker.md (2152b), audit/modules/16-disk.md (790b), audit/modules/17-integrity.md (1096b), audit/modules/18-rootkit.md (1549b), BASELINE.md (964b), crons/active/nightly-audit.md (1078b), cve/cve-scan.sh (25129b), cve/external-sources.md (10102b), hooks/audit-runner.md (6021b), hooks/mail-sender.md (972b), hooks/on-confirm-reply.md (1501b), hooks/on-critical.md (1951b), hooks/post-action.md (916b), hooks/pre-action.md (1600b), memory/schema.json (3449b), SERVER_PROFILE.md (3564b), skill-card.md (3152b), SKILL.md (13648b), SOUL.md (2118b), STATS.md (460b), templates/finding.md (902b), templates/firewall-change.md (739b), templates/pending-action.md (940b), _meta.json (142b)\n\nArchive v1.2.0: 40 files, 54499 bytes\n\nFiles: AGENT.md (4862b), AUDIT_LOG.md (56b), audit/modules/01-system.md (1500b), audit/modules/02-users.md (1781b), audit/modules/03-ssh.md (1646b), audit/modules/04-auth.md (1780b), audit/modules/05-services.md (1826b), audit/modules/06-packages.md (1304b), audit/modules/07-cve.md (10039b), audit/modules/08-network.md (1438b), audit/modules/09-firewall.md (1972b), audit/modules/10-filesystem.md (1958b), audit/modules/11-kernel.md (1882b), audit/modules/12-logs.md (1867b), audit/modules/13-crons.md (1225b), audit/modules/14-ssl.md (1473b), audit/modules/15-docker.md (2152b), audit/modules/16-disk.md (790b), audit/modules/17-integrity.md (1096b), audit/modules/18-rootkit.md (1549b), BASELINE.md (964b), crons/active/nightly-audit.md (1078b), cve/cve-scan.sh (25129b), cve/external-sources.md (10102b), hooks/audit-runner.md (5500b), hooks/mail-sender.md (972b), hooks/on-confirm-reply.md (1501b), hooks/on-critical.md (1951b), hooks/post-action.md (916b), hooks/pre-action.md (1600b), memory/schema.json (3449b), SERVER_PROFILE.md (3559b), skill-card.md (2741b), SKILL.md (12603b), SOUL.md (2118b), STATS.md (460b), templates/finding.md (902b), templates/firewall-change.md (739b), templates/pending-action.md (940b), _meta.json (142b)\n\nArchive v1.1.0: 40 files, 54755 bytes\n\nFiles: AGENT.md (4896b), AUDIT_LOG.md (56b), audit/modules/01-system.md (1500b), audit/modules/02-users.md (1781b), audit/modules/03-ssh.md (1646b), audit/modules/04-auth.md (1780b), audit/modules/05-services.md (1826b), audit/modules/06-packages.md (1304b), audit/modules/07-cve.md (10039b), audit/modules/08-network.md (1438b), audit/modules/09-firewall.md (1972b), audit/modules/10-filesystem.md (1958b), audit/modules/11-kernel.md (1882b), audit/modules/12-logs.md (1867b), audit/modules/13-crons.md (1225b), audit/modules/14-ssl.md (1473b), audit/modules/15-docker.md (2152b), audit/modules/16-disk.md (790b), audit/modules/17-integrity.md (1096b), audit/modules/18-rootkit.md (1549b), BASELINE.md (964b), crons/active/nightly-audit.md (1042b), cve/cve-scan.sh (25129b), cve/external-sources.md (10102b), hooks/audit-runner.md (5279b), hooks/mail-sender.md (1575b), hooks/on-confirm-reply.md (1501b), hooks/on-critical.md (1777b), hooks/post-action.md (916b), hooks/pre-action.md (1600b), memory/schema.json (3449b), SERVER_PROFILE.md (3520b), skill-card.md (2968b), SKILL.md (12613b), SOUL.md (2112b), STATS.md (460b), templates/finding.md (902b), templates/firewall-change.md (739b), templates/pending-action.md (940b), _meta.json (142b)\n\nArchive v1.0.0: 38 files, 37458 bytes\n\nFiles: AGENT.md (4896b), AUDIT_LOG.md (56b), audit/modules/01-system.md (1500b), audit/modules/02-users.md (1781b), audit/modules/03-ssh.md (1646b), audit/modules/04-auth.md (1780b), audit/modules/05-services.md (1826b), audit/modules/06-packages.md (1304b), audit/modules/07-cve.md (1869b), audit/modules/08-network.md (1438b), audit/modules/09-firewall.md (1972b), audit/modules/10-filesystem.md (1958b), audit/modules/11-kernel.md (1882b), audit/modules/12-logs.md (1867b), audit/modules/13-crons.md (1225b), audit/modules/14-ssl.md (1473b), audit/modules/15-docker.md (2152b), audit/modules/16-disk.md (790b), audit/modules/17-integrity.md (1096b), audit/modules/18-rootkit.md (1549b), BASELINE.md (964b), crons/active/nightly-audit.md (872b), hooks/audit-runner.md (2556b), hooks/mail-sender.md (1575b), hooks/on-confirm-reply.md (1501b), hooks/on-critical.md (1142b), hooks/post-action.md (916b), hooks/pre-action.md (1600b), memory/schema.json (3449b), SERVER_PROFILE.md (2256b), skill-card.md (2673b), SKILL.md (7596b), SOUL.md (2112b), STATS.md (460b), templates/finding.md (902b), templates/firewall-change.md (739b), templates/pending-action.md (940b), _meta.json (142b)","readmeExcerpt":"Skill: Linux Security Guardian Owner: cyber-bye Summary: Autonomous multi-client Linux server security management via SSH MCP. Runs full audit at 1 AM IST nightly via cron. Iterates over all clients and their serve... Tags: latest:1.6.0 Version history: v1.6.0 | 2026-07-14T10:06:54.523Z | user v1.6.0 — 8 new audit modules (19-26), 5 enhanced modules, backup-restore hook - New: 19-cis-scoring (CIS benchmark alignment ","codeSnippets":[],"executableExamples":[{"language":"yaml","snippet":"# SSH MCP server must be running and accessible\ndependency: ssh_mcp\nstatus: required    # if unavailable → ABORT, alert owner"},{"language":"yaml","snippet":"ssh_mcp:\n  connection_id: \"<id-name-or-alias-from-ssh-conn-list>\"   # Saved connection ID, Name, or Alias\n  # OR inline config:\n  # host: \"<server-ip>\"\n  # port: 22\n  # username: \"<user>\"\n  # key_path: \"</path/to/key>\""},{"language":"text","snippet":"module command → ssh_exec(op=\"run\", sessionId, command=\"module command\")\n              → ssh_exec(op=\"logs\", commandId=cmdId)\n              → parse output"},{"language":"bash","snippet":"bash cve/cve-scan.sh --client \"client-1\" --server \"server-01\"\n\n# Writes results to:\n#   cve/<client>/<server>/scan-results/YYYY-MM-DD.md\n#   cve/<client>/<server>/advisories/<CVE-ID>.md"},{"language":"bash","snippet":"# 1. SSH MCP: ssh_exec(op=\"run\", sessionId, command=\"dpkg-query -W ...\") → save locally\n# 2. Read from cve/<client>/<server>/scan-results/installed-packages.txt\n# 3. curl CISA KEV → filter Linux entries → write advisories\n# 4. curl POST OSV.dev batch → match packages → write advisories\n# 5. curl NVD API (optional) → cross-check → write advisories"},{"language":"text","snippet":"At session start → load core-extra/config/profile.md\n→ Owner.name  → used in SOUL.md [WORKSPACE OWNER]\n→ Email.noreply → used as from: in mail-sender.md\n→ Domain.primary → used in config generation\n\nTo change: edit core-extra/config/profile.md only."}],"parameters":null,"dependencies":[],"permissions":[],"extractedFiles":[{"path":"SKILL.md","content":"---\nname: linux-security-guardian\ndescription: Autonomous multi-client Linux server security management via SSH MCP. Runs full audit at 1 AM IST nightly via cron. Iterates over all clients and their server fleets. Covers system hardening, CVE scanning (CISA KEV + OSV.dev + NVD API), user auditing, SSH config (incl. weak ciphers/MACs/Kex), firewall rules, running services, file permissions, log analysis, SSL certs, kernel parameters (incl. BPF restrictions), Docker daemon security defaults (userns-remap, no-new-privileges, seccomp), fail2ban auto-install, unattended-upgrades auto-enable, CIS benchmark scoring, systemd sandbox analysis, AppArmor/SELinux audit, and swap encryption check. Non-breaking actions auto-applied. Critical patches and network/firewall changes require owner confirmation. Report sent per-server and per-client via email plugin/skill (not bundled). All owner-specific config lives in core-extra/config/ — no hardcoded names, domains, or emails.\nversion: 1.6.0\nmetadata: {\"openclaw\": {\"emoji\": \"🛡️\", \"requires\": {\"bins\": [\"bash\",\"python3\",\"ss\",\"iptables\",\"systemctl\",\"grep\",\"awk\",\"sed\",\"find\",\"curl\"], \"mcp\": [\"ssh_conn\",\"ssh_exec\"]}}}\n---\n\n# Linux Security Guardian\n\n## ⚡ SSH MCP — REQUIRED DEPENDENCY\n\n> **SSH MCP is a hard dependency. The agent MUST have SSH MCP tools available to operate.**\n> No local/legacy fallback. All operations go through SSH MCP.\n\n### Prerequisite\n\n```yaml\n# SSH MCP server must be running and accessible\ndependency: ssh_mcp\nstatus: required    # if unavailable → ABORT, alert owner\n```\n\n### Server Profile Config\n\nEach target server needs a saved connection in SSH MCP database. Configure in `SERVER_PROFILE.md`:\n\n```yaml\nssh_mcp:\n  connection_id: \"<id-name-or-alias-from-ssh-conn-list>\"   # Saved connection ID, Name, or Alias\n  # OR inline config:\n  # host: \"<server-ip>\"\n  # port: 22\n  # username: \"<user>\"\n  # key_path: \"</path/to/key>\"\n```\n\n### Audit Modules\n\nAll 26 modules execute commands via SSH MCP. Each module file lists commands that get wrapped with `ssh_exec(op=\"run\", sessionId, command)`:\n\n```\nmodule command → ssh_exec(op=\"run\", sessionId, command=\"module command\")\n              → ssh_exec(op=\"logs\", commandId=cmdId)\n              → parse output\n```\n\n### CVE Scan\n\nThe external CVE scan runs locally (on the guardian host) using curl to CISA KEV, OSV.dev, and NVD API.\nUsage requires `--client` and `--server` to write results to per-server paths:\n\n```bash\nbash cve/cve-scan.sh --client \"client-1\" --server \"server-01\"\n\n# Writes results to:\n#   cve/<client>/<server>/scan-results/YYYY-MM-DD.md\n#   cve/<client>/<server>/advisories/<CVE-ID>.md\n```\n\nSteps:\n```bash\n# 1. SSH MCP: ssh_exec(op=\"run\", sessionId, command=\"dpkg-query -W ...\") → save locally\n# 2. Read from cve/<client>/<server>/scan-results/installed-packages.txt\n# 3. curl CISA KEV → filter Linux entries → write advisories\n# 4. curl POST OSV.dev batch → match packages → write advisories\n# 5. curl NVD API (optional) → cross-check → write advisories\n```\n\n---"},{"path":"_meta.json","content":"{\n  \"ownerId\": \"kn79djxt41q03wtr3nth5h8y8184mgcm\",\n  \"slug\": \"linux-security-guardian\",\n  \"version\": \"1.6.0\",\n  \"publishedAt\": 1784023614523\n}"},{"path":"AGENT.md","content":"---\nname: linux-security-guardian-agent\ndescription: Behavioral rules for linux-security-guardian. Multi-client, SSH MCP hard dependency, safe-first actions, mandatory confirmations for critical changes, complete audit coverage.\n---\n\n# Agent Rules — Linux Security Guardian\n\n## THE PRIME RULE — SAFE FIRST\n\nWhen in doubt about whether an action is safe: DON'T DO IT.\nLog it. Alert owner. Wait for explicit approval.\nA delayed fix is always better than an accidental outage.\n\n---\n\n## Rule 1 — SSH MCP Hard Dependency\n\nSSH MCP is a hard dependency. The agent MUST have SSH MCP tools available to operate.\n\n```yaml\nrequired_tools: [ssh_conn, ssh_exec]\nversion: v2  # 13 tools: ssh_conn, ssh_exec, ssh_bulk_exec, ssh_bulk_audit, ssh_client, etc.\n```\n\nIf SSH MCP tools are unavailable → ABORT audit, alert owner: \"SSH MCP not available\".\nNo local/legacy fallback. All operations go through SSH MCP.\n\n---\n\n## Rule 2 — Multi-Client Audit Flow\n\nSERVER_PROFILE.md contains one or more `## Client:` sections.\nThe audit MUST iterate over ALL clients and ALL servers:\n\n```\nfor each client in SERVER_PROFILE.md:\n  for each server in client.server_fleet:\n    ssh_conn → test/save connection if needed\n    ssh_exec(op=\"open\", connectionId) → sessionId\n    Run all 26 modules via ssh_exec(op=\"run\", sessionId, ...)\n    Compile per-server findings → audit/results/<client>/<server>/<severity>/\n    Compile per-server report → reports/<client>/<server>/daily/YYYY-MM-DD.md\n    ssh_exec(op=\"close\", sessionId)\n  Compile per-client summary\nAppend master report\nSend via default email account\n```\n\n---\n\n## Rule 3 — Email Account Selection\n\n- **Default account**: Used for ALL outgoing reports and alerts.\n- **Admin account**: Personal account. NEVER use for automated reports.\n- Rule: Always use default account. Never specify `--account admin`.\n- Check available accounts: `himalaya account list` (identify default vs admin).\n- If no email plugin available → log to AUDIT_LOG.md, report is on disk. Non-fatal.\n\n---\n\n## Rule 4 — Read SERVER_PROFILE.md Before Every Audit\n\nLoad SERVER_PROFILE.md at audit start.\nParse each `## Client:` section. Extract server fleet table.\nExpected ports, services, users, SUID list — all per-server from this file.\nDeviation from profile = finding.\nProfile not filled = abort audit, alert owner.\n\n---\n\n## Rule 5 — Auto-Actions Whitelist Only\n\nAgent can ONLY auto-execute actions listed in SERVER_PROFILE.md under `Auto-Actions Allowed`.\nAnything not explicitly whitelisted → queue for confirmation.\nNo exceptions. Owner preference > agent judgment.\n\nAuto-action execution:\n1. Run pre-action safety check (hooks/pre-action.md)\n2. Execute action via SSH MCP\n3. Verify result (hooks/post-action.md)\n4. Log to actions/<client>/<server>/auto-done/\n5. Include in email report\n\n---\n\n## Rule 6 — Confirmation Queue Protocol\n\nWhen action requires confirmation:\n1. Generate unique ID: `ACT-YYYYMMDD-NNN`\n2. Write to actions/<client>/<server>/pending-confirm/<id>-<slug>.md\n3. Include in email repor"},{"path":"AUDIT_LOG.md","content":"# Audit Log\n*Append-only. One entry per audit run.*\n---"},{"path":"audit/modules/01-system.md","content":"# Module 01 — System Info\n\n## Commands\n```bash\nuname -r                           # kernel version\nuname -a                           # full kernel info\nlsb_release -a 2>/dev/null        # OS info\ncat /etc/os-release                # OS info fallback\nuptime -p                          # uptime\nlast reboot | head -5              # reboot history\ndf -h                              # disk usage\nfree -h                            # memory\nnproc                              # CPU count\ncat /proc/cpuinfo | grep \"model name\" | head -1\ntimedatectl                        # NTP sync status\n```\n\n## Checks & Findings\n\n### OS EOL Check\n- Ubuntu 20.04 LTS → EOL April 2025 → if still running: HIGH finding\n- Ubuntu 22.04 LTS → EOL April 2027 → OK\n- Ubuntu 24.04 LTS → EOL April 2029 → OK\n- Debian 11 → EOL June 2026 → OK\n- Debian 10 → EOL June 2024 → HIGH if still running\n\n### Kernel Version Check\n- Compare against latest stable for the distro\n- More than 2 major versions behind → HIGH\n- Security patch available → MEDIUM\n\n### NTP Sync\n- timedatectl | grep \"NTP service: active\" → PASS\n- NTP not synced → MEDIUM (time drift breaks certs/logs)\n\n### Disk Usage\n- < 80% → PASS\n- 80-85% → LOW\n- 85-95% → WARNING\n- > 95% → CRITICAL (auto-alert)\n\n### Last Reboot\n- No reboot in > 90 days with kernel updates pending → MEDIUM\n- Server rebooted unexpectedly (not matching known maintenance) → HIGH\n\n## Output Format\n```\n[PASS/FINDING] 01-system: <check> | <result>\n```"}],"languages":[],"docsSourceLabel":"CLAWHUB","editorialOverview":"Autonomous multi-client Linux server security management via SSH MCP. Runs full audit at 1 AM IST nightly via cron. Iterates over all clients and their serve... Skill: Linux Security Guardian Owner: cyber-bye Summary: Autonomous multi-client Linux server security management via SSH MCP. Runs full audit at 1 AM IST nightly via cron. Iterates over all clients and their serve... Tags: latest:1.6.0 Version history: v1.6.0 | 2026-07-14T10:06:54.523Z | user v1.6.0 — 8 new audit modules (19-26), 5 enhanced modules, backup-restore hook - New: 19-cis-scoring (CIS benchmark alignment","editorialQuality":{"score":100,"threshold":65,"status":"ready","wordCount":1598,"uniquenessScore":48,"reasons":[]}},"media":{"evidence":{"source":"no-media","verified":false,"confidence":"low","updatedAt":"2026-10-10T17:55:01.674Z","emptyReason":"No screenshots, media assets, or demo links are available."},"primaryImageUrl":null,"mediaAssetCount":0,"assets":[],"demoUrl":null},"ownerResources":{"evidence":{"source":"unclaimed","verified":false,"confidence":"low","updatedAt":"2026-10-10T17:55:01.674Z","emptyReason":"This page has not been claimed by the agent owner."},"hasCustomPage":false,"customPageUpdatedAt":null,"customLinks":[],"structuredLinks":{"docsUrl":null,"demoUrl":null,"supportUrl":null,"pricingUrl":null,"statusUrl":null},"customPage":null},"relatedAgents":{"evidence":{"source":"protocol-neighbors","verified":false,"confidence":"medium","updatedAt":"2026-10-10T21:42:16.458Z","emptyReason":null},"items":[{"id":"8ebccd8e-3863-4187-8355-c3f14e1f9edf","entityType":"agent","canonicalPath":"/agent/iofficeai-aionui","slug":"iofficeai-aionui","name":"AionUi","description":"Free, local, open-source 24/7 Cowork app and OpenClaw for Gemini CLI, Claude Code, Codex, OpenCode, Qwen Code, Goose CLI, Auggie, and more | 🌟 Star if you like it!","url":"https://github.com/iOfficeAI/AionUi","homepage":"https://www.aionui.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-10-09T19:11:12.944Z","createdAt":"2026-02-25T03:38:16.584Z","downloads":null},{"id":"b917f68a-ebff-438e-84f8-3f4b2494c0bc","entityType":"agent","canonicalPath":"/agent/activepieces-activepieces","slug":"activepieces-activepieces","name":"activepieces","description":"AI Agents & MCPs & AI Workflow Automation • (~400 MCP servers for AI agents) • AI Automation / AI Agent with MCPs • AI Workflows & AI Agents • MCPs for AI Agents","url":"https://github.com/activepieces/activepieces","homepage":"https://www.activepieces.com","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-15T02:22:12.426Z","createdAt":"2026-02-25T03:38:12.412Z","downloads":null},{"id":"5cb26759-3a39-483f-94cf-276a98c13bb8","entityType":"agent","canonicalPath":"/agent/cherryhq-cherry-studio","slug":"cherryhq-cherry-studio","name":"cherry-studio","description":"AI productivity studio with smart chat, autonomous agents, and 300+ assistants. Unified access to frontier LLMs","url":"https://github.com/CherryHQ/cherry-studio","homepage":"https://cherry-ai.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-11T14:38:40.986Z","createdAt":"2026-02-25T03:38:19.379Z","downloads":null},{"id":"6f6582d0-5d76-4f0f-b81d-86520247950b","entityType":"agent","canonicalPath":"/agent/copilotkit-copilotkit","slug":"copilotkit-copilotkit","name":"CopilotKit","description":"The Frontend for Agents & Generative UI. React + Angular","url":"https://github.com/CopilotKit/CopilotKit","homepage":"https://docs.copilotkit.ai","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-03-25T09:50:57.846Z","createdAt":"2026-02-25T03:39:14.617Z","downloads":null}],"links":{"hub":"/agent","source":"/agent/source/clawhub","protocols":[{"label":"OpenClaw","href":"/agent/protocol/openclew"}]}}}