前言
最近本地运行的 AI Agent 网关 OpenClaw 很火,我们尝试用它结合飞书搭建了一个能随时响应运维请求的机器人。它的核心逻辑很简单:通过飞书接收指令,OpenClaw 路由给大模型,模型调用本地 Shell 或文件系统工具执行任务,最后把结果回传给飞书。这样就能实现随时随地查看服务器状态、检索日志或管理进程。

架构概览
整个链路依赖 WebSocket 长连接,不需要公网回调地址,数据流如下:
飞书 App (WebSocket 长连接) ↕ OpenClaw Gateway (服务器上 systemd 常驻) ↕ AI 模型 (DeepSeek v3.2/GLM 4.7) ↕ 服务器 Shell (受白名单限制的命令执行)
关键组件包括管理会话和渠道连接的 OpenClaw Gateway、负责收发消息的飞书插件、以及支持白名单安全策略的 exec 工具。模型方面,本文选用 OneRouter 提供的 DeepSeek V3.2,当然任何兼容 OpenAI API 格式的提供商都可以接入。
环境准备
我们需要一台 Linux 服务器(Ubuntu),安装 Node.js 22+ 和 npm 10+。另外准备好飞书企业账号(免费)以及一个可用的 AI 模型 API Key。
部署 OpenClaw 网关
为了让机器人直接管理服务,建议直接在裸机上全局安装,而不是用 Docker,这样权限更灵活。
npm install -g openclaw
安装完成后确认 openclaw 命令可用。如果提示找不到命令,记得把 npm 的全局 bin 目录加入 PATH:
echo 'export PATH="$HOME/.npm-global/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc
接下来让 Gateway 开机自启并后台常驻,这步很重要,否则重启后服务就断了。
openclaw gateway install
openclaw gateway start
openclaw gateway status
配置模型与飞书
模型接入
编辑 ~/.openclaw/openclaw.json,添加模型配置。这里以 OneRouter + DeepSeek V3.2 为例:
{
"agents": {
"defaults": {
"model": {
"primary": "onerouter/deepinfra/deepseek-v3.2"
}
}
},
"models": {
"mode": "merge",
"providers": {
"onerouter": {
"baseUrl": "https://your-api-endpoint/v1",
"apiKey": "your-api-key",
"api": "openai-completions",
"models": [
{
"id": "deepinfra/deepseek-v3.2",
"name": "DeepSeek V3.2"
}
]
}
}
}
}
只要符合 OpenAI API 格式,其他提供商也能这么配。
飞书对接
先在飞书开放平台创建企业自建应用,记下 App ID 和 Secret。在权限管理里勾选以下关键权限:
im:message— 发送消息im:message:send_as_bot— 以机器人身份发送im:message.p2p_msg:readonly— 读取私聊消息im:message.group_at_msg:readonly— 读取群聊@消息im:resource— 读取资源contact:contact.base:readonly— 读取联系人基本信息(可选)
启用机器人能力后,安装飞书插件:
openclaw plugins install @openclaw/feishu
接着用 CLI 向导配置应用信息,输入刚才记下的 ID 和 Secret:
openclaw channels add
选择 Feishu 即可。也可以手动在配置文件里加:
{
"channels": {
"feishu": {
"enabled": true,
"accounts": {
"main": {
"appId": "cli_xxxxx",
"appSecret": "your-app-secret"
}
}
}
}
}
重启网关并观察日志,看到 feishu[main]: WebSocket client started 说明长连接建立成功。
注意: 飞书后台的事件订阅必须选'使用长连接接收事件',并且必须先启动 Gateway 才能保存这个订阅方式。记得发布版本生效。
配置运维 Agent 与安全策略
设定人设
编辑 ~/.openclaw/workspace/AGENTS.md,明确告诉 AI 它是个运维助手,限制它的工作范围。比如只允许操作 /home/youruser/projects 目录,禁止触碰其他用户文件。
配置 exec 工具
为了让 Agent 能执行命令,需要在 openclaw.json 中添加工具配置:
{
"tools": {
"exec": {
"host": "gateway",
"security": "allowlist",
"ask": "off"
}
}
}
这里 host 设为 gateway 表示在本机执行,security 设为 allowlist 开启白名单模式,ask 关闭审批提示以实现 7x24 自动化。
命令白名单
这是最关键的安全环节。编辑 ~/.openclaw/exec-approvals.json,列出允许执行的二进制文件路径:
{
"version": 1,
"defaults": {
"security": "allowlist",
"ask": "off",
"askFallback": "allowlist"
},
"agents": {
"main": {
"security": "allowlist",
"ask": "off",
"askFallback": "allowlist",
"allowlist": [
{ "pattern": "/usr/bin/bash" },
{ "pattern": "/usr/bin/sh" },
{ "pattern": "/usr/bin/ls" },
{ "pattern": "/usr/bin/cat" },
{ "pattern": "/usr/bin/tail" },
{ "pattern": "/usr/bin/head" },
{ "pattern": "/usr/bin/find" },
{ "pattern": "/usr/bin/du" },
{ "pattern": "/usr/bin/df" },
{ "pattern": "/usr/bin/free" },
{ "pattern": "/usr/bin/ps" },
{ "pattern": "/usr/bin/top" },
{ "pattern": "/usr/bin/ss" },
{ "pattern": "/usr/bin/netstat" },
{ "pattern": "/usr/bin/journalctl" },
{ "pattern": "/usr/bin/systemctl" },
{ "pattern": "/usr/bin/git" },
{ "pattern": "/usr/bin/docker" },
{ "pattern": "/usr/bin/node" },
{ "pattern": "/usr/bin/python3" }
]
}
}
}
特别提醒:/usr/bin/bash 和 /usr/bin/sh 必须加上,否则带管道的复杂命令无法执行。具体路径可以用 which <command> 确认。
测试与验证
重启 Gateway 后,直接在飞书里对机器人说话试试:
帮我看看服务器上哪些服务在运行
机器人会自动调用 systemctl、ps 等命令,收集信息后返回一份结构化的报告。后续还可以尝试:
- "查看 xxx 服务的最近日志"
- "服务器磁盘还剩多少空间"
- "帮我重启一下 xxx 服务"
- "看看哪些端口在监听"
安全策略总结
| 层级 | 措施 | 说明 |
|---|---|---|
| 命令执行 | allowlist 白名单 | 只允许指定的二进制文件 |
| 工作范围 | AGENTS.md 规则 | Agent 被指示只操作特定目录 |
| 飞书接入 | pairing 配对 | 新用户需要管理员批准才能使用 |
| 系统权限 | 非 root 运行 | Gateway 以普通用户身份运行 |
最终配置结构参考
整合后的 openclaw.json 大致结构如下,方便你对照检查:
{
"plugins": { "entries": { "feishu": { "enabled": true } } },
"agents": {
"defaults": {
"model": { "primary": "your-provider/your-model" }
}
},
"models": {
"mode": "merge",
"providers": { "...": "..." }
},
"tools": {
"exec": {
"host": "gateway",
"security": "allowlist",
"ask": "off"
}
},
"channels": {
"feishu": {
"enabled": true,
"accounts": {
"main": {
"appId": "cli_xxxxx",
"appSecret": "your-secret"
}
}
}
},
"gateway": { "mode": "local" }
}



