Linux Security Guardian

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...

vk

@cyber-bye

What This Skill Does

Autonomous multi-client Linux server security management tool that runs nightly audits via SSH MCP. Covers 26 modules including system hardening, CVE scanning (CISA KEV, OSV.dev, NVD), user auditing, SSH config, firewall rules, Docker security, fail2ban, unattended-upgrades, CIS benchmarking, and AppArmor/SELinux checks. Non-breaking fixes auto-apply; critical changes require owner approval.

Replaces manual server-by-server security audits and scattered security scripts by automating comprehensive nightly checks across all clients with auto-remediation and owner confirmation for critical changes.

When to Use It

  • Run a full security audit across all managed Linux servers at 1 AM IST nightly
  • Scan servers for known CVEs using CISA KEV, OSV.dev, and NVD databases
  • Auto-apply non-breaking security fixes like fail2ban install and unattended-upgrades
  • Audit SSH configurations for weak ciphers, MACs, and Kex algorithms
  • Check Docker daemon security defaults including userns-remap and seccomp profiles
  • Generate per-server and per-client security reports with CIS benchmark scores

Install

$ openclaw skills install @cyber-bye/linux-security-guardian

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

# SSH MCP server must be running and accessible
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:

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>"

Audit Modules

All 26 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 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:

# 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

Core-Extra Config System

All owner-specific data lives in core-extra/config/never hardcoded in hooks or modules.

Profile

FileContainsFields
core-extra/config/profile.mdOwner identity + domain + emailOwner.name, Domain.primary, Email.noreply

How Agents Use It

At session start → load core-extra/config/profile.md
→ Owner.name  → used in SOUL.md [WORKSPACE OWNER]
→ Email.noreply → used as from: in mail-sender.md
→ Domain.primary → used in config generation

To change: edit core-extra/config/profile.md only.

Rule

  • NO hardcoded names, domains, or emails in hooks/, modules/, or root files
  • All personal/owner data comes from core-extra/config/profile.md
  • The core-extra directory is part of the skill (published to ClawHub with placeholders)
  • Owner fills profile.md ONCE after install

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 TypeCVSS / SeverityAction
CVE — Critical≥ 9.0EMAIL ALERT immediately + queue for confirm
CVE — High7.0–8.9Queue for confirm + include in report
CVE — Medium4.0–6.9Include in report + advisory
CVE — Low< 4.0Info in report only
CVE — KEV (CISA)anyTreated as CRITICAL — immediate alert + confirm within due date
CVE — KEV + Ransomwareany🔥 HIGHEST PRIORITY — immediate alert, confirm ASAP
Kernel update availableanyConfirm required before patch
Security-only pkg updateanyConfirm required
SSH: PermitRootLogin yescriticalAlert + confirm to fix
SSH: PasswordAuth yeshighAlert + confirm to fix
SSH: Port 22mediumAdvisory only
Empty password accountcriticalAUTO-LOCK immediately
Unknown root-uid accountcriticalAlert + confirm to lock
Inactive account > 90dmediumAlert + confirm to lock
World-writable /tmpmediumAUTO-FIX chmod
World-writable system dirhighAlert + confirm to fix
Unexpected SUID binaryhighAlert only (owner decides)
Failed login spike > 20/hrhighAlert immediately
New unknown cron jobhighAlert immediately
Firewall rule change neededanyCONFIRM REQUIRED always
Open unexpected porthighAlert + confirm to close
Service: unnecessary runningmediumAlert + confirm to stop
SSL cert expiring < 30dwarningAlert
SSL cert expiredcriticalAlert immediately
Disk > 85% fullwarningAlert
Disk > 95% fullcriticalAlert immediately
Auditd not runninghighAUTO-START + alert
fail2ban not runninghighAUTO-START + alert
Log file suspicious entryhighAlert with extract

Audit Modules

