沙箱化代理式 AI :针对 OpenClaw 及通用代理式AI的实用安全指南

内容摘要与导读:
一种安全运行代理式AI工具(如OpenClaw、Claude Code)的多层沙箱隔离架构。通过虚拟机隔离、主机pf防火墙、Squid代理域名白名单、VM内部防火墙、标准用户账户和LuLu进程监控等六层防御,实现对AI代理行为的精细控制和实时可见性。文章强调防御深度和最小权限原则,提供了具体的配置示例、验证脚本和操作工作流,帮助用户在实验环境下安全地审计AI代理的行为,并在意外发生时快速回滚。
如何安全运行智能 AI 代理:完整沙盒隔离指南
当 AI 获得行动力,安全性变得至关重要
让 AI 写一首诗或代码,与赋予它在你的机器上执行指令的能力,两者之间存在根本性区别。前者是对话。后者是授权——而授权需要信任。
像 OpenClaw、Claude Code 这样的智能 AI 工具正在跨越这一门槛。它们不仅仅建议代码,还会执行代码。它们不仅仅推荐操作,还会执行操作。它们可以浏览、下载、安装、修改和删除。它们非常强大,而这种强大也伴随着真正的风险。
当智能 AI 出现以下情况时,会发生什么:
-
决定通过从一个已遭入侵的仓库下载包来“修复”问题? -
对“清理我的文件”的理解比你的预期更宽泛? -
在浏览网页时被提示注入? -
获取你的 Git 凭证来“帮助”推送代码?
我并不是说这些工具有恶意。我的意思是,信任应该被验证,而非假设——尤其是当我们仍在学习这些系统能做什么以及会做什么的时候。
本文内容(及非内容)
本文是关于架构和原则的。 它记录了我为测试 OpenClaw 构建隔离环境的历程——特别是每一层保护背后的思考以及它们如何协同工作。

本文不是:
-
一份可复制粘贴的配置指南(你的网络与我的不同) -
关于特定防火墙语法的教程(与 AI 合作,将规则适配到你的环境) -
OpenClaw 设置指南(网上有很多)
目标是帮助你理解要隔离什么以及为什么,这样你就能为自己的基础设施构建合适的沙盒。具体的 IP、端口和域名列表会有所不同——在信任之前,务必在你自己的环境中验证一切。
把这看作是为你家招待一位新客人做准备。一位乐于助人、有能力且渴望提供帮助的客人——但也是你仍在了解中的客人。
⚠️重要提示:以下展示的代码片段和配置是我环境中的示例。网络布局、IP 方案和安全要求各不相同。在依赖这些规则之前,务必在你的环境中验证它们是否按预期工作。如有疑问,请先使用非破坏性操作进行测试。
架构:纵深防御
在深入实施之前,让我们先了解我们要构建什么。假设我们的虚拟机网络在 192.168.64.x 上,主机网络在 192.168.2.x 上。我们试图让虚拟机访问我们的 Mac Studio(LLM 访问)和群晖共享卷(专用于代理),但不能访问 LAN 上的太多其他设备。

关键原则是分层安全。当运行自主或半自主 AI 代理时,真正的问题不是_“会出什么问题吗?”_——而是:
当问题确实发生时,它被控制得有多好?
我不依赖单一保护层,而是使用基于虚拟机(VM)的纵深防御模型。每一层都限制不同维度的风险。即使某一层失效,其他层也能限制影响范围。

为什么用虚拟机?隔离与回滚的力量
我们可以问:
“为什么不直接在专用 Mac 上运行,并配置防火墙规则?”
这种方法可行——但它缺乏真正的隔离和回滚能力。
以下是直接对比:

关键特性是快照/克隆。在每个实验会话之前:
-
将虚拟机恢复到干净状态 -
运行智能 AI -
发生意外?几秒钟内回滚 -
从受信任的主机上分析发生了什么
虚拟机是可丢弃的。你的数据和凭证不是。
实施:构建沙盒
以下各部分在概念上介绍每个安全层,并附有我设置中的示例配置。你的具体值会不同——适应模式,而不是精确数字。
我们的目标:

