mcpField
O
OPNsense Guard

OPNsense Guard

本地服务
github.com/d3ltasecurity安全12 周前更新

关于 OPNsense Guard

OPNsense Guard 是面向 OPNsense 26.7+ 的安全优先 MCP 服务,默认只读。写入操作需经过策略检查、人工确认、应用验证,并在未确认时自动回滚。

主要功能

  1. 01默认只读的防火墙查询
  2. 02策略约束的变更计划与差异预览
  3. 03写入后验证并自动回滚
  4. 04哈希链式审计日志
  5. 05支持 stdio 与认证 HTTPS

适用场景

  1. 01检查防火墙规则、接口和日志
  2. 02预览并审核规则或别名变更
  3. 03确认变更后应用并监测回滚
  4. 04验证审计日志是否被修改

MCP 相关

该 MCP 服务向客户端暴露 OPNsense 状态、规则、日志及策略检查工具。启用写入配置后,可规划并执行经确认的变更。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"d3ltasecurity-opnsense-guard": {
"command": "uvx",
"args": [
"opnsense-guard-mcp"
],
"env": {
"OPNSENSE_URL": "<OPNSENSE_URL>",
"OPNSENSE_API_KEY": "<OPNSENSE_API_KEY>",
"OPNSENSE_API_SECRET": "<OPNSENSE_API_SECRET>",
"OPNSENSE_CA_BUNDLE": "<OPNSENSE_CA_BUNDLE>"
}
}
}
}
启动命令uvx opnsense-guard-mcp
需要配置的环境变量
OPNSENSE_URLFirewall base URL, e.g. https://firewall.example.internal
OPNSENSE_API_KEY密钥API key of a least-privilege read user
OPNSENSE_API_SECRET密钥API secret of the read user
OPNSENSE_CA_BUNDLECA file for a self-signed firewall certificate

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
pypiopnsense-guard-mcp0.1.1

工具

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 编辑功能

快速开始(只读)

  1. 在 OPNsense 中(系统 → 访问 → 用户),创建一个使用随机密码的用户,不添加任何组(不要添加 admins),授予以下权限,然后为该用户创建 API 密钥。跳过尚未安装的组件;对应工具只会报告“禁止访问”。

    权限用途
    Firewall: Rules [new]firewall_rules、firewall_rule_get、规划
    Firewall: Aliases (view-only)firewall_aliases、规划
    Status: Interfacesinterfaces
    Status: Servicesservice_list
    Diagnostics: ARP Tablearp_table
    Diagnostics: Routing tablesrouting_table
    Diagnostics: Show Statesfirewall_states
    Diagnostics: Logs: Firewall: Live Viewfirewall_log
    Diagnostics: Logs: Systemsystem_log
    Lobby: Dashboardsystem_information、system_resources、健康探测
    Services: Intrusion Detectionsuricata_*
    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 自身强制执行这些权限。

  2. 安装:

    pipx install opnsense-guard-mcp
    
  3. 配置(将 .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
    
  4. 检查配置(不会连接防火墙):

    opnsense-guard-mcp --check
    
  5. 添加到你的 MCP 客户端,例如 Claude Code:

    claude mcp add opnsense -- opnsense-guard-mcp --env-file /path/to/.env
    

HTTP 模式(共享服务)

HTTP 始终需要身份验证。出现以下情况时,服务会拒绝启动:

  • 没有令牌;或
  • 绑定到非环回地址且未启用 TLS (仅在 TLS 代理后方可通过 MCP_ALLOW_PLAINTEXT=true 覆盖)。
  1. 为每个客户端创建一个令牌。令牌只会显示一次;系统只存储其 SHA-256 值:

    opnsense-guard-mcp token new --name laptop --scope read
    

    token list 会显示名称和范围;token revoke --name laptop 会在下一个请求时生效,无需重启。

  2. 启动服务:

    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
    
  3. 将客户端指向 https://<host>:8848/mcp,并设置请求头 Authorization: Bearer <token>。

变量默认值用途
MCP_HOST / MCP_PORT127.0.0.1 / 8848监听地址
OPNSENSE_GUARD_TOKENS_FILE./tokens.json令牌哈希值
MCP_TLS_CERT / MCP_TLS_KEY–提供 HTTPS 服务
MCP_TLS_CLIENT_CA–要求客户端证书(mTLS)
MCP_ALLOWED_HOSTSlocalhost/127.0.0.1/端口上的 MCP_HOST接受的 Host 请求头(防 DNS 重绑定)
MCP_ALLOWED_ORIGINS无允许的浏览器来源;拒绝任何其他 Origin
MCP_RATE_LIMIT_PER_MIN120每个令牌每分钟的请求数
MCP_ALLOW_PLAINTEXTfalse允许在非环回地址上使用纯 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 的令牌。

流程:

  1. rule_plan / alias_plan → 差异 + plan_id(不会更改任何内容)。
  2. change_apply(plan_id) → 请求用户批准差异(客户端支持时使用 MCP elicitation;否则工具会返回差异,且必须再次调用并设置 user_confirmed=true)。随后重新读取防火墙(如果自规划以来有任何变动, 则拒绝执行),保存更改前的状态,写入并应用更改,重新读取所有内容进行验证, 并检查 API 是否仍可访问。任何步骤失败 → 撤销所有更改。
  3. 更改处于待确认状态:除非调用 change_confirm,否则在 confirm_timeout_s(默认值为 60 s)后自动撤销。
  4. 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。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。