ModuleWhat it checksSSH MCP Command
01-systemOS, kernel, uptime, last reboot, hardwaressh_exec(op="run", sessionId, command="uname -a; cat /etc/*release")
02-usersAccounts, root access, sudo, empty passwords, inactivessh_exec(op="run", sessionId, command="cat /etc/passwd; cat /etc/shadow; ...")
03-sshsshd_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
04-authLogin history, failed logins, PAM config, fail2ban auto-install + SSH jail config, password policy enforcementssh_exec(op="run", sessionId, command="last; cat /var/log/auth.log")
05-servicesRunning services, unnecessary ones, failed unitsssh_exec(op="run", sessionId, command="systemctl list-units ...")
06-packagesPending updates, security updates count, unattended-upgrades auto-enable (security-only)ssh_exec(op="run", sessionId, command="apt list --upgradable 2>/dev/null")
07-cveCVE scan — remote via SSH MCP + API-basedssh_exec(op="run", sessionId, command="dpkg-query -W ...; curl ...")
08-networkOpen ports, listening services, active connectionsssh_exec(op="run", sessionId, command="ss -tulpn; netstat -tulpn")
09-firewalliptables/nftables/ufw rules auditssh_exec(op="run", sessionId, command="iptables-save 2>/dev/null")
10-filesystemSUID/SGID, world-writable, /tmp, sticky bitsssh_exec(op="run", sessionId, command="find / -perm -4000 ...")
11-kernelsysctl security params — 15+ checks + BPF restrictions (unprivileged_bpf_disabled, bpf_jit_enable)ssh_exec(op="run", sessionId, command="sysctl -a 2>/dev/null")
12-logsauth.log, syslog, kern.log — anomaly scanssh_exec(op="run", sessionId, command="tail -100 /var/log/syslog")
13-cronsSystem + user cron jobs — unknown jobs flaggedssh_exec(op="run", sessionId, command="cat /etc/crontab; ls -la /var/spool/cron/")
14-sslCert expiry check for all domains/servicesssh_exec(op="run", sessionId, command="openssl x509 -in ... -noout -dates")
15-dockerIf 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")
16-diskDisk usage, inode usagessh_exec(op="run", sessionId, command="df -h; df -i")
17-integrityAIDE/tripwire check if installedssh_exec(op="run", sessionId, command="aide --check")
18-rootkitrkhunter/chkrootkit if installedssh_exec(op="run", sessionId, command="rkhunter --check --skip-keypress")
19-cis-scoringCIS benchmark alignment score across all modules(aggregated from all modules)
20-systemd-analyzesystemd service sandboxing — 80+ security directives per servicessh_exec(op="run", sessionId, command="systemd-analyze security --json=short 2>/dev/null")
21-mount-hardeningMount point security — noexec, nosuid, nodev on /tmp, /dev/shm, /var/tmp`ssh_exec(op="run", sessionId, command="mount
22-apparmor-selinuxAppArmor/SELinux MAC status — enforcement mode, confined processes`ssh_exec(op="run", sessionId, command="aa-status 2>/dev/null
23-proc-hidepid/proc hidepid enforcement — process visibility isolation`ssh_exec(op="run", sessionId, command="mount
24-swap-encryptionSwap partition encryption — LUKS/dm-crypt checkssh_exec(op="run", sessionId, command="swapon --show 2>/dev/null")
25-usbguardUSB device authorization — USBGuard policy and daemon statusssh_exec(op="run", sessionId, command="systemctl is-active usbguard")
26-ipv6-auditIPv6 security — RA acceptance, redirects, privacy extensions, NDP hardeningssh_exec(op="run", sessionId, command="sysctl net.ipv6.conf.all.disable_ipv6")

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

LevelColorMeaning
CRITICAL🔴Immediate risk, action required now
HIGH🟠Significant risk, fix this week
MEDIUM🟡Moderate risk, fix this month
LOW🔵Minor issue, fix when possible
INFOInformational, 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 ... 26-ipv6-audit.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/

  core-extra/
    config/
      profile.md                 ← owner name, domain, email (fill ONCE, no hardcode)
    hooks/                       ← shared hooks (mirrors hooks/ structure)
    templates/                   ← shared templates

  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

Top skills in this category