mcpField
R
rust-panosmcp

rust-panosmcp

本地服务
mechub.org安全12 天前更新

关于 rust-panosmcp

rust-panosmcp 是用于通过范围受限且可审计的工具管理 Palo Alto Networks PAN-OS 防火墙的 Rust MCP 服务。它支持读取操作和受保护的配置变更,包括需要独立审批的持久化变更集。

主要功能

  1. 01stdio 与 HTTP 共 27 个工具
  2. 02按令牌限制设备和工具范围
  3. 03TLS 与有界请求处理
  4. 04可审计的 PAN-OS 配置流程
  5. 05需独立审批的变更集

适用场景

  1. 01检查防火墙清单与状态
  2. 02查询 PAN-OS 配置和日志
  3. 03暂存并审批防火墙配置变更

MCP 相关

通过 stdio 或经过身份验证的 Streamable HTTP 向 MCP 客户端提供 PAN-OS 防火墙操作。工具涵盖只读操作和受范围限制的配置变更,并设有验证、审批和审计控制。

配置

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

mcp.json · 通用配置
{
"mcpServers": {
"mechubsec-rustpanosmcp": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"ghcr.io/mechubsec/rustpanosmcp:0.17.0"
]
}
}
}
启动命令docker run -i --rm ghcr.io/mechubsec/rustpanosmcp:0.17.0

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

安装包
ocighcr.io/mechubsec/rustpanosmcp:0.17.0

工具

还没有获取到工具列表

本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。

详细介绍

mechub 标志

rust-panosmcp

面向 Palo Alto Networks PAN-OS 防火墙的异步 Rust Model Context Protocol 服务
mechub 项目——自主网络安全自动化

非官方/社区项目。 这是一个独立的社区项目,不声称与 Palo Alto Networks 有任何关联,也未获得其认可。产品名称和商标仅用于标识本软件可互操作的系统。

本仓库包含 v0.16.2 版本:一个受 bearer 令牌保护的服务,具备结构化审计日志、受保护的 PAN-OS 候选配置生命周期管理以及强化的发布打包;身份验证和审计由共享的 mecmcp-auth 和 mecmcp-audit crate 提供。

项目目标是构建一个小巧、快速、面向生产环境的服务,并具备与 rust-junosmcp 相同的安全态势:bearer 令牌身份验证、按令牌划分的设备和工具作用域、TLS、严格的远程绑定拒绝规则、有界输入和输出、可审计的变更操作,以及高效的连接复用。

架构和交付计划见 PLAN.md。安全边界和会阻止发布的控制措施记录在 THREAT_MODEL.md 中。

工作区

rust-panosmcp/          # MCP binary and stdio adapter
rust-panosmcp-auth/     # bearer and secret-handling foundations
rust-panosmcp-core/     # inventory, PAN-OS client, validation, tool logic
config/                 # secret-free inventory examples
docs/                   # operator guidance and phase notes
fuzz/                   # isolated cargo-fuzz workspace
packaging/              # distroless/container and systemd assets
scripts/                # release, matrix, fuzz, and benchmark gates

快速开始

安装

选择以下三种安装方式之一:

发布压缩包(Linux x86_64)

从 GitHub 发布页下载最新版本。资源文件命名格式为 rust-panosmcp-v0.16.2-x86_64-unknown-linux-gnu.tar.gz,并附带对应的 .sha256 文件。

# Download and verify
curl -LO https://github.com/mechubsec/rustpanosmcp/releases/download/v0.16.2/rust-panosmcp-v0.16.2-x86_64-unknown-linux-gnu.tar.gz
curl -LO https://github.com/mechubsec/rustpanosmcp/releases/download/v0.16.2/rust-panosmcp-v0.16.2-x86_64-unknown-linux-gnu.tar.gz.sha256
sha256sum -c rust-panosmcp-v0.16.2-x86_64-unknown-linux-gnu.tar.gz.sha256

# Extract
tar xzf rust-panosmcp-v0.16.2-x86_64-unknown-linux-gnu.tar.gz
cd rust-panosmcp-v0.16.2

# Install the binary and systemd assets
sudo install -m 0755 bin/rust-panosmcp /usr/local/bin/rust-panosmcp
sudo install -m 0644 packaging/systemd/rust-panosmcp.sysusers /usr/lib/sysusers.d/rust-panosmcp.conf
sudo install -m 0644 packaging/systemd/rust-panosmcp.tmpfiles /usr/lib/tmpfiles.d/rust-panosmcp.conf
sudo install -m 0644 packaging/systemd/rust-panosmcp.service /etc/systemd/system/rust-panosmcp.service

# Create the service user and directories
sudo systemd-sysusers
sudo systemd-tmpfiles --create

