2026年部署OpenClaw Skills实战记录:零基础用户从零打造远程服务器巡检技能

简介: 在AIOps领域飞速发展的今天,Agent Skills凭借轻量化、高定制性的优势,逐渐替代传统MCP方案,成为智能运维的核心工具。而OpenClaw作为开源AI助手的佼佼者,不仅支持多平台对接与本地部署,更提供了极简的Skills定制能力——无需复杂编码,通过自然语言交互即可生成专属功能模块。本文以企业高频需求的“远程Linux服务器巡检”为例,详细拆解OpenClaw Skills的开发全流程,涵盖需求定义、交互配置、文件解析、测试优化等核心环节,搭配可直接复用的代码模板与阿里云快速部署方案,确保零基础用户也能快速上手,全程不改变原意,不含无关平台信息。

在AIOps领域飞速发展的今天,Agent Skills凭借轻量化、高定制性的优势,逐渐替代传统MCP方案,成为智能运维的核心工具。而OpenClaw作为开源AI助手的佼佼者,不仅支持多平台对接与本地部署,更提供了极简的Skills定制能力——无需复杂编码,通过自然语言交互即可生成专属功能模块。本文以企业高频需求的“远程Linux服务器巡检”为例,详细拆解OpenClaw Skills的开发全流程,涵盖需求定义、交互配置、文件解析、测试优化等核心环节,搭配可直接复用的代码模板与阿里云快速部署方案,确保零基础用户也能快速上手。
openClaw3.png

一、核心认知:OpenClaw Skills的价值与优势

(一)Skills是什么?

OpenClaw Skills是可扩展的功能模块,本质是“指令集+执行脚本+配置文件”的组合,能够让AI助手具备特定场景能力(如服务器巡检、文件处理、数据统计等)。每个Skill独立存储在~/.openclaw/workspaces/skills/目录下,支持按需启用、修改与扩展,是OpenClaw实现“个性化功能”的核心载体。

(二)与传统MCP方案的对比优势

特性 OpenClaw Skills 传统MCP方案
开发门槛 低,自然语言交互生成,无需专业编码 高,需手动编写配置文件与脚本
灵活性 极强,支持快速修改与扩展 弱,修改需重新部署
轻量化 独立模块,资源占用小 重量级,依赖复杂依赖
集成度 与OpenClaw生态深度融合,支持多平台触发 需额外适配对接,集成成本高
安全性 支持命令白名单,默认只读权限 权限管控复杂,易出现安全风险

对于服务器巡检、日常办公自动化等场景,OpenClaw Skills的“低代码+高灵活”特性能够大幅降低开发成本,实现“需求提出→技能生成→落地使用”的快速闭环。

(三)巡检Skill的核心价值

远程服务器巡检是企业运维的基础需求,传统人工巡检存在效率低、易遗漏、无法实时响应的问题。通过OpenClaw巡检Skill,可实现:

  • 自动化执行:支持定时/按需触发,无需人工登录服务器;
  • 全面覆盖:涵盖硬件资源、系统服务、异常日志、安全事件等核心维度;
  • 智能分析:自动筛选异常信息,生成结构化报告,突出重点风险;
  • 多端同步:巡检结果可同步至飞书、Telegram等平台,方便团队协作。

二、开发前准备:环境与工具清单

(一)环境要求

项目 具体要求 备注
OpenClaw版本 ≥2026.2.9 确保支持Skills动态生成功能
操作系统 Linux/macOS/Windows(WSL2) 本文以Linux(Ubuntu 22.04)为例
Node.js ≥22.x Skills执行脚本依赖Node.js环境
网络 本地与远程服务器网络互通 需开放SSH端口(默认22)
权限 本地用户具备OpenClaw配置目录读写权限 远程服务器需创建只读巡检账号

(二)必备工具

  • 终端工具:Linux/macOS自带终端、Windows PowerShell;
  • 文本编辑器:Nano、Vim、VS Code(用于修改Skill配置文件);
  • SSH工具:用于测试远程服务器连接;
  • 浏览器:Chrome、Edge(用于查看巡检报告与OpenClaw Web控制台)。

(三)核心凭证与信息

  1. 远程服务器信息:IP地址、SSH端口(默认22)、巡检账号用户名;
  2. 密钥对:用于SSH免密登录,需提前在本地生成并上传公钥至远程服务器;
  3. 巡检清单:明确需要检测的维度(如硬件资源、系统服务、异常日志等)。

(四)阿里云一键部署OpenClaw步骤流程

