Skill: cyber-bye/linux-security-guardian (version 1.4.0)

--- name: linux-security-guardian 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 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. version: 1.4.0 metadata: {"openclaw": {"emoji": "🛡️", "requires": {"bins": ["bash","python3","ss","iptables","systemctl","grep","awk","sed","find","curl"], "mcp": ["ssh_conn","ssh_exec"]}}} --- # Linux Security Guardian ## ⚡ SSH MCP — REQUIRED DEPENDENCY > **SSH MCP is a hard dependency. The agent MUST have SSH MCP tools available to operate.** > No local/legacy fallback. All operations go through SSH MCP. ### Prerequisite ```yaml # SSH MCP server must be running and accessible # Tools required: ssh_conn, ssh_exec # Config reference: /save_data/projects/ssh_mcp/ dependency: ssh_mcp status: required # if unavailable → ABORT, alert owner ``` ### Server Profile Config Each target server needs a saved connection in SSH MCP database. Configure in `SERVER_PROFILE.md`: ```yaml ssh_mcp: connection_id: "<id-name-or-alias-from-ssh-conn-list>" # Saved connection ID, Name, or Alias # OR inline config: # host: "<server-ip>" # port: 22 # username: "<user>" # key_path: "</path/to/key>" ``` ### Connection Lifecycle ``` 1. ssh_conn(op="list") → find target server connection_id → If not found → log error, ABORT audit (no fallback) 2. ssh_exec(op="open", connectionId) → returns sessionId → If fails → log error, ABORT audit → sessionId used for ALL subsequent commands 3. Run commands in audit modules: → 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. → Alternatively, run individually: `ssh_exec(op="run", sessionId, command="<command>")`. → 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. → Retrieve output: `ssh_exec(op="logs", commandId=commandId, stream="stdout")`. 4. ssh_exec(op="close", sessionId) after audit complete ``` ### SSH MCP Tool Usage | Operation | SSH MCP Tool | Notes | |-----------|-------------|-------| | List/Manage connections | `ssh_conn(op="list")` | Find target server by name/IP | | Connect to server | `ssh_exec(op="open", connectionId)` | Returns sessionId | | Execute command | `ssh_exec(op="run", sessionId, command)` | Returns commandId (non-blocking) | | Get command output | `ssh_exec(op="logs", commandId)` | Can filter: grep, head, tail, fromLine, toLine | | Get command status | `ssh_exec(op="status", commandId)` | Check if still running | | Disconnect | `ssh_exec(op="close", sessionId)` | Always disconnect after audit | | List active sessions | `ssh_exec(op="list")` | Monitor active connections | | Bulk execution | `ssh_bulk_exec(commands, connectionIds)` | Run command(s) in bulk across servers | | Bulk audit checks | `ssh_bulk_audit(op, client)` | Run health/sysinfo/security checks in bulk | | Client CRUD management | `ssh_client(op="list")` | Manage client groups and servers ownership | ### Audit Modules All 18 modules execute commands via SSH MCP. Each module file lists commands that get wrapped with `ssh_exec(op="run", sessionId, command)`: ``` module command → ssh_exec(op="run", sessionId, command="module command") → ssh_exec(op="logs", commandId=cmdId) → parse output ``` ### CVE Scan The external CVE scan runs locally (on the guardian host) using curl to CISA KEV, OSV.dev, and NVD API. Usage requires `--client` and `--server` to write results to per-server paths: ```bash bash cve/cve-scan.sh --client "client-1" --server "server-01" # Writes results to: # cve/<client>/<server>/scan-results/YYYY-MM-DD.md # cve/<client>/<server>/advisories/<CVE-ID>.md ``` Steps: ```bash # 1. SSH MCP: ssh_exec(op="run", sessionId, command="dpkg-query -W ...") → save locally # 2. Read from cve/<client>/<server>/scan-results/installed-packages.txt # 3. curl CISA KEV → filter Linux entries → write advisories # 4. curl POST OSV.dev batch → match packages → write advisories # 5. curl NVD API (optional) → cross-check → write advisories ``` --- ## Multi-Client Architecture The guardian manages **multiple clients**, each with their own server fleet. SERVER_PROFILE.md defines `## Client:` sections. The audit iterates ALL. ``` SERVER_PROFILE.md ├── ## Client: client-1 (7 servers) │ ├── server-01 │ ├── server-02 │ └── ... server-07 ├── ## Client: client-2 (N servers) ← add as needed │ └── ... └── ## Client: [NEXT-CLIENT] ``` All paths use `<client>/<server>/` prefix: - Findings: `audit/results/<client>/<server>/<severity>/` - Actions: `actions/<client>/<server>/auto-done/` - CVEs: `cve/<client>/<server>/advisories/` - Reports: `reports/<client>/<server>/daily/` --- ## Purpose Agent manages complete Linux server security autonomously via SSH MCP. Every night at 1 AM IST: - Iterates all clients → all servers - Full security audit runs via SSH MCP - CVEs scanned against installed packages - Auto-fixes applied for safe issues - Critical issues queued for owner confirmation - Per-server, per-client, and master email reports delivered --- ## Action Decision Matrix The most important thing — what agent does vs what it asks first: | Finding Type | CVSS / Severity | Action | |---|---|---| | CVE — Critical | ≥ 9.0 | EMAIL ALERT immediately + queue for confirm | | CVE — High | 7.0–8.9 | Queue for confirm + include in report | | CVE — Medium | 4.0–6.9 | Include in report + advisory | | CVE — Low | < 4.0 | Info in report only | | CVE — KEV (CISA) | any | **Treated as CRITICAL** — immediate alert + confirm within due date | | CVE — KEV + Ransomware | any | **🔥 HIGHEST PRIORITY** — immediate alert, confirm ASAP | | Kernel update available | any | Confirm required before patch | | Security-only pkg update | any | Confirm required | | SSH: PermitRootLogin yes | critical | Alert + confirm to fix | | SSH: PasswordAuth yes | high | Alert + confirm to fix | | SSH: Port 22 | medium | Advisory only | | Empty password account | critical | AUTO-LOCK immediately | | Unknown root-uid account | critical | Alert + confirm to lock | | Inactive account > 90d | medium | Alert + confirm to lock | | World-writable /tmp | medium | AUTO-FIX chmod | | World-writable system dir | high | Alert + confirm to fix | | Unexpected SUID binary | high | Alert only (owner decides) | | Failed login spike > 20/hr | high | Alert immediately | | New unknown cron job | high | Alert immediately | | Firewall rule change needed | any | CONFIRM REQUIRED always | | Open unexpected port | high | Alert + confirm to close | | Service: unnecessary running | medium | Alert + confirm to stop | | SSL cert expiring < 30d | warning | Alert | | SSL cert expired | critical | Alert immediately | | Disk > 85% full | warning | Alert | | Disk > 95% full | critical | Alert immediately | | Auditd not running | high | AUTO-START + alert | | fail2ban not running | high | AUTO-START + alert | | Log file suspicious entry | high | Alert with extract | --- ## Audit Modules | Module | What it checks | SSH MCP Command | |--------|---------------|-----------------| | `01-system` | OS, kernel, uptime, last reboot, hardware | `ssh_exec(op="run", sessionId, command="uname -a; cat /etc/*release")` | | `02-users` | Accounts, root access, sudo, empty passwords, inactive | `ssh_exec(op="run", sessionId, command="cat /etc/passwd; cat /etc/shadow; ...")` | | `03-ssh` | sshd_config full audit — 20+ checks | `ssh_exec(op="run", sessionId, command="cat /etc/ssh/sshd_config")` | | `04-auth` | Login history, failed logins, PAM config | `ssh_exec(op="run", sessionId, command="last; cat /var/log/auth.log")` | | `05-services` | Running services, unnecessary ones, failed units | `ssh_exec(op="run", sessionId, command="systemctl list-units ...")` | | `06-packages` | Pending updates, security updates count | `ssh_exec(op="run", sessionId, command="apt list --upgradable 2>/dev/null")` | | `07-cve` | CVE scan — remote via SSH MCP + API-based | `ssh_exec(op="run", sessionId, command="dpkg-query -W ...; curl ...")` | | `08-network` | Open ports, listening services, active connections | `ssh_exec(op="run", sessionId, command="ss -tulpn; netstat -tulpn")` | | `09-firewall` | iptables/nftables/ufw rules audit | `ssh_exec(op="run", sessionId, command="iptables-save 2>/dev/null")` | | `10-filesystem` | SUID/SGID, world-writable, /tmp, sticky bits | `ssh_exec(op="run", sessionId, command="find / -perm -4000 ...")` | | `11-kernel` | sysctl security params — 15+ checks | `ssh_exec(op="run", sessionId, command="sysctl -a 2>/dev/null")` | | `12-logs` | auth.log, syslog, kern.log — anomaly scan | `ssh_exec(op="run", sessionId, command="tail -100 /var/log/syslog")` | | `13-crons` | System + user cron jobs — unknown jobs flagged | `ssh_exec(op="run", sessionId, command="cat /etc/crontab; ls -la /var/spool/cron/")` | | `14-ssl` | Cert expiry check for all domains/services | `ssh_exec(op="run", sessionId, command="openssl x509 -in ... -noout -dates")` | | `15-docker` | If running — image vulns, container config | `ssh_exec(op="run", sessionId, command="docker ps; docker images")` | | `16-disk` | Disk usage, inode usage | `ssh_exec(op="run", sessionId, command="df -h; df -i")` | | `17-integrity` | AIDE/tripwire check if installed | `ssh_exec(op="run", sessionId, command="aide --check")` | | `18-rootkit` | rkhunter/chkrootkit if installed | `ssh_exec(op="run", sessionId, command="rkhunter --check --skip-keypress")` | **Execution rule**: All commands go through `ssh_exec(op="run", sessionId, command="<command>")` → `ssh_exec(op="logs", commandId=cmdId)`. No local execution. --- ## Finding Severity Levels | Level | Color | Meaning | |---|---|---| | `CRITICAL` | 🔴 | Immediate risk, action required now | | `HIGH` | 🟠 | Significant risk, fix this week | | `MEDIUM` | 🟡 | Moderate risk, fix this month | | `LOW` | 🔵 | Minor issue, fix when possible | | `INFO` | ⚪ | Informational, no action needed | | `PASS` | 🟢 | Check passed, all good | --- ## Confirmation Flow When owner confirmation is needed: ``` Finding detected (requires confirm) on <client>/<server> ↓ Write to actions/<client>/<server>/pending-confirm/<client>-<server>-<id>-<slug>.md ↓ Include in email report under "NEEDS YOUR DECISION" with <client>/<server> context ↓ Owner replies with: APPROVE <id> / DENY <id> / SKIP <id> (Full ID format: <client>-<server>-<type>-<NNN>, e.g. client-1-server-01-ACT-20260529-001) ↓ Search all actions/*/*/pending-confirm/ for the ID ↓ APPROVE → agent connects to <client>/<server> via SSH MCP → executes action → logs to history/ DENY → action skipped, noted SKIP → deferred to next audit ``` --- ## Email Report Structure Reports are sent per-server, per-client (summary), and master. All via email plugin/skill. ### Per-Server Report ``` Subject: [Linux Guardian] <client>/<server> — YYYY-MM-DD | Score: N/100 | CRITICAL:N HIGH:N ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ LINUX SECURITY GUARDIAN — NIGHTLY REPORT Client: <client> | Server: <server> | <IP> | YYYY-MM-DD 01:00 IST ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ EXECUTIVE SUMMARY Security Score: N/100 | Grade: X Critical: N | High: N | Medium: N | Low: N Auto-fixed: N | Pending confirm: N | Passed: N ━━ 🔴 CRITICAL (immediate action needed) [Finding details] ━━ 🟠 HIGH [Finding details] ━━ ⚡ AUTO-ACTIONS TAKEN (safe, non-breaking) [What was auto-fixed] ━━ 🔑 NEEDS YOUR DECISION (reply APPROVE/DENY/SKIP <id>) [Pending confirmations with IDs — includes <client>/<server> prefix] ━━ 📦 CVE REPORT [CVEs found by severity] ━━ 🌐 NETWORK & FIREWALL [Port/firewall status] ━━ 🟡 MEDIUM / LOW [Less urgent findings] ━━ 🟢 ALL PASSING [Checks that passed] ━━ NEXT AUDIT: Tomorrow 01:00 IST ``` ### Per-Client Summary Report ``` Subject: [Linux Guardian] <client> Summary — YYYY-MM-DD | Servers: N/N | CRITICAL:N HIGH:N Client: <client> Servers audited: N of N total Average score: N/100 | Server | Score | Critical | High | Score Grade | |--------|-------|----------|------|-------------| | ... | ... | ... | ... | ... | Cross-server patterns: [same vuln found on multiple servers] ``` --- ## Security Score Formula ``` score = 100 score -= (critical_count × 20) score -= (high_count × 10) score -= (medium_count × 3) score -= (low_count × 1) score = max(0, score) Grade: 90-100 = A | 75-89 = B | 60-74 = C | < 60 = F ``` --- ## Folder Structure ``` linux-security-guardian/ audit/ modules/ ← 01-system.md ... 18-rootkit.md results/ <client>/<server>/ critical/ high/ warning/ info/ pass/ YYYY-MM-DD-<check>.md ← per-client/per-server findings actions/ <client>/<server>/ auto-done/ ← auto-fixed actions (logged) YYYY-MM-DD-<slug>.md pending-confirm/ ← waiting for owner <id>-<slug>.md history/ ← all approved/denied actions cve/ cve-scan.sh ← external CVE scanner (takes --client --server) external-sources.md ← all API URLs, query params, working examples .cache/ ← shared cached API responses (6h TTL) <client>/<server>/ scan-results/ ← YYYY-MM-DD.md advisories/ ← <cve-id>.md reports/ <client>/<server>/ daily/YYYY-MM-DD.md weekly/YYYY-WNN.md network/ <client>/<server>/ firewall-snapshots/ ← YYYY-MM-DD-rules.txt port-scans/ ← YYYY-MM-DD.md proposed-changes/ ← <id>-<change>.md hooks/ audit-runner.md ← main 1 AM audit orchestrator (multi-client loop) on-critical.md ← fires on any critical finding (with client/server) on-confirm-reply.md ← processes owner APPROVE/DENY/SKIP pre-action.md ← safety check before any action post-action.md ← verify action succeeded mail-sender.md ← uses email plugin/skill to send report crons/ active/ nightly-audit.md ← 1 AM IST permanent completed/ errors/ raw/ ← raw error logs memory/ schema.json index.json SOUL.md ← soul context (multi-client aware) AGENT.md ← behavioral rules (multi-client, SSH MCP hard dep) SERVER_PROFILE.md ← multi-client server details AUDIT_LOG.md ← append-only master log BASELINE.md ← expected state snapshot STATS.md ```


Security scan verdicts — ClawScan: suspicious | static analysis: clean | VirusTotal: clean | SkillSpector: suspicious (CRITICAL)