# Generate the HMAC key for audit redaction (required).
# Guarded: NEVER overwrite an existing key. The key is what makes an HMAC-redacted
# device identifier comparable across audit history, so replacing it silently
# breaks correlation with every record already written. These steps are safe to
# re-run during an upgrade only because of this guard.
sudo sh -c '[ -f /etc/rust-panosmcp/audit-hmac.key ] ||
    head -c 32 /dev/urandom | base64 > /etc/rust-panosmcp/audit-hmac.key'
sudo chmod 0600 /etc/rust-panosmcp/audit-hmac.key
sudo chown rust-panosmcp:rust-panosmcp /etc/rust-panosmcp/audit-hmac.key

# Start the service
sudo systemctl daemon-reload
sudo systemctl enable --now rust-panosmcp

此操作会创建专用的 rust-panosmcp 系统用户,并配置 /etc/rust-panosmcp(配置,root 所有)和 /var/lib/rust-panosmcp(状态)。审计日志中对设备进行脱敏需要使用 /etc/rust-panosmcp/audit-hmac.key 中的 HMAC 密钥;没有该密钥,服务将无法启动。解压后的归档中包含 config/ 下的配置示例——启动前,请将 devices.example.json 和 tokens.example.json 用作 /etc/rust-panosmcp 下的起始模板。单元详情见 packaging/systemd/。

LXC(Debian 13)

对于 Proxmox 上的专用非特权 LXC 容器,或独立的 systemd-nspawn,发布压缩包包含一个幂等安装程序,可自动执行上述手动步骤。如需包含容器创建步骤的完整设置指南,请参阅 HOW-TO-SETUP-LXC.md。

# Download and verify
curl -LO https://github.com/mechubsec/rustpanosmcp/releases/download/v0.16.2/rust-panosmcp-v0.16.2-x86_64-unknown-linux-gnu.tar.gz
curl -LO https://github.com/mechubsec/rustpanosmcp/releases/download/v0.16.2/rust-panosmcp-v0.16.2-x86_64-unknown-linux-gnu.tar.gz.sha256
sha256sum -c rust-panosmcp-v0.16.2-x86_64-unknown-linux-gnu.tar.gz.sha256

# Extract and run the installer
tar xzf rust-panosmcp-v0.16.2-x86_64-unknown-linux-gnu.tar.gz
cd rust-panosmcp-v0.16.2
sudo packaging/lxc/install.sh

# Configure the inventory and mint the first token
sudo vi /etc/rust-panosmcp/devices.json
sudo rust-panosmcp token add \
  --tokens-file /var/lib/rust-panosmcp/tokens.json \
  --name initial-token \
  --devices fw-example \
  --tools list_devices,gather_device_facts,execute_panos_op,get_panos_config

# Start the service
sudo systemctl enable --now rust-panosmcp.service

安装程序通过 systemd-sysusers 和 systemd-tmpfiles 创建 rust-panosmcp 用户和目录,安装二进制文件和单元,创建权限模式为 0600 的空 tokens.json,并且如果 /var/lib/rust-panosmcp/mutation-state.json 已存在,则绝不会覆盖它(变更集审计跟踪)。端点默认监听 http://127.0.0.1:30031/mcp。环境变量覆盖项和升级行为见 packaging/lxc/install.sh。

Docker / GHCR

每个 release 标签都会将预构建映像发布到 ghcr.io/mechubsec/rustpanosmcp。有关构建流水线,请参阅 .github/workflows/release-image.yml。如需完整的设置指南(包括双人模式和实验室模式),请参阅 HOW-TO-SETUP-DOCKER.md。

# Pull the image
docker pull ghcr.io/mechubsec/rustpanosmcp:latest

默认的 CMD 会在容器内部绑定到 127.0.0.1:30031,因此,直接运行 docker run,不带 -p、--host、--allowed-host 或 --allowed-origin,可以正常启动,但容器外部无法访问。请按照 HOW-TO-SETUP-DOCKER.md 中的说明,使用可正常工作的双人模式或实验室模式 docker run 命令(包括端口发布以及内置 ENTRYPOINT 已提供的标志),或者使用随附的 compose.example.yaml。

使用 Docker 运行(stdio)

对于通过 stdin/stdout 启动服务的 MCP 客户端,请准备一份结构与 config/devices.example.json 相同的设备清单:

{
  "version": 1,
  "policy": {
    "mode": "allowlist",
    "allow": ["show system info", "show interface all"]
  },
  "devices": [
    {
      "name": "panos-demo",
      "endpoint": "https://panos-demo.example.net",
      "vsys": "vsys1",
      "api_key": { "type": "env", "name": "PANOS_DEMO_API_KEY" },
      "tags": ["lab", "read-only"]
    }
  ]
}

启动容器前,请先导出 API 密钥变量。这种传递方式可避免密钥出现在命令行中,但 Docker 守护进程的访问权限仍可能通过检查操作暴露环境变量值。如需更严格的处理方式,请使用下文配置部分所述的基于文件的 API 密钥形式({"type":"file","path":"/protected/path"}),并以只读方式挂载该文件,权限设为 0600。