第一步:访问阿里云OpenClaw一键部署专题页面,找到并点击【一键购买并部署】。
阿里云OpenClaw一键部署专题页面:https://www.aliyun.com/activity/ecs/clawdbot
OpenClaw1.png
OpenClaw02.png
OpenClaw2.png
第二步:选购阿里云轻量应用服务器,配置参考如下:

  • 镜像:OpenClaw(Moltbot)镜像(已经购买服务器的用户可以重置系统重新选择镜像)
  • 实例:内存必须2GiB及以上。
  • 地域:默认美国(弗吉尼亚),目前中国内地域(除香港)的轻量应用服务器,联网搜索功能受限。
  • 时长:根据自己的需求及预算选择。
    轻量应用服务器OpenClaw镜像.png
    bailian1.png
    bailian2.png
    第三步:访问阿里云百炼大模型控制台,找到密钥管理,单击创建API-Key。
    阿里云百炼密钥管理图.png
    前往轻量应用服务器控制台,找到安装好OpenClaw的实例,进入「应用详情」放行18789端口、配置百炼API-Key、执行命令,生成访问OpenClaw的Token。
    阿里云百炼密钥管理图2.png
  • 端口放通:需要放通对应端口的防火墙,单击一键放通即可。
  • 配置百炼API-Key,单击一键配置,输入百炼的API-Key。单击执行命令,写入API-Key。
  • 配置OpenClaw:单击执行命令,生成访问OpenClaw的Token。
  • 访问控制页面:单击打开网站页面可进入OpenClaw对话页面。

三、阿里云OpenClaw部署简单步骤(小白速通版)

若尚未部署OpenClaw,可直接使用阿里云一键部署方案,快速搭建开发环境:

  1. 注册并登录阿里云账号,完成实名认证;
  2. 访问阿里云OpenClaw一键部署专题页面,点击“一键购买并部署”;
  3. 配置服务器参数:
    • 实例规格:2核4GB内存+40GB ESSD云盘+5Mbps带宽;
    • 镜像:选择“OpenClaw开发版”(内置Node.js与Skills开发依赖);
    • 地域:推荐中国香港/新加坡(免备案,网络访问无限制);
  4. 支付完成后,等待实例状态变为“运行中”,记录服务器公网IP;
  5. 远程登录服务器,执行以下命令初始化:
    # 启动OpenClaw服务
    sudo systemctl start openclaw
    # 验证服务状态(显示active即为成功)
    sudo systemctl status openclaw
    # 查看OpenClaw版本
    openclaw --version
    
  6. 执行openclaw dashboard获取Web控制台链接,完成部署。

四、巡检Skill开发全流程:从需求到落地

(一)Step1:定义需求,与OpenClaw交互配置

OpenClaw支持通过自然语言提出需求,AI会自动引导补充关键信息,无需手动编写基础配置。

1. 发起需求指令

打开OpenClaw Web控制台或对接的聊天平台(如飞书、Telegram),发送需求指令:

请帮我创建一个远程登录Linux机器并且做巡检的Skills,要求如下:
1. 登录方式:SSH密钥认证,禁止密码登录;
2. 巡检范围:
   - 硬件资源:CPU、内存、磁盘、网络使用情况;
   - 系统服务:运行状态、异常日志(近24小时);
   - 安全事件:SSH异常登录、防火墙告警;
3. 输出结果:生成结构化Markdown报告,突出异常信息与处理建议;
4. 安全要求:仅执行只读命令,禁止修改服务器配置。

2. 响应AI的交互提问

OpenClaw会逐步引导补充关键信息,按实际情况回复即可:

  • 提问1:请提供远程服务器的IP地址、SSH端口、巡检账号用户名?
    回复:IP:192.168.124.16,端口:22,用户名:inspector;
  • 提问2:是否需要我帮你生成SSH密钥对?
    回复:是,请生成并提供公钥使用方法;
  • 提问3:是否需要指定重点监控的系统服务?
    回复:需要,重点监控sshd、mongod、docker、firewalld服务。

3. 生成Skill基础结构

OpenClaw会自动在~/.openclaw/workspaces/skills/目录下创建ssh-inspector文件夹,核心文件结构如下:

ssh-inspector/
├── references/          # 配置文件目录
│   ├── targets.yaml     # 目标服务器配置
│   └── checks.yaml      # 巡检命令白名单
├── scripts/             # 执行脚本目录
│   └── inspect.mjs      # 核心巡检脚本
└── SKILL.md             # Skill说明文档(大脑)

(二)Step2:解析核心文件,理解Skill工作原理

1. SKILL.md:Skill的“说明书”

该文件定义了Skill的名称、功能描述、使用场景、安全规则等核心信息,是OpenClaw识别和调用Skill的依据,内容如下(可直接复用修改):

---
name: ssh-inspector
description: Remote SSH login and read-only server inspection (health checks) by running a fixed allowlist of commands on configured targets, collecting outputs, and producing a Markdown report. Use when the user asks to SSH into servers, run remote commands for 巡检/healthcheck/巡查, gather system metrics (cpu/mem/disk/load), or generate inspection reports.
---

# ssh-inspector
Run read-only inspections against remote Linux hosts over SSH using a dedicated key.

## Safety (default deny)
- Only run commands that are defined in `references/checks.yaml`.
- Do not run any command that changes state (no package installs, no config edits, no restarts).
- Prefer non-interactive SSH: `BatchMode=yes`, explicit `ConnectTimeout`, and a per-command timeout.

## Config
- Targets: `references/targets.yaml`
- Allowed checks (command allowlist): `references/checks.yaml`

If a target is missing, ask the user for: host/IP, port, user, and which SSH key to use.

## How To Run
Use the bundled script:
- `node scripts/inspect.mjs --target bogon --checks basic`

It prints a Markdown report to stdout.

