SILO 20260804 发布说明

节点间存储边界加固、S3/IAM 策略修复、分片上传正确性、流式响应可靠性、通知修复、Go 1.26.5,以及重建并签名的发布流水线。

版本: RELEASE.2026-08-04T00-00-00Z · 提交: d88f46ccee345a9c2fabe2d221d9a9e56bc11aec

SILO 20260804 是 pgsty/minio 社区分支的一次安全、正确性与发布工程更新。该版本完成 CVE-2026-42600 所开启的节点间存储边界治理,阻止客户端输入冒充服务端计算出的 S3/IAM 策略条件值,恢复流式响应 flush 语义,修复多项 multipart 与版本控制边界问题,加固通知配置迁移,将构建基线升级到 Go 1.26.5,并接入由 SILO 维护的 Console、共享包与 mcli 版本。发布流水线经过重建,产出可复现的二进制与 GPG 签名的软件包。

本次发布覆盖 2026-06-18 前基线之后的 50 个提交,共修改 155 个文件,新增 9,241 行、删除 981 行。每一处改动都针对已打标签的提交进行审查,并在 macOS ARM64 与 Linux AMD64 上验证,GitHub CI 在已发布 HEAD 上全部通过。

版本亮点

  • 节点间边界收尾: 在存储边界校验 storage-REST 消息体、storage Grid 帧与 peer-S3 Grid 请求,关闭移除 ReadMultiple 后残留的路径、卷、纠删元数据、panic 与无界分配缺陷。
  • S3/IAM 决策使用真实有效值: 客户端输入不再能遮蔽内部条件值;请求标签与既有对象标签被分离;s3:signatureAge 被限制在经过验证的预签名请求内;s3:versionid 跟随服务端实际操作的版本。
  • Bucket 与 Object 资源分离: 十二项敏感的 bucket 级写操作不再能通过仅对象的 bucket/* 资源模式被授权。提供一个有文档记录的兼容开关用于迁移。
  • Multipart 兼容性与正确性改进: 协议允许时,完整对象校验和补全无需逐分片校验和即可工作;零长度 multipart 对象的校验和被保留;重复的分片编号被拒绝,而不是拼装出重复数据。
  • 流式可靠性恢复: trackingResponseWriter 现在正确实现 Flush 并记录隐式 HTTP 200 响应,修复了 20260618 发布中记录的继承回归所影响的 mcli watch、bucket 通知监听器与 S3 Select keep-alive。
  • 通知配置加固: 解析器与旧迁移读取的 NATS、AMQP 键被注册并正确往返;libpq 连接参数被安全引用;非法键错误不再回显 secret 值。
  • 可复现、已签名的发布流水线: 二进制不再嵌入构建机路径,软件包安装到规范的 systemd 路径,RPM 经过 GPG 签名。容器入口现在在每条权限路径上都能优雅退出。
  • 发布基线刷新: Go 1.26.5、klauspost/compress 1.18.7、Apache Thrift 0.24.0、SILO Console 2.0.0、silo-pkg 3.11.0 与 mcli 20260804。

安全加固

节点间 storage 与 Grid 边界 — SN-2026-002

20260618 移除过时的 ReadMultiple 端点关闭了一条可达路径,但并未关闭底层缺陷类别。storage-REST 请求体与 Grid RPC 帧不经过 HTTP 查询校验中间件,而 peer-S3 RPC 可以完全绕过 storage-REST 包装层。

本次发布把边界收敛到存储层,在使用前校验每一个调用方可控的路径、卷、纠删参数、分片大小、shard 长度与分配长度。修复包括:

  • 在路径与卷两个维度拒绝穿越,包括 Windows 卷根别名;
  • 覆盖那些不经 storage-REST 包装层就触达磁盘的 peer-S3 bucket RPC;
  • 在 shard 运算之前拒绝为零或不可用的 data/parity/block-size 组合;
  • 拒绝负的分片大小与被截断的 shard,而不是把它们报告为健康;
  • 将 storage-REST ReadFile 的分配上限设为 5 GiB;
  • 约束其他源自节点间声明的分配;
  • 在不阻塞调用方的前提下遏制 deadline-bounded 存储任务中的 panic;
  • 在 keep-alive 响应间保留 ReadParts 错误,并避免空分片列表的 trace panic。

这些路由需要集群 root 或节点间凭据,且仅在分布式纠删部署中注册。单节点 S3 行为不变。协议面分析见 节点间路径边界审计

策略条件绑定真实有效值 — SN-2026-003

策略条件映射历史上把服务端计算的值与原始请求条目混在一起。因此一个客户端可控的拼写可以遮蔽或合成一个内部条件值。SILO 20260804 将 silo-pkg 3.11.0 的精确键查找规则与服务端来源归一化配对:

  • 内部条件名不能作为任意客户端值提供;
  • s3:prefixs3:delimiters3:max-keys 取自各自的有效查询输入;
  • 基于 Header 的 x-amz-* 条件不接受无关的查询替代值;
  • 当存储类别或上传标签同时支持两种形式时,显式存在的 Header 胜出,包括空 Header;
  • s3:ExistingObjectTag/* 仅来自已存储的对象元数据;
  • s3:RequestObjectTag/* 绑定到相关操作实际消费的标签输入;
  • s3:signatureAge 只在经过验证的 SigV4 预签名认证计算出它之后才暴露;
  • s3:versionid 在未指定版本时缺席,并在 DeleteObjects 中按条目重新绑定到实际解析出的有效版本。

版本 ID 行为关闭了一个"简单省略空值"式修复本会为 Multi-Delete 制造的 fail-open 陷阱。见 缺席不等于为空

Bucket/Object 资源边界 — SN-2026-004

IAM 匹配器过去会给 bucket 级请求追加一个斜杠,使得像 arn:aws:s3:::bucket/* 这样仅对象的资源能授权部分 bucket 级操作。本次发布在 Allow 语句上,将这十二项敏感写操作从该模式中排除:

PutBucketPolicyDeleteBucketPolicyPutBucketObjectLockConfigurationPutBucketVersioningPutReplicationConfigurationPutBucketLifecycleDeleteBucketForceDeleteBucketPutBucketCorsDeleteBucketCorsPutBucketQOSPutInventoryConfiguration

DenyNotResource 行为不变。读取/列举操作、CreateBucket、bucket 标签、默认加密与通知配置保持兼容。内置策略使用 Resource: "*",不受影响。

可信客户端地址边界

MINIO_API_TRUSTED_PROXIESaws:SourceIp、审计 remotehost、事件通知 Host 以及 mcli admin trace 显示的客户端地址提供了一个可强制执行、按需启用的边界:

  • 设为地址/CIDR 列表,则仅信任来自这些对端的转发头,并从右向左遍历转发链;
  • 设为 none,则忽略所有转发头;
  • 保持未设置,则完全维持历史行为。

旧的 _MINIO_API_XFF_HEADER=off 开关仍然只抑制 X-Forwarded-For,它不防护 X-Real-IP 或 RFC 7239 Forwarded。如果基于 IP 的策略是你安全边界的一部分,请显式配置可信代理,并阻止对 S3 API 端口的直接访问。多节点部署应当允许自己的节点地址。见 客户端源地址信任

S3 与存储正确性

Multipart Upload

  • 当补全请求不提供逐分片校验和、且上传元数据不要求它们时,CompleteMultipartUpload 接受 S3 完整对象校验和模式。
  • 零长度 multipart 对象的校验和被保留,而不是作为空元数据丢弃。
  • 分片编号必须严格递增。像 [1,1] 这样的重复条目现在返回 InvalidPartOrder,而不是消费掉上传并把同一分片拼装两次。带间隙或非 1 起始的合法分片列表仍被接受。见 重复分片编号

对象读取与 Buffer 所有权

  • 纠删读取仅在所有权允许复用时才池化 buffer;
  • 更新下载返回调用方拥有的 buffer,而不是暴露返回后可能被覆盖的数据;
  • 移除 ReadMultiple 后遗留的旧 HTTP 流式辅助函数,在引用与平台 tag 检查后被删除。

HTTP Response Tracking 与 S3 Select

  • trackingResponseWriter.Flush() 委托给底层 flusher 并正确提交响应状态;
  • 第一次隐式写入记录 HTTP 200,保持审计与指标准确;
  • S3 Select 测试不再让客户端解析器与响应体所有权竞争;
  • CSV、JSON、Parquet 选择路径保持覆盖,包括 range/错误与 keep-alive 行为。

因此 SILO 20260618 中指出的继承性静默 flush 回归在本次发布中得到修复。

IAM、版本控制与审计行为

  • DeleteObject 以及 DeleteObjects 中的每个条目,都针对服务端选定的有效版本评估 s3:versionid
  • 请求标签在策略评估期间不再能冒充既有对象标签。
  • 在发出悬垂对象删除记录时恢复 merrs 标签,保持预期的审计分类。
  • Bucket-policy 与 IAM 路径共享加固后的条件来源规则,同时保留各自既定的 S3 路由与错误行为。

通知配置

  • 注册解析器读取的 NATS user_credentialsnkey_seedtls_handshake_first 键;
  • 将旧 NATS 环境变量拼写与存储的配置键分离;
  • 修复 NATS 迁移往返与 AMQP immediate/internal 映射;
  • 增加一项机械审计,把通知代码读写的键与各子系统注册的 schema 做比对;
  • 引用 libpq 连接串参数,使空白、引号与反斜杠保持其预期取值;
  • 阻止非法键诊断回显 secret 值。

通知键空间注册

组件与依赖

  • Go 1.26.5: 包含 crypto/tlsos 的安全修复,以及编译器、运行时、网络与 syscall 的修正。
  • klauspost/compress 1.18.7: 刷新对象与归档路径使用的压缩栈。
  • Apache Thrift 0.24.0: 更新经由 Parquet 支持编译进来的依赖。
  • go-systemd 22.6.0: 有意保留而非升级到 22.7.0,因为后者引入了与受支持交叉构建矩阵不兼容的 NetBSD 时钟依赖。
  • SILO Console 2.0.0: 嵌入式 console 选自 pgsty/silo-console,同时保留兼容的 github.com/minio/console 导入路径。
  • silo-pkg 3.11.0: 提供配套的策略、LDAP、证书、RNG 与时间格式修复,同时保留 github.com/minio/pkg/v3 模块路径。
  • mcli 20260804: 嵌入式客户端来自 pgsty/mc;发布镜像将其暴露为 mcli 并保留 mc 兼容别名。

配套发布说明见 silo-pkg 3.11.0mcli 20260804SILO Console 2.0.0

构建、CI 与软件包

本次发布为可复现性与供应链完整性重建了发布流水线:

  • 每条路径都优雅退出。 入口脚本的自定义 UID/GID 分支现在 exec 进入服务端,使其以 PID 1 运行并直接接收 SIGTERM;此前这些分支把一个中间 shell 留作 PID 1,服务端会在容器停止超时后被强杀。一个 CI 烟测会构建发布运行时镜像,并在默认路径与降权路径上断言优雅退出。
  • 可复现二进制。 发布二进制不再嵌入构建机的 GOPATH/GOROOT,因此 -trimpath 生效,第三方从标签重建可得到一致的字节。已发布的 Linux 二进制不含任何构建机路径。
  • 加固的发布工作流。 发布标签通过环境传入并做白名单校验,而不是拼接进 shell;构建检出的是正在发布的那个标签;一个可能越过流程发布或移动 latest 的、未跟踪的影子 GoReleaser 配置被移除。
  • 诚实的门禁。 CI 对构建、vet、单元测试、lint、生成漂移、race 测试与交叉编译把关;交叉编译矩阵对齐到实际发布目标的精确集合;lint 与依赖安装步骤现在会在真实错误上失败,而不是掩盖它们。
  • 签名的规范软件包。 RPM、DEB、APK 软件包以 PGSTY 身份用 nFPM 产出,systemd unit 安装到 /usr/lib/systemd/system/minio.service 并使用 Type=notify,RPM 由 PGSTY 维护者密钥离线 GPG 签名(指纹 9592A7BC 7A682E73 33376E09 E7935D8D B9BD8B20)。
  • 发布与容器发布仍是分离的门禁。 GoReleaser 产出平台归档、校验和与软件包;多架构镜像从完成的发布按需发布。本地快照不能证明公开发布或镜像已存在。

兼容性与升级说明

  1. 集群滚动升级期间保持所有节点在同一发布版本。 节点间校验在 storage-REST 与 Grid 面上发生了改变;混合二进制未经生产测试。
  2. 审查自定义 IAM 策略。 为这十二项受保护的 bucket 写操作补上裸 bucket ARN。仅将 MINIO_API_LEGACY_BUCKET_RESOURCE_MATCH=on 作为临时迁移控制。
  3. 有意识地配置客户端地址信任。 如果 aws:SourceIp 或审计归属重要,请设置 MINIO_API_TRUSTED_PROXIES 并封闭代理周围的直连网络路径。
  4. 审查旧的数据库通知设置。 在重启前把 Postgres/MySQL 的 host/user/password 字段转换为受支持的连接串格式。
  5. 预期重复的 multipart 补全条目会失败。 多次发送同一分片编号的客户端现在会收到 InvalidPartOrder,而不是一个损坏但成功的对象。
  6. 使用匹配的 mcli 20260804 客户端禁用了自更新,必须通过软件包或 GitHub Releases 升级;mcli update 保留为兼容命令但以非零码退出。
  7. RPM 用户可启用签名校验。 软件包用上述维护者密钥签名;在为 SILO 软件包启用 gpgcheck 之前先导入该密钥。

已执行验证

改动针对已打标签的提交进行审查并重新验证,而非信任既有报告:

  • git diff --check、gofmt、模块校验以及 YAML/shell 语法;
  • go build ./...go vet ./...、项目 lint 与 govulncheck ./...
  • 完整的 go test ./...、完整 race 套件,以及针对存储、策略、通知、HTTP tracking 与 S3 Select 改动的重复 race 测试;
  • 生成器幂等性,加上刻意构造的陈旧源与未跟踪产物反例;
  • 对每个发布目标的交叉编译;
  • Linux AMD64 原生全量测试、定向 race 测试、真实 S3/mcli 冒烟测试(创建/上传/下载/复制、range、版本控制、删除标记、健康检查、优雅退出、重启持久化)与 systemd notify 行为;
  • 发布产物验证:GitHub CI 在已发布 HEAD 上全绿、可复现二进制不含构建机路径、systemd unit 安装到 /usr/lib/systemd/system、RPM 签名以 rpmkeys --checksig 校验通过。

govulncheck 未发现可从 Server 或 mcli 代码到达的漏洞。对无人维护的 golang.org/x/crypto/openpgp 包仍有一条模块级提示(GO-2026-5932);该包未被编译进这些二进制。

验证边界

以下内容未被本次发布证明,也不应从交叉编译或单元测试推断:

  • 原生 Windows 执行与 Windows 文件系统语义;
  • Intel macOS 与物理 Linux ARM64 主机;
  • 生产环境的多节点滚动升级、站点复制或生命周期过期运行;
  • 真实的反向代理链与直连入口隔离;
  • 外部 LDAP、OIDC、KMS、STS、Postgres、MySQL、NATS、AMQP 服务;
  • 在真实 systemd 主机上安装并升级签名软件包。

发布产物

  • GitHub release RELEASE.2026-08-04T00-00-00Z,含 Linux、Darwin、Windows 在 amd64 与 arm64 上带校验和的平台归档;
  • PGSTY 身份下的 RPM、DEB、APK 软件包,其中 RPM 经 GPG 签名;
  • docker.io/pgsty/minio:RELEASE.2026-08-04T00-00-00Z 以及发布选定的 latest 标签,从发布按需产出;
  • 配套的 SILO Console 2.0.0silo-pkg 3.11.0mcli 20260804 引用。

重点提交

  • ca7baa67080e8eaa42b6f70ab08:校验节点间路径、纠删元数据与分配大小
  • a36fd8fff:遏制 deadline-bounded 存储任务中的 panic
  • 2f55347f7:将 S3/IAM 策略条件绑定到真实请求值
  • 744a9dcd7:将 s3:versionid 绑定到有效对象版本
  • 97b7d2804:强制 bucket/object 资源边界
  • fe6dc4780:新增可信代理客户端地址边界
  • 22c1e41fd:拒绝重复的 multipart 分片编号
  • c8590413f3e14733f1:恢复完整对象与零长度 multipart 校验和行为
  • 8069a32ac65795ee1f:恢复响应提交与流式 flush 语义
  • 162ded3430c14d8151:修复通知键注册与 libpq 引用
  • 92471792689d346bf5:恢复安全的 buffer 池化与返回 buffer 所有权
  • 3b8a55dee:exec 进入降权进程使信号抵达服务端
  • 2ca4971d9:停止把构建机路径烧入二进制
  • 4c185d5a6e064b5555:加固发布工作流并移除影子配置
  • aa5139369:将 systemd unit 安装到 /usr/lib
  • 11d79fddcca674a696021110b45d88f46cce:对构建、vet、测试、lint、生成、race 与交叉编译把关,并对发布镜像做烟测
最后修改:2026-08-05: 2026-08-05 release (23a05b5)