export PANOS_DEMO_API_KEY=replace-with-runtime-secret

确保挂载的设备清单和状态文件仅对容器用户(uid:gid 65532:65532)可读写;包含机密的文件必须设置为 0600 权限。stdio 在进程边界上没有身份验证:启动器可以使用挂载设备清单中的所有设备和所有工具,因此请限制设备清单的范围,并使用只读 PAN-OS API 角色来限定访问权限。状态目录必须可写,因为服务会在其中创建审计状态。

mkdir -p state
chmod 0600 devices.json
sudo chown 65532:65532 devices.json state

docker run --rm -i \
  --user 65532:65532 \
  -e PANOS_DEMO_API_KEY \
  -v "$PWD/devices.json:/etc/rust-panosmcp/devices.json:ro" \
  -v "$PWD/state:/var/lib/rust-panosmcp" \
  ghcr.io/mechubsec/rustpanosmcp:0.15.0 \
  --transport stdio

映像的 ENTRYPOINT 已提供配置、令牌、状态和审计密钥路径,因此请勿在映像名称后重复这些标志。令牌路径仅用于 HTTP。此命令不会启用 HTTP 和监听器 TLS:提供 --transport stdio 会替换映像的 CMD,包括其中的 HTTP 绑定地址和端口标志。与防火墙的连接仍会根据设备清单中的 TLS 信任设置使用 HTTPS。

从源代码构建

需要 Rust 1.89 或更高版本(MSRV)。

git clone https://github.com/mechubsec/rustpanosmcp.git
cd rustpanosmcp
cargo build --release --locked
./target/release/rust-panosmcp --version
运行(stdio)

从 config/devices.example.json 开始,将真实设备清单保留在 Git 之外,并提供其中引用的环境机密:

export PANOS_LAB_API_KEY='runtime-secret'
cargo run --locked --release -- --device-mapping /absolute/path/devices.json
运行(带身份验证的 streamable-http)

先创建一个遵循最小权限原则的令牌,然后启动 TLS Streamable HTTP 传输:

cargo run --locked --release -- \
  --device-mapping /etc/rust-panosmcp/devices.json \
  token add \
  --tokens-file /etc/rust-panosmcp/tokens.json \
  --name read-only-client \
  --devices fw-example \
  --tools list_devices,gather_device_facts,execute_panos_op,get_panos_config

cargo run --locked --release -- \
  --device-mapping /etc/rust-panosmcp/devices.json \
  --transport streamable-http \
  --host 0.0.0.0 --port 30031 \
  --tokens-file /etc/rust-panosmcp/tokens.json \
  --tls-cert /etc/rust-panosmcp/server.crt \
  --tls-key /etc/rust-panosmcp/server.key \
  --allowed-host mcp.example.net \
  --allowed-origin https://client.example.net

请安全地捕获第一条命令的标准输出:这是新 bearer 密钥唯一一次显示。有关令牌轮换、重新加载、拒绝规则、反向代理部署以及所有安全默认设置,请参阅 docs/PHASE2_OPERATIONS.md。第一阶段的设备清单和防火墙 TLS 详情仍请参阅 docs/PHASE1_OPERATIONS.md。

下一步:了解 reader、writer 和 reviewer MCP 角色工作流。

状态

阶段 1 实现了经过验证的资产清单和密钥提供程序、使用系统根证书/自定义 CA/精确叶证书固定的严格 HTTPS、池化异步 PAN-OS XML API 调用、类型化错误、超时、取消、输出上限,以及每台设备一个信号量。 阶段 2 添加了仅存储摘要的 bearer token、精确的设备/工具作用域、原子化资产清单/token 重新加载、TLS Streamable HTTP、Host/Origin 验证、受限请求正文、IP/token 速率限制,以及审计安全的请求跟踪。两种传输共用下文参考 MCP 工具中介绍的同一组 27 个工具;通配符 * token 作用域只能访问其中 16 个只读工具(list_devices、gather_device_facts、 execute_panos_op、get_panos_config、list_panos_entries、 get_panos_entry_digest、list_panorama_device_groups、 list_panorama_templates、get_panorama_push_status、 list_panos_rulebase_entries、get_panos_ha_state、get_panos_license_info、 get_panos_content_status、get_panos_software_status、 test_panos_security_policy_match、query_panos_logs);11 个生命周期/变更工具必须逐一明确列出。

阶段 3 增加了可选的候选配置指纹、严格限定的 XPath 策略、PAN-OS 配置锁、每台设备串行处理、暂存/差异/完整验证、管理员作用域的部分提交/回滚、作业协调,以及结构化变更审计。写入工具需要明确的 token 作用域;* 仍为只读。

阶段 4 增加了摘要固定的非 root distroless 镜像、强化的 systemd 单元、只读部署指南、PAN-OS 发布系列矩阵、五个解析器模糊测试目标、字节级可复现的归档、安全/运维手册文档,以及已发布的 Rust/Python 测量结果。