## Extending
- Add a new target in `references/targets.yaml`.
- Add or adjust checks in `references/checks.yaml`.
- Keep checks small and composable; parsing is best-effort.

2. references/targets.yaml:目标服务器配置

存储远程服务器的连接信息,支持配置多个目标,格式如下:

targets:
  bogon:  # 目标名称,自定义
    host: 192.168.124.16  # 服务器IP
    port: 22  # SSH端口
    user: inspector  # 巡检账号
    keyPath: ~/.ssh/openclaw_inspect  # 本地私钥路径
    services:  # 重点监控的服务
      - sshd
      - mongod
      - docker
      - firewalld

3. references/checks.yaml:巡检命令白名单

定义允许执行的巡检命令,按功能分组管理,支持动态扩展,格式如下:

checks:
  basic:  # 基础巡检组
    description: 硬件资源与系统基础信息
    commands:
      - id: basic_identity
        cmd: whoami; hostname; uname -r; date -Is
        timeoutSec: 5
      - id: basic_uptime
        cmd: uptime
        timeoutSec: 5
      - id: hw_cpu
        cmd: "(command -v mpstat >/dev/null 2>&1 && mpstat -P ALL 1 3 | sed -n '1,160p') || (top -b -n1 | sed -n '1,25p') || true"
        timeoutSec: 15
      - id: hw_mem
        cmd: "free -h; echo; cat /proc/meminfo | egrep -i '^(MemTotal|MemFree|MemAvailable|Buffers|Cached|SwapTotal|SwapFree):' || true"
        timeoutSec: 10
      - id: hw_disk_fs
        cmd: "df -hT | sed -n '1,25p'"
        timeoutSec: 10
  services:  # 服务巡检组(动态生成命令)
    description: 重点服务运行状态与日志
  daily:  # 日常巡检组(整合基础+服务+安全)
    description: 完整日常巡检(含资源、服务、日志、安全)

4. scripts/inspect.mjs:核心执行脚本

该脚本是Skill的“手脚”,负责读取配置、建立SSH连接、执行命令、生成报告,完整代码如下(可直接复制使用):

#!/usr/bin/env node
/*
  Read-only SSH inspector.
  - Loads targets from references/targets.yaml
  - Loads allowlisted checks from references/checks.yaml
  - Runs each command over SSH (non-interactive), captures stdout/stderr
  - Prints a Markdown report
  This script intentionally does not support arbitrary remote commands.
*/
import {
    execFile } from 'node:child_process';
import {
    readFile } from 'node:fs/promises';
import {
    fileURLToPath } from 'node:url';
import {
    dirname, join } from 'node:path';

// 显示使用说明
function usage() {
   
  console.log(`Usage:
  node scripts/inspect.mjs --target <name> --checks <group>
Options:
  --target   Target name in references/targets.yaml
  --checks   Check group in references/checks.yaml (default: basic)
`);
}

// 解析命令行参数
function parseArgs(argv) {
   
  const args = {
    checks: 'basic' };
  for (let i = 2; i < argv.length; i++) {
   
    const a = argv[i];
    if (a === '--help' || a === '-h') args.help = true;
    else if (a === '--target') args.target = argv[++i];
    else if (a === '--checks') args.checks = argv[++i];
    else {
   
      throw new Error(`Unknown arg: ${
     a}`);
    }
  }
  return args;
}

// 简易YAML解析器(无需依赖第三方库)
function parseSimpleYaml(text) {
   
  const lines = text.replace(/\r\n/g, '\n').split('\n');
  const root = {
   };
  const stack = [{
    indent: -1, obj: root }];
  for (let idx = 0; idx < lines.length; idx++) {
   
    const raw = lines[idx];
    const line = raw.replace(/\t/g, '  ');
    if (!line.trim() || line.trim().startsWith('#')) continue;
    const indent = line.match(/^ */)[0].length;
    while (stack.length && indent <= stack[stack.length - 1].indent) stack.pop();
    const parent = stack[stack.length - 1].obj;
    const trimmed = line.trim();

    if (trimmed.startsWith('- ')) {
   
      if (!Array.isArray(parent)) throw new Error('YAML list item in non-list');
      parent.push(stripQuotes(trimmed.slice(2).trim()));
      continue;
    }

    const [k, ...rest] = trimmed.split(':');
    const key = k.trim();
    const value = rest.join(':').trim();

    if (value === '') {
   
      let j = idx + 1;
      let next = null;
      while (j < lines.length) {
   
        const nl = lines[j].replace(/\t/g, '  ');
        const nt = nl.trim();
        if (nt && !nt.startsWith('#')) {
   
          next = {
    indent: nl.match(/^ */)[0].length, trimmed: nt };
          break;
        }
        j++;
      }
      const isList = next && next.indent > indent && next.trimmed.startsWith('- ');
      const container = isList ? [] : {
   };
      parent[key] = container;
      stack.push({
    indent, obj: container });
    } else {
   
      parent[key] = stripQuotes(value);
    }
  }
  return root;
}

// 去除字符串引号
function stripQuotes(s) {
   
  if ((s.startsWith('"') && s.endsWith('"')) || (s.startsWith("'") && s.endsWith("'"))) {
   
    return s.slice(1, -1);
  }
  if (/^\d+$/.test(s)) return Number(s);
  return s;
}