前提条件
-
Mac(主机)——专用或共享 -
UTM 用于虚拟化(免费,原生支持 Apple Silicon) -
macOS 虚拟机镜像 -
现有基础设施(我使用本地 LLM,但云端 API 也可以)
步骤1:虚拟机网络配置
在 UTM 中,将虚拟机设置为共享网络模式。这会给虚拟机分配一个私有 IP(192.168.64.x),并让所有流量都通过主机路由——这正是我们拦截所需的。
主机 Mac: 192.168.64.1(网关)
虚拟机: 192.168.64.3(DHCP 分配)
步骤2:主机 pf 防火墙(守门人)
创建 /etc/pf.anchors/vm-isolation:
vm_subnet = "192.168.64.0/24"
lan_subnet = "192.168.2.0/24"
mac_studio = "192.168.2.196"
synology = "192.168.2.150"
dns_server = "192.168.2.1"
llm_ports = "{ 4000, 8081, 8082, 8083}"
smb_ports = "{ 445, 139 }"
## 允许 DNS
pass out quick on en0 proto { tcp, udp } from dns_server port 53
## 允许本地 LLM 服务器(直接访问,无需代理)
pass out quick on en0 proto tcp from mac_studio port $llm_ports
## 允许文件共享
pass out quick on en0 proto tcp from synology port $smb_ports
## 阻止 LAN 上的其他所有流量
block out quick on en0 from lan_subnet
## 阻止直接互联网访问(必须使用代理)
block out quick on en0 proto tcp from $vm_subnet to any port { 80, 443 }
## 阻止其他所有流量
block out on en0 from $vm_subnet to any
添加到 /etc/pf.conf:
## 虚拟机子网的 NAT(访问 LAN 所需)
nat on en0 from 192.168.64.0/24 to 192.168.2.0/24 -> (en0)
anchor "vm-isolation"
load anchor "vm-isolation" from "/etc/pf.anchors/vm-isolation"
启用:
sudo pfctl -f /etc/pf.conf
sudo pfctl -e
这实现了什么:
-
虚拟机可以访问特定的 LAN 主机(LLM 服务器、NAS) -
虚拟机不能访问其他 LAN 设备(Git 服务器、其他机器) -
虚拟机不能直接访问互联网(HTTP/HTTPS 被阻止) -
所有互联网访问必须通过代理
步骤3:Squid 代理(域名白名单)
在主机上安装 Squid:
bash
brew install squid
配置 /opt/homebrew/etc/squid.conf:
workers 1
visible_hostname sq
http_port 3128
## 源网络
acl localnet src 192.168.64.0/24
acl localhost src 127.0.0.1
## SSL 和安全端口
acl SSL_ports port 443
acl Safe_ports port 80 443
acl CONNECT method CONNECT
## 允许的域名 - 白名单
acl allowed_domains dstdomain .pypi.org
acl allowed_domains dstdomain .pythonhosted.org
acl allowed_domains dstdomain .github.com
acl allowed_domains dstdomain .githubusercontent.com
acl allowed_domains dstdomain .npmjs.org
acl allowed_domains dstdomain .huggingface.co
acl allowed_domains dstdomain .openai.com
acl allowed_domains dstdomain .anthropic.com
## 通过代理阻止 LAN 访问(双重保险)
acl to_lan dst 192.168.0.0/16 10.0.0.0/8 172.16.0.0/12
http_access deny to_lan
## 允许白名单域名
http_access allow localnet allowed_domains
http_access allow localhost allowed_domains
## 拒绝其他所有
http_access deny all
## 日志记录 - 完全可见性
access_log /opt/homebrew/var/log/squid/access.log
启动 Squid:
brew services start squid
这实现了什么:
-
只有明确列入白名单的域名可以访问 -
每个访问的 URL 都有完整日志 -
根据需要轻松添加/移除域名 -
被阻止的域名返回 403,便于调试
步骤4:虚拟机内部防火墙(纵深防御)
在虚拟机内部,创建 /etc/pf.anchors/openclaw-sandbox:
dns_server = "192.168.2.1"
mac_studio = "192.168.2.196"
synology = "192.168.2.150"
proxy_host = "192.168.64.1"
llm_ports = "{ 4000, 8081, 8082, 8083}"
smb_ports = "{ 445, 139 }"
set skip on lo0
block out all
## 允许 DNS
pass out proto { tcp, udp } to $dns_server port 53
## 允许主机上的代理
pass out proto tcp to $proxy_host port 3128
## 允许直接 LLM 访问
pass out proto tcp to llm_ports
## 允许文件共享
pass out proto tcp to smb_ports
为什么重复规则? 如果虚拟机被攻破,内部 pf 被禁用,主机 pf 仍然会阻止。这就是纵深防御。
步骤5:虚拟机代理配置
配置系统级代理:
networksetup -setwebproxy "Ethernet" 192.168.64.1 3128
networksetup -setsecurewebproxy "Ethernet" 192.168.64.1 3128
networksetup -setproxybypassdomains "Ethernet" \
"*.local" "127.0.0.1" "localhost" "192.168.64.*" "192.168.2.196"
在 /etc/profile.d/proxy.sh 中设置环境变量:
export http_proxy="http://192.168.64.1:3128"
export https_proxy="http://192.168.64.1:3128"
export no_proxy="localhost,127.0.0.1,192.168.64.*,192.168.2.196"
步骤6:标准用户账户
创建一个非管理员用户用于运行代理:
sudo dscl . -create /Users/openclaw
sudo dscl . -create /Users/openclaw UserShell /bin/zsh
sudo dscl . -create /Users/openclaw RealName "OpenClaw Agent"
sudo dscl . -create /Users/openclaw UniqueID 510
sudo dscl . -create /Users/openclaw PrimaryGroupID 20
sudo dscl . -passwd /Users/openclaw
sudo createhomedir -c -u openclaw
这实现了什么:
-
代理无法安装系统软件 -
代理无法修改防火墙规则 -
代理无法访问管理员用户的文件 -
即使代理“逃脱”,它仍然受限
步骤7:LuLu 用于进程可见性
这是隔离变得可观察的地方。在虚拟机中安装 LuLu,用于每个进程的网络监控。
记住我以便更快登录
关键洞察: pf 和 Squid 告诉你访问了哪些 IP 和域名。LuLu 告诉你哪个进程在做这件事。这就是“虚拟机中的某个东西访问了 github.com”和“从 /Users/openclaw/.openclaw/ 运行的 python3 通过代理访问了 github.com”之间的区别。
最大可见性的配置:
-
允许 Apple 程序:✅ 是(系统进程需要网络) -
允许已安装的程序:❌ 否(你希望看到一切) -
允许 DNS 流量:✅ 是(域名解析所需)
你将会看到:
当一个进程尝试连接时,LuLu 会显示一个警报,包含:
-
进程名称: curl,python3,node -
完整路径: /usr/bin/curl或/Users/openclaw/.local/bin/... -
参数:实际运行的命令 -
目标 IP 和端口:它试图连接到哪里 -
协议:TCP/UDP