v0.2 增加了持久化的多操作变更集、特定于 token 的 XPath/操作授权和过期时间、规范端点串行处理,以及绑定到精确所有者/设备/指纹/操作摘要的独立审批。已批准的变更集在一个 PAN-OS 配置锁下应用;如果后续操作失败,则自动由管理员回滚。随后使用现有的差异、完整验证、提交或放弃生命周期。参见 docs/V0.2_CHANGE_SETS.md。

v0.2.1 将 PAN-OS 配置锁释放变为经过确认的状态转换:只有设备接受解锁后,提交/放弃记录才会清除 config_lock_held;解锁失败则会持久化为 indeterminate,以供明确协调。该版本还在 docs/V0.2.1_ACCEPTANCE.md 中记录了默认信任 TLS 和实验室部署的证据。

v0.2.2 更新了维护中的 Rust 依赖关系图和 GitHub Actions,同时保留 v0.2.1 的 PAN-OS 工具、授权、资产清单和变更状态接口。已发布版本和受控实验室部署的证据见 docs/V0.2.2_ACCEPTANCE.md。多 vsys、HA 和 Panorama 工作仍暂缓。

v0.3.0 将身份验证迁移到共享的 mecmcp-auth crate,弃用此仓库自身的 token、存储和 token 文件实现,改用一个共享且经过单独测试的 crate。PAN-OS 工具范围、授权作用域、资产清单和变更状态接口均未改变。两项运维人员可见的变更:tokens.json 必须为 mode 0600,否则服务器会拒绝启动;磁盘上的封装版本现在会在写入时保留,因此此版本触及的文件仍可由上一个版本读取。升级步骤见 CHANGELOG.md。

完整的 HTTPS 模拟、MCP 端到端,以及显式配置的 panosvm 实验室防火墙验收测试套件均已通过。阶段 1 已完成;可复现的证据记录在 docs/PHASE1_ACCEPTANCE.md。 Phase 2 验收证据记录在 docs/PHASE2_ACCEPTANCE.md 中。配置变更验收记录在 docs/PHASE3_ACCEPTANCE.md 中,操作员要求见 docs/PHASE3_OPERATIONS.md。 Phase 4 发布证据记录在 docs/PHASE4_ACCEPTANCE.md 中。生产部署、 轮换、备份/恢复和升级的相关说明见 docs/OPERATIONS.md;另请参阅 docs/COMPATIBILITY.md、 docs/BENCHMARKS.md 和 SECURITY.md。关于 PAN-OS 侧的最小权限管理员账户(与上述 MCP bearer 角色不同),请参阅 docs/PANOS_ADMIN_ROLES.md。

MCP 工具参考

该服务提供 27 个 MCP 工具,按操作类型分组:

只读工具
  • list_devices — 列出已授权的 PAN-OS 设备及安全元数据;绝不返回 API 密钥。
  • gather_device_facts — 从已授权设备收集主机名、型号、序列号、版本、管理 IP 和运行时间。
  • execute_panos_op — 在已授权设备上执行以 <show> 为根节点的只读 PAN-OS XML 命令,并限制输出大小。
  • get_panos_config — 在已授权设备上读取经过验证的 /config XPath 处的 PAN-OS 运行配置或候选配置。
  • list_panos_entries — 将规则或对象列表容器的 <entry> 子项分页读取为结构化 JSON;遇到大型规则库时会标记为截断,而不会报错。
  • get_panos_entry_digest — 通过 XPath 获取并哈希恰好一个 PAN-OS 配置条目,用于检测单条规则的变更。
  • list_panorama_device_groups — 列出 Panorama 设备组及其成员防火墙的序列号。
  • list_panorama_templates — 列出 Panorama 模板及其已声明变量的名称。
  • get_panorama_push_status — 根据作业 ID 读取 Panorama commit-all/推送作业的总体状态和各目标防火墙的状态。
  • list_panos_rulebase_entries — 将某个 vsys 的安全规则、NAT 规则、地址对象或服务对象分页列为结构化 JSON,并标记截断内容。
  • get_panos_ha_state — 在已授权设备上读取 PAN-OS 高可用状态(是否启用、模式、本地状态和对端状态)。
  • get_panos_license_info — 在已授权设备上读取 PAN-OS 许可证状态(功能、序列号、签发时间、到期时间、是否已过期)。
  • get_panos_content_status — 在已授权设备上读取 PAN-OS 内容版本状态(版本、发布日期、是否已下载、是否为当前版本)。
  • get_panos_software_status — 在已授权设备上读取 PAN-OS 软件版本状态(版本、发布日期、是否已下载、是否为当前版本、最新版本)。
  • test_panos_security_policy_match — 在已授权设备上测试模拟数据包会匹配哪条 PAN-OS 安全规则(如果有)。
  • query_panos_logs — 在已授权设备上获取有界时间范围内的 PAN-OS 日志(流量、威胁、系统或配置);始终限制查询范围,绝不进行无界查询。
