乐于分享
好东西不私藏

�� 小龙虾 OpenClaw 养殖日记(三)

�� 小龙虾 OpenClaw 养殖日记(三)

上一期回顾

上回说到,我们给小龙虾安装了各种技能包,让它从一只普通的虾变成了一只多才多艺的小助手。

今天,我们来聊聊养殖小龙虾最重要的事情:安全


灵魂拷问:你的小龙虾安全吗?

养过宠物的人都知道,最可怕的事情不是宠物不听话,而是宠物走丢或者被坏人偷走

OpenClaw 也是如此。如果不注意安全:

  • 🔓 服务器被入侵,数据泄露

  • 🤖 AI 被恶意诱导,说出不该说的话

  • 💰 工具被滥用,产生意外费用

  • 📴 服务突然宕机,业务中断

所以,今天我们就来给小龙虾装上门锁、加固体质、自动巡检、让它自己发现问题自己处理


一、安全加固:给小龙虾装上门锁

1.1 为什么要加固?

小龙虾虽然聪明,但它毕竟是一只虾——不会自己判断危险

举几个例子:

  • 有人问你服务器密码,小龙虾可能会直接回答

  • 有人发送恶意链接,小龙虾可能会帮你点击

  • 有人想让小龙虾删库跑路,小龙虾可能会执行

所以我们需要安全策略来限制它的行为。

1.2 配置文件介绍

OpenClaw 的安全配置在 ~/.openclaw/config.yml 中:

security:
# 允许执行的命令白名单
  allowCommands:
    - git
    - npm
    - node
    - python

# 禁止执行的命令黑名单
  denyCommands:
    - rm -rf /
    - drop database
    - shutdown

# 是否允许外部网络请求
  allowExternalRequeststrue

# 是否允许执行 Shell 命令
  allowShellExectrue

# 权限级别
permissions:
# 初级模式:只允许安全的只读操作
  level"read-only"

# 中级模式:允许执行预定义的工具
# 高级模式:允许执行任意命令(危险!)
# level: "full"

1.3 推荐的安全配置

入门级(新手推荐):

security:
  allowCommands:
    - git
    - npm
    - node
    - python
    - curl

  denyCommands:
    - rm -rf /
    - mkfs
    - shutdown

  allowExternalRequeststrue
  allowShellExecfalse  # 关闭 Shell 执行,更安全

进阶级(有经验者):

security:
  allowCommands:
    - git
    - npm
    - node
    - python
    - docker
    - systemctl

  denyCommands:
    - rm -rf / --no-preserve-root
    - init 0
    - init 6

  allowExternalRequeststrue
  allowShellExectrue
  maxExecTimeout300  # 单次命令最长 5 分钟

1.4 SSH 密钥管理

如果你的 OpenClaw 需要连接远程服务器,一定要用 SSH 密钥而不是密码

# 1. 生成 SSH 密钥
ssh-keygen -t ed25519 -C"openclaw@your-server"

# 2. 把公钥复制到服务器
ssh-copy-id -i ~/.ssh/openclaw.pub user@your-server

# 3. 配置 SSH 客户端使用这个密钥
cat >> ~/.ssh/config <<EOF
Host openclaw-server
    HostName your-server.com
    User admin
    IdentityFile ~/.ssh/openclaw
    IdentitiesOnly yes
EOF

1.5 环境变量保密

敏感信息(如 API Key、密码)不要写在代码里,要放在环境变量中:

# 在 ~/.bashrc 或 ~/.zshrc 中添加
exportOPENAI_API_KEY="sk-xxxxx"
exportFEISHU_APP_ID="cli_xxxxx"
exportFEISHU_APP_SECRET="xxxxx"

然后在代码中这样使用:

constapiKey=process.env.OPENAI_API_KEY;
if (!apiKey) {
console.error("❌ 请设置 OPENAI_API_KEY 环境变量");
process.exit(1);
}

二、自动化巡检:让小龙虾每天自己巡检

2.1 什么是自动化巡检?

想象你有一个员工,每天自动检查服务器状态、监控指标、磁盘空间——发现问题就报警,不需要你操心。

这就是自动化巡检。

2.2 使用 Cron 定时任务

Linux 的 cron 可以让小龙虾自动执行任务:

# 编辑定时任务
crontab -e

# 添加以下任务:

# 每小时检查一次服务器状态
0 * * * * cd ~/.openclaw && node scripts/health-check.js