监控工作流程:
-
以管理员用户身份登录虚拟机 -
以标准用户身份运行智能 AI: su - openclaw -c "openclaw chat" -
LuLu 警报会出现在管理员的 GUI 会话中 -
实时批准/拒绝连接 -
在 LuLu → 规则窗口中查看积累的规则
应该允许的内容:
-
任何进程 → 代理(192.168.64.1:3128)——这是正确行为 -
任何进程 → 你的 LLM 服务器——按设计直接访问 -
任何进程 → 你的 NAS——文件存储访问
需要调查的内容:
-
连接到任何地方的未知二进制文件 -
任何尝试直接互联网访问(非通过代理)的进程 -
连接到意外 LAN 主机的连接
初始测试后,你可以将 LuLu 切换到被动模式,它会记录但不提示——你的其他安全层(pf、Squid)仍然在执行策略。
验证:测试隔离
在运行任何智能 AI 之前,验证隔离是否正常工作:
##!/bin/bash
echo "=== 隔离测试 ==="
## 应该通过
echo "代理到 GitHub:"
curl -s -m 10 -o /dev/null -w "%{http_code}" https://github.com
echo "Mac Studio LLM:"
nc -zv 192.168.2.196 4000
## 应该失败
echo "被阻止的域名(reddit):"
curl -s -m 5 -o /dev/null -w "%{http_code}" https://reddit.com
echo "直接互联网(绕过代理):"
curl -s -m 5 --noproxy '*' https://example.com
echo "被阻止的 LAN 主机:"
nc -zv 192.168.2.100 22
预期结果:
-
✅ GitHub 返回 200 -
✅ Mac Studio 连接成功 -
✅ Reddit 返回 403(被 Squid 阻止) -
✅ 直接互联网超时(被 pf 阻止) -
✅ 其他 LAN 主机被阻止
操作工作流程