候选配置生命周期工具(变更)
  • get_candidate_fingerprint — 返回涵盖所有操作员授权候选子树的 SHA-256 指纹。
  • stage_panos_config — 使用预期指纹暂存一组受策略约束的 PAN-OS 候选配置设置/删除操作。
  • diff_panos_candidate — 返回针对确切已暂存候选指纹的有界 PAN-OS 变更摘要。
  • validate_panos_candidate — 验证已暂存候选配置,并仅使相同指纹具备提交资格。
  • commit_panos_candidate — 仅使用确切候选指纹提交已成功验证的操作。
  • discard_panos_candidate — 通过管理员范围的部分候选配置回退,丢弃已暂存操作。
  • get_panos_operation — 返回由调用方拥有的 PAN-OS 候选配置生命周期操作的安全状态。
变更集工具(v0.2+)
  • create_panos_change_set — 在清单和令牌 XPath/操作范围内,规划并持久化 1-64 个有序的 PAN-OS 候选操作。
  • approve_panos_change_set — 批准尚未过期且摘要完全匹配的变更集;拒绝自我批准。
  • get_panos_change_set — 返回准确的操作、摘要、批准状态、过期时间和操作状态,以供审核或恢复。
  • apply_panos_change_set — 在单个端点/配置锁下应用已独立批准的变更集,并在部分失败时回滚。

写入工具需要明确的令牌范围;通配符 * 授权仍为只读。

配置

config/ 中的三个示例文件展示了配置选项:

  • devices.example.json — 设备清单,包含身份验证、TLS 验证模式(系统根证书、自定义 CA 或精确叶证书固定)、每台设备的并发限制,以及用于候选操作的可选管理员覆盖。
  • tokens.example.json — Bearer 令牌存储格式:仅存储摘要、每个令牌的设备和工具允许列表、可选的变更授权(XPath 根路径、允许的操作)以及过期时间戳。
  • devices.mutation.example.json — 清单变体,展示变更根路径配置和管理员范围的候选工作流字段。

清单文件绝不存放内联凭据:每台设备的 api_key 都是一个引用——环境变量使用 {"type": "env", "name": "VAR_NAME"},受模式限制的机密文件使用 {"type": "file", "path": "/protected/path"}。

命令策略(execute_panos_op、test_panos_security_policy_match)

清单文件顶层的 policy 键决定 execute_panos_op 会运行哪些操作命令,同样的限制也适用于服务器构建的 <test><security-policy-match> 命令,该命令由 test_panos_security_policy_match 发出:

  • mode: "allowlist"(失败时拒绝,默认模式)——除非命令匹配 allow 中的某个条目(对于管道输出,则匹配 allowed_pipes),否则会被拒绝。新生成的清单以及完全没有 policy 部分的清单,都会使用此模式。 config/devices.example.json 附带一组只读起始配置:

    "policy": {
      "mode": "allowlist",
      "allow": [
        "show system info",
        "show interface all",
        "show routing route",
        "show running security-policy",
        "show session info",
        "test security-policy-match"
      ]
    }
    

    允许列表条目根据命令自身 XML 结构中的精确元素标签路径进行匹配,而非根据 CLI 文本匹配——不会展开缩写,因此像 sh sys info 这样的简写形式,会和任何其他未列入 allow 的命令一样被拒绝。要在允许列表模式下运行 test_panos_security_policy_match,必须包含 test security-policy-match 条目;否则,无论其他配置如何,所有调用都会被拒绝。

  • mode: "blocklist"(失败时放行,旧版模式)——允许所有命令,但与设备 blocklist.commands 中的拒绝规则匹配的命令除外。为保持向后兼容,存在拒绝规则但未显式设置 policy.mode 键的清单会以此模式加载;由于失败时放行的阻止列表模式在规则缺少某个情况时没有允许列表可回退,服务器会在启动时记录一条 WARN。新部署应改为设置 mode: "allowlist"。

每台设备都可以通过其自身的 blocklist.allow/blocklist.allowed_pipes 数组,在共享的 policy.allow/policy.allowed_pipes 列表中添加设备专属条目;合并方式与当前合并 blocklist.commands 拒绝规则的方式相同。

无论使用哪种模式,每次拒绝都会连同底层策略库提供的原因代码写入审计日志。

审计日志记录

v0.4.0 通过共享的 mecmcp-audit crate 引入结构化审计日志记录。每次工具调用都会生成一条事件,其中包含调用方归属、目标设备、结果和执行时长。

变更集生命周期审计提供独立的审批证据:approve_panos_change_set 事件同时包含变更集 ID 和指纹摘要,证明第二个主体审核了之后通过 apply_panos_change_set 应用的确切摘要。