# 每天早上 9 点巡检(北京时间)
01 * * * cd ~/.openclaw && node scripts/daily-inspection.js  # UTC 1点 = 北京 9点

# 每周一早上 9 点生成周报
01 * * 1cd ~/.openclaw && node scripts/weekly-report.js

2.3 巡检脚本示例

// scripts/health-check.js
const { execSync } =require('child_process');
constaxios=require('axios');

asyncfunctionhealthCheck() {
console.log("🔍 开始巡检...");

constresults= {
cpuawaitcheckCPU(),
memoryawaitcheckMemory(),
diskawaitcheckDisk(),
servicesawaitcheckServices()
  };

// 如果有问题,发送报警
if (results.cpu>90||results.disk>85) {
awaitsendAlert("⚠️ 服务器状态异常!"results);
  }

console.log("✅ 巡检完成");
console.log(JSON.stringify(resultsnull2));
}

asyncfunctioncheckCPU() {
// 使用 top 命令获取 CPU 使用率
constoutput=execSync("top -bn1 | grep 'Cpu(s)' | awk '{print $2}'").toString();
returnparseFloat(output);
}

asyncfunctioncheckMemory() {
constoutput=execSync("free -m | grep Mem | awk '{print $3/$2 * 100}'").toString();
returnparseFloat(output);
}

asyncfunctioncheckDisk() {
constoutput=execSync("df -h / | tail -1 | awk '{print $5}' | sed 's/%//'").toString();
returnparseFloat(output);
}

