MXC 策略示例

这些示例演示工作负载要求如何转换为 MXC 资源权限。 可以从 C#、TypeScript 或 Rust 快速入门开始,然后将配置适应工作负荷。

下面的 JSON 针对 MXC 1.0.0 架构采用了原始执行配置结构。 完整配置包括版本和命令;标记为片段的节必须合并到现有配置中。 使用 C#、TypeScript 或 Rust 进行创作时,请使用不需要特定架构版本的相应 V1 SDK 类型。

下面是Windows示例。 将路径替换为主机上的现有资源,有针对性地授予任何其他工具依赖项,并确认 SDK 版本和后端支持所选的控件。

运行存储库范围的工具

此完整配置使用与快速入门相同的读取输入/写入输出模式。 在运行之前,先创建 C:\src\my-app\input.txt 和 C:\src\mxc-output 目录。 该命令可以读取源目录并写入输出目录,但无法写入源目录,也无法使用网络或 UI。

{
  "$schema": "https://raw.githubusercontent.com/microsoft/mxc/main/schemas/stable/mxc-config.schema.1.0.0.json",
  "version": "1.0.0",
  "containment": "process",
  "process": {
    "commandLine": "C:\\Windows\\System32\\cmd.exe /d /c type input.txt > C:\\src\\mxc-output\\result.txt",
    "cwd": "C:\\src\\my-app",
    "env": [
      "SystemRoot=C:\\Windows",
      "LOCALAPPDATA=C:\\src\\mxc-output",
      "TEMP=C:\\src\\mxc-output",
      "TMP=C:\\src\\mxc-output"
    ],
    "timeout": 30000
  },
  "filesystem": {
    "readonlyPaths": ["C:\\src\\my-app", "C:\\Windows\\System32\\cmd.exe"],
    "readwritePaths": ["C:\\src\\mxc-output"]
  },
  "network": {
    "egress": { "default": "deny" },
    "ingress": { "default": "deny", "hostLoopback": "deny" }
  },
  "ui": {
    "disable": true,
    "clipboard": "none",
    "injection": false
  }
}

此示例假定Windows安装在C:\Windows;使用主机上的实际系统目录。 具有显式env列表的 Windows ProcessContainer 请求必须同时包含SystemRoot和LOCALAPPDATA。 将命令替换为生成或分析工具时,请配置其缓存和临时文件以使用专用可写目录,而不是授予对整个存储库的写入访问权限。

在更广泛的授权内保护凭据

上述配置授予对C:\src\my-app的读取访问权限。 如果该目录包含环境文件或机密目录,请在其现有 filesystem 部分中添加此片段,同时保留只读和读写列表:

{
  "deniedPaths": [
    "C:\\src\\my-app\\.env",
    "C:\\src\\my-app\\secrets"
  ]
}

这些被拒绝的路径位于已授权的源目录中。 将不相关的存储库和用户配置文件目录置于授权范围之外。

尽可能将机密置于授权树范围之外。 验证所选后端上重叠的授予项与拒绝项;某些已装载的目录后端会拒绝嵌套的拒绝项,而不是强制执行它们。

允许直接访问 IP 范围

此配置片段将替换 network 部分。 它允许到已批准的 CIDR 范围的出站 TCP 端口 443,并拒绝其他传出、传入和主机环回访问。 应从受信任的配置中提供已批准的范围,而不是从工作负荷中接受它们。

{
  "network": {
    "egress": {
      "default": "deny",
      "allow": [
        {
          "to": [{ "cidr": "192.0.2.0/24" }],
          "ports": [{ "protocol": "tcp", "port": 443 }]
        }
      ]
    },
    "ingress": { "default": "deny", "hostLoopback": "deny" }
  }
}

192.0.2.0/24 是仅用于文档的范围。 将其替换为预期服务的已批准地址。 该规则允许该端口上的 TCP,而不仅限于 HTTPS、一个主机名或一项应用程序服务。 直接主机名解析可能需要单独的 DNS 规则。

此示例需要支持直接出口规则的后端和主机。 不要将其与runtimeConfig.networkProxy组合使用。 对于基于主机名的 HTTP(S) 决策,请改用受支持的基于代理的配置。

使用应用程序提供的代理

在启动工作负载之前,主机应用必须启动其代理。 此示例将 MXC 配置为使用现有代理;它不实现、启动或批准代理的请求处理策略。