审计配置标志
  • --audit-format {text|json} — 选择 text(默认,人类可读)或 json(机器可解析)。
  • --audit-log-file <PATH> — 将审计事件写入文件路径。
  • --audit-journald — 将审计事件发送到 systemd 日志。
  • --audit-redact — 对声明的字段(设备名称、调用方身份)进行 HMAC 假名化,以便将日志发送到 SIEM,而不会泄露运营标识符。
  • --audit-hmac-key-file <PATH> — 用于脱敏的 HMAC 密钥路径;启用 --audit-redact 时必需。

所有审计目标均为可选,且可以组合使用。未指定审计目标时,不会发出审计事件。

转发到事件存储

审计跟踪不会留在此主机上。此服务遵循该系列标准——AUDIT-FORWARDING-STANDARD.md。

仅存在于生成该记录的机器上的审计记录并非审计跟踪:它只是某台设备上的日志文件,而该设备的操作员正是记录所涉及的一方。

发出方式(当前已生效)
--audit-format json \
--audit-log-file /var/lib/rust-panosmcp/audit.jsonl

JSON 为必需格式。text 格式用于在终端中阅读,不可作为解析目标。文件是面向操作员的产物,必须进行轮换——服务绝不会截断该文件。

传输方式(已规范,尚未实现)

记录会直接写入 SSDF 的 ssdf.audit,作为哈希链式行,符合 SSDF 合并证据约定,因此可以检测出行的删除或编辑。相关工作跟踪于 mecmcp#292。

我们曾设计并否决了成本更低的 syslog 路径:它可行,但记录没有链式关联,而此处其他每个环节都通过设计具备防篡改能力——计划摘要绑定审批,审批会注明不同的主体,且 token_verified_fields 将经佐证的来源信息与声明的信息区分开来。若最后一跳不使用链式关联,就会恰恰在审计人员最需要保障的地方丢弃这项保证。相关理由已记录在标准中。

解读结果

token_verified_fields 列出了由 令牌 佐证的来源字段。同一组中的其他字段——client_name、model_id、session_id——由客户端自行声明,且未经任何方式认证。不要将它们视为同等可信。

request_id 用于关联传输事件、处理程序事件,以及(在 Junos 上)设备提交注释。

安全性

完整说明请参阅 THREAT_MODEL.md 和 SECURITY.md。要点如下:

  • HTTP 必须经过身份验证 — 使用仅存储 SHA-256 摘要的 Bearer 令牌;不会持久保存明文机密。
  • 默认仅限环回地址 — 非环回 HTTP 需要 TLS 或显式指定 --allow-insecure-bind;非环回 TLS 需要 --allowed-host。
  • 始终验证 TLS — 使用系统根证书、自定义 CA 证书包或精确的叶证书固定;不采用首次使用即信任或禁用验证。
  • 有界 I/O — 输出上限(默认 512 KiB,最大 5 MiB)、请求正文大小限制(默认 1 MiB),并为所有 PAN-OS 调用设置超时。
  • 变更均经过审计 — 候选操作按设备串行执行,记录主体和指纹,验证后要求显式提交,并持久化锁和作业状态以供恢复。

CLI 参考

Secure, async MCP server for PAN-OS firewalls

Usage: rust-panosmcp [OPTIONS] [COMMAND]

Commands:
  token  Manage the digest-only bearer-token store
  state  Perform offline recovery on the private mutation-state file
  help   Print this message or the help of the given subcommand(s)