asyncfunctioncheckServices() {
constservices= ["docker""redis""mysql"];
constresults= {};

for (constsvcofservices) {
try {
execSync(`systemctl is-active ${svc}`, { stdio'ignore' });
results[svc="✅ 运行中";
    } catch {
results[svc="❌ 已停止";
    }
  }

returnresults;
}

asyncfunctionsendAlert(messagedata) {
// 这里可以接入飞书机器人、邮件等报警渠道
console.error("🚨 报警:"messagedata);
}

healthCheck().catch(console.error);

2.4 巡检报告样例

运行巡检后,你会收到这样的报告:

🦞 小龙虾自动巡检报告
时间: 2026-04-02 10:00:00

【服务器状态】
| 指标 | 状态 | 值 |
|------|------|-----|
| CPU | ✅ 正常 | 35.2% |
| 内存 | ⚠️ 偏高 | 78.5% |
| 磁盘 | ✅ 正常 | 62.1% |

【服务状态】
| 服务 | 状态 |
|------|------|
| Docker | ✅ 运行中 |
| Redis | ✅ 运行中 |
| MySQL | ❌ 已停止 |

【建议】
内存使用率偏高,建议关注。
MySQL 服务已停止,请立即检查!

三、故障自愈:让小龙虾自己发现问题自己处理

3.1 什么是故障自愈?

想象你的小龙虾不仅能发现问题,还能自动解决问题

  • Redis 挂了 → 自动重启

  • 磁盘满了 → 自动清理旧日志

  • 服务超时 → 自动重试

这就是故障自愈

3.2 常见故障处理策略

策略一:自动重启服务

asyncfunctionautoRestart(service) {
console.log(`🔄 尝试重启 ${service}...`);

try {
// 先停止服务
execSync(`systemctl stop ${service}`, { stdio'ignore' });
awaitsleep(2000);

// 再启动服务
execSync(`systemctl start ${service}`);

// 检查是否启动成功
constisActive=execSync(`systemctl is-active ${service}`).toString().trim();

if (isActive==='active') {
console.log(`✅ ${service}重启成功`);
returntrue;
    }
  } catch (e) {
console.error(`❌ ${service}重启失败:`e.message);
  }

returnfalse;
}

策略二:清理磁盘空间

asyncfunctioncleanupDisk() {
console.log("🧹 开始清理磁盘...");

// 清理旧日志(保留最近 7 天)
execSync(`find /var/log -name "*.log" -mtime +7 -delete`);

// 清理 Docker 临时文件
execSync("docker system prune -f");

// 清理 npm 缓存
execSync("npm cache clean --force");

// 清理旧的 core dump 文件
execSync(`find / -name "core.*" -mtime +1 -delete 2>/dev/null`);

console.log("✅ 清理完成");
}

策略三:自动扩容

asyncfunctionautoScale() {
// 检查当前负载
constcpu=awaitcheckCPU();
constmemory=awaitcheckMemory();

if (cpu>80||memory>85) {
console.log("📈 负载过高,尝试扩容...");

// 这里是伪代码,实际需要根据你的基础设施来写
execSync("docker-compose up -d --scale app=3");

console.log("✅ 已扩容,当前实例数: 3");
  }
}

3.3 自愈编排示例

// scripts/self-healing.js
classSelfHealing {
constructor() {
this.strategies= [
      { name"redis"checkthis.checkRedisfix: () =>this.autoRestart("redis") },
      { name"docker"checkthis.checkDockerfix: () =>this.autoRestart("docker") },
      { name"disk"checkthis.checkDiskfixthis.cleanupDisk },
    ];
  }

asyncrun() {
console.log("🔧 开始故障自愈检查...");

for (conststrategyofthis.strategies) {
constisHealthy=awaitstrategy.check();

if (!isHealthy) {
console.log(`⚠️ ${strategy.name}状态异常,尝试自愈...`);
awaitstrategy.fix();
      } else {
console.log(`✅ ${strategy.name}状态正常`);
      }
    }

console.log("🔧 自愈检查完成");
  }

asynccheckRedis() {
try {
execSync("redis-cli ping", { stdio'ignore' });
returntrue;
    } catch {
returnfalse;
    }
  }

asynccheckDocker() {
try {
execSync("docker info", { stdio'ignore' });
returntrue;
    } catch {
returnfalse;
    }
  }

asynccheckDisk() {
constusage=parseFloat(execSync("df / | tail -1 | awk '{print $5}'").toString().replace('%'''));
returnusage<85;
  }

asyncautoRestart(service) {
// 实现自动重启...
  }

asynccleanupDisk() {
// 实现磁盘清理...
  }
}

newSelfHealing().run();

四、定制外观:让小龙虾的输出更好看

4.1 为什么外观很重要?

同样的内容,好看的排版让人更愿意看。

试想两个版本的巡检报告:

普通版:

cpu 35% memory 78% disk 62%

美观版:

📊 服务器状态
CPU: ████████░░ 35%
内存: ████████████████░░░ 78%
磁盘: ████████████░░░░░░ 62%

哪个更想看?

4.2 使用 Emoji

Emoji 是让输出变好看的最简单方法:

场景推荐 EMOJI
成功✅ 🎉 🚀 💪
失败❌ 🚨 ⚠️ 🔴
进行中🔄 ⏳ 🔍 🦞
信息📢 📊 💡 🔗

4.3 使用进度条

functionrenderProgressBar(valuemax=100width=20) {
constpercentage=Math.min(value/max1);
constfilled=Math.round(percentage*width);
constempty=width-filled;

constbar='█'.repeat(filled+'░'.repeat(empty);
constpercent=Math.round(percentage*100);

return`[${bar}] ${percent}%`;
}

console.log("CPU:   "+renderProgressBar(35));
console.log("内存:  "+renderProgressBar(78));
console.log("磁盘:  "+renderProgressBar(62));

输出:

CPU:   [███████░░░░░░░░░░░░] 35%
内存:  [████████████████░░░░] 78%
磁盘:  [███████████░░░░░░░░] 62%

4.4 使用表格

functionrenderTable(headersrows) {
// 计算每列宽度
constwidths=headers.map((hi=> {
constmaxRow=Math.max(...rows.map(r=>String(r[i]).length));
returnMath.max(h.lengthmaxRow);
  });

// 表头
constheaderLine='| '+headers.map((hi=>h.padEnd(widths[i])).join(' | '+' |';
constdivider='|'+widths.map(w=>'-'.repeat(w+2)).join('+|'+'|';

// 数据行
constdataLines=rows.map(row=> {
return'| '+row.map((celli=>String(cell).padEnd(widths[i])).join(' | '+' |';
  });

return [headerLinedivider...dataLines].join('\n');
}

// 使用
constheaders= ["服务""状态""响应时间"];
constrows= [
  ["API""✅ 正常""45ms"],
  ["数据库""✅ 正常""12ms"],
  ["Redis""❌ 异常""-"],
];

console.log(renderTable(headersrows));

输出:

| 服务   | 状态   | 响应时间 |
|--------|--------|----------|
| API    | ✅ 正常 | 45ms     |
| 数据库 | ✅ 正常 | 12ms     |
| Redis  | ❌ 异常 | -        |

4.5 使用颜色(终端)

如果你的终端支持 ANSI 颜色码:

constcolors= {
reset'\x1b[0m',
red'\x1b[31m',
green'\x1b[32m',
yellow'\x1b[33m',
blue'\x1b[34m',
};

functioncolor(textcolor) {
return`${colors[color]}${text}${colors.reset}`;
}

console.log(color("✅ 成功""green"));
console.log(color("❌ 失败""red"));
console.log(color("⚠️ 警告""yellow"));
console.log(color("ℹ️ 信息""blue"));

五、实战:打造你的专属运维助手

结合今天学到的所有内容,我们可以打造一个完整的运维助手:

// scripts/ops-assistant.js
classOpsAssistant {
constructor() {
this.name="小龙虾运维助手";
this.version="1.0.0";
  }

asyncrun() {
console.log(`
🦞 ${this.name}v${this.version}
${'='.repeat(40)}
`);

// 1. 健康检查
awaitthis.healthCheck();

// 2. 自动化巡检
awaitthis.inspection();

// 3. 故障自愈
awaitthis.selfHealing();

console.log(`
${'='.repeat(40)}
🦞 运维巡检完成
`);
  }

asynchealthCheck() {
console.log("📊 健康检查...\n");
// ... 实现见 2.3 节
  }

asyncinspection() {
console.log("🔍 自动化巡检...\n");
// ... 实现见 2.3 节
  }

asyncselfHealing() {
console.log("🔧 故障自愈检查...\n");
// ... 实现见 3.3 节
  }
}

newOpsAssistant().run();

运行效果:

🦞 小龙虾运维助手 v1.0.0
========================================

📊 健康检查...

【服务器状态】
| 指标 | 状态 | 值 |
|------|------|-----|
| CPU | ✅ 正常 | 35.2% |
| 内存 | ⚠️ 偏高 | 78.5% |
| 磁盘 | ✅ 正常 | 62.1% |

🔍 自动化巡检...

【服务状态】
| 服务 | 状态 |
|------|------|
| Docker | ✅ 运行中 |
| Redis | ✅ 运行中 |

🔧 故障自愈检查...

✅ Redis 状态正常
✅ Docker 状态正常
✅ 无需自愈

========================================
🦞 运维巡检完成

六、常见问题

Q1: 自动巡检太频繁影响服务器性能?

把巡检间隔调大,或者使用轻量级的检查方式:

# 原来每分钟巡检
* * * * * /root/.openclaw/node/bin/node /root/.openclaw/workspace/skills/prometheus/scripts/health-check.js

# 改成每小时一次
0 * * * * /root/.openclaw/node/bin/node /root/.openclaw/workspace/skills/prometheus/scripts/health-check.js

Q2: 自愈操作失败了怎么办?

加入人工确认机制:

asyncfunctionautoFixWithConfirm(service) {
console.log(`⚠️ ${service}需要修复`);
console.log(`建议操作: systemctl restart ${service}`);
console.log(`请输入 "yes" 确认执行:`);

constanswer=awaitprompt();  // 等待用户输入

if (answer.toLowerCase() ==='yes') {
awaitautoRestart(service);
  } else {
console.log("❌ 已取消,等待人工处理");
  }
}

Q3: 如何让巡检报告发送到飞书?

参考 feishu-im 技能的说明,调用飞书机器人 API:

asyncfunctionsendToFeishu(message) {
awaitaxios.post('https://open.feishu.cn/open-apis/bot/v2/hook/xxx', {
msg_type'text',
content: { textmessage }
  });
}

今日小结

今天我们学会了:

  • ✅ 安全加固:配置白名单/黑名单、使用 SSH 密钥、管理环境变量

  • ✅ 自动化巡检:用 cron 定时任务 + 巡检脚本

  • ✅ 故障自愈:自动重启、清理磁盘、自动扩容

  • ✅ 定制外观:Emoji、进度条、表格、颜色


下期预告

小龙虾养殖日记(四)将会介绍:

  • 🌐 开放 API:让小龙虾可以被其他系统调用

  • 🔗 Webhook:小龙虾如何接收外部事件

  • 🤖 多 Agent 协作:多只小龙虾一起工作

  • 🏠 智能家居:用小龙虾控制家里的设备

敬请期待!


往期回顾:

  • 🦞 小龙虾 OpenClaw 养殖日记(一)

  • 🦞 小龙虾 OpenClaw 养殖日记(二)


🦞 小龙虾养殖日记,记录你与 AI 助手的日常