双用户模式
一个关键的操作见解:以管理员身份登录虚拟机 GUI,以标准用户身份运行代理。
为什么这很重要:
-
LuLu 警报会出现在 GUI 会话中(管理员能看到) -
代理以有限权限运行(标准用户) -
你可以实时批准/拒绝连接 -
方便切换上下文进行故障排除
## 在虚拟机中,以管理员身份登录
su - openclaw -c "your-agent-command"
## 或用于交互式会话
su - openclaw
your-agent-command
如果你直接以标准用户身份登录,LuLu 提示可能不会出现(或者出现但你没有管理员凭证无法批准)。双用户模式在不牺牲隔离性的前提下提供了可见性。
每次测试会话前
-
将虚拟机恢复到干净快照 -
启动虚拟机 -
运行隔离测试 -
启动智能 AI 会话
会话期间
从主机监控:
## 终端1:查看 Squid 日志
tail -f /opt/homebrew/var/log/squid/access.log
## 终端2:查看被阻止的连接
sudo tcpdump -i pflog0 -n
当出现问题时
-
立即暂停虚拟机(UTM → 暂停) -
拍摄诊断快照 -
从主机查看日志 -
恢复到干净基线 -
调查发生了什么
添加新权限
这就是白名单方法的优势所在。当代理需要访问新内容时,你会有意识地决定是否授予。
概念:逐步扩展访问权限
需要访问新域名?将其添加到代理白名单并重载。
需要访问新的 LAN 主机?将其添加到主机和虚拟机的 pf 规则中,然后重载。
这种摩擦是故意的。每次扩展都是有意识的决定,而不是意外。
如果使用共享机器呢?
如果你没有专用 Mac 来运行这个,架构仍然可以通过修改来工作:
-
Squid 影响:代理仅拦截虚拟机流量(通过源 IP 过滤),因此不会影响你的正常浏览 -
pf 规则:规则专门针对虚拟机子网,你的正常流量不受影响 -
资源使用:Apple Silicon 上的 macOS 虚拟机效率很高;预期性能约为 90–95%
主要权衡是安全基础设施与你的正常工作同时运行。专用机器提供更清晰的隔离,但并非严格必需。
结论
智能 AI 非常强大。这种力量需要尊重——以及在建立信任之前的适当约束。
这种设置并非反 AI 或反进步。而是关于深思熟虑。关于安全地进行实验。关于当(而不是如果)意外发生时拥有恢复计划。
记住:本文是关于架构,而非特定配置。 原则——纵深防御、最小权限、白名单优先于黑名单、进程可见性——适用于任何网络布局。在你的环境中,具体的 IP、域名和端口号会有所不同。与 AI 工具合作,将这些概念适配到你的基础设施,并且在信任规则之前务必验证它们是否按预期工作。
我所描述的架构适用于当今任何智能 AI 工具,并且是为未来而设计的。随着这些工具的进化——变得更强大、更自主、更集成——拥有一个坚实的隔离框架会变得更有价值,而非更少。
从约束开始。有意识地扩展权限。信任但要验证。
谢谢!
原文链接: manjit28.medium.com/sand… 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~

夜雨聆风