Options:
  -f, --device-mapping <DEVICE_MAPPING>
          Validated JSON device inventory [default: devices.json]
  -t, --transport <TRANSPORT>
          MCP transport [default: stdio] [possible values: stdio, streamable-http]
  -H, --host <HOST>
          Numeric bind address for Streamable HTTP [default: 127.0.0.1]
  -p, --port <PORT>
          TCP port for Streamable HTTP [default: 30031]
      --tokens-file <TOKENS_FILE>
          Absolute digest-only bearer-token file path
      --state-file <STATE_FILE>
          Absolute private JSON file for persistent change-set and operation state
      --lab-mode
          Run without two-person control: change sets are approved on creation
      --approval-timeout-secs <APPROVAL_TIMEOUT_SECS>
          Seconds a change-set approval stays valid before it expires [default: 900]
      --allow-plane-owned-writes
          Allow destructive operations on devices owned by a management plane
      --allow-direct-commit
          Allow committing an operation with no change-set approval at all
      --tls-cert <TLS_CERT>
          Absolute PEM certificate path; requires `--tls-key`
      --tls-key <TLS_KEY>
          Absolute PEM private-key path; requires `--tls-cert`
      --allow-no-auth
          Disable bearer auth for a loopback-only development listener
      --allow-insecure-bind
          Permit a non-loopback plaintext listener behind a trusted TLS proxy
      --allowed-host <ALLOWED_HOST>
          Additional accepted HTTP Host authority. Repeat for multiple values
      --allowed-origin <ALLOWED_ORIGIN>
          Accepted browser Origin URL. Repeat for multiple values
      --ip-rate-per-minute <IP_RATE_PER_MINUTE>
          Per-source-IP requests allowed per rolling minute window [default: 120]
      --token-rate-per-minute <TOKEN_RATE_PER_MINUTE>
          Per-authenticated-token requests allowed per rolling minute window [default: 240]
      --request-body-limit <REQUEST_BODY_LIMIT>
          Maximum Streamable HTTP request body in bytes [default: 1048576]
      --max-inflight-requests <MAX_INFLIGHT_REQUESTS>
          Max concurrent in-flight requests across all callers. 0 = unlimited [default: 64]
      --max-inflight-requests-per-token <MAX_INFLIGHT_REQUESTS_PER_TOKEN>
          Max concurrent in-flight requests per bearer token. 0 = unlimited [default: 16]
      --max-inflight-requests-per-target <MAX_INFLIGHT_REQUESTS_PER_TARGET>
          Max concurrent in-flight requests per target device. 0 = unlimited [default: 4]
      --max-sessions <MAX_SESSIONS>
          Max concurrent MCP sessions. 0 = unlimited [default: 128]
      --max-sessions-per-token <MAX_SESSIONS_PER_TOKEN>
          Max concurrent MCP sessions per bearer token. 0 = unlimited [default: 16]
      --enable-metrics
          Expose unauthenticated Prometheus metrics at /metrics (streamable-http only)
      --audit-format <AUDIT_FORMAT>
          Audit log format: `text` or `json` [default: text]
      --audit-log-file <AUDIT_LOG_FILE>
          Optional dedicated JSON audit log file path
      --audit-journald
          Enable journald audit sink for `target="audit"` events
      --audit-redact <AUDIT_REDACT>
          Optional per-field redaction policy (e.g., `devices=hmac,host=drop`)
      --audit-hmac-key-file <AUDIT_HMAC_KEY_FILE>
          HMAC key file for audit redaction (required if audit-redact requests hmac)
      --ssdf-audit-endpoint <SSDF_AUDIT_ENDPOINT>
          ClickHouse endpoint for the SSDF evidence sink. Enables the pipeline
      --ssdf-audit-server-id <SSDF_AUDIT_SERVER_ID>
          This writer's chain identity. Required whenever the endpoint is set
      --ssdf-audit-database <SSDF_AUDIT_DATABASE>
          ClickHouse database holding the audit table [default: ssdf]
      --ssdf-audit-user <SSDF_AUDIT_USER>
          INSERT-only write identity [default: ssdf_audit]
      --ssdf-audit-password-file <SSDF_AUDIT_PASSWORD_FILE>
          File holding the write identity's password. Must be 0600
      --ssdf-audit-verify-user <SSDF_AUDIT_VERIFY_USER>
          SELECT-only read identity, used for the high-water and tail reads [default: ssdf_audit_verify]
      --ssdf-audit-verify-password-file <SSDF_AUDIT_VERIFY_PASSWORD_FILE>
          File holding the read identity's password. Must be 0600
      --ssdf-audit-ca-file <SSDF_AUDIT_CA_FILE>
          PEM trust anchor for the ClickHouse certificate. Required for `https://`
      --ssdf-audit-outbox <SSDF_AUDIT_OUTBOX>
          Durable outbox for closed segments. Required when the endpoint is set
      --ssdf-audit-ledger <SSDF_AUDIT_LEDGER>
          Delivery ledger. Required when the endpoint is set
      --ssdf-audit-interval-secs <SSDF_AUDIT_INTERVAL_SECS>
          Seconds between delivery attempts. Must be positive [default: 30]
      --ssdf-audit-records-per-segment <SSDF_AUDIT_RECORDS_PER_SEGMENT>
          Records per segment before one is closed and spooled [default: 64]
  -h, --help
          Print help (see more with '--help')
  -V, --version
          Print version

Token subcommands:
  add         Mint a token, store only its digest, and print the secret once
  list        List token names and scopes without secrets or digests
  revoke      Revoke a named token
  rotate      Replace a token secret while preserving its scopes
  set-scopes  Replace a token's scopes or mutation grant, keeping its secret

State subcommands:
  resolve  Mark an indeterminate operation terminal after manual PAN-OS reconciliation
--lab-mode

--lab-mode 会免除第二个主体的要求,适用于只有一名操作员的实验环境;在这种环境中,双人控制只是走形式,并非真正的控制措施。此选项默认关闭,凡是涉及重要资产的环境都应保持关闭。

它会和不会改变的内容:

  • 创建变更集时会自动应用此豁免。没有豁免工具,流程仍与生产环境一致:create → apply。
  • 规划、计划摘要、漂移检测和应用时重新验证仍会执行。实验室模式移除的是第二位审核者,而不是变更记录。
  • 绝不会伪造审批者。 被豁免的变更集会记录 approver: null 和 approval_waiver: "lab-mode",并携带针对 (change_set_id, plan_digest, owner, approved_at) 生成的豁免摘要。它在密码学上可与真实的双人审批区分开来,之后也无法重新标记——如果日后有人需要证明哪些变更真正做到了职责分离,这一点就很重要。
  • 启用此模式时,服务启动会发出醒目的警告。

