如何用 mise exec 的 sandboxing 参数限制子命令的网络与文件写入?
【免费下载链接】misedev tools, env vars, task runner项目地址: https://gitcode.com/GitHub_Trending/mi/mise
当你用mise exec运行构建脚本或来源不完全可信的命令时,可能不希望它访问网络、也不希望它往输出目录之外写文件。mise 的 sandboxing 功能可以为mise exec和mise run启动的子命令施加操作系统级别的限制:阻断网络、限定可写入的文件系统路径、过滤环境变量。这些限制由宿主 OS 强制(Linux 使用 Landlock 与 seccomp-bpf,macOS 使用 Seatbelt),适用于 Linux 与 macOS;Windows 上不执行文件与网络限制,mise 只给出警告并照常运行,不要把它当成策略已生效的证据。
沙箱只作用于子命令本身。mise 的配置求值、工具安装等准备工作发生在沙箱之外;对不受信任的项目配置,文档建议另行启用 safe mode。
前置条件
- 已安装 mise(
mise --version可执行),并且子命令依赖的工具已在项目中配置好。文档示例以 Node 为例,即项目里已安装 Node; - 运行平台为 Linux 或 macOS。Linux 的文件系统沙箱依赖 Landlock(Linux 5.13 起可用);若 Landlock 不可用或无法施加文件系统限制,命令会直接失败,而不是降级运行;
- 用
--分隔 mise 的 sandboxing 参数与真正的子命令,例如mise exec --deny-net -- npm run build。
用 CLI 参数阻断网络与写入
任何--deny-*或--allow-*标志都会启用对应类别的限制。文档给出的最短路径(在一个已安装 Node 的项目中):
# 阻断本地构建的网络访问 mise exec --deny-net -- npm run build # 只允许写入已存在的输出目录(加上隐式系统例外路径) mkdir -p dist mise exec --allow-write=./dist -- npm run build # 拒绝读、写、网络和非必要环境变量,再放行本项目读取与输出目录写入 mise exec --deny-all --allow-read=. --allow-write=./dist -- node build.js三条命令分别对应:只需要断网、只需要限定写目标、以及最小权限组合。npm run build需要项目里有buildscript,最后一条命令需要存在build.js;允许的路径要按你的构建实际用到的文件和缓存调整。注意--deny-all仍保留下文列出的隐式访问,它不是一个空文件系统的容器。
mise exec(别名mise x)与mise run支持的 sandboxing 参数:
| 参数 | 作用 |
|---|---|
--deny-all | 同时阻断读、写、网络与环境变量 |
--deny-read | 阻断文件系统读取(系统库和工具目录仍可访问) |
--deny-write | 阻断写入,隐式临时/设备路径除外 |
--deny-net | 阻断全部网络访问 |
--deny-env | 阻断环境变量继承(必要变量与显式例外仍可通过) |
--allow-read=<path> | 只允许读取指定路径(隐式对其他路径启用--deny-read) |
--allow-write=<path> | 只允许写入指定路径(隐式对其他路径启用--deny-write) |
--allow-net=<host> | 在 macOS 上申请主机例外(见平台限制);Linux 上会被拒绝 |
--allow-env=<var> | 放行特定环境变量(隐式启用--deny-env),支持通配符,如--allow-env='MYAPP_*' |
只限制脚本写入、或给make build做网络隔离这类单参数用法:
mise x --deny-write -- bash script.sh mise x --deny-net -- make build理解隐式访问,避免策略配过头
文件系统限制生效时,以下路径始终保持可访问,保证工具能正常工作(摘自 sandboxing 文档):
始终可读:
- Linux 系统路径:
/usr、/lib、/lib64、/bin、/sbin、/etc、/dev、/proc、/sys、/tmp、/nix、/snap、/home/linuxbrew; - macOS 系统路径:
/System、/Library、/usr、/bin、/sbin、/dev、/etc、/var/run、/tmp、/private/tmp、/private/etc、/private/var/run、/opt/homebrew、/nix; - mise 数据目录:配置中的
MISE_DATA_DIR,而不仅仅是单个工具二进制。
始终可写:/tmp(macOS 上还有/private/tmp)、/dev(/dev/null、/dev/tty等)。
此外:--allow-write的路径隐式可读;--allow-read的路径包含上述系统必需项。启用环境变量过滤时,PATH、HOME、USER、SHELL、TERM、COLORTERM、LANG仍可用;即使加了--deny-net,Unix socket 依然可用。也就是说,配--allow-write=./dist时你只需要考虑项目内的写目标,系统路径不需要逐一放行。
平台差异与必须知道的限制
Linux
文件系统限制用 Landlock,网络限制用 seccomp-bpf(只拦截 inet socket 创建,Unix socket 放行);
按主机过滤不支持:
--allow-net=<host>在 Linux 上会被拒绝,mise 在启动子命令之前就返回错误,不会静默放行全部网络。需要断网就用--deny-net,需要网络就去掉网络限制;允许的路径在沙箱构建时必须已存在。Landlock 把每条规则绑定到一个打开的文件描述符上,尚未创建的路径无法被引用,mise 会警告该规则被丢弃(dropped rule)。任务仍可能通过覆盖它的另一条规则(例如允许了父目录)访问该路径,但被丢弃的规则本身不会带来任何权限。要让任务能创建新目录,就放行一个已存在、且包含它的目录。文档示例(
mise.toml中的任务):[tasks.install] run = "npm install" allow_read = ["package.json", "~/.npm"] # 不能写 ["node_modules"] —— 任务创建它之前它不存在 allow_write = [".", "~/.npm"]Landlock 无法把创建限制到单个文件名,因此放行包含目录就必然授予该目录内其他内容的写权限。此限制只影响 Linux;macOS 的 Seatbelt 规则是路径模式,不要求路径存在。
macOS
- 沙箱基于
sandbox-exec(Seatbelt)与生成的 profile;--allow-net=<host>的例外在构建 profile 时把主机名解析为 IP,策略允许的是这些 IP 而不是某个 HTTP 主机名或 URL 路径,共享同一 IP 的服务也可能可达; sandbox-exec可能以host must be * or localhost in network address拒绝生成的主机例外 profile。此时子命令无法启动,mise 不会回退到无限制网络。若需要访问特定主机而--allow-net表达不出来,文档建议在你的 macOS 版本上验证策略,并在必要时用外部网络控制手段。
Windows
文件系统与网络沙箱均不受支持。mise 会给出警告并按原样运行命令——带 sandboxing 参数成功执行不代表策略被强制执行。
可选:把限制设为默认或任务策略
全局默认
在配置中开启[settings.sandbox],让每次mise exec/mise run默认带 deny 规则(可选项):
[settings.sandbox] deny_all = true可用设置与 deny 参数一一对应:deny_all、deny_read、deny_write、deny_net、deny_env。任务与 CLI 参数仍可按需追加allow_read、allow_write、allow_net、allow_env例外。
任务级声明
在mise.toml的任务定义里直接写限制(任务路径相对任务的工作目录,CLI 参数相对调用 mise 的目录;CLI allow 列表是在任务策略之上追加例外,而非替换):
[tasks.build] run = "npm run build" deny_net = true allow_write = ["./dist"] [tasks.lint] run = "npm run lint" deny_write = truemkdir -p dist mise run build各任务级字段的类型、默认值与说明见 task configuration 文档。
如何判断策略是否生效
文档没有给出固定的“成功日志”,可以核对的是以下几处明确行为:
- Landlock 不可用时命令直接失败:在 Linux 上如果文件系统限制无法施加,命令不会静默降级,会以失败结束——此时应先解决内核/Landlock 问题,而不是移除限制;
- Linux 上
--allow-net在启动前报错:看到执行前的错误信息,说明主机过滤被拒绝,属于预期行为; - 被丢弃的规则会收到警告:在 Linux 上引用了尚不存在的路径时,mise 会警告该规则被 dropped,此时需要按“允许已存在目录”的方式改写路径;
- macOS 主机例外被拒绝时:若出现
host must be * or localhost in network address,说明 profile 被sandbox-exec拒绝,子命令没有运行,也不存在“回退到无网络限制”的情况; - Windows 上:若看到 sandboxing 不受支持的警告,说明文件与网络限制实际未生效,应换到 Linux/macOS 环境验证策略。
对写入阻断的直观核对方式与文档一致:把输出目录之外的写入留给 OS 拒绝,例如mise exec --deny-all --allow-read=. --allow-write=./dist -- node build.js中,build.js若尝试写./dist之外的文件,将由系统拒绝而不是被 mise 拦截记录。
边界说明
- 沙箱不覆盖 mise 自身的配置求值与工具安装;处理不受信任配置请用 safe mode(
MISE_SAFE=1); - 包管理器(如 npm)可能访问额外主机并在输出目录外写缓存或 lockfile,文档建议只放行命令实际需要的资源;
- 允许通配符环境变量(如
NODE_*、npm_*)会同时暴露匹配到的凭据或运行时选项,需要更窄策略时列出精确变量名。
以上限制全部依据 Sandboxing 文档;mise exec的完整参数与--用法见 mise exec 命令文档,任务级 sandboxing 字段参考 task configuration。
【免费下载链接】misedev tools, env vars, task runner项目地址: https://gitcode.com/GitHub_Trending/mi/mise
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考