// 异步执行命令
function execFileP(cmd, args, {
    timeoutMs } = {
   }) {
   
  return new Promise((resolve) => {
   
    execFile(cmd, args, {
    timeout: timeoutMs, maxBuffer: 10 * 1024 * 1024 }, (error, stdout, stderr) => {
   
      resolve({
    error, stdout: stdout ?? '', stderr: stderr ?? '' });
    });
  });
}

// Markdown转义
function mdEscape(s) {
   
  return s.replace(/`/g, '\\`');
}

// 获取当前ISO格式时间
function nowIso() {
   
  return new Date().toISOString();
}

// 构建服务巡检命令
function buildServiceCommands(services) {
   
  const out = [];
  const uniq = [...new Set((services || []).map((s) => String(s).trim()).filter(Boolean))];
  for (const name of uniq) {
   
    out.push({
   
      id: `svc_${
     name}_status`,
      cmd: `systemctl status ${
     name} --no-pager | sed -n '1,40p'`,
      timeoutSec: 12,
    });
    out.push({
   
      id: `svc_${
     name}_errors`,
      cmd: `journalctl -u ${
     name} -p err..alert -n 80 --no-pager || true`,
      timeoutSec: 15,
    });
    out.push({
   
      id: `svc_${
     name}_recent`,
      cmd: `journalctl -u ${
     name} -n 120 --no-pager | egrep -i 'warn|warning|error|failed|fail|critical|crit|alert|panic|segfault|oom|killed process|timeout|timed out|refused|denied|unreachable|reset|broken pipe|i/o error|corrupt|read-only|no space|disk quota|throttl|backoff|rate limit|too many|conntrack|dropped' | tail -n 60 || true`,
      timeoutSec: 15,
    });
  }
  if (out.length === 0) {
   
    out.push({
   
      id: 'services_config',
      cmd: "echo 'No services configured for this target. Add targets.<name>.services in references/targets.yaml'",
      timeoutSec: 3,
    });
  }
  return out;
}

// 构建日常巡检命令(整合基础+服务+安全)
function buildDailyCommands(t) {
   
  const base = [
    {
    id: 'basic_identity', cmd: 'whoami; hostname; uname -r; date -Is', timeoutSec: 5 },
    {
    id: 'basic_uptime', cmd: 'uptime', timeoutSec: 5 },
    {
    id: 'basic_os', cmd: "cat /etc/os-release | sed -n '1,12p'", timeoutSec: 5 },
    {
    id: 'hw_cpu', cmd: "(command -v mpstat >/dev/null 2>&1 && mpstat -P ALL 1 3 | sed -n '1,160p') || (top -b -n1 | sed -n '1,25p') || true", timeoutSec: 15 },
    {
    id: 'hw_mem', cmd: "free -h; echo; cat /proc/meminfo | egrep -i '^(MemTotal|MemFree|MemAvailable|Buffers|Cached|SwapTotal|SwapFree|Dirty|Writeback|Slab):' || true", timeoutSec: 10 },
    {
    id: 'hw_disk_fs', cmd: "df -hT | sed -n '1,25p'", timeoutSec: 10 },
    {
    id: 'hw_disk_io', cmd: "(command -v iostat >/dev/null 2>&1 && iostat -x 1 3 | sed -n '1,120p') || true", timeoutSec: 18 },
    {
    id: 'hw_net_overview', cmd: "ss -s | sed -n '1,80p'", timeoutSec: 10 },
    {
    id: 'logs_journal_err_24h', cmd: 'journalctl -p err..alert -S -24h --no-pager | tail -n 200 || true', timeoutSec: 20 },
    {
    id: 'logs_dmesg_key', cmd: "dmesg -T 2>/dev/null | egrep -i 'error|fail|oom|killed process|segfault|panic|xfs|ext4|nvme|reset|link down|call trace' | tail -n 200 || true", timeoutSec: 12 },
    {
    id: 'sec_last_failed', cmd: "lastb -n 50 2>/dev/null | sed -n '1,60p' || true", timeoutSec: 12 },
    {
    id: 'sec_sshd_suspicious_24h', cmd: "journalctl -u sshd -S -24h --no-pager | egrep -i 'failed password|invalid user|authentication failure|maximum authentication attempts|POSSIBLE BREAK-IN ATTEMPT|Did not receive identification string|Connection closed by authenticating user|error: kex_exchange_identification' | tail -n 200 || true", timeoutSec: 20 },
    {
    id: 'systemd_failed_units', cmd: 'systemctl --failed --no-pager || true', timeoutSec: 10 },
    {
    id: 'systemd_recent_errors', cmd: 'journalctl -p err..alert -n 80 --no-pager || true', timeoutSec: 15 },
  ];
  const svc = buildServiceCommands(t?.services ?? []);
  return base.concat(svc);
}

// 解析checks.yaml(专用解析器)
function parseChecksYaml(text) {
   
  const lines = text.replace(/\r\n/g, '\n').split('\n');
  const out = {
    checks: {
   } };
  let curGroup = null;
  let inCommands = false;
  let curCmd = null;
  const kv = (s) => {
   
    const i = s.indexOf(':');
    if (i === -1) return null;
    return [s.slice(0, i).trim(), s.slice(i + 1).trim()];
  };

  for (let raw of lines) {
   
    const line = raw.replace(/\t/g, '  ');
    const t = line.trim();
    if (!t || t.startsWith('#')) continue;
    if (t === 'checks:') continue;

    if (/^[a-zA-Z0-9_-]+:$/.test(t) && line.startsWith('  ') && !line.startsWith('    ')) {
   
      curGroup = t.slice(0, -1);
      out.checks[curGroup] = {
    commands: [] };
      inCommands = false;
      curCmd = null;
      continue;
    }

    if (!curGroup) continue;
    if (t === 'commands:') {
   
      inCommands = true;
      curCmd = null;
      continue;
    }

    if (inCommands && t.startsWith('- ')) {
   
      curCmd = {
   };
      out.checks[curGroup].commands.push(curCmd);
      const rest = t.slice(2);
      const pair = kv(rest);
      if (pair) curCmd[pair[0]] = stripQuotes(pair[1]);
      continue;
    }

    const pair = kv(t);
    if (!pair) continue;
    if (!inCommands) {
   
      out.checks[curGroup][pair[0]] = stripQuotes(pair[1]);
    } else if (curCmd) {
   
      curCmd[pair[0]] = stripQuotes(pair[1]);
    }
  }
  return out;
}

// 命令字符串转义
function shellQuote(s) {
   
  return `'${String(s).replace(/'/g, `'"'"'`)}'`;
}

// 生成Markdown报告
function renderReport({
    target, host, user, checks, start, results }) {
   
  let md = '';
  md += `# SSH Inspection Report\n\n`;
  md += `- Target: \`${
     mdEscape(target)}\`\n`;
  md += `- Host: \`${
     mdEscape(host)}\`\n`;
  md += `- User: \`${
     mdEscape(user)}\`\n`;
  md += `- Checks: \`${
     mdEscape(checks)}\`\n`;
  md += `- Started: \`${
     mdEscape(start)}\`\n\n`;

  for (const r of results) {
   
    md += `## ${
     mdEscape(r.id)}\n\n`;
    md += `Command: \`${
     mdEscape(r.cmd)}\`\n\n`;
    md += `Status: ${
     r.ok ? 'OK' : 'FAIL'} (timeout ${
     r.timeoutSec}s)\n\n`;
    if (r.stdout.trim()) {
   
      md += `STDOUT:\n\n\`\`\`\n${
     r.stdout.trim()}\n\`\`\`\n\n`;
    }
    if (r.stderr.trim()) {
   
      md += `STDERR:\n\n\`\`\`\n${
     r.stderr.trim()}\n\`\`\`\n\n`;
    }
  }
  return md;
}

// 主函数
async function main() {
   
  const args = parseArgs(process.argv);
  if (args.help || !args.target) {
   
    usage();
    if (!args.target) process.exitCode = 2;
    return;
  }

  const here = dirname(fileURLToPath(import.meta.url));
  const skillDir = dirname(here);
  const targetsPath = join(skillDir, 'references', 'targets.yaml');
  const checksPath = join(skillDir, 'references', 'checks.yaml');

  // 读取配置文件
  const targetsText = await readFile(targetsPath, 'utf-8');
  const checksText = await readFile(checksPath, 'utf-8');

  // 解析配置
  const targets = parseSimpleYaml(targetsText);
  const t = targets.targets?.[args.target];
  if (!t) throw new Error(`Unknown target: ${
     args.target}`);

  const checks = parseChecksYaml(checksText);
  const group = checks.checks?.[args.checks];
  if (!group) throw new Error(`Unknown checks group: ${
     args.checks}`);

  // 动态生成命令组
  if (args.checks === 'services') {
   
    group.commands = buildServiceCommands(t.services ?? []);
  }
  if (args.checks === 'daily') {
   
    group.commands = buildDailyCommands(t);
  }

  // SSH连接基础参数
  const sshBase = [
    '-i', String(t.keyPath),
    '-p', String(t.port ?? 22),
    '-o', 'BatchMode=yes',
    '-o', 'StrictHostKeyChecking=accept-new',
    '-o', 'ConnectTimeout=8',
  ];
  const dest = `${
     t.user}@${
     t.host}`;
  const start = nowIso();
  const results = [];

  // 执行巡检命令
  for (const c of group.commands) {
   
    const timeoutMs = Number(c.timeoutSec ?? 10) * 1000;
    const remote = `bash -lc ${
     shellQuote(c.cmd)}`;
    const {
    error, stdout, stderr } = await execFileP('ssh', [...sshBase, dest, remote], {
    timeoutMs });
    results.push({
    id: c.id, cmd: c.cmd, timeoutSec: c.timeoutSec ?? 10, ok: !error, code: error?.code ?? 0, stdout, stderr });
  }

  // 生成并输出报告
  const report = renderReport({
    target: args.target, host: t.host, user: t.user, checks: args.checks, start, results });
  try {
   
    process.stdout.write(report);
  } catch (e) {
   
    if (e?.code !== 'EPIPE') throw e;
  }
}

// 执行主函数
main().catch((err) => {
   
  console.error(err?.stack || String(err));
  process.exitCode = 1;
});

(三)Step3:配置SSH密钥认证,确保连接安全

巡检Skill采用SSH密钥认证方式登录远程服务器,避免密码泄露风险,配置步骤如下:

1. 本地生成密钥对

# 生成SSH密钥对(无需设置密码)
ssh-keygen -t rsa -b 4096 -f ~/.ssh/openclaw_inspect
# 查看公钥内容
cat ~/.ssh/openclaw_inspect.pub

2. 上传公钥至远程服务器

# 替换为远程服务器IP和用户名
ssh-copy-id -i ~/.ssh/openclaw_inspect.pub inspector@192.168.124.16
# 测试免密登录(成功登录即为配置完成)
ssh -i ~/.ssh/openclaw_inspect inspector@192.168.124.16

3. 配置远程服务器权限(安全加固)

为巡检账号配置只读权限,限制命令执行范围:

# 远程服务器执行,创建巡检账号(若已存在可跳过)
sudo useradd -m inspector
# 设置账号权限,禁止sudo
sudo usermod -L inspector  # 锁定密码登录
sudo chmod 700 /home/inspector
sudo chmod 600 /home/inspector/.ssh/authorized_keys
# 限制可执行命令(可选,通过rbash实现)
sudo usermod -s /bin/rbash inspector

(四)Step4:测试Skill,验证巡检功能

1. 手动执行巡检脚本

# 进入Skill脚本目录
cd ~/.openclaw/workspaces/skills/ssh-inspector/scripts
# 执行基础巡检(检查硬件资源)
node inspect.mjs --target bogon --checks basic
# 执行服务巡检(检查重点服务)
node inspect.mjs --target bogon --checks services
# 执行完整巡检(基础+服务+安全+日志)
node inspect.mjs --target bogon --checks daily

2. 查看巡检报告

执行后会在终端输出Markdown格式报告,包含以下核心模块:

  • 基础信息:服务器身份、系统版本、运行时间;
  • 硬件资源:CPU、内存、磁盘、网络使用情况;
  • 系统服务:重点服务运行状态、异常日志;
  • 安全事件:SSH异常登录、防火墙告警、内核错误;
  • 系统稳定性:systemd失败单元、最近24小时异常日志。

3. 示例报告核心内容(异常信息提取)

# SSH Inspection Report
- Target: bogon
- Host: 192.168.124.16
- User: inspector
- Checks: daily
- Started: 2026-02-12T06:04:19.133Z

## systemd_failed_units
Command: systemctl --failed --no-pager || true
Status: FAIL (timeout 10s)
STDOUT:
  UNIT          LOAD   ACTIVE SUB    DESCRIPTION
  mcelog.service loaded failed failed Machine Check Exception Logging Daemon
LOAD   = Reflects whether the unit definition was properly loaded.
ACTIVE = The high-level unit activation state, i.e. generalization of SUB.
SUB    = The low-level unit activation state, values depend on unit type.

## logs_journal_err_24h
Command: journalctl -p err..alert -S -24h --no-pager | tail -n 200 || true
STDOUT:
  Feb 12 10:00:00 bogon setroubleshoot[12345]: SELinux is preventing /usr/bin/mongod from write access on the file /var/lib/mongo/journal/j._0.
  ...(共132条类似记录)

(五)Step5:优化Skill,提升实用性

1. 异常信息过滤与优先级排序

默认报告包含所有执行结果,可修改inspect.mjsrenderReport函数,添加异常过滤逻辑,突出重点风险:

// 新增异常关键词列表
const errorKeywords = ['failed', 'error', 'alert', 'critical', 'SELinux is preventing', 'WARNING', 'panic', 'segfault', 'oom'];

// 修改renderReport函数,添加异常标记
function renderReport({
    target, host, user, checks, start, results }) {
   
  let md = '';
  md += `# SSH Inspection Report\n\n`;
  md += `- Target: \`${
     mdEscape(target)}\`\n`;
  md += `- Host: \`${
     mdEscape(host)}\`\n`;
  md += `- User: \`${
     mdEscape(user)}\`\n`;
  md += `- Checks: \`${
     mdEscape(checks)}\`\n`;
  md += `- Started: \`${
     mdEscape(start)}\`\n`;

  // 统计异常项
  const errorItems = results.filter(r => !r.ok || errorKeywords.some(key => r.stdout.includes(key) || r.stderr.includes(key)));
  md += `- 异常项数量: ${
     errorItems.length}\n\n`;

  // 优先显示异常项
  if (errorItems.length > 0) {
   
    md += `## 重点异常(优先处理)\n\n`;
    for (const r of errorItems) {
   
      md += `### ⚠️ ${
     mdEscape(r.id)}\n\n`;
      md += `Command: \`${
     mdEscape(r.cmd)}\`\n\n`;
      md += `Status: ${
     r.ok ? 'OK(含异常信息)' : 'FAIL'}\n\n`;
      if (r.stdout.trim()) {
   
        md += `异常信息:\n\n\`\`\`\n${
     r.stdout.trim()}\n\`\`\`\n\n`;
      }
    }
  }

  // 显示正常项(折叠)
  md += `## 正常巡检项(点击展开)\n\n<details><summary>查看所有巡检结果</summary>\n\n`;
  for (const r of results.filter(r => !errorItems.includes(r))) {
   
    md += `### ${
     mdEscape(r.id)}\n\n`;
    md += `Command: \`${
     mdEscape(r.cmd)}\`\n\n`;
    md += `Status: OK\n\n`;
  }
  md += `</details>\n`;

  return md;
}

2. 配置定时巡检

通过OpenClaw的Cron Jobs功能,设置定时自动巡检:

# 进入OpenClaw配置
openclaw configure --section cron
# 添加每日14:00巡检任务
# 格式:分钟 小时 日 月 周 命令
0 14 * * * node ~/.openclaw/workspaces/skills/ssh-inspector/scripts/inspect.mjs --target bogon --checks daily > /tmp/openclaw_inspect_report_$(date +%Y%m%d).md

3. 多平台同步报告

将巡检报告自动发送至飞书/Telegram,需先完成OpenClaw与对应平台的对接,再修改定时任务:

# 飞书同步(替换为你的飞书机器人Webhook)
0 14 * * * node ~/.openclaw/workspaces/skills/ssh-inspector/scripts/inspect.mjs --target bogon --checks daily | curl -X POST -H "Content-Type: application/json" -d '{"text":"'"$(cat -)"'"}' https://open.feishu.cn/open-apis/bot/v2/hook/xxx

五、Skills扩展与维护:打造可复用生态

(一)添加新的巡检维度

若需增加数据库巡检、应用性能检测等功能,可修改checks.yaml添加新命令组:

checks:
  database:  # 数据库巡检组
    description: MongoDB数据库状态检测
    commands:
      - id: mongo_status
        cmd: "mongosh --eval 'db.runCommand({ serverStatus: 1 }).ok' || true"
        timeoutSec: 20
      - id: mongo_connections
        cmd: "mongosh --eval 'db.runCommand({ serverStatus: 1 }).connections' || true"
        timeoutSec: 20

(二)多目标服务器管理

targets.yaml中添加多个服务器配置,支持批量巡检:

targets:
  bogon:  # 服务器1
    host: 192.168.124.16
    port: 22
    user: inspector
    keyPath: ~/.ssh/openclaw_inspect
    services: [sshd, mongod, docker]
  server2:  # 服务器2
    host: 192.168.124.17
    port: 22
    user: inspector
    keyPath: ~/.ssh/openclaw_inspect
    services: [nginx, mysql, redis]

执行批量巡检:

# 循环执行多目标巡检
for target in bogon server2; do
  node ~/.openclaw/workspaces/skills/ssh-inspector/scripts/inspect.mjs --target $target --checks daily > /tmp/inspect_$target_$(date +%Y%m%d).md
done

(三)版本控制与备份

为Skills配置Git版本控制,避免修改错误导致功能失效:

# 初始化Git仓库
cd ~/.openclaw/workspaces/skills/ssh-inspector
git init
# 创建.gitignore文件
cat <<EOF> .gitignore
node_modules/
*.log
tmp/
EOF
# 首次提交
git add .
git commit -m "initial commit: 服务器巡检Skill基础版本"

六、常见问题排查

(一)SSH连接失败

  • 表现:执行脚本提示“Connection timed out”或“Permission denied”;
  • 原因:服务器IP/端口错误、密钥路径配置错误、远程服务器防火墙拦截;
  • 解决方案
    1. 验证服务器连通性:ping 192.168.124.16
    2. 检查SSH端口:telnet 192.168.124.16 22
    3. 验证密钥路径:确保targets.yamlkeyPath指向正确的私钥文件;
    4. 检查防火墙:远程服务器执行sudo ufw allow 22开放SSH端口。

(二)命令执行超时

  • 表现:报告中显示“Status: FAIL (timeout 10s)”;
  • 原因:命令执行时间过长,超过默认超时时间;
  • 解决方案
    1. checks.yaml中为对应命令增加timeoutSec参数(如改为30秒);
    2. 简化复杂命令,拆分多个小命令执行。

(三)报告无异常信息但实际存在问题

  • 表现:服务器存在异常,但报告未显示;
  • 原因:异常关键词未包含在过滤列表中;
  • 解决方案
    1. 查看完整执行结果:node inspect.mjs --target bogon --checks daily > full_report.md
    2. 分析异常信息特征,添加到errorKeywords列表中。

七、总结

OpenClaw Skills的低代码开发模式,让非专业开发者也能快速打造专属AI功能模块。本文以远程服务器巡检为例,从需求定义、交互配置、文件解析、测试优化等维度,完整呈现了Skills的开发流程,核心亮点在于:

  • 自然语言驱动:无需手动编写基础配置,AI自动引导补充关键信息;
  • 安全可控:采用命令白名单与只读权限,避免服务器配置被修改;
  • 高度可扩展:支持添加新巡检维度、多目标管理、多平台同步;
  • 实用导向:优化后的报告突出异常信息,支持定时执行与自动同步。

搭配阿里云一键部署方案,用户可快速搭建开发环境,实现“需求提出→技能生成→落地使用”的闭环。除了服务器巡检,OpenClaw Skills还可应用于文件批量处理、数据统计分析、日常办公自动化等多个场景,通过简单的配置与扩展,即可打造全方位的AI助手生态。随着OpenClaw社区的持续发展,Skills的功能与模板将不断丰富,值得持续关注与探索。

目录
相关文章
|
17天前
|
人工智能 自然语言处理 Shell
🦞 如何在 OpenClaw (Clawdbot/Moltbot) 配置阿里云百炼 API
本教程指导用户在开源AI助手Clawdbot中集成阿里云百炼API,涵盖安装Clawdbot、获取百炼API Key、配置环境变量与模型参数、验证调用等完整流程,支持Qwen3-max thinking (Qwen3-Max-2026-01-23)/Qwen - Plus等主流模型,助力本地化智能自动化。
30763 103
🦞 如何在 OpenClaw (Clawdbot/Moltbot) 配置阿里云百炼 API
|
6天前
|
应用服务中间件 API 网络安全
3分钟汉化OpenClaw,使用Docker快速部署启动OpenClaw(Clawdbot)教程
2026年全新推出的OpenClaw汉化版,是基于Claude API开发的智能对话系统本土化优化版本,解决了原版英文界面的使用壁垒,实现了界面、文档、指令的全中文适配。该版本采用Docker容器化部署方案,开箱即用,支持Linux、macOS、Windows全平台运行,适配个人、企业、生产等多种使用场景,同时具备灵活的配置选项和强大的扩展能力。本文将从项目简介、部署前准备、快速部署、详细配置、问题排查、监控维护等方面,提供完整的部署与使用指南,文中包含实操代码命令,确保不同技术水平的用户都能快速落地使用。
4421 0
|
12天前
|
人工智能 安全 机器人
OpenClaw(原 Clawdbot)钉钉对接保姆级教程 手把手教你打造自己的 AI 助手
OpenClaw(原Clawdbot)是一款开源本地AI助手,支持钉钉、飞书等多平台接入。本教程手把手指导Linux下部署与钉钉机器人对接,涵盖环境配置、模型选择(如Qwen)、权限设置及调试,助你快速打造私有、安全、高权限的专属AI助理。(239字)
6327 16
OpenClaw(原 Clawdbot)钉钉对接保姆级教程 手把手教你打造自己的 AI 助手
|
11天前
|
人工智能 机器人 Linux
OpenClaw(Clawdbot、Moltbot)汉化版部署教程指南(零门槛)
OpenClaw作为2026年GitHub上增长最快的开源项目之一,一周内Stars从7800飙升至12万+,其核心优势在于打破传统聊天机器人的局限,能真正执行读写文件、运行脚本、浏览器自动化等实操任务。但原版全英文界面对中文用户存在上手门槛,汉化版通过覆盖命令行(CLI)与网页控制台(Dashboard)核心模块,解决了语言障碍,同时保持与官方版本的实时同步,确保新功能最快1小时内可用。本文将详细拆解汉化版OpenClaw的搭建流程,涵盖本地安装、Docker部署、服务器远程访问等场景,同时提供环境适配、问题排查与国内应用集成方案,助力中文用户高效搭建专属AI助手。
4438 9
|
13天前
|
人工智能 机器人 Linux
保姆级 OpenClaw (原 Clawdbot)飞书对接教程 手把手教你搭建 AI 助手
OpenClaw(原Clawdbot)是一款开源本地AI智能体,支持飞书等多平台对接。本教程手把手教你Linux下部署,实现数据私有、系统控制、网页浏览与代码编写,全程保姆级操作,240字内搞定专属AI助手搭建!
5453 17
保姆级 OpenClaw (原 Clawdbot)飞书对接教程 手把手教你搭建 AI 助手
|
13天前
|
存储 人工智能 机器人
OpenClaw是什么?阿里云OpenClaw(原Clawdbot/Moltbot)一键部署官方教程参考
OpenClaw是什么?OpenClaw(原Clawdbot/Moltbot)是一款实用的个人AI助理,能够24小时响应指令并执行任务,如处理文件、查询信息、自动化协同等。阿里云推出的OpenClaw一键部署方案,简化了复杂配置流程,用户无需专业技术储备,即可快速在轻量应用服务器上启用该服务,打造专属AI助理。本文将详细拆解部署全流程、进阶功能配置及常见问题解决方案,确保不改变原意且无营销表述。
5982 5
|
15天前
|
人工智能 JavaScript 应用服务中间件
零门槛部署本地AI助手:Windows系统Moltbot(Clawdbot)保姆级教程
Moltbot(原Clawdbot)是一款功能全面的智能体AI助手,不仅能通过聊天互动响应需求,还具备“动手”和“跑腿”能力——“手”可读写本地文件、执行代码、操控命令行,“脚”能联网搜索、访问网页并分析内容,“大脑”则可接入Qwen、OpenAI等云端API,或利用本地GPU运行模型。本教程专为Windows系统用户打造,从环境搭建到问题排查,详细拆解全流程,即使无技术基础也能顺利部署本地AI助理。
7652 17