如果你想在不豁免控制措施的情况下独自测试写入操作,可以创建两个名称不同的令牌,分别用于创建和审批:主体是令牌名称,系统会拒绝自我审批。这样一人即可完成整个生命周期,同时保留控制措施;只要流程本身有任何价值,这都是更好的选择。

启用此模式

将标志添加到服务单元中。安装软件包时,请使用 drop-in 配置,而不要编辑随软件包提供的单元文件,以免升级时意外移除该标志:

sudo systemctl edit rust-panosmcp

替换 ExecStart 意味着必须完整重述其内容,因此请复制随软件包提供的命令并追加标志,不要写一个更短的命令。省略其他参数会在启用实验室模式时顺带悄悄改变状态文件位置或传输设置:

[Service]
# Clear the shipped ExecStart before replacing it; systemd appends otherwise.
ExecStart=
ExecStart=/usr/local/bin/rust-panosmcp \
    --device-mapping /etc/rust-panosmcp/devices.json \
    --transport streamable-http \
    --host 127.0.0.1 \
    --port 30031 \
    --tokens-file /var/lib/rust-panosmcp/tokens.json \
    --state-file /var/lib/rust-panosmcp/mutation-state.json \
    --lab-mode

应用前,请对照 packaging/systemd/rust-panosmcp.service 检查;随软件包提供的参数是权威依据,而此代码片段只是副本,可能会过时。

sudo systemctl daemon-reload && sudo systemctl restart rust-panosmcp

确认设置已生效。启动警告的说明文字中会使用 lab mode,结果描述中则会使用 approval_waiver=lab-mode:

sudo journalctl -u rust-panosmcp --since='5 minutes ago' | grep -i lab

预期输出:

Aug 15 12:34:56 host rust-panosmcp[1234]: lab mode enabled: change sets are approved on creation with no second principal. Records carry approval_waiver=lab-mode. Do not run this against production devices.
审批者令牌必须标记为 human

approve_panos_change_set 只接受令牌标记为 actor_type: human 的第二个主体作为审批者。未使用 --actor-type 签发的令牌为 unknown,会被拒绝作为审批者;agent 令牌同样如此。请使用 rust-panosmcp token add ... --actor-type human 签发审批者令牌。stdio 会话不携带调用方身份,因此无法进行审批;审批必须通过经过身份验证的 HTTP 进行。

--allow-direct-commit

对直接由 stage_config 创建的操作调用 commit_panos_candidate,而不是通过 create_panos_change_set / approve_panos_change_set / apply_panos_change_set 创建的操作,会在一个生命周期内完成暂存、验证和提交,完全没有独立的第二方审核:因为没有可供其审核的变更集。默认关闭:未设置此标志时,该提交会在触及防火墙之前被拒绝;无论使用 stdio 还是 HTTP,行为都相同(stdio 完全不携带调用方上下文,因此不能比经过身份验证的会话获得更宽松的处理)。

残余风险。 --allow-direct-commit 是一个应急开关,并非修复方案。设置该标志的操作员已认定,在此部署中以没有独立审核的方式运行这条特定路径,风险可以接受。此决定将:

  • 在启动时醒目记录,与上文的 --lab-mode 相同。
  • 在每次调用时审计。 在该标志启用期间执行的 commit_panos_candidate 调用,其审计记录中会包含 direct_commit_allowed=true;拒绝操作也会记录为 authorization=denied,并带有 reason=direct_commit_disabled。

它不会增加第二方审核;它只会让无审核运行的情况清晰可见。只要工作流允许,就优先使用变更集流程(create_panos_change_set → approve_panos_change_set → apply_panos_change_set),并仅在操作确实无法采用该流程时才使用此标志。

启用方式与 --lab-mode 相同:通过 systemd drop-in 将 --allow-direct-commit 附加到服务单元的 ExecStart 中,并完整复制随附命令。确认标志已生效——与实验室模式横幅不同,此处的提示不会与审计流的逐次调用架构归在一起,因此请 grep 普通启动消息:

sudo journalctl -u rust-panosmcp --since='5 minutes ago' | grep -i "allow-direct-commit is enabled"

验证

cargo fmt --all -- --check
cargo clippy --workspace --all-targets --all-features -- -D warnings
cargo test --workspace --locked
cargo check --manifest-path fuzz/Cargo.toml --bins --locked
scripts/verify-packaging.sh

使用 scripts/build-release.sh 创建确定性的发布归档,或者编译两次,并使用 scripts/verify-reproducible-build.sh 要求两次生成的字节完全一致。容器/systemd 安装说明见运维手册。

许可证

基于 MIT 许可授权。


README 配图
a mechub project · 确定性决策 · 模型负责解释 · 人类负责批准
github.com/fastrevmd-lab

评论

支持 Markdown

第一次接触 MCP?

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

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