第 14 章 · 安全运维

安全加固与暴露面收口

本章围绕一次真实 OpenClaw 生产环境加固经验,整理出可复用的方法、流程与验收标准,适合用来排查暴露面、收口端口并建立长期可维护的安全基线。

使用提醒:文中的命令与检查项适合迁移到自己的服务器环境,但具体端口、白名单、系统用户与权限范围仍要按你的当前架构逐项核对。

🎯 1) 这一章解决什么问题

收口公网暴露面

把网站流量与管理流量分开:站点继续公网可达,OpenClaw 控制面只给白名单或内网。

形成可重启恢复的规则

不是临时打一条 iptables,而是用脚本 + systemd 保证重启后规则仍然存在。

给后续低权限迁移铺路

先盘点 sudo 与 Docker 依赖,再把 OpenClaw 从高权限账号迁到专用服务账号。

🧭 2) 先画出暴露面,而不是直接改规则

对象 是否应公网开放 建议动作 备注
网站 80/443 继续公网放行 普通访问者只需要站点,不需要控制面。
SSH 22/TCP 仅对白名单 IP 放行 白名单 IP 变更时要同步更新主机与云侧规则。
OpenClaw 控制面 18789/TCP 仅允许 lo、内网接口和白名单 本文以 18789 为例;若你自定义端口,所有命令同步替换。
Tailscale / 叠加网络 UDP 按需 仅在确实使用时保留 若不用 Tailscale,就不要保留对应 UDP 端口。
日志、配置目录、导出 CSV 只做内审,不公开下载 尤其避免在公开文档中留下真实路径、账号或导入文件名。

🛡️ 3) 三层收口架构:主机、防火墙持久化、云安全组

A. 主机级白名单:先把控制面单独拎出来

推荐给 OpenClaw 控制面建立专用链,例如 OPENCLAW_PANEL。只允许本机回环、内网接口和明确白名单。

#!/usr/bin/env bash
set -euo pipefail

PORT="${OPENCLAW_PORT:-18789}"
CHAIN="OPENCLAW_PANEL"
ALLOWED_IPV4=("203.0.113.10" "198.51.100.25")

sudo iptables -N "$CHAIN" 2>/dev/null || true
sudo iptables -F "$CHAIN"
sudo iptables -A "$CHAIN" -i lo -j ACCEPT
sudo iptables -A "$CHAIN" -i tailscale0 -j ACCEPT 2>/dev/null || true
for ip in "${ALLOWED_IPV4[@]}"; do
  sudo iptables -A "$CHAIN" -p tcp -s "$ip" --dport "$PORT" -j ACCEPT
done
sudo iptables -A "$CHAIN" -p tcp --dport "$PORT" -j DROP

B. 持久化:重启后规则仍能恢复

如果你只在当前 shell 临时执行规则,服务器重启后风险会回来。建议把脚本托管给一个简单的 systemd one-shot 服务。

# /etc/systemd/system/openclaw-panel-filter.service
[Unit]
Description=Restore whitelist for OpenClaw control plane
After=network-online.target
Wants=network-online.target

[Service]
Type=oneshot
ExecStart=/usr/local/sbin/openclaw-panel-filter.sh
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

C. 云安全组:主机和云侧都要收口

只做主机白名单不够;若未来主机规则被删、容器旁路监听或实例迁移,云安全组仍可能把端口重新暴露。主机与云侧要双层一致。

☁️ 4) 腾讯云安全组最小放行模板(也可迁移到其他云)

端口 / 协议 来源 是否保留 用途
22 / TCP 白名单 IP 保留 SSH 管理入口
80 / TCP 0.0.0.0/0 保留 HTTP 访问
443 / TCP 0.0.0.0/0 保留 HTTPS 访问
41641 / UDP 0.0.0.0/0 或按实际需求 按需 Tailscale / 叠加网络入口
18789 / TCP 白名单 IP 保留 OpenClaw 控制面
必须人工复核:确认已经删除任何“全部 TCP / 全部 UDP”之类的宽放通规则。最危险的不是少放一个端口,而是忘记删掉整段 1-65535 的全开规则。

5) 验收矩阵:证据先于结论

检查点 命令示例 通过标准
过滤服务已启用 sudo systemctl status openclaw-panel-filter --no-pager 服务为 enabled,执行成功,无报错
白名单规则存在 sudo iptables -S OPENCLAW_PANEL 能看到 lo、内网接口、白名单与最终 DROP
本机控制面仍可达 curl -I --max-time 6 http://127.0.0.1:18789/ 返回 200 或控制面正常响应
网站公网访问正常 curl -I --max-time 10 https://your-domain.example 网站继续返回 200 / 301 / 302 等预期状态
非白名单无法直连控制面 curl -I --max-time 8 http://<server-ip>:18789/ 从非白名单网络访问时应失败、超时或被拒绝

⚠️ 6) 还没结束:真正的风险常在权限与日志里

  • 如果 OpenClaw 长期运行在拥有广泛 sudo 能力的账号下,即使端口收口,风险仍然偏高。
  • 运维日志、journal 与 shell history 可能残留命令痕迹、路径、导入文件名,甚至凭证痕迹。
  • 如果你在文档、skill、截图或 handoff 中写过明文密码、服务器地址、二维码或接口密钥,应按“已暴露”处理并轮换。
  • 不要把真实白名单、导出 CSV 文件名或服务器内网结构直接贴到公开教程页。

🪜 7) 低权限迁移路线:先盘点依赖,再迁用户

Step 1:盘点 OpenClaw 是否真的需要 sudo cp/chown/chmod、Docker 组权限、systemctl 重启能力,不要先改用户后补救。
Step 2:创建专用服务账号,把配置目录、工作目录和日志目录迁移给该账号,避免继续挂在管理员主账号下。
Step 3:若确实有少量特权操作,优先改为精确白名单 sudo,而不是保留 NOPASSWD: ALL
Step 4:迁移后重新执行本章验收矩阵,确认网站访问、控制面白名单与自动恢复规则都还正常。

📋 8) 最简执行清单(适合季度复盘)

网络侧

  • 删除全端口放通
  • 控制面只留白名单 / 内网
  • 网站 80/443 继续公网开放
  • 叠加网络端口按需保留

主机与账号侧

  • 规则脚本纳入 systemd 持久化
  • 核查日志是否残留敏感信息
  • 逐步迁出高权限运行账号
  • 轮换已暴露的密码 / 密钥

第14章完成:把“服务能访问”升级成“服务能长期安全运行”

最核心的原则不是多配几条规则,而是把暴露面、权限边界和验收证据都固定下来。