关于 OPNsense Guard
OPNsense Guard 是面向 OPNsense 26.7+ 的安全优先 MCP 服务,默认只读。写入操作需经过策略检查、人工确认、应用验证,并在未确认时自动回滚。
主要功能
- 01默认只读的防火墙查询
- 02策略约束的变更计划与差异预览
- 03写入后验证并自动回滚
- 04哈希链式审计日志
- 05支持 stdio 与认证 HTTPS
适用场景
- 01检查防火墙规则、接口和日志
- 02预览并审核规则或别名变更
- 03确认变更后应用并监测回滚
- 04验证审计日志是否被修改
MCP 相关
该 MCP 服务向客户端暴露 OPNsense 状态、规则、日志及策略检查工具。启用写入配置后,可规划并执行经确认的变更。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
uvx opnsense-guard-mcpOPNSENSE_URLFirewall base URL, e.g. https://firewall.example.internalOPNSENSE_API_KEY密钥API key of a least-privilege read userOPNSENSE_API_SECRET密钥API secret of the read userOPNSENSE_CA_BUNDLECA file for a self-signed firewall certificate本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。
工具
21收录的工具列表 · 更新于 2 周前
此工具无需参数。
详细介绍
opnsense-guard-mcp
一款以安全为先的 MCP 服务,适用于 OPNsense 26.7+。
默认只读。所有写入操作都会先规划、检查策略并记录日志;除非你确认,否则会自动回滚。
状态:Alpha。 已在运行中的 OPNsense 26.7.4 上使用最小权限 API 用户进行测试:读取工具、策略文件、包含差异对比的变更规划、应用变更并进行验证和自动回滚、崩溃恢复,以及哈希链式审计日志;支持 stdio 或经身份验证的 HTTPS。详见 DESIGN.md。
与 Deciso B.V. 无关联。“OPNsense”是 Deciso B.V. 的商标。
有何不同
| opnsense-guard-mcp | |
|---|---|
| 默认模式 | 只读 |
| 读取路径 | GET,以及仅针对两个搜索端点(状态、规则)发送 POST;请求体固定为三个字段;使用路径允许列表,动词拒绝列表;拒绝路径遍历和编码;不跟随重定向 |
| 写入 | 使用独立 API 用户、精确的端点允许列表,按“规划 → 策略检查 → 人工批准 → 应用 → 验证”的流程执行;除非确认,否则自动回滚 |
| 26.7+ 上的回滚 | 自有对象级快照 + 回滚(26.7 中已移除保存点 API);重启后仍可恢复 |
| 安全护栏 | 允许列表策略文件:接口、网络、规则限制、防止锁定 |
| 审计 | 哈希链式 JSONL(audit verify 可检测篡改);计划支持 syslog |
| 传输 | stdio,或始终需要 bearer token 的 Streamable HTTP;可选 TLS / mTLS |
| 危险工具 | 不存在:没有重启、固件、服务控制、SSH 或 XML 编辑功能 |
快速开始(只读)
-
在 OPNsense 中(系统 → 访问 → 用户),创建一个使用随机密码的用户,不添加任何组(不要添加
admins),授予以下权限,然后为该用户创建 API 密钥。跳过尚未安装的组件;对应工具只会报告“禁止访问”。权限 用途 Firewall: Rules [new] firewall_rules、firewall_rule_get、规划Firewall: Aliases (view-only) firewall_aliases、规划Status: Interfaces interfacesStatus: Services service_listDiagnostics: ARP Table arp_tableDiagnostics: Routing tables routing_tableDiagnostics: Show States firewall_statesDiagnostics: Logs: Firewall: Live View firewall_logDiagnostics: Logs: System system_logLobby: Dashboard system_information、system_resources、健康探测Services: Intrusion Detection suricata_*Services: DHCP: Kea(v4) / Services: Dnsmasq DNS/DHCP: Settings / Status: DHCP leases (ISC) dhcp_leases:仅授予你使用的那一项System: Firmware (可选) system_status。此权限还允许安装更新,因此除非确有需要,否则不要授予。OPNsense 的大多数权限都不只是只读权限(Firewall: Aliases 是个例外):其中几项还允许通过 API 进行编辑。除针对两个精确端点(
diagnostics/firewall/query_states、firewall/filter/searchRule)的搜索 POST 外,服务只会使用此密钥发送 GET 请求;搜索 POST 的请求体由服务自行构建(current、rowCount、searchPhrase)。OPNsense 只有通过 POST 才能正确返回这些列表。仍应尽量缩短权限列表:最终由 OPNsense 自身强制执行这些权限。 -
安装:
pipx install opnsense-guard-mcp -
配置(将
.env.example复制为.env,或设置环境变量):OPNSENSE_URL=https://firewall.example.internal OPNSENSE_API_KEY=... OPNSENSE_API_SECRET=... OPNSENSE_CA_BUNDLE=/path/to/firewall-ca.pem # or OPNSENSE_VERIFY_SSL=false -
检查配置(不会连接防火墙):
opnsense-guard-mcp --check -
添加到你的 MCP 客户端,例如 Claude Code:
claude mcp add opnsense -- opnsense-guard-mcp --env-file /path/to/.env
HTTP 模式(共享服务)
HTTP 始终需要身份验证。出现以下情况时,服务会拒绝启动:
- 没有令牌;或
- 绑定到非环回地址且未启用 TLS
(仅在 TLS 代理后方可通过
MCP_ALLOW_PLAINTEXT=true覆盖)。
-
为每个客户端创建一个令牌。令牌只会显示一次;系统只存储其 SHA-256 值:
opnsense-guard-mcp token new --name laptop --scope readtoken list会显示名称和范围;token revoke --name laptop会在下一个请求时生效,无需重启。 -
启动服务:
MCP_TRANSPORT=http MCP_HOST=0.0.0.0 MCP_PORT=8848 \ MCP_TLS_CERT=server.pem MCP_TLS_KEY=server.key \ opnsense-guard-mcp -
将客户端指向
https://<host>:8848/mcp,并设置请求头Authorization: Bearer <token>。
| 变量 | 默认值 | 用途 |
|---|---|---|
MCP_HOST / MCP_PORT | 127.0.0.1 / 8848 | 监听地址 |
OPNSENSE_GUARD_TOKENS_FILE | ./tokens.json | 令牌哈希值 |
MCP_TLS_CERT / MCP_TLS_KEY | – | 提供 HTTPS 服务 |
MCP_TLS_CLIENT_CA | – | 要求客户端证书(mTLS) |
MCP_ALLOWED_HOSTS | localhost/127.0.0.1/端口上的 MCP_HOST | 接受的 Host 请求头(防 DNS 重绑定) |
MCP_ALLOWED_ORIGINS | 无 | 允许的浏览器来源;拒绝任何其他 Origin |
MCP_RATE_LIMIT_PER_MIN | 120 | 每个令牌每分钟的请求数 |
MCP_ALLOW_PLAINTEXT | false | 允许在非环回地址上使用纯 HTTP |
来自同一 IP 的重复登录失败(每分钟 10 次)会受到限流,并返回 HTTP 429。
Claude Code 和私有 CA: Claude Code(Node)不会为 MCP 服务使用 Windows/macOS 证书存储。请在 ~/.claude/settings.json 的 env 块中,将 NODE_EXTRA_CA_CERTS 指向你的 CA 文件,然后完全退出并重新打开 Claude,否则连接会因 UNABLE_TO_VERIFY_LEAF_SIGNATURE 而失败。
在 Docker 中运行
镜像以非 root 用户运行,并将审计日志、变更日志和令牌保存在 /data 中。
docker build -t opnsense-guard-mcp .
# stdio, for a local MCP client
docker run -i --rm --env-file .env -v guard-data:/data opnsense-guard-mcp
# HTTP: create a token, then serve (put the TLS files in the volume or mount them)
docker run --rm -v guard-data:/data opnsense-guard-mcp token new --name laptop --scope read
docker run -d --name opnsense-guard --env-file .env -v guard-data:/data -p 8848:8848 \
-e MCP_TRANSPORT=http -e MCP_HOST=0.0.0.0 -e MCP_ALLOWED_HOSTS=mcp.example.internal:8848 \
-e MCP_TLS_CERT=/data/tls/server.pem -e MCP_TLS_KEY=/data/tls/server.key \
opnsense-guard-mcp
挂载策略文件,并设置 OPNSENSE_GUARD_POLICY 以启用写入。请使用 docker stop(而非 kill)停止容器,以便回滚尚未确认的变更。
策略与规划
没有 policy.yaml 时,服务为只读模式。要启用规划,请将
policy.example.yaml 复制为 policy.yaml(或将
OPNSENSE_GUARD_POLICY 指向该文件)并进行编辑。未知键会导致错误。
规划工具(rule_plan、alias_plan)会读取当前状态、执行所有策略检查,并返回差异以及拒绝操作的原因。它们绝不会更改防火墙。 以下是规则被拒绝时的结果示例:
+ [wan] pass in inet any from any to any '[mcp]'
interface 'wan' is not in the allowed interfaces
any -> any pass rules are forbidden
inbound pass rules on WAN are forbidden
every rule written by this server must have logging on
内置防护措施:仅允许列出的接口/操作/方向;每个 IP 都必须位于
allow_networks 内;禁止 any→any 放行规则、WAN 入站放行规则、浮动规则或未启用日志记录的规则;只能编辑标记为 [mcp] 的规则(除非 only_modify_own: false);防止锁定自身(不允许创建匹配本服务自身 IP 的阻止规则;只能在 API 流量所经接口上创建新的放行规则)。如果同一规划还添加了一条 sequence 更小的放行规则,且能够证明所有 MCP 主机都能访问 API(源地址涵盖主机 IP,目标地址为 any/(self)/API IP,协议为 TCP,端口涵盖 API 端口),则允许在该接口上创建新的阻止或拒绝规则;两条规则都必须设置 sequence。
应用更改
只有在策略处于写入模式且已配置第二个具有写入权限的 API 用户时,更改工具才会出现:
OPNSENSE_WRITE_API_KEY=... # a different OPNsense user than the read one
OPNSENSE_WRITE_API_SECRET=...
为该用户仅授予以下两项权限:Firewall: Rules [new] 和
Firewall: Alias: Edit,不要分配任何组。(普通的 Firewall: Aliases 仅供查看:
允许搜索和获取,但不允许 addItem/setItem/delItem/reconfigure。)通过 HTTP 时,
更改工具需要使用带有 --scope write 的令牌。
流程:
rule_plan/alias_plan→ 差异 +plan_id(不会更改任何内容)。change_apply(plan_id)→ 请求用户批准差异(客户端支持时使用 MCP elicitation;否则工具会返回差异,且必须再次调用并设置user_confirmed=true)。随后重新读取防火墙(如果自规划以来有任何变动, 则拒绝执行),保存更改前的状态,写入并应用更改,重新读取所有内容进行验证, 并检查 API 是否仍可访问。任何步骤失败 → 撤销所有更改。- 更改处于待确认状态:除非调用
change_confirm,否则在confirm_timeout_s(默认值为 60 s)后自动撤销。 change_rollback可撤销待确认或已确认的更改。撤销时绝不会覆盖其他人 期间编辑过的对象(状态为conflict)。
服务器停止时,以及发生崩溃后再次启动时,也会撤销未确认的更改。同一时间只能
有一个未完成的更改,并且会强制执行 max_changes_per_hour 限制。
限制,直言不讳
- 撤销计时器运行在 MCP 主机上。如果某项更改导致该主机无法访问防火墙 API, 撤销操作就无法触达防火墙。防止锁定自己的策略和应用后立即执行的健康检查, 旨在避免并发现这种情况,但它们并不等同于较旧版本 OPNsense 曾提供的防火墙端 保存点。
- 如果不支持 elicitation,
user_confirmed=true就代表模型声称用户已同意。 审计日志会记录所用的方法。
审计日志
每次规划(无论获准还是被拒绝)以及每次服务器启动,都会写入
$OPNSENSE_GUARD_DATA_DIR/audit.jsonl(默认路径为 ./data)。每一行都包含
上一行的哈希,因此可以检测出编辑、删除和重排:
opnsense-guard-mcp audit verify
opnsense-guard-mcp audit tail -n 20
凭据绝不会写入其中。
工具(只读)
system_status、system_information、system_resources、service_list、
posture_check、suricata_status、suricata_settings、suricata_alert_status、
firewall_rules、firewall_rule_get、firewall_aliases、firewall_log、
firewall_states、system_log、interfaces、arp_table、routing_table、
dhcp_leases、raw_get、policy_show、security_audit。
在写入模式下还包括:rule_plan、alias_plan、plan_get、audit_tail。
配置写入凭据后还包括:change_apply、change_confirm、change_rollback、
change_list、change_get。
firewall_rules 每条规则返回一行(默认 50 条),便于在聊天中容纳完整规则集;
传入 detail=true 可获取原始 OPNsense 行,或使用 firewall_rule_get 获取单条规则。
通过 HTTP 时,读令牌仍会在工具列表中看到更改工具,但调用时会被拒绝(needs a token with scope 'write')。
开发
python -m venv .venv && . .venv/bin/activate
pip install -e ".[dev]"
ruff check . && mypy && pytest
安全
请参阅 SECURITY.md。请通过私密渠道报告漏洞。
许可证
MIT。请参阅 LICENSE。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。