以下配置片段面向采用受支持的操作系统范围代理强制执行路径的 Windows ProcessContainer。 将其合并到完整配置中,保留命令、文件系统权限、超时和 UI 限制。 将终结点和对等名称替换为正在运行的代理的终结点和对等名称。

{
  "containment": "processcontainer",
  "network": {
    "egress": { "default": "deny" },
    "ingress": { "default": "allow", "hostLoopback": "deny" }
  },
  "runtimeConfig": {
    "networkProxy": "http://127.0.0.1:8080"
  },
  "processContainer": {
    "network": {
      "allowedProxyPeer": "<package-family-name-or-appcontainer-profile-name>"
    }
  }
}

allowedProxyPeer 标识代理的已安装包或未打包的 AppContainer 配置文件。 代理必须侦听配置的环回地址和端口,并满足文档中说明的 Windows 先决条件。 MXC 不会从 URL 推断该身份信息。

Important

此 Windows 映射需要 ingress.default: "allow",这同时会许可专用网络服务器流量通过。 hostLoopback: "deny" 当配置的代理对等方可访问时,保持常规主机环回访问关闭。 该示例不是全部入站流量均被拒绝的配置。

强制执行路径上仍然拒绝直接 Internet 访问。 代理控制其转发哪些 HTTP(S) 请求。 没有 AppContainer 标识的普通未打包主机代理需要不同的更广泛的兼容性配置:请勿删除 allowedProxyPeer 并假定保留相同的限制。

在依赖于仅可通过代理访问之前,请使用相应的 SDK 类型并验证支持。 有关 Windows 先决条件,请参阅 ProcessContainer 代理部署选项;有关其他后端的信息,请参阅定向联网。

允许可见工具在不具有广泛 UI 访问权限的情况下运行

对于需要可见窗口和剪贴板输入的工作负荷,此配置片段将替换 ui。 它允许 Windows 和剪贴板读取,但不允许剪贴板写入或合成键盘和指针输入:

{
  "ui": {
    "disable": false,
    "clipboard": "read",
    "injection": false
  }
}

在 V1 SDK ContainerRequest中,等效的 UI 属性是 disable, clipboard以及 allowInputInjection。 仅当工作负载需要读取剪贴板时,才授予剪贴板读取权限。 检查运行时 UI 支持,并测试每个目标主机上所需的限制。

重复使用状态感知沙盒

当命令必须共享环境时,请使用状态感知执行。 预配并启动它,执行命令,然后在完成后停止并取消预配它。 在失败和取消后安排清理,而不是只在成功后安排清理。

状态感知调用使用特定于阶段的 ProvisionRequest,并为每个命令使用单独的 ExecutionRequest,而不是上述完整的一次性配置。 预配返回一个不透明的 ContainerId;将其原样传递给后续阶段。 在 .NET 中使用 MxcLifecycle、TypeScript 生命周期函数(如 provisionContainer),或结合 IsolationSession 或 WSLc(V1 生命周期 API 支持的后端)使用 Rust v1::container 函数(如 provision_container)。 有关确切要求,请参阅生命周期概念、MXC 容器生命周期和 .NET、TypeScript 或 Rust SDK 指南。

在选择每个生命周期后端之前,请检查每个生命周期后端强制实施的内容。 IsolationSession 分隔工作负荷的用户和会话,但不应用 MXC 文件系统、UI 或网络筛选,并且其请求必须显式允许所有网络流量。 WSLc 网络功能是完全隔离的或完全桥接的,没有针对各个目标的规则。 有关详细信息,请参阅“选择容器类型”和“后端选择和设置”。

验证示例

对于每个调整的策略,请测试预期行为和尝试滥用:

  • 确认可以读取所需的输入,并且可以写入所需的输出。
  • 确认凭据和不相关的文件仍然不可访问。
  • 确认直接、本地网络、环回和入站连接是否与策略匹配。
  • 对于基于代理的访问,请确认已获批准的请求能够成功,并且直接 Internet 尝试失败。
  • 确认剪贴板、输入注入和可见窗口是否与 UI 策略匹配。
  • 确认超时和清理在成功、失败和取消后都能正常工作。

使用学习模式调查缺失的访问权限。 不要自动授予代表运行观察到的每个资源。