这是本节的多页打印视图。 .
发布注记
- 1: Silo Console 2.1.0 发布
- 2: Silo Console 2.0.0 发布
- 3: Silo Pkg 3.11.0 发布
- 4: mcli 20260806 发布
- 5: Silo 20260806 发布
- 6: Silo 20260804 发布
- 7: mcli 20260804 发布
- 8: Silo 20260618 发布
- 9: Silo 20260417 发布
- 10: Silo 20260325 发布
- 11: Silo 20260321 发布
- 12: Silo 20260314 发布
- 13: Silo 20260214 发布
- 14: Silo 20251203 发布
每个 SILO 正式版本均有独立页面,记录发布日期、主要变更、安全修复、依赖更新与相关提交。
1 - Silo Console 2.1.0 发布
发布日期: 2026-08-06 · 版本: v2.1.0 · 仓库: pgsty/silo-console
SILO Console 2.1.0 是独立发布 2.0.0 之后的第一个功能版本,做了三件事:
- 会说两种语言——全部控制台页面、帮助条目与文档链接都能以中文或英文呈现,切换按钮出现在每一页,且不引入任何新的运行时依赖;
- 读对了指标——仪表盘从 MinIO Metrics V2 名称迁移到 V3,并针对 V3 在底层改变的语义逐条做了显式处理;
- 在边界情况下不再说谎——全选框与批量操作作用于同一批对象,占位符能扛住包含
$&的对象名,时间戳带上了时区,空指标显示"无数据"而不是编造出来的0。
这是一个 小版本。环境变量、模块路径、API 契约、二进制名称和数据布局均无变化,升级就是换二进制或换镜像。
同日已发布 2.1.1 补丁
v2.1.1 与本版本同日发布,补全了下文所述的图例加固:图例构造器无法解析的标签占位符会被直接移除,而不是把字面花括号漏进 Traffic 图表的图例;最后一处替换分支也完成了转义加固,标签值中的 $& 或 $1 不会再被当作替换指令;License 页面显示的版本号也从 2.0.0 修正为实际版本。除此之外没有任何变化——直接升级到 2.1.1 即可,本文所有内容照旧适用。
如果你内嵌了这套控制台,请重新生成嵌入资产
2.1.0 修复了 2.0.0 之后 main 分支上的一个打包缺陷:go:embed 负载中仍是 2.0.0 的前端构建产物,因此从中间提交构建出的二进制会提供旧版界面。2.1.0 的正式发布产物基于重新生成的负载构建,不受影响。
双语控制台
这是一套对象存储的管理界面,而它的运维使用者中有相当一部分以中文为第一语言。2.1.0 在不引入 i18n 框架的前提下把界面变成双语——嵌入式交付意味着每一 KB 都要计入二进制体积。这对应 issue #6:该 issue 原本提议使用 i18next,而"零依赖"是本次实现相对它唯一一处有意的偏离。
实现方式
设计约束是:不加新依赖、不加构建步骤、不引入字符串抽取流水线,并且 部分覆盖绝不能让页面出错。
- 英文原文就是字典的 key。
t("Create Bucket")查找对应的中文条目;查不到则原样返回英文。因此覆盖度可以增量生长,写错 key 的后果是退化成英文,而不是暴露console.bucket.create这样的裸标识。 - 三份字典,一次合并。
zh.ts(165 条界面框架)、zhHelp.ts(247 条帮助内容)、zhScreens.ts(1373 条功能页面)合并时以框架优先,合计约 1785 条。 - 语言偏好完全复用暗色模式的模式:
localStorage→systemSlice→setLanguage。不做浏览器语言探测,默认英文,选择完全显式。 - 集中拦截而非逐点改写:页头包装器、确认对话框、帮助条目、路由定义、仪表盘面板渲染器各自在输出的最后一步翻译。这正是 220 个页面文件能够在不触碰业务逻辑的情况下完成本地化的原因。
- 模块拆分是必要的。
i18n/lang.ts只存放纯函数原语(translate、localizeUrl)且不导入 store——systemSlice依赖它,反向导入会形成循环依赖。Hooks(useT、useLanguage、useLocalizedLink)与interpolate()放在i18n/index.tsx。
切换控件是一个描边风格的 文/A 图标,挂载在所有页面的页头,登录页复用同一控件。
覆盖范围
登录与 SSO 流程、导航与命令面板、仪表盘与全部指标面板、存储桶与完整对象浏览器(上传、预览、分享、版本、回溯)、用户/用户组/策略/访问密钥、配置与事件目标、IDP 与 KMS、日志、健康报告、性能测试、性能剖析、对象检查、跟踪、监视,以及许可证页面。
除可见文本之外:
- 文档链接会本地化。
silo.pgsty.com的链接在中文下加/zh前缀;Pigsty 站点做域名对调(pigsty.io↔pigsty.cc)。GitHub、MinIO、AWS、YouTube 链接保持不变。 - 帮助面板的博客源按语言区分,中文下拉取
/zh/blog/index.xml,并为每种语言维护独立缓存。 - 命令面板在两种语言下都能搜到。菜单项显示时翻译,但保留英文原文作为关键词,因此"桶"和 “buckets” 都能命中。
- 图表图例只翻译静态前缀。
translateLegend保留[server:drive]这类实例后缀;数据层保留原始图例,所以那些依赖图例做数值匹配(容量求和)的组件继续正常工作。 - 时间戳做的是统一,而不只是翻译,详见下文。
代价
嵌入负载增加约 61 KB(2.79 MB → 2.85 MB,+2.2%),零新增依赖,字典进入独立的按需加载分块。英文渲染路径字节稳定:使用默认语言时,输出与 2.0.0 完全一致。
仍然是英文的部分
后端错误信息(182 条)由 Go 服务端产生,前端无法翻译。少量硬编码在 vendored mds 组件库内部的字符串——收起态菜单的 “Sign Out” 提示,以及数据表格的 “Columns”、“Loading…” 和 ON/OFF 开关——仍是英文;其中两处(“Sign Out”、“Actions:")通过作用域 CSS 规则做了中文替换,其余需要改动 vendor 才能处理。
Metrics V3 迁移
仪表盘此前查询的是 MinIO Metrics V2 名称,而 SILO 部署抓取的是 V3(/minio/metrics/v3)——也就是说,仪表盘依赖的是监控流水线已经不再采集的端点。2.1.0 将全部 26 个部件 重写到 V3 目录——31 条查询,涉及 29 个不同的指标名——并移除三个从未被任何布局引用的部件(51/61/62)。这对应 issue #7,Info 页面的那一半是 #8。
这里的决定是 V3 only:不做运行时回退、不做探测、不提供版本选择开关。SILO Console 面向的是 SILO 部署,服务端、抓取流水线与控制台是一同交付的。SILO 服务端继续为外部消费者提供 V2 端点,只是控制台不再使用。回退机制在这里反而有害——保留 15 天 V2 序列的指标库会让 or 回退悄悄读到过期数据。
V3 改变的语义
有三条 V3 特性会让"照名字改写"的迁移出错,每一条都需要明确的应对:
- 集群组指标由每个节点重复导出。
/cluster/*指标不带 server 标签,也不做 leader 门控,因此 N 节点的抓取会得到 N 条重复序列。查询统一用max()/min()聚合——绝不能用sum(),那会把集群总量乘以节点数。 - 零值根本不导出。任何取值 ≤ 0 的指标都会被跳过。离线磁盘数、修复中磁盘数、纠删集健康状态不是报
0,而是直接消失——统计卡片会渲染成空白面板。所有受影响的查询都配了伴随守卫,让面板读出真实的0。 - 完全不存在
minio_heal_*命名空间。V2 的修复活动信号本身就是内存态的:重启即清零,任何扫描都会刷新它。它被两张语义可辩护的卡片取代:纠删健康(以写入法定人数为基线)和 用量数据时效(扫描器用量快照的陈旧程度)。
零值语义
这次迁移经过了一轮对抗性审查,产出 8 项发现,全部在发布前修复。它们共享同一个主题——区分 零、无数据 与 尚未扫描:
- 容量 的空闲/已用以恒定存在的总量为基线,因此写满的集群显示
0 空闲,而不是整个消失。 - 在线磁盘 针对全部离线的场景加了守卫——恰恰是最需要看到这个数字的时候,零值跳过会抹掉面板。
- 桶与对象计数 改用用量组自身的新鲜度指标做守卫,因此尚未完成首次扫描的集群显示 无数据,而不是编造一个
0。 - 空的单值结果 渲染为
—,而不是0。 - 空的大小分布 不再伪造七个零高度的柱子。
- 小数速率保持可见(
parseFloat轴域、两位小数的 CPU 格式化器),不再被压成0。 - 不足一秒的用量数据时效 收敛到"1 秒”,而不是渲染成空白。
回归测试套件(api/admin_info_metrics_test.go)现在把每条部件查询钉死在 V3 目录上,校验部件 ID 唯一性,并强制执行逐部件的守卫分类法:健康与流量类需要在线节点数伴随项,用量计数类需要用量组新鲜度伴随项,容量类需要总量基线。完整映射记录在 docs/metrics-v3.md。
顺带修复
- 部件 17 把
sent_bytes查了两次,部件 11 把syscall_read查了两次——两组节点间/系统调用的收发配对都退化成了重复项。 - 无标签矩阵(
max()聚合的结果)序列化时 完全没有metric字段,导致前端的标签提取崩溃,表现为容量环图显示0 B、用量增长图为空。已加守卫。 - 一个从未被使用的逐部件 Prometheus label-values 预取请求,让每次部件请求最多多等一秒。已删除。
- 仪表盘的用量卡片、图表控件以及密集的流量/资源面板按统一语法重建,现在在平板宽度下也能正常重排。
工作中还发现两个 服务端 缺陷,选择上游跟踪而非在此绕过:minio_cluster_usage_buckets_since_last_update_seconds 发出的是纳秒(对象变体是正确的),以及 V3 桶级发送/接收流量被对调。
正确性修复
能扛住真实对象名的占位符
String.prototype.replace 会把 替换值中 的 $&、$'、$`、$1 当作指令解释。而 S3 的 key 合法地允许包含 $。于是一个名为 report$&.csv 的对象不会按原样渲染——它会把匹配到的占位符文本重新注入输出,破坏整条消息。全部 37 处 字典占位符替换现已改为传入函数形式的替换值,函数形式不做任何此类解释。这是原本英文界面里就存在的潜在缺陷,并非 i18n 引入;只是 i18n 审计把它找了出来。
名副其实的全选
vendored 数据表格在缺少 onSelectAll 时会渲染一个无法翻译的纯文本 “Select” 表头——七张可选表格全都如此。更麻烦的是,直觉的修法是错的:直接用可见行替换整个选择集,会 丢掉被当前过滤条件隐藏的行,于是表头复选框与随后的批量操作可能作用于不同的集合。实现只切换当前可见行,并保留被过滤隐藏的选择,因此表头状态不可能再暗示一个与实际操作对象不同的集合。
带时区的时间戳
桶、对象、版本、回溯与访问密钥的时间戳此前混用冗长英文格式,并且有几处使用 不带 AM/PM 的 12 小时制——这根本是歧义的。现在它们在两种语言下统一渲染为 yyyy-MM-dd HH:mm[:ss] (ZZZZ)。
扛得住实时数据的翻译运行时
t() 同样会收到运行时字符串:User-Agent、RSS 标题、对象名。由此做了两项加固:
- 未命中时 无条件原样返回——隐式的
@context后缀剥离被移除,因为它会悄悄改写恰好含有@的实时数据; - 字典查找加上
hasOwnProperty守卫,因此恶意输入即便命中继承自Object.prototype的成员(constructor、toString)也无法把函数泄漏到界面上。
交互与可访问性
- 会话过期后打开深链会在
/login之间 来回弹跳,不断累积重定向链,而不是干脆落到登录表单上(#1)。 - 收起态的侧边栏按钮没有可访问名称,屏幕阅读器只能报为未命名控件(#4)。访问密钥输入框现在显式声明 autocomplete 意图,而不是让密码管理器去猜(#5)。
- 移动端的指标与存储桶面板改为滚动,不再被裁切(#3)。
- 性能测试的控件行改为换行而不是溢出卡片,时长可填秒或分钟,大小的默认单位改为 MiB 以匹配其自身的单位列表。
- 侧边栏桶列表的虚拟行距与 44px 的行高对齐,选中与悬停高亮不再互相重叠。
- 单位标签渲染所选单位的 显示名,而不是原始取值。
没有 SUBNET,没有遥测
上游已移除 Subnet、Registration 与 Call Home,本项目继承了该状态,但仍残留三处痕迹。2.1.0 予以清除:
- 健康诊断 websocket 的
subnetResponse字段从来就不指向任何 subnet——它只是一个"报告已生成"的哨兵值——现改为reportStatus: "ok"; - 两条帮助文案声称健康报告"会自动上传到 SUBNET"、检查输出"传输到 SILO SUBNET"。两者都不属实。它们现在描述真实行为:报告在部署端生成,由浏览器下载;
- 删除从未被引用的
CONSOLE_SUBNET_PROXY常量。
顺带说明,2.1.0 的出网行为没有变化,仍然是:无分析、无遥测、无埋点、无外部脚本与字体。silo-console update 依旧禁用。版本目录仅在显式设置 SILO_RELEASE_SERVICE_HOST(或 RELEASE_SERVICE_HOST)时才会连接——没有默认值。浏览器唯一的自动出网请求是帮助面板的博客源,且只在用户打开 Blog 标签页之后发生。
升级指南
没有任何需要迁移的内容。2.0.0 到 2.1.0 之间,环境变量、模块路径、协议字段、systemd 单元、二进制名称与数据布局均无变化。
有两点值得知道:
- 仪表盘现在要求 Metrics V3。如果你的 Prometheus 只抓取 V2 端点,仪表盘面板会显示无数据。请把抓取目标指向
/minio/metrics/v3;由 Pigsty 管理的部署已经如此。 - 语言默认为英文,按浏览器选择并存入
localStorage。不存在服务端默认值,也不做浏览器语言探测,因此现有部署升级后外观不会发生变化。
验证范围
打标签之前,完整变更集经过审阅,并针对最终代码树执行了以下门禁:go build、go vet、golangci-lint(0 问题)、全部 Go 包的单元测试、gofmt、TypeScript 类型检查、前端生产构建、全量 Prettier 检查、字典重复 key 检查,以及对完整 diff 的调试残留扫描。
29 个过程提交通过纯树操作重组为 20 个逻辑提交,重建后的分支顶端与重写前的代码树验证为 逐字节一致。嵌入负载从干净目录重建两次并确认字节一致——这正是发布流水线零差异门禁所依赖的性质。重写前的历史保留在备份引用中。
Metrics V3 迁移另外接受了一轮由独立模型执行的对抗性审查,8 项发现全部修复(见零值语义);其查询在含真实集群数据的线上指标库上做过验证。
已知限制
- SSO 端到端测试套件依赖外部 OpenLDAP/Dex/MinIO 拓扑,本轮未在该环境中运行;OIDC 代码路径已由单元测试覆盖。
- 后端错误信息与若干 vendored
mds组件字符串仍为英文(见仍然是英文的部分)。 - 中文翻译覆盖控制台自身的界面;帮助条目正文已翻译,但它们所链接的文档页面遵循文档站自身的语言覆盖情况。
- 两个服务端 V3 指标缺陷(桶用量时效的纳秒单位、桶级流量对调)在上游跟踪,控制台侧未做绕过。
- 自动自更新仍然禁用,升级需要显式执行。
已关闭的 Issue
2.1.0 关闭了针对 2.0.0 提出的全部 issue。每个 issue 在 tracker 上都留有一条评论,说明修复方式、涉及的提交,以及补充的测试覆盖。
| Issue | 解决方式 |
|---|---|
#1 — 未认证深链无限递归 /login |
改为绝对且感知 base path 的登录目标;补充深链与子路径部署的测试 |
| #2 — Uptime 陈旧、图例畸形、菜单局促 | Uptime 取自真实服务器状态,图例改用 V3 的 name 标签解析,图表控件 32 px,弹出菜单设最小宽度 |
| #3 — 390 px 视口裁切内容 | 指标标签页改为可横向滚动;桶列表在移动端使用明确的列宽预算 |
| #4 — 收起态侧边栏按钮无名称 | 标签改为视觉隐藏而非从可访问性树中移除;折叠开关具名且可键盘操作 |
| #5 — 访问密钥字段缺少 autocomplete 元数据 | 在独立的自动填充 section 中声明 username / new-password 字段级 token |
| #6 — 中英文本地化 | 手写双语层,零新增依赖,以英文原文为 key 兜底 |
| #7 — 监控查询迁移到 Metrics V3 | 仅 V3;26 个部件、31 条查询、29 个指标名,配套守卫分类与回归测试 |
| #8 — 用可用的 V3 健康信号替换 N/A | Erasure Health 与 Usage Data Age,与高级仪表盘共用同一份部件数据 |
有三项验收标准如实记为未达成,而不是含糊勾掉:web-app 目前没有单元测试运行器,因此 #6 的 i18n 测试套件与 #2 中针对 constructLabelNames 的专项测试都需要先引入测试工具链;另外 #6 要求的"如何新增翻译 key"的贡献者文档尚未编写。
关联提交与链接
v2.1.0 的完整变更由以下 20 个逻辑提交构成。v2.1.0 标签另外还带有三个更晚的文档提交,它们重写了仓库 README,不改变任何已交付的行为。
8764f5d— fix(web): stop recursive login redirects437c56c— fix(ui): make the dashboard and bucket list usable on narrow screens85fc0c6— fix(a11y): name collapsed sidebar controls and credential fieldse3fed07— fix(metrics): rebuild dashboard cards, chart controls, and layoutfa11576— feat(login): polish controls and legal attribution9fc17c1— feat(i18n): add hand-rolled EN/ZH core, dictionaries, and language toggle622c02e— feat(i18n): localize login, navigation, and the help system6a03719— feat(i18n): localize dashboard and metrics screens14b1c2d— feat(i18n): localize bucket and object browser screens0298062— feat(i18n): localize identity, configuration, and event destinations41094f6— feat(i18n): localize observability, admin tools, and shared componentse964992— feat(metrics): migrate the dashboard to MinIO Metrics V30b2251f— fix(i18n): harden the translation runtime for live data and chart legends9b60148— fix(console): unify timestamps on a timezone-carrying standard formatbf110ae— fix(console): give selectable tables a visible-rows select-all5fc8f22— fix(i18n): escape-proof all placeholder substitutionsfef8fab— fix(console): polish speedtest, sidebar, and help chromec4911e8— chore(console): drop SUBNET remnants from health reporting1d631c4— docs: record the SILO Console v2.1.0 changelog912d847— build: regenerate optimized embedded web assets
相关链接:
2 - Silo Console 2.0.0 发布
发布日期: 2026-08-04 · 版本: v2.0.0 · 仓库: pgsty/silo-console
SILO Console 2.0.0 是这套对象存储管理控制台以独立项目身份发布的第一个主版本。它从 georgmangold/console 的 v1.9.1 维护线继续演进,完成了三件事:
- 建立独立身份——产品名称、视觉系统、文档入口、源码归属与发布链路全部迁移到 SILO 项目体系,同时刻意保留 Go 模块路径、环境变量等兼容契约;
- 重塑用户界面——登录页、主题系统、仪表盘与全站细节按统一的设计语言重新打磨,配套全新的品牌图标集;
- 强化工程质量——嵌入式前端资产从约 10MB 压缩到 3.5MB,已知依赖漏洞清零,并修复了包括运行时数据竞争在内的一批上游遗留缺陷。
发布前,本版本经过了两轮独立审查:一轮完整的代码审查与提交历史重组,以及一轮对抗性复核(穷举资产校验、HTTP 语义探测、全站路由回归与发布产物冒烟测试)。
升级前先看兼容边界
2.0.0 的主版本变化发生在 公共身份和交付契约 上,而不是对象数据格式或 S3 协议上。使用旧仓库、旧发布二进制名或旧容器镜像名的安装脚本必须更新;使用 CONSOLE_MINIO_SERVER、CONSOLE_MINIO_REGION、github.com/minio/console 或 MinIO-compatible Admin API 的现有集成则不应做全局替换。
为什么是 2.0.0
这套控制台最初源自 MinIO Console,随后由 Alevsk/console 与 georgmangold/console 两条社区维护线继续发展。SILO Console 在此基础上由 Pigsty 社区接续维护,为 SILO 提供浏览器管理界面。
版本号从 v1.9.1 提升到 v2.0.0,主要是因为以下对外契约同时发生变化:
- 产品名称统一为 SILO Console,主仓库迁移到
pgsty/silo-console; - 正式发布二进制从
console改为silo-console,容器镜像迁移到ghcr.io/pgsty/silo-console; - 发布资产、校验和、软件包元数据、命令行说明与项目链接全部切换到 SILO;
- 界面中的项目身份、帮助入口、版权归属、源代码供应与商标说明重新建立。
2.0.0 采取的是"对外身份清晰、对内兼容克制"的迁移策略:需要运维人员明确感知,但不对底层兼容接口做机械式改名。
名称与交付契约
| 范围 | 旧名称或旧位置 | 2.0.0 契约 |
|---|---|---|
| 产品 | Console / MinIO Console 的遗留表述 | SILO Console |
| 源码仓库 | georgmangold/console |
pgsty/silo-console |
| 正式二进制 | console |
silo-console |
| 容器镜像 | ghcr.io/georgmangold/console |
ghcr.io/pgsty/silo-console |
| 二进制资产 | console-<os>-<arch> |
silo-console-<os>-<arch> |
| 校验和文件 | console_<version>_checksums.txt |
silo-console_<version>_checksums.txt |
| 网站与文档 | 上游或前维护者入口 | silo.pgsty.com 与 silo.pgsty.com/docs/ |
命令行程序的作者、用途、帮助文本和项目描述已切换为 Pigsty 与 SILO Console。DEB/RPM/APK 软件包的厂商、维护者、主页、描述与许可证元数据相应更新,可执行文件安装到 /usr/local/bin/silo-console。
刻意保留的兼容标识
以下名称虽然包含 minio 或沿用旧的 console,但它们是接口、协议或安装兼容层的一部分,不属于遗漏的品牌文本:
| 兼容面 | 2.0.0 中的状态 | 原因 |
|---|---|---|
| Go 模块 | 保持 github.com/minio/console |
改动会破坏全部 Go import 与生成代码 |
| 服务端地址 | 保持 CONSOLE_MINIO_SERVER |
现有部署广泛使用的环境变量 |
| 服务端区域 | 保持 CONSOLE_MINIO_REGION |
现有部署兼容契约 |
| 其他配置 | 既有 CONSOLE_* 变量继续有效 |
避免无收益的配置迁移 |
| S3/Admin API 名称 | 保留 MinIO-compatible 字段与枚举 | 它们描述实际协议和 SDK 接口 |
| 源码开发产物 | make console 仍生成 ./console |
保持开发工作流和脚本兼容 |
| 软件包 systemd 单元 | 保持 minio-console.service |
避免升级时出现两个服务或丢失原服务状态 |
| systemd 用户与配置 | 保持 console-user 与 /etc/default/console |
避免不必要的账户和配置文件迁移 |
因此,升级脚本不能简单执行全仓库或全配置的 minio → silo、console → silo-console 替换。未来若要迁移这些兼容接口,需要提供别名、弃用周期和明确的双读策略;2.0.0 不做这件事。
全新界面
2.0.0 不是换个 Logo 的品牌迁移,而是对整套界面的重新设计。
登录页
登录页完全重写:左侧品牌面板以纯 Canvas 生成缓慢流动的正弦光网动画(零外部依赖,遵循 prefers-reduced-motion,切至后台标签页时暂停),文案以 “Keep the S3 Interface / Own the Object Store” 呈现项目主张,底部保留完整的 MinIO 商标声明;右侧表单功能与既有自动化测试选择器完全不变。SILO 字标所用的 Chakra Petch 字体以约 20KB 的本地子集打包,不产生任何外部网络请求。
统一主题系统
控制台的全部颜色收敛到一个亮暗两套的主题层:中性灰阶承载正文与边框,品牌钢蓝色承载主操作与选中态,侧边栏在明暗模式下统一使用与登录页同源的深色系。表单控件与卡片采用统一的圆角与过渡,输入框获得键盘焦点光环,模态框有入场动画(同样遵循 reduced-motion)。服务端下发自定义样式(customStyles)的优先级保持不变。
控制台细节
- 仪表盘(Metrics):统计卡片按统一语法重构——弱化标签、等宽数字、状态圆点对齐;环形图与信息条接入主题;移除了上游实现中的绝对定位布局。
- 空态统一:Watch、Trace、桶事件/复制/生命周期等所有数据面板的占位文本统一为居中弱化样式,不再是左上角的裸文本。
- 垂直选项卡:桶详情等页面的选项卡从带边框的灰色矩阵改为安静的药丸列表,并消除了栏底的空白残留格。
- 许可证页:新增 VERSION 区,同时显示所连接服务端的版本与 Console 自身版本;无
admin:ServerInfo权限的账号不会发起请求,该行自动隐藏。页面同时集中说明 AGPLv3 授权、AGPL 第 13 节下的源码获取权利、来源谱系与商标边界。 - 一批交互修复:移动端首次加载即收起侧边栏(原先要等窗口 resize 事件);侧边栏底部导航不再在窗口高度变化时延迟跟随;桶列表手风琴的高亮条铺满整行;仪表盘在窄屏下不再产生隐式横向溢出;帮助面板改为真正的按需加载——登录页不再向任何外部站点发起请求。
品牌图标集
favicon、PWA 与 Apple Touch 图标此前仍是上一代手绘徽标的 PNG 导出。2.0.0 将全部尺寸(ico 16+32、favicon 16/32/96、apple 180、manifest 192/512)从官方 silo.svg 矢量徽标重新光栅化,主屏尺寸带防裁切安全边距;Web App Manifest 裁剪为现代图标集,移除 2014 时代的 legacy density 条目。图标总体积从 473KB 降至 160KB,浏览器标签页图标从此与站内品牌完全一致。
更小、更快
嵌入式交付是这套控制台的核心形态——前端资产通过 go:embed 打进二进制。2.0.0 对这条链路做了系统性优化:
- 嵌入负载从约 9.6MB 降至 3.5MB。文本资产(JS/CSS/SVG 等)在构建期以确定性 gzip 预压缩后嵌入;仅被现代浏览器忽略的 legacy WOFF 字体(约 1.25MB)、以及一批完全未被引用的孤儿图片资产被移除。
- 首屏传输从约 5.7MB 降至约 1.7MB。此前静态资产完全未压缩传输;现在预压缩资产直接以
Content-Encoding: gzip发出(零运行时压缩开销),对极少数不接受 gzip 的客户端动态解压回退。 - 正确的 HTTP 语义。Accept-Encoding 按 RFC 9110 完整解析 q 值(
gzip;q=0会得到未压缩内容),响应携带Vary: Accept-Encoding;静态路径与 SPA 入口对非 GET/HEAD 请求返回 405 并带Allow头。 - 可复现构建。压缩使用纯 JS 实现(fflate)以保证跨平台字节级确定性;发布流水线新增强制门禁——在干净环境重建嵌入资产后必须与提交内容零差异。
发布二进制(含全部前端资产、strip 后)约 35–40MB;对下游 SILO 服务端而言,内嵌这套控制台的体积代价从约 10MB 降到约 3.5MB。
安全与依赖
Go 侧:构建基线升级到 Go 1.26.5,golang.org/x 系列全部更新至最新。govulncheck 报告的全部可达漏洞已清零:
| 依赖 | 修复版本 | 公告 |
|---|---|---|
google.golang.org/grpc |
v1.82.1 | GO-2026-6061 |
github.com/prometheus/prometheus |
v0.311.3 | GO-2026-5710 / -5662 / -5381 / -5264(含远程读 DoS) |
github.com/klauspost/compress |
v1.18.7 | GO-2026-5841 |
唯一剩余公告位于 golang.org/x/crypto,官方尚未发布修复且代码路径不可达,作为已知事项记录。
前端侧:生产与开发依赖树的完整审计清零,包括 form-data 的高危 CRLF 注入、DOMPurify 与 qs 的多项公告;React Router 迁移至 7.18.2(保留 v6 兼容的声明式 API,全站路由经过完整回归验证)。唯一被显式豁免的公告仅涉及本项目未使用的 unstable API。
运行时正确性:修复了 HTTP 日志目标在初始化与关闭之间的真实数据竞争,以及测试套件中共享 mock 的竞态;受支持的 Go 包全量通过 -race 检测。作为附带收益,go-m1cpu 升级修复了新版 macOS 上本地 go run 的 cgo 崩溃。
更新检查与默认网络行为
本版本对升级和版本目录功能采取保守默认:
silo-console update的自动自更新被禁用,命令只给出提示,不会下载或替换二进制;- 版本目录新增
SILO_RELEASE_SERVICE_HOST配置,原有RELEASE_SERVICE_HOST作为兼容回退;两者均未设置时不连接任何远端版本服务; - 帮助面板的 Blog 内容仅在用户打开时按需拉取,跳转链接只接受
https://silo.pgsty.com。
自动更新会在发布资产签名与回滚链路稳定后再重新评估。
发布产物与平台矩阵
正式发布包含 16 个资产:
| 类型 | 覆盖范围 |
|---|---|
| 独立二进制 | Linux amd64/arm64/arm、macOS amd64/arm64、Windows amd64 |
| 系统软件包 | DEB / RPM / APK × amd64/arm64/armv6 |
| 校验和 | silo-console_2.0.0_checksums.txt(SHA-256) |
发布流水线在 tag 推送时触发,工作流的第三方 Action 已固定到具体提交,并在构建前强制执行"干净检出 + 资产重建零差异"门禁。
升级指南
独立二进制
从源码构建时,make console 仍生成 ./console;用于正式服务前按发布名称安装。
DEB/RPM/APK 与 systemd
软件包继续安装 /etc/systemd/system/minio-console.service,单元内部启动 /usr/local/bin/silo-console。EnvironmentFile=/etc/default/console、console-user 与既有 CONSOLE_* 变量不变。这个保留让软件包升级继续作用于原有服务,而不是平行创建一个新服务。
配置与集成
- 不要重命名
CONSOLE_MINIO_SERVER或CONSOLE_MINIO_REGION; - 不要修改 Go import 中的
github.com/minio/console; - 自建版本目录优先迁移到
SILO_RELEASE_SERVICE_HOST; - 依赖
console update的脚本改为显式下载、校验并部署发布资产; - 按进程路径识别服务的监控更新为
/usr/local/bin/silo-console。
本版本不改变对象数据布局,也不要求对存储桶和对象执行迁移。
双重审查与验证范围
2.0.0 在发布前经过两轮独立审查。第一轮完成了全量代码审查、缺陷修复与提交历史重组(13 个过程提交整理为 8 个逻辑提交),并执行了 Go 全包 -race、go vet、golangci-lint、govulncheck、前端类型检查、生产构建、Prettier、死代码检查与完整依赖审计。第二轮为对抗性复核,独立重跑核心门禁并补充:
- 对全部 184 个嵌入文件各发起 gzip 客户端、普通客户端与 HEAD 三种请求,响应体与嵌入源做逐一哈希比对;
- RFC 语义探测(含
gzip;q=0, *;q=0.5等组合 q 值)、方法限制、OIDC 回调与 SPA 深链; - React Router 7 全站路由回归:深链、客户端导航、桶详情选项卡切换与浏览器历史后退;
- 移动端首屏侧边栏行为、登录页外部请求监听、明暗主题全站巡回;
- 下载正式发布资产验证校验和逐字节匹配、二进制版本自报一致,并用发布产物直连真实服务端完成冒烟测试;
- macOS 与 Linux 双平台的资产重建零差异验证。
改写前的完整历史保留在仓库的备份引用中,可随时回滚。
已知限制
- 自动自更新暂时禁用,升级需要显式执行;
- SSO 端到端测试套件依赖外部 OpenLDAP/Dex/MinIO 拓扑,本轮未在该环境中运行(OIDC 代码路径已由单元测试与 HTTP 层验证覆盖);
golang.org/x/crypto存在一条官方尚未发布修复、且代码路径不可达的公告;- SILO 尚未维护独立的视频资料库,帮助面板中的视频是明确标注的上游兼容性资料;
- 管理能力依赖 MinIO-compatible Admin API,不能把 SILO Console 当作适用于任意 S3 服务的通用浏览器;
- 保留的 Go 模块、环境变量、协议字段和 systemd 服务名仍会在代码、配置和进程管理界面中出现。
关联提交与链接
v2.0.0 的完整变更由以下 8 个逻辑提交构成:
50797de— feat: establish SILO Console identity and compatibility23ae6e8— feat: redesign and harden the SILO Console web app7a83a77— build: update Go toolchain and dependencies1330d25— fix: eliminate logger shutdown and test mock races06b3a34— docs: publish the SILO Console v2.0.0 guide4b24372— build: regenerate optimized embedded web assetsc38eb64— ci: package and publish SILO Console v2 releasesb952a12— brand: regenerate the icon set from the official silo.svg emblem
相关链接:
3 - Silo Pkg 3.11.0 发布
发布日期: 2026-08-04 · 版本: v3.11.0 · 提交: d8b1fa7 · 仓库: pgsty/silo-pkg
这是本分支的 第一个定版。它恢复了上游 minio/minio#20449 所报告的 IAM 桶/对象资源边界:策略条件键绕过修复、三个 LDAP 连接缺陷、证书监听器泄漏、有种子 RNG 的缺陷,以及模块真实的最低 Go 版本。
升级前需要确认两件事
- 本版本收紧了鉴权。 十二个桶级写操作不再能通过
arn:aws:s3:::bucket/*这样的对象级资源模式被授权。如果你自己编写桶级策略,请阅读 IAM 桶/对象边界——受影响者只需改一行策略,而MINIO_API_LEGACY_BUCKET_RESOURCE_MATCH=on可完整恢复原有行为。 - 条件键修复仍需服务端另一半。 本版本的策略解析改动与服务端"保留内部条件键名"的改动各自覆盖问题的一半。服务端配套改动位于
pgsty/minio提交2f55347f7,但尚未进入公开的origin/master,也没有任何已发布的 Silo 服务端版本包含它。请确认后续服务端发布说明明确包含该改动。
这个仓库是什么
silo-pkg 是 minio/pkg 的维护分支,为社区版 MinIO 分支提供上游(现由闭源产品驱动)不会再接纳的修复。仓库于 2026-08-02 由 pgsty/minio-pkg 改名而来。
模块路径刻意保持不变,仍然是 github.com/minio/pkg/v3,因此所有 import "github.com/minio/pkg/v3/..." 无需改动,只有 replace 指令的右侧需要更新:
/v3 后缀是模块的主版本号,不是目录名,不可省略。这也正是本次发布编号为 v3.11.0 而非 v4.0.0 的原因:Go 要求标签的主版本必须与 go.mod 中声明的主版本后缀一致,因此在一个 .../v3 模块上打 v4.0.0 会被工具链直接拒绝。真要发布 v4,就必须修改模块路径,并改写服务端、mc 与 Console 中约 395 处 import——那等于放弃"保留上游路径"所换来的直接替换能力,而这正是保持上游路径的意义所在。
IAM 桶/对象边界
每一个桶级 S3 操作,鉴权时对象名都是空的。IAM 匹配器把它拼成资源串,而对空对象名的情况补了一个尾斜杠:
"bucket/" 会被通配模式 "bucket/*" 命中,因为 * 匹配空串。于是一条把 s3:* 授在 arn:aws:s3:::bucket/* 上的策略——读起来是 “任意操作,但只作用于这个桶里的对象”——也连带授予了桶级操作。在多租户集群里,只持有这条授权的租户可以调用 PutBucketPolicy 装上 {"Principal":"*"},把桶变成匿名公网可读或可写,或者给自己授予桶级控制权;它也可以直接把桶删掉,而这正是上游 issue 中的复现步骤。
匿名访问所走的桶策略评估路径从来没有这个斜杠,是正确参照。只有 IAM 这条路径错了,而且只错在一个地方。
为何不修正整条边界
对所有桶级请求都不再补斜杠,是显而易见的修法,上游也试过:那次改动当天就因打破依赖旧行为的策略而被回滚。有两个性质让"完整修正"成为一次迁移,而不是一个补丁。
它会撤销真实部署所依赖的授权。 它撤销的不只是危险的桶写入——通过 bucket/* 授予的 ListBucket、GetBucketLocation、ListBucketMultipartUploads 同样会被撤销。证据就是上游自己的测试套件:11 个 STS 集成测试把 s3:ListBucket 授在 bucket/* 上,然后断言列举能成功。连写服务端的项目都这么写,生产策略里只会更多。
它切的是两个方向。 匹配器对 Allow 和 Deny 拼的是同一套资源串,所以删掉斜杠在收紧过度授予的 Allow 的 同时,也放松了过度阻断的 Deny。一个用 Deny s3:* on bucket/* 锁死某个桶的管理员,会悄无声息地失去那层保护。
保护集合是如何确定的
范围由一个问题决定:够到这个动作,能让调用者拿到它的对象级授权本来就给不了的东西吗?
之所以该问这个问题,取决于缺陷的触发条件。资源匹配发生在动作匹配 之后,所以这个 bug 只有在语句本身已经授予了那个桶级动作时才会咬人——现实中这意味着 s3:*。因此受影响的主体本就对这个桶里的每个对象拥有完整的读、写、删权限。有用的问题不是"这个动作抽象地看有多危险",而是"在一个已经握有全部数据的位置上,够到它还能多拿到什么"。
不再接受对象级授权的十二个动作:
| 动作 | 入选理由 |
|---|---|
PutBucketPolicy、DeleteBucketPolicy |
能把访问权发给别的主体(包括匿名),也能给调用者自己补上从未授予的桶级动作。自我提权与公开暴露。 |
PutBucketObjectLockConfiguration、PutBucketVersioning |
击穿的恰恰是专门用来"防住有写权限的人销毁数据"的保护。 |
PutReplicationConfiguration、PutLifecycleConfiguration |
以服务端凭据运行,并在调用者权限被吊销后继续生效。 |
DeleteBucket、ForceDeleteBucket |
不可逆地销毁桶实体及其配置。上游 issue 的原始复现动作。 |
PutBucketCors、DeleteBucketCors、PutBucketQOS、PutInventoryConfiguration |
在今天的服务端没有挂任何行为——要么根本没有 handler,要么 handler 在鉴权之后直接返回 NotImplemented。收走它们不影响任何能用的东西,并且提前覆盖。 |
刻意不予保护,并且有测试对此做出断言——于是把其中任何一个加回去,都是一次带可见代价的明确决定,而不是往列表里添一行:
PutBucketTagging、PutBucketEncryption、PutBucketNotification。 它们都是桶级写入,早期草案确实纳入过保护。三者都不给调用者任何它还没有的访问权——受损的是所有者的合规姿态,不是访问边界;而一个拿到s3:*onbucket/*、并被告知"这个桶归你"的租户,完全合理地会去给它打标签、设默认加密、配事件通知。用很低的安全收益去换实打实的兼容成本,在维护版本里是个错误的交易。CreateBucket。 它作用于一个还不存在的桶,没有东西可篡改、可摧毁;而供应流程常用租户自己的bucket/*凭据去创建租户的桶。- 读/列举族(
ListBucket、GetBucketLocation、各类配置读取)。打破它们正是上游那次完整修复被回滚的原因,它们要等一次带迁移路径的发布。
改动只作用于 Allow 语句。Deny 语句保持历史资源串,因此任何桶级封锁都不会被削弱,NotResource 排除也保持完整覆盖范围。
单调性,以及那个错了两次的论断
上面这一切都建立在一条性质上:这个变更可以收走权限,但绝不能新增权限。 而这条性质被断言过两次,两次都是凭推理而非凭测试,也两次都是错的。把"怎么错的"记录下来,比只记录最终状态更有价值。
第一次尝试让省略的斜杠同样作用在了 NotResource 匹配上——而 NotResource 是 排除。Allow s3:* NotResource bucket/* 这样的语句,历史上不会作用于该桶的桶级请求;把排除拿去和裸桶名匹配,排除就不再命中,于是它所限定的那条 Allow 反而变宽了,而且恰恰是在受保护的那些写入上。
第二次尝试修好了这一处,并在发布时写着结论"可证明地单调"。对该版本做的独立对抗性复核给出了反例。省略斜杠并不只是"少了一次匹配"——它改变了 模式所匹配的那个字符串,而一个模式完全可能匹配 "mybucket",却从来匹配不上 "mybucket/"。定长通配是最干净的例子:
? 恰好匹配一个字符。对九字符的 "mybucket/" 它匹配不上,所以这条语句从来没有授予过那个桶级写入;而对八字符的 "mybucket" 它匹配上了,于是这次加固 授予了 有缺陷的匹配器都拒绝的东西。
修法不是再加一个特例。在受保护路径上,匹配器现在要求 两种形式同时命中——裸桶名,以及历史的 "bucket/"。结果是与历史判定取交集,于是它 在构造上 就是单调的:不存在任何它能新满足的模式,也不再有下一次会推理错的论证。mybucket* 照旧授予(它本来两种形式都匹配),mybucket/* 照旧被收走,mybucke? 被拒绝——和它一直以来的行为一样。
有两点值得带走。鉴权路径上的正确性修复,绝不能让任何东西变成新允许的——而确认它的唯一办法是把两个方向都测一遍,因为在这两次里,推理给人的感觉都是无懈可击的。以及:当一条安全性质是承重的,就 用一个不可能违反它的操作把它构造出来,而不是用一份你认为已经穷尽的分情况讨论。
证据
这条性质是被验证的,不是被论证的。我们生成了一份 27000 条鉴权判定 的语料——15 种资源模式 × 3 个桶 × 5 种对象名 × 20 个动作 × 6 种语句形式——分别在加固前基线与本版本上执行,并逐条比对:
| 迁移方向 | 条数 |
|---|---|
false → true(变宽) |
0 |
true → false(收窄) |
144 |
| 不变 | 26856 |
那 144 条收窄全部落在设计意图之内,没有一条溢出:动作恰好是受保护的十二个;语句形式只有三种 Allow,Deny、NotResource 排除与 deny-NotResource 三种形式 零变化;资源模式只有四种对象级模式;请求只有桶级请求,对象级请求完全未被触碰。12 × 4 × 3 = 144,严丝合缝。
两个层次都有回归测试。本仓库有十二条匹配器测试钉死每个方向,其中包括一条不变量测试,确保受保护动作个个都是纯桶级动作——ResetBucketReplicationState 名字唬人,实为对象动作,不入集合。服务端有三条端到端测试驱动真实 handler,分别位于客户端、内联会话策略与 S3 路由三个层次;三条在修复前的构建上全部失败,在本版本上全部通过。
需要改什么
只有当你的存量策略把十二个动作之一(或 s3:*)授在含 / 的资源模式上、且同一个桶没有裸桶 ARN 时,你才会受影响。修法是在对象模式旁边补上裸桶 ARN:
这种配对写法是惯例形式,也是上游自己的测试所采用的写法,在本版本之前同样有效。内置策略不受影响——readwrite、readonly、writeonly、diagnostics 全部使用 Resource: "*"。
MINIO_API_LEGACY_BUCKET_RESOURCE_MATCH=on 在启动时读取一次,可完整恢复历史匹配行为——过度授予与过度阻断两个方向一并恢复。它目前是单一的全局开关,按动作粒度的作用域已列入待办。
策略条件键解析顺序
getValuesByKey() 此前会先按规范 MIME 拼写(http.CanonicalHeaderKey)查找策略条件键,再尝试原始名称。而它读取的那张表里,混放着服务端为当前请求计算出的值(SourceIp、SecureTransport、CurrentTime、username 等,以条件键拼写存储)和请求自带的 HTTP 头(以规范 MIME 拼写存储)。
先查规范拼写,就让客户端的请求头能够覆盖服务端算出来的值。
对 MinIO 服务端而言这是一次策略绕过。最简单的例子是 s3:prefix:一个 Prefix 请求头可以满足家目录前缀条件,而真正的 ?prefix= 查询参数仍然列举整个桶。同一条路径还能触及 aws:SourceIp、aws:SecureTransport、aws:CurrentTime、aws:EpochTime、aws:username、aws:userid、aws:principaltype、aws:UserAgent、aws:groups、ldap:username、ldap:groups、jwt:groups、s3:versionid、s3:signatureversion、s3:signatureAge、s3:authType 与 s3:LocationConstraint。匿名桶策略直接暴露。SigV4 也拦不住,因为客户端可以添加不在 SignedHeaders 列表里的头。
还有第二重后果:当服务端以一种拼写存值、而策略键解析到另一种拼写时,错误的条目会胜出。s3:object-lock-mode 可能解析到调用者的 X-Amz-Object-Lock-Mode 请求头,而不是服务端实际会施加的保留模式。
修复反转了查找顺序:先精确匹配条件键本身的名字,只对确实指代请求头的条件键(例如 s3:x-amz-* 家族)才回退到规范拼写。这移植了 minio/pkg#226,并补上了上游那次改动没有携带的回归测试。
在库的原始映射层面,如果生产者把同一个逻辑字段同时以精确条件名和规范 MIME 名存入,现在精确名胜出。这是一条库层查找规则,不是"查询参数优先"的 S3 线缆协议规则。Silo 服务端会先按真实来源规范化条件值。对于存储类别与上传标签这两处 Header 与查询形式都保持兼容的字段,Header 只要出现就胜出,包括空值,查询参数仅作回退。
LDAP 连接路径
connect() 中的三个缺陷,其中两个由本分支自己在 b0c08a7 中引入,随 v3.6.2 与 v3.6.3 发布。使用这两个版本的用户应尽快升级。
ServerInsecure 开启时 StartTLS 被跳过。 上游把 StartTLS 调用放在只由 ServerStartTLS 控制的外层块里,因此同时开启两个选项时,会先建立明文连接再升级。b0c08a7 把该调用移进了 else 分支,导致只要 ServerInsecure 为真,StartTLS 就不可达。连接保持明文,随后的 bind 就在这条连接上发送了凭据。MinIO 的 MINIO_IDENTITY_LDAP_SERVER_INSECURE 与 MINIO_IDENTITY_LDAP_SERVER_STARTTLS 是独立开关,Validate() 不拒绝任何组合,所以这个状态是可达的。
本版本恢复了上游语义:两个开关是 叠加关系,而非互斥。ServerInsecure 关闭隐式 ldaps://;ServerStartTLS 仍然执行升级。暴露窗口仅限 v3.6.2 与 v3.6.3。
没有 TLS 配置段的 Config 可能在 ldaps:// 路径上 panic。 l.TLS.Clone() 移出 StartTLS 分支之后,普通 ldaps:// 连接也会调用它。Clone() 对 nil 接收者返回 nil,而下一行却给 ServerName 赋值。MinIO 服务端总会提供 TLS 设置,但这是一个库,mc 同样在消费它。现在代码会回退到空的 tls.Config,与 DialURL 本来会构造的一致。
StartTLS 没有超时。 go-ldap 只在 requestTimeout > 0 时才启动请求计时器,而 StartTLS 本身没有超时。一台完成了 TCP 建连、随后对扩展请求不再响应的服务器,可以让连接 goroutine 永久挂住。现在计时器在 StartTLS 之前就已武装。
StartTLS 失败会泄漏连接。 这一条继承自上游。拨号失败不会返回连接,因此 StartTLS 失败是 connect() 里唯一可能同时返回连接与错误的路径。调用方只在错误为 nil 时接管所有权,于是对一台升级功能损坏的服务器,每次登录尝试都会遗留一个 socket。失败路径现在会关闭连接并返回 nil。
其它修复
- certs:文件监听器从未被停止。
Manager.AddCertificate()注册了两个notify.Watch()却一个都不停:如果第二个失败,第一个就泄漏;而且两个都会在 manager 关闭后一直存活到进程退出。Certificate.Watch()与watchFile()有同样的问题。四条路径现在统一使用watchDirSafe(),它返回一个在出错与ctx.Done()时被调用的停止函数。这移植了 minio/pkg#228 的certs/部分。在 Windows 上该函数用轮询替代文件系统通知,而不是把轮询仅作为失败回退,因此证书重载可能滞后一个symlinkReloadInterval(10 秒)。本分支没有 Windows CI,该平台仅做了交叉编译。 - rng:reader 的子密钥取自一个被清零的局部变量。
init()把 32 字节熵读进r.tmp,却从一个同名的、已清零的局部变量派生出四个子密钥,把四条按块划分的流坍缩成了一条。随后Reset()与ResetSize()会逐字节重放上一条流。MinIO 每次randreader.New()都创建新的 reader 且从不 reset,因此实际服务端影响有限;这个缺陷是 warp 暴露出来的。这移植了 minio/pkg#230。 - xtime:
Duration实现了UnmarshalJSON却没有MarshalJSON。 编码产出的是纳秒整数,而解码无条件剥掉首尾各一个字节并期待带引号的字符串,两个方向都无法往返。现在它使用time.Duration的字符串形式编码。这移植了 minio/pkg#242。
兼容性影响
- 十二个桶级写操作不再能通过对象级资源模式获得授权。 见需要改什么。对象访问、
ListBucket、CreateBucket、桶标签、默认加密与事件通知均不受影响,Deny语句与NotResource排除同样不受影响。 - 最低 Go 版本从
1.26.1降回1.25.0。go指令里的补丁号对每一个消费者都是硬性下限,而不是构建该模块所用工具链的记录。惯例做法是go行写语言版本、单独的toolchain行写开发版本。1.25.0才是依赖图实际要求的版本,也是上游声明的版本。CI 会在GOTOOLCHAIN=local下用 Go 1.25 构建完整测试套件,因此这个下限是被证明的,而不是宣称的。 xtime.Duration的 JSON 线缆格式变更,从纳秒整数改为"2h"、"30m"这样的时长字符串。已持久化的数值形式无法再读回。在 MinIO 与mc中未发现此类用法:批处理作业定义以 YAML 持久化,msgp 路径仍为 int64。- 同时开启
ServerInsecure与ServerStartTLS、且 LDAP 服务器不支持 StartTLS 的部署,在 v3.6.2/v3.6.3 上会以明文成功连接,现在则连接失败。这是正确结果,但它暴露在连接阶段而非配置校验阶段。对这类服务器请关闭ServerStartTLS。 Policy.IsAllowedActions对那十二个受保护动作可能与直接判定不一致。 它遍历SupportedActions,其中包含s3:*这个模式本身,因此返回的集合可能包含s3:*——从而看起来允许某个受保护动作——而直接求值却是拒绝。服务端没有任何地方调用它,Console 调用时传的是空桶名,永远走不到加固分支。此处选择记录而非修改:在维护版本里改变一个公开 API 的输出,风险更大。
与上游 v3.11.0 的差异
版本号跟随上游的线,不声称内容一致。以 policy/ 下的动作字符串常量为口径,实测差异如下:
| 数量 | |
|---|---|
上游 minio/pkg v3.11.0 |
291 |
silo-pkg v3.11.0 |
270 |
有 24 个动作只存在于上游: 6 个 s3:*ObjectAnnotation*、5 个 admin: 动作(DistJobStatus、Get/SetBucketCompression、两个 TablesReplication*),以及 13 个覆盖函数 CRUD 与打标签的 s3tables: 动作。它们属于本分支刻意不采纳的 AIStor 词表,因为社区版服务端并不实现这些功能。
有 3 个动作在两侧名称不同。 上游对它们做了改名与拆分,本分支保留较早的名称:
silo-pkg v3.11.0 |
上游 minio/pkg v3.11.0 |
|---|---|
s3tables:TagResource |
s3tables:TagTable、s3tables:TagWarehouse |
s3tables:UntagResource |
s3tables:UntagTable、s3tables:UntagWarehouse |
s3tables:ListTagsForResource |
s3tables:ListTagsForTable、s3tables:ListTagsForWarehouse |
因此,一条写了这六个动作名之一的策略,在两者之间 只有一个 能通过校验。Silo 服务端、mc 与 Console 都没有引用它们,所以在本生态内没有影响;但从上游 v3.11.0 切换过来的消费者应当知道,动作词表并不可互换。
rng 没有 arm64 汇编。 上游在本分支分叉点之后加入了 rng/xor_arm64.{go,s},本版本在 arm64 上回退到纯 Go 的 xor_noasm.go 路径。结果正确、交叉编译干净,但在该架构上比上游慢。它是未来同步的一个干净候选:纯性能改动,不牵涉词表分歧。
服务端配套行为
- 本版本的条件键改动 必须 与服务端"保留内部条件键名、按语义来源填充取值"的改动配对,见文首提示。
s3:signatureAge只有在 SigV4 预签名请求校验器算出它之后才会暴露。在其它任何请求类型上,客户端提供的x-amz-signature-age头都会被忽略。s3:prefix、s3:delimiter、s3:max-keys只来自查询参数。内容哈希、拷贝源、元数据指令、SSE 与对象锁条件只来自对应的请求头。校验预签名请求时消费的X-Amz-Content-Sha256查询值不会成为策略条件。s3:x-amz-storage-class保留其兼容的查询形式,PutObject与CreateMultipartUpload上的请求标签同样保留。这两个字段都是 Header 出现即胜出,只有 Header 缺失时才使用查询参数。s3:ExistingObjectTag/*只来自从已存储对象加载的标签,因此请求自带的X-Amz-Tagging不能再冒充既有对象状态。PutObject、CreateMultipartUpload与PutObjectTagging把s3:RequestObjectTag/*绑定到这些 handler 实际消费的标签输入。其余动作路径出于兼容保留了历史的X-Amz-Tagging头回退,因此只在 API 确实消费标签的地方,才把请求标签条件当作约束使用。aws:SourceIp由转发头计算得出。它是否可强制执行,取决于服务端的可信代理配置;参见服务端自己关于MINIO_API_TRUSTED_PROXIES的发布说明。
验证
以下全部在打标签的那个提交上执行,工作树干净,标签与 HEAD 一致:
make test——golangci-lint 加go test -race -tags kqueue ./...,全部包通过。go mod tidy -diff干净;gofmt -l为空;go vet ./...干净。linux/amd64、linux/arm64、darwin/arm64、windows/amd64四个组合的交叉编译。govulncheck ./...——零个可达漏洞。仅剩一条模块级提示 GO-2026-5932(x/crypto/openpgp):该包已停止维护、没有修复版本,且本仓库并未 import 它。- 从空模块缓存经公共 proxy 解析,确认发布出去的版本确实可获取。
- 上文所述的 27000 条鉴权判定语料。
依赖与工具链
依赖更新清除了 govulncheck 此前报告的九项 可达 问题:经 sftp 触达的七个 x/crypto/ssh 问题、经 etcd 触达的 gRPC GO-2026-6061,以及经 oidc 触达的 go-jose GO-2026-4945。
有五个依赖——minio-go、minio/mux、etcd client/v3、go-oidc、lestrrat-go/jwx——刻意未升级。MinIO 通过 replace 消费本模块,而最小版本选择会取整个依赖图中的最高版本,因此在这里升级它们会连带把服务端也拽着往前走。这五个都没有必须升级的已报告漏洞。
三个工作流此前都向 setup-go 索要低于 go.mod 要求的 Go 版本,并在第一条 Go 命令上失败,现已对齐。linter 此前还从 master 分支拉取安装脚本并每次重装;URL 与版本现已固定到 v2.11.3,且当已安装版本匹配时会跳过下载。
刻意未采纳的上游改动
- AIStor 策略词表(Memory/cortex、Tables/Iceberg、KMS、压缩与注解)以及带类型的动作常量重构,社区版服务端均不实现。这也是动作词表差异的来源。
securityAuditAdmin:它授予admin:ExportIAM,因而会暴露每一个密钥,与名字给人的印象相反。- rng 的 AVX2/NEON 汇编。其中 arm64 那一半已在上文列为未来同步候选。
net.BandwidthBytesPerSec(上游声明了却从未读取)、replicationAdmin与DistJobStatusAction。- 两项先采纳、复核后又移除的改动:
consolereadonly内置策略与GetAllGlobalCertificates,两者都没有消费者。一旦运维把内置策略名绑定到用户身上,再撤回就格外危险:策略映射按名字持久化,而无法解析的名字会并入一个拒绝一切的空策略;它继承的admin:CreateUserDeny 也无法与iamAdmin组合使用。那个证书辅助函数清点的是社区版服务端从不填充的缓存。 - 上游的 golangci-lint
tool指令,它会给每个下游消费者的模块图增加约 200 个 linter 依赖。
刻意推迟的部分
minio/minio#20449 的一般性问题——bucket/* 仍会触及 ListBucket、GetBucketLocation、各类配置读取、CreateBucket 以及上述三个租户可能合理使用的写入——在这里 没有 被关闭。彻底关掉它意味着撤销真实部署所依赖的授权,因此它属于一次带迁移路径的发布。
那次发布欠运维的东西,比"一份更长的动作清单"要多,因为没有人能穷举所有部署的存量策略——这给"靠猜来划定保护集合"的做法设了一个硬上限。有三件事能抬高它:
- 启动时的策略审计:遍历存量策略,逐条点名哪一条的含义会改变,授予与拒绝两个方向都点。它是只读的,甚至可以 先于 强制生效单独发布,从而把"升级后的意外"变成"升级前的清单"。
- 会自我解释的拒绝:当一个请求因为"只有对象级授权匹配上"而被拒时,就把这句话说出来,并点名那个兼容开关。一次 30 秒能自诊断的破坏,成本比静默破坏低一个数量级。
- 带作用域的开关:
MINIO_API_LEGACY_BUCKET_RESOURCE_MATCH今天是全有全无,只想要回一个动作的运维,被迫连自我提权那条路一起重新打开。
相关提交
- d8b1fa7:fix(policy): settle the bucket-write hardening’s scope and monotonicity
- 1f97549:fix(policy): extend the bucket-write hardening to every bucket-only write
- 3c24ad1:fix(policy): withhold object-only grants from sensitive bucket writes
- da6a22a:docs: say what this fork is and how to depend on it
- 4055b2f:fix(xtime): marshal Duration as a duration string
- 13c26cd:fix(rng): initialize the reader subkeys from the seeded entropy
- 88b37ac:fix(certs): stop file watchers on every exit path
- 74dd36e:fix(ldap): keep StartTLS when ServerInsecure is also set
- 424c3d0:fix(ldap): close the connection when StartTLS fails
- 045d10f:fix(ldap): guard a nil TLS config and arm the StartTLS deadline
- 5c4bf50:fix(policy): prefer the exact key name over the canonical header form
- 802539f:chore(deps): refresh the dependency set and declare the real minimum Go
- e4ec64a:ci: build on the Go version go.mod requires, and prove the declared minimum
- 747d8b8:build: pin the golangci-lint installer and skip a matching install
4 - mcli 20260806 发布
发布日期: 2026-08-06 · 版本: RELEASE.2026-08-06T00-00-00Z
距离 mcli 20260804 仅两天,本次发布完成了客户端向 Silo 身份的整体切换。这是一次刻意保持「纯品牌与封闭」性质的发布:--version 与 --help 现在以 Silo 客户端的身份呈现,所有残余的 MinIO SUBNET 外联路径在构建期被关闭,诊断工具链中内置的厂商加密公钥被移除,贡献政策改为无 CLA + 强制 DCO 签署。本周期 零依赖变更、零协议变更 —— go.mod 与 20260804 逐字节一致 —— 因此回归面被严格限制在文案、命令门禁与 CI 三个层面。
行为变更
所有原先会连接 MinIO SUBNET 的路径均已在构建期关闭,且无法在运行时重新开启:
mcli license register、mcli support upload、mcli support proxy set、mcli support callhome enable,以及mcli license update ALIAS的在线续期形态,均打印稳定的提示信息 —— “MinIO SUBNET services (registration, licensing, uploads) are disabled in this Silo build of mc; diagnostics remain available locally.” —— 并恒定以退出码1结束。脚本中如有这些调用应予移除。基于本地文件的mcli license update ALIAS license.key仍然可用,许可证使用内置公钥离线验签。mcli support diag/perf/profile/inspect恒定以本地(airgap)模式运行:诊断报告、性能剖析与 inspect 归档全部写入本地文件,不向任何地方上传。--airgap参数保留以维持兼容(实际上始终生效),SUBNET 注册不再是任何诊断命令的前置条件。mcli support callhome disable|status、mcli support proxy show|remove、mcli license info与mcli license unregister照常工作 —— 它们只读取或清除本地与服务端配置。- 全新生成的配置不再自动写入指向 MinIO 公共演示集群的
play别名,默认别名为local、s3、gcs。已有配置文件永远不会被修改,旧版配置迁移逻辑仍识别历史条目。 mcli --version增加一行身份说明(“Silo object storage client, based on MinIO technology”)与第二行版权信息。首行的机器可读格式保持不变,解析首行的脚本不受影响。
主要变更
- CLI 全面切换 Silo 身份:客户端自我介绍改为 “Silo client for object storage and filesystems”。约 220 处帮助文本重写:涉及被管服务器的用法说明改用 “Silo/MinIO server” 措辞,示例别名从
myminio/play换成mysilo,LDAP 示例 DN 换成dc=example,dc=com,示例分层名称换成SILOTIER-*。事实性表述保持事实:minio分层 类型、协议头以及第三方互操作提及均未触碰。 - SUBNET 构建期关闭:连接能力在编译期被单一开关移除,所有 SUBNET 请求汇聚的唯一 HTTP 出口以上述稳定错误拒绝。命令入口提前拦截,诊断命令强制本地模式,
mcli license info显示的 AGPL 许可说明不再附带商业订阅推销。专门的回归测试(cmd/subnet-disabled_test.go)钉住了全部行为,上游合并无法悄悄恢复任何外联。 - 治理 —— 无 CLA,强制 DCO:贡献按 inbound=outbound 原则以 AGPL-3.0-or-later 接收;贡献者保留自己的版权,维护者不获取项目许可证之外的任何权利。每个提交必须携带
Signed-off-by尾注,由新增的 CI 工作流强制校验(尾注须与提交作者邮箱匹配,仅豁免 GitHub 官方 bot 地址)。CONTRIBUTING.md、PR 模板与中英文 README 均已写明政策,行为准则的联系方式改为本分支维护者。 - 双版权署名:运行时输出与帮助信息同时致谢两条脉络 ——
Copyright (c) 2015-2025 MinIO, Inc.与Copyright (c) 2025-2026 PGSTY,源码构建动态计算截止年份。NOTICE明确声明分支关系,以及与 MinIO, Inc. 无隶属、无背书关系。 - 发布线更名为
main:工作流分支过滤器、文档与贡献指引全部指向main,旧的master引用已清除。
安全加固
- 移除厂商加密公钥:此前
mcli support inspect在未提供密钥时,会回退到用内置的 MinIO RSA 公钥加密输出 —— 产生只有厂商才能解密的归档。内置公钥现已移除:inspect 改用服务端为每次请求生成并回传给调用方的随机密钥(或运维人员自备的密钥),而任何未配置接收方的加密上传路径都会直接失败,绝不静默借用第三方密钥。运维人员产出的诊断数据,现在始终由其本人掌握解密能力。 - 品牌政策门禁:
buildscripts/check-branding.sh接入make verifiers与 CI。一旦命令树中重新出现 MinIO 运营的端点、商业推销 URL、上游产品身份、或任何内嵌的MII…公钥,构建即失败 —— 同时显式豁免有意保留的兼容标识(环境变量、协议头、模块路径、旧配置迁移默认值与原始版权头)。
工程与交付
- CI 迁移到 Node 24 Actions 运行时:
actions/checkoutv7、actions/setup-gov7、goreleaser-actionv7 及 Docker 系列 Actions —— 全部继续钉在 commit SHA 上,由 dependabot 保持更新。 - 功能测试只针对受控服务器:测试套件默认连接本地服务器(
localhost:9000)而非 MinIO 公共演示集群;CI 从pgsty/silo下载钉死的 SILO 服务端版本RELEASE.2026-08-04T00-00-00Z(经 SHA-256 校验)后再运行套件。 - 零依赖变更:本周期没有任何模块升级;20260804 建立的安全基线(Go 1.26.5、零个可达已知漏洞)原样延续。
- 打标签前经过审计:本次发布以一轮独立的对抗性审查作为门禁 —— 通读 245 个文件的全量 diff、品牌/兼容分类的 grep 全集扫描、沿调用图验证任何命令与参数组合都无法触达
subnet.min.io/play.min.io/dl.min.io,并以冒烟测试确认每条被禁用路径都返回稳定错误与退出码1。
兼容性
脚本与集成所依赖的一切均有意保持不变:mc 命令名与 mcli 包名/二进制名;~/.mc / ~/.mcli 配置目录(由调用名派生);github.com/minio/mc 模块路径及全部 import 路径;MC_* 环境变量;协议头(x-minio-*)与 minio-go SDK 的 User-Agent 前缀;minio 分层类型;.part.minio 断点传输后缀;Prometheus 抓取任务名 minio-job;以及软件包格式、发布资产命名与 YYYYMMDDHHMMSS.0.0 版本方案。客户端与 MinIO 服务器及其他 S3 兼容端点保持完全兼容。
已知问题
20260804 发布说明中标记的 mcli watch 回归已在服务端解决:修复随 SILO 20260804 交付,本客户端的 CI 现在正是针对该版本运行包括 watch 在内的功能测试套件。将 mcli 与 SILO 服务端 20260804 或更新版本搭配即可正常接收桶事件;更早的已发布服务端版本仍受影响。
上游未修复的历史缺陷继续适用,其中最严重的是 minio/mc#5139:mirror --remove --watch 在源端删除对象的 非当前版本 时,可能误删目标端的现存对象。在版本化桶上组合使用 --remove --watch 时请务必谨慎。
关联提交
- 8a883ca:ci: move the branch filters to main and fetch the server from pgsty/silo
- 8c304dd:ci: move the pinned actions onto the Node 24 runtime
- 02b1c11:docs: name the release line main, not master
- 810bbd2:ci: pin the functional-test server to a release whose watch API works
- d145647:fix: disable SUBNET connectivity and licensing upsell paths
- 5061c4f:rebrand: adopt Silo identity in CLI help and examples
- c7f7706:docs: align governance files and package metadata with the fork
- 65c71b2:test: default functional tests to a local server and add brand gate
- c62a64d:fix: credit both MinIO and PGSTY in copyright notices
- d205f88:docs: adopt no-CLA plus DCO contribution policy
- 95326ce:docs: add related-projects table and polish contribution wording
- d2c0db7:fix: remove the vendor encryption key and close the proxy-set path
- 0c6704d:fix: repair a link and help text damaged by the brand sweep
5 - Silo 20260806 发布
版本: RELEASE.2026-08-06T00-00-00Z · 提交: 3be10fcc1a44f6620ded0bd303461f9d688cca23
SILO 20260806 是 首个以 Silo 之名发布的版本。上一个版本 20260804 是以 pgsty/minio 名义交付的最后一版;本版本完成了向 github.com/pgsty/silo 的切换,重命名了每一个交付表面——二进制、软件包、容器镜像、systemd 服务、Helm chart——同时刻意原样保留了 MinIO 部署所依赖的每一个线上协议与配置表面。在改名之外,本版本新增了原生健康检查(silo healthcheck)、单二进制的 Distroless 容器镜像试点、装入每个交付物的完整许可合规材料,以及以兼容性快照与构建溯源为门禁的发布管线。
本版本覆盖 RELEASE.2026-08-04T00-00-00Z 之后的 28 个提交,变更 396 个文件,新增 27,188 行、删除 19,561 行。发布前通过了六阶段验收,包括一次真实的四节点 TLS 集群从 MinIO 到 Silo 的迁移——数据逐字节校验、维护闸门滚动重启、故障注入,以及完整的回滚彩排。
亮点
- 品牌切换完成,兼容性即契约。 仓库、二进制(
/usr/bin/silo)、软件包(silorpm/deb/apk)、镜像(docker.io/pgsty/silo)、服务(silo.service)全部改名;S3 与管理 API、/minio/*路由、MINIO_*环境变量、x-minio-*响应头、磁盘上的.minio.sys格式、Go 模块路径全部保留,并由 CI 兼容性守卫冻结。 - 原生健康检查:
silo healthcheck [live|ready|cluster|cluster-read]探测服务器自己的健康 API——正确的退出码、解码后的 quorum 诊断、TLS 自动探测、--maintenance下线前闸门——容器内无需 shell、curl或mc。 - Distroless 镜像试点:
pgsty/silo:<RELEASE>-distroless基于gcr.io/distroless/static,恰好装载一个程序——silo二进制——内置 exec 形式HEALTHCHECK,/data在镜像层内以可写方式创建。 - 经典镜像行为不变: 同样的入口脚本、同样的捆绑工具,
mc ready local继续可用,也没有给它添加HEALTHCHECK。捆绑客户端升级为mcli20260806。 - 合规补齐: LICENSE 与 NOTICE 装入每个软件包与镜像,CREDITS 按实际链接的模块集合(291 个模块)重新生成并纳入 CI 守卫,项目采用无 CLA、基于 DCO 的贡献政策。
- 组件刷新: 内嵌 SILO Console 2.1.1、
silo-pkg3.11.0、mcli20260806、Go 1.26.5。 - 以溯源为门禁的发布: 容器镜像只从已发布、校验和与 attestation 双重验证过的发布产物构建;镜像 SBOM 与溯源 attestation 现在同样覆盖 Distroless 变体。
改名
改了什么,与刻意没改什么:
| 已重命名(交付表面) | 已保留(兼容表面) |
|---|---|
仓库:github.com/pgsty/silo(main 分支) |
S3 API、管理 API 与请求签名行为 |
二进制:/usr/bin/silo |
/minio/* 路由,含 /minio/health/* 与指标端点 |
软件包:silo-*.rpm、silo_*.deb、silo_*.apk |
MINIO_* 环境变量与 x-minio-* 响应头 |
镜像:docker.io/pgsty/silo(另有 -distroless) |
磁盘格式(.minio.sys)、纠删码、版本控制 |
服务:silo.service(与 minio.service 冲突并取而代之) |
Go 模块与导入路径(github.com/minio/...) |
默认配置目录:~/.silo(存在旧 ~/.minio 时回退兼容) |
捆绑 mcli 的 mc 兼容别名 |
服务器呈现自己的身份——silo --version 输出 AGPL-3.0 许可、MinIO 2015-2025 版权、PGSTY 修改版权与 “based on MinIO technology” 归属——所有继承自上游的 MinIO 运营服务连接(更新源及其验签密钥、SUBNET、遥测)被切断而非重定向。容器入口脚本翻译 legacy minio argv 词元,因此 docker run pgsty/silo minio server /data 继续可用。
CI 中运行快照式 rebrand 守卫:对 334 个路由字面量、437 个环境变量词元、84 个响应头与 9,014 个导出符号的任意双向漂移直接判失败。
原生健康检查
服务器二进制现在可以探测自己的健康端点,使容器健康检查不再需要第二个二进制——这也是 Distroless 镜像的依赖所在:
- 检查词汇与
/minio/health/<path>一一对应;live(默认)回答"这个进程是否在服务",ready在配置了 KMS/etcd 时追加其可达性,cluster一对评估每个纠删集的写/读 quorum。 - 退出码只有
0(健康)与1(其余一切)——绝不使用 Docker 保留的2。单行诊断解码服务端的x-minio-server-status与 quorum 响应头供docker inspect采集;--json输出机器可读判定。 - 探测目标按服务器推导自身监听地址的方式推导:
--address/MINIO_ADDRESS,HTTPS 由 certs 目录中public.crt+private.key的存在自动判定,或用--url/MINIO_HEALTHCHECK_URL整体覆盖。环境变量形式的存在是因为探针进程看不到服务器的命令行——当服务器地址或 TLS 来自 CLI 参数时,一个环境变量即可矫正内置探针。 silo healthcheck --maintenance cluster回答下线前的问题:退出0表示此节点可安全下线而不失去高可用;HTTP 412(退出1)表示不可以。- 跳过证书校验,与 kubelet 对 HTTPS 探针的文档行为一致;传输层忽略
HTTP_PROXY,环回探测永不进代理。
Kubernetes 完全不需要这些——kubelet 的 httpGet 探针从容器外打 /minio/health/live 与 /minio/health/ready——且 cluster 检查不应进入单容器探针:它反映的是全集群 quorum,不是单个进程。完整设计依据(含源码核实的端点语义)记录于健康检查设计笔记。
Distroless 镜像试点
在经典镜像之外,本版本发布 Distroless 变体:pgsty/silo:RELEASE.2026-08-06T00-00-00Z-distroless,另有滚动 distroless 标签。
- 基底为
gcr.io/distroless/static-debian12:CA 证书、tzdata、/tmp、含nonroot(65532)条目的/etc/passwd——没有 shell、没有包管理器、没有 libc。之上恰好一个程序:/usr/bin/silo(外加/licenses/下的许可三件套)。镜像 128 MB,对比经典镜像 199 MB。 - 二进制即
ENTRYPOINT;内置 exec 形式HEALTHCHECK运行silo healthcheck ready(interval 30s、timeout 10s、start-period 2m、retries 3),Compose 用户零配置即获得可用的depends_on: condition: service_healthy。 /data在镜像层内以全员可写方式创建——运行时已没有入口脚本可以修补卷属主,而这正是让所有权限模式(含--user)都能工作的原因。这在 Distroless 变体中修复了 #55 记录的非 root 失败。- 此变体不支持:已弃用的
MINIO_USERNAME/MINIO_GROUPNAME降权路径(改用--user或 KubernetesrunAsUser)、docker exec <c> sh式调试(改用临时容器工具)、镜像内mc(改用已发布的mcli或客户端镜像)。 - TLS:把证书挂到
/tmp/.silo/certs(容器内默认 certs 目录),服务器与内置探针会从同一位置各自推导出 HTTPS;CLI 参数配置的服务器则设置MINIO_HEALTHCHECK_URL。
经典镜像仍是默认且保持不变。试点验证充分后,Distroless 变体将成为推荐镜像;决策记录见上述设计笔记。
容器镜像
经典镜像与 pgsty/minio:RELEASE.2026-08-04T00-00-00Z 做了逐字段对照:入口、暴露端口、卷、工作目录、用户与(不存在的)健康检查配置完全一致。差异恰好三处且均为刻意变更:Cmd 由 ["minio"] 改为 ["silo"];移除上游更新验签密钥变量 MINIO_UPDATE_MINISIGN_PUBKEY(上游渠道更新永久关闭);声明 HOME=/tmp 以与入口脚本的可写 home 保证一致。
捆绑客户端升级为 mcli RELEASE.2026-08-06T00-00-00Z(保留 mc 别名),按架构以 SHA-256 摘要钉版并在构建期对照发布校验和验证。已发布的 mcli 20260806 与本服务器的互操作性——分段上传、版本控制、预签名 URL、metadata/tags、用户与策略管理——已在发布验收中验证。
Helm chart
Chart 以 silo 7.0.1 发布,经迁移守卫验证在模拟升级中与旧 chart 的 7 个渲染资源身份保持稳定。默认镜像标签现在指向本版本——docker.io/pgsty/silo 是全新仓库,继承的旧默认值本不可能拉取成功。Chart 仍未附带 liveness/readiness/startup 探针;按设计笔记的后续阶段规划补齐。
打包与迁移
RPM、DEB、APK 软件包恰好安装六个文件:/usr/bin/silo、silo.service、sysusers 定义(创建 silo 系统用户)、/etc/default/silo(config/noreplace)、LICENSE 与 NOTICE。RPM 以 PGSTY 维护者密钥 GPG 签名(9592A7BC 7A682E73 33376E09 E7935D8D B9BD8B20)。RPM 与 DEB 现在统一携带 PGDG 风格的 1PGSTY release 段——silo-<版本>-1PGSTY.<架构>.rpm 与 silo_<版本>-1PGSTY_<架构>.deb——取代此前 RPM 继承的裸 -1 与 DEB 缺失的 revision;APK 命名保持不变,因为 Alpine pkgrel 只接受 -r<整数>。
silo.service 为接管而设计:Type=notify(就绪由服务器自己发信号)、Conflicts=minio.service + After=minio.service(启动 Silo 会停掉运行中的 MinIO 服务)、以及 两个 环境文件——先读 /etc/default/minio、后以 /etc/default/silo 覆盖——现有 MinIO 配置无需编辑即被继承。对数据属主为 minio 用户的既有部署,用文档规定的 drop-in 保持属主不动:
分布式迁移必须全体节点一起切换。
集群引导会(按校验和)验证每个节点运行相同的二进制。混合集群——部分节点 Silo、部分仍是 MinIO——无法组网:新节点停在 activating,无限期记录 Expected Silo binary checksum ... seen: ... 与 Waiting for at least 1 remote servers with valid configuration。请在 所有 节点上停止 MinIO,然后(近同时地)在所有节点上启动 Silo。全部节点运行 Silo 之后,滚动重启一切正常——每台重启前用 silo healthcheck --maintenance cluster 做闸门。
来自验收实测的迁移排障提示:若 Silo 以软件包默认的 silo 用户启动,而部署的 TLS 证书位于 minio 用户家目录之下,会以 HTTPS specified in endpoints, but no TLS certificate is found 失败并连续重启直至 systemd 启动限制生效——上面的 legacy-user drop-in 即是解法。迁移窗口期间保留 MinIO 软件包与服务(处于 disabled):回滚路径——停 Silo、起 MinIO——已经彩排,且能读取 Silo 窗口期写入的全部数据,因为迁移既不动数据属主也不动数据格式。
组件与依赖
- SILO Console 2.1.1 —— 内嵌控制台,取自
pgsty/silo-console,保留github.com/minio/console导入路径。 silo-pkg3.11.0 —— 保留策略/LDAP/证书修复,含 #15 跟踪的 LDAP-over-TLS 修复。mcli20260806 —— 镜像内捆绑并已单独发布;见其发布说明。- Go 1.26.5 —— 工具链与 20260804 一致。
构建、CI 与发布管线
- 兼容性即 CI 门禁: rebrand 守卫对路由、环境变量词元、响应头、指标、存储/策略标识符与导出符号做快照,任何未经评审的漂移直接失败;配套脚本断言交付表面(二进制路径、unit 内容、镜像布局),并确保运行时代码中不再存在任何上游在线端点。
- 发布镜像门禁: 发布管线的每次运行都构建两个容器镜像并断言(除其他外):Distroless 的
HEALTHCHECK存活于镜像配置(它是 OCI 规范之外的 Docker 扩展)、/data以全员可写交付、不存在 shell 与/usr/bin/minio、Docker 健康状态仅凭内置探针即转 healthy、SIGTERM 在 root 与--user 1001:1001双路径下均优雅停机。 - 溯源链: 镜像从已发布的发布产物构建,先经校验和验证与对确切 tag 的
gh attestation verify;经典与 Distroless 镜像均推送分架构 SBOM 与溯源 attestation;Distroless 健康检查门禁在多架构 manifest 提升之前运行。 - 工作流运行时 全面迁移到 Node 24。
兼容性与升级注意
- 软件包升级是接管而非原地更新。 安装
silo,保持/etc/default/minio原样(会被继承),启用silo.service;启动它会经冲突关系停掉minio.service。数据不动。 - 用上述 legacy-user drop-in 保持数据属主稳定;迁移期间不要 chown 存储、不要移动证书。
- 分布式集群:只能全停切换。 见上方警告——Silo/MinIO 混合节点无法组网。
- 容器用户: 镜像现为
docker.io/pgsty/silo;docker.io/pgsty/minio冻结在 20260804 作为存档。经典镜像行为不变——包括mc ready local健康检查——Distroless 变体严格自愿选用。 - Distroless 的差异是刻意的: 无 shell、无镜像内
mc、无MINIO_USERNAME路径;健康检查原生;CLI 参数配置的服务器需为内置探针设置MINIO_HEALTHCHECK_URL。 - Helm 用户: chart 7.0.1 的默认值现在能拉取本版本;若钉版本请显式覆盖
image.tag。 - 已知且未变: 经典镜像仍不在层内创建
/data,因此完全非 root 的docker run配 Docker 管理卷会一如既往失败(#55,Distroless 变体已修复);20260804 说明中继承的 Postgres/MySQL 遗留通知迁移限制仍然适用(#53)。 - 客户端配套使用
mcli20260806;旧客户端在未变的线上协议下继续可用。
验证
本版本分阶段验证,每一步留有证据记录:
- 健康检查命令的单元与端到端矩阵:目标推导与优先级链(flag/env/派生)、真实 TLS 自动探测、退出码契约、JSON schema、超时有界性、用法错误;
- 四节点集群上的语义验证:停掉 4 节点中的 2 个后,
cluster报告 503 且write-quorum=5,而cluster-read与live保持 200——写/读 quorum 分野现场观测,与纠删码推演一致; - 镜像验收:经典镜像与 20260804 基线逐字段对照;Distroless 镜像断言至文件清单、精确健康检查配置,及 root/非 root/TLS/环境变量覆盖四个运行场景;
- 对新增代码的对抗性模型评审,全部确认发现均已修复并复验;
- 以真实迁移收尾的六阶段发布前验收:Pigsty 部署的四节点 TLS MinIO 20260804 集群(16 盘、EC:4)经软件包接管路径迁移至 Silo——参考数据(分段、多版本、带标签对象)逐字节读回一致、四轮维护闸门滚动重启、
kill -9故障注入下负载均衡持续 IO 24 轮成功 23 轮(唯一失败恰在击杀当秒)、Prometheus 指标连续,以及完整的回滚至 MinIO 再切回——证明迁移可逆。
验证边界
以下内容本版本未予证明,亦不应据此推断:外部 LDAP/OIDC/KMS/etcd 服务(ready 与 live 分叉的唯一情形未对真实 KMS 演练);amd64 软件包做了交叉构建与 payload 检查但未在物理 x86-64 主机上安装;改名后的 Docker 发布工作流(含新增的 SBOM/attestation 通道)在本版本发布时才有首次生产运行;Windows 与 Intel macOS 未测试。
交付物
pgsty/silo的 GitHub ReleaseRELEASE.2026-08-06T00-00-00Z:带校验和的平台归档、溯源 attestation、RPM/DEB/APK 软件包(RPM 带 GPG 签名);docker.io/pgsty/silo:RELEASE.2026-08-06T00-00-00Z与latest;docker.io/pgsty/silo:RELEASE.2026-08-06T00-00-00Z-distroless与distroless——从完成的 Release 按需发布;- 配套发布:
mcli20260806、silo-pkg3.11.0、内嵌 SILO Console 2.1.1; - 设计记录:原生健康检查与 Distroless 镜像。
选定变更
15def34dc、77bdc4c0c:清除上游交付残留;呈现 Silo 身份并关闭继承的上游服务15ab10833:交付物改名为 silo 并补全软件包载荷30749911b:镜像装载 silo 二进制并翻译 legacy argv 命令e071bb77e:以保持身份的 silo chart 替换 minio chartbd8df5166:以兼容性、打包与溯源证据为 rebrand 设门禁6613c2a3c:钉住外部测试固件并针对 silo 二进制运行套件fd2ca1c6d、c46b16ec6、c47733abc、f1c77d5a2:切换到 pgsty/silo 与 main;记录归档分支6740e6978:工作流迁移到 Node 24 运行时b57275be3:采用无 CLA + DCO 政策并修正版权条款62717d7bf、a6d6d9b02:内嵌 Console 升级到 2.1.0、再到 2.1.16bd9cf77e:按实际链接模块集合重新生成 CREDITS 并纳入 CI 守卫219670d31:LICENSE 与 NOTICE 装入每个软件包与镜像2ff594f4b:新增原生silo healthcheck子命令4c34d2309:新增 Distroless 镜像变体试点b6d47b739、9462cce16:按对抗性评审加固;lint 清理16b78eb4e:捆绑 mcli 20260806 并将 Helm 默认值指向本版本062a91bee:将 CREDITS 模块闭包钉定到实际发布的 linux 目标467931455:统一 rpm 与 deb 的 release 段为1PGSTYb14ea22aa:镜像发布通道精确匹配校验和清单条目3be10fcc1:新增手动 finalize 通道,为已签名的 Draft 软件包刷新 SBOM 与校验和
致谢
已有四位贡献者的代码合入本分支,Git 历史中保留着他们的署名:@ZouhairCharef 修复了 go-jose 中的 CVE-2026-34986(#18),@mfredenhagen 修复了 OpenTelemetry 中的 CVE-2026-39883(#19),@pinginfo 为 trackingResponseWriter 实现了 Flush,修好了桶通知的流式输出(#34),@waterkip 将文档链接指向了 Silo 门户(#41)。
以新名字发布的第一个版本,也正是感谢所有为这个分支提交过 issue 的人的时刻——缺陷报告、兼容性发现与提案,无论已解决还是仍在处理:
@mosesdd(#1)、@Xavier-777(#2、#17)、@jiadzh(#3)、@TLINDEN(#4)、@AntonOfTheWoods(#5)、@zylpsrs(#6)、@nsanitate(#7)、@makinikm(#9)、@magicxor(#10)、@spaceg00se-r(#11、#14)、@heroes1412(#13)、@vampywiz17(#15)、@davinkevin(#20)、@chalukyaj(#30)、@cbornet(#31、#32)、@jvasile(#33)、@Kesavaambati(#35)、@redfoxfox(#38)、@kuldeep-link11(#39、#40)、@meesudzu(#42)、@pmezhuev(#43)、@kh0mka(#51)。
本版本的多项核心内容可以直接追溯到这些报告:内置客户端的保证来自 #4 与 #9,LDAP-over-TLS 修复来自 #15,软件包载荷补全来自 #33,RPM GPG 签名来自 #43,迁移指南来自 #42,distroless 的 /data 修复来自 #55。
仍在处理中的 PR 同样值得一提。@davinkevin 的 distroless 镜像 PR(#21)比本版本的试点早了数月——最终交付的变体以内置原生健康检查取代了该 PR,但方向是在那里首先提出的。@magicxor(#12)与 @ycjlin(#37)的一致性修复 PR 将在本版本发布后立即进入评审。
所有为本分支做出贡献的人都记录在 CONTRIBUTORS.md 中。GitHub 不为 fork 仓库生成贡献者图表,该文件即本项目的署名记录。
6 - Silo 20260804 发布
版本: 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/compress1.18.7、Apache Thrift 0.24.0、SILO Console 2.0.0、silo-pkg3.11.0 与mcli20260804。
安全加固
节点间 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:prefix、s3:delimiter、s3: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 语句上,将这十二项敏感写操作从该模式中排除:
PutBucketPolicy、DeleteBucketPolicy、PutBucketObjectLockConfiguration、PutBucketVersioning、PutReplicationConfiguration、PutBucketLifecycle、DeleteBucket、ForceDeleteBucket、PutBucketCors、DeleteBucketCors、PutBucketQOS 与 PutInventoryConfiguration。
Deny 与 NotResource 行为不变。读取/列举操作、CreateBucket、bucket 标签、默认加密与通知配置保持兼容。内置策略使用 Resource: "*",不受影响。
自定义 bucket 授权需要迁移策略
如果某个自定义策略仅用 arn:aws:s3:::bucket/*(常常通过 s3:*)授予这十二项操作之一,请补上裸 bucket ARN:
MINIO_API_LEGACY_BUCKET_RESOURCE_MATCH=on 在策略迁移期间恢复历史匹配器。它同时也恢复了历史上的过度授权,因此只应作为临时回滚控制使用。
可信客户端地址边界
MINIO_API_TRUSTED_PROXIES 为 aws: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_credentials、nkey_seed、tls_handshake_first键; - 将旧 NATS 环境变量拼写与存储的配置键分离;
- 修复 NATS 迁移往返与 AMQP
immediate/internal映射; - 增加一项机械审计,把通知代码读写的键与各子系统注册的 schema 做比对;
- 引用 libpq 连接串参数,使空白、引号与反斜杠保持其预期取值;
- 阻止非法键诊断回显 secret 值。
见 通知键空间注册。
已知的旧迁移限制
继承的 Postgres 与 MySQL 旧迁移函数仍然写入未注册的 host、port、username、password、database 字段。因此迁移后的配置可能在下次加载时校验失败,而通知目标加载是跨子系统 fail-fast 的。此问题早于 20260804,但从连接串之前的数据库通知配置升级时,必须在重启前审查并转换。存储的 password 字段可能包含明文数据库密码。
组件与依赖
- Go 1.26.5: 包含
crypto/tls与os的安全修复,以及编译器、运行时、网络与 syscall 的修正。 klauspost/compress1.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-pkg3.11.0: 提供配套的策略、LDAP、证书、RNG 与时间格式修复,同时保留github.com/minio/pkg/v3模块路径。mcli20260804: 嵌入式客户端来自pgsty/mc;发布镜像将其暴露为mcli并保留mc兼容别名。
配套发布说明见 silo-pkg 3.11.0、mcli 20260804 与 SILO 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 产出平台归档、校验和与软件包;多架构镜像从完成的发布按需发布。本地快照不能证明公开发布或镜像已存在。
兼容性与升级说明
- 集群滚动升级期间保持所有节点在同一发布版本。 节点间校验在 storage-REST 与 Grid 面上发生了改变;混合二进制未经生产测试。
- 审查自定义 IAM 策略。 为这十二项受保护的 bucket 写操作补上裸 bucket ARN。仅将
MINIO_API_LEGACY_BUCKET_RESOURCE_MATCH=on作为临时迁移控制。 - 有意识地配置客户端地址信任。 如果
aws:SourceIp或审计归属重要,请设置MINIO_API_TRUSTED_PROXIES并封闭代理周围的直连网络路径。 - 审查旧的数据库通知设置。 在重启前把 Postgres/MySQL 的 host/user/password 字段转换为受支持的连接串格式。
- 预期重复的 multipart 补全条目会失败。 多次发送同一分片编号的客户端现在会收到
InvalidPartOrder,而不是一个损坏但成功的对象。 - 使用匹配的
mcli。 20260804 客户端禁用了自更新,必须通过软件包或 GitHub Releases 升级;mcli update保留为兼容命令但以非零码退出。 - 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.0、
silo-pkg3.11.0 与mcli20260804 引用。
重点提交
ca7baa670、80e8eaa42、b6f70ab08:校验节点间路径、纠删元数据与分配大小a36fd8fff:遏制 deadline-bounded 存储任务中的 panic2f55347f7:将 S3/IAM 策略条件绑定到真实请求值744a9dcd7:将s3:versionid绑定到有效对象版本97b7d2804:强制 bucket/object 资源边界fe6dc4780:新增可信代理客户端地址边界22c1e41fd:拒绝重复的 multipart 分片编号c8590413f、3e14733f1:恢复完整对象与零长度 multipart 校验和行为8069a32ac、65795ee1f:恢复响应提交与流式 flush 语义162ded343、0c14d8151:修复通知键注册与 libpq 引用924717926、89d346bf5:恢复安全的 buffer 池化与返回 buffer 所有权3b8a55dee:exec 进入降权进程使信号抵达服务端2ca4971d9:停止把构建机路径烧入二进制4c185d5a6、e064b5555:加固发布工作流并移除影子配置aa5139369:将 systemd unit 安装到/usr/lib11d79fddc、ca674a696、021110b45、d88f46cce:对构建、vet、测试、lint、生成、race 与交叉编译把关,并对发布镜像做烟测
7 - mcli 20260804 发布
发布日期: 2026-08-04 · 版本: RELEASE.2026-08-04T00-00-00Z
这是 pgsty/mc 社区分支自 20260417 以来的首次发布。本次更新修复了一处调试日志泄密问题,彻底切断了客户端与上游发布渠道之间的所有连接,将容器与软件包完全改由本分支自建,并把打包体系从 MinIO 的 pkger 迁移到标准 nFPM,同时首次为 RPM 包提供 GPG 签名。
上游 minio/mc 仓库已于 2026 年 7 月归档。其最后一个提交 77f82e18 正是本分支的基线,而上游从未发布过包含该提交的版本 —— 因此本次构建比历史上任何官方 mc 二进制都要新。
行为变更
mcli update 自更新功能在本分支中 已被禁用。命令本身保留(接受原有参数以维持脚本兼容),但不再联网检查、也不会替换自身二进制,执行时会打印明确的提示信息,并恒定以退出码 1 结束。上游 mc update 在已是最新版时返回 0,脚本中如有依赖其退出码的调用应予移除。请通过 Pigsty 软件仓库或 GitHub Releases 升级。
同时,每次执行命令时向上游发布源发起的 自动版本检查已完全移除,MC_UPDATE / MINIO_UPDATE 环境变量不再被读取。
主要变更
- 禁用自更新,切断上游发布渠道:移除
minio/selfupdate与aead.dev/minisign依赖及全部二进制替换逻辑,删除更新通知器与 FIPS/非 FIPS 更新分支。update命令保留为兼容壳,运行时辅助函数(Docker / DCOS / Kubernetes / 源码构建检测)迁移至独立的cmd/runtime-info.go。此前该客户端会在每次执行时静默访问上游发布源并提示升级,现已不再有任何出站发布探测。 - 容器与制品全部本地化:默认镜像改为从检出的分支源码构建,hotfix 二进制从本地构建上下文拷贝,不再下载任何上游预编译产物。移除上游发布用的
Dockerfile.release、Dockerfile.release.old_cpu与docker-buildx.sh,并禁用已失效的 MinIO hotfix 上传目标。 - 打包体系迁移至 nFPM:从 MinIO 的
pkger迁移到标准 nFPM。产物结构与安装路径保持完全一致(/usr/local/bin/mcli、包名mcli、版本方案YYYYMMDDHHMMSS.0.0),但供应商信息改为 PGSTY,许可证改用 SPDX 标识AGPL-3.0-or-later,DebianSection由空值改为utils。 - RPM 包首次提供 GPG 签名:RPM 由维护者主密钥在本地离线签名(密钥指纹
9592A7BC7A682E7333376E09E7935D8DB9BD8B20),签名前校验全部包元数据,签名后复验并重新生成校验和。DEB 与 APK 不做包级签名,其信任锚位于软件仓库层。 - 构建溯源加固:此前所有已发布二进制都被 Go 工具链标记为「来自被修改的工作树」(
vcs.modified=true),导致产物无法与其 Git 标签对应。本次修复该问题,并在发布与测试流水线中加入强制校验,确保每个二进制都能追溯到确切的提交。
安全修复
- SUBNET 调试日志凭据脱敏:启用
--debug时,SUBNET 相关的 HTTP 请求会打印完整报文。此前api-key/api_key查询参数、认证头以及响应体均以明文进入日志,而 SUBNET 的认证与注册端点会在响应中返回 API Key、License 与 Token。本次修复对两种参数拼写、重复参数值统一脱敏,屏蔽敏感响应头,并将 SUBNET 响应体整体排除在调试转储之外。该泄漏继承自上游,存在于包括上游mc在内的所有历史版本中:如果你曾对外分享过 SUBNET 相关命令(mcli license .../mcli support ...)的--debug输出,请将其中的 API Key 与 License 视为已泄露并及时轮换。 - 调试脱敏与调用方状态隔离:调试追踪改为转储请求与响应的 副本,确保脱敏动作不会污染调用方持有的对象;覆盖零长度、定长与未知长度三种响应体形态,且不影响调用方正常读取响应内容。
依赖更新
本周期的依赖工作属于安全维护而非例行升级:除 term / mod / sync / tools 四项例行刷新外,以下每一项升级都至少关闭一个 Go 漏洞数据库中已发布的安全公告;govulncheck 对本次发布的代码报告 零个可达的已知漏洞。minio/mc、minio-go、madmin-go、minio/pkg 四个包本身从未有过任何安全公告。
- Go 构建基线由
1.26.2升级至1.26.5(截至发布时 1.26 线最新版),纳入 1.26.3–1.26.5 各批安全修复,包括 GO-2026-4970(os包符号链接根逃逸)与 GO-2026-5856(crypto/tlsECH 隐私泄漏)—— 对一个通过 TLS 下载对象并写入本地文件的 S3 客户端而言最直接相关的两项。 github.com/klauspost/compress由v1.18.5升级至v1.18.7(关闭 GO-2026-5841)。github.com/prometheus/prometheus由v0.310.0升级至v0.311.3(关闭 GO-2026-5264、GO-2026-5381、GO-2026-5710)。google.golang.org/grpc由v1.79.3升级至v1.82.1(关闭 GO-2026-6061),同步刷新genproto系列。golang.org/x/*系列整体刷新:cryptov0.49.0→v0.53.0(GO-2026-5005…5033 共 14 项公告)、netv0.52.0→v0.56.0(GO-2026-5025…5030 及 GO-2026-5942)、sysv0.42.0→v0.46.0(GO-2026-5024)、textv0.35.0→v0.39.0(GO-2026-5970),term、mod、sync、tools同步升级。- 移除
aead.dev/minisign与github.com/minio/selfupdate,并同步更新第三方致谢清单。
工程与交付
- 集成测试依赖钉死:CI 不再从上游可变地址下载 MinIO 服务端,改用带 SHA-256 校验的
pgsty/minio版本化发布归档,Go 版本钉在1.26.5。 - 发布流水线校验:新增打包验证工作流,逐字节比对三种包格式内的二进制与构建产物是否一致,并校验包名、校验和、架构字段与全部元数据。RPM 元数据的期望值以签名脚本为唯一事实源,避免配置漂移导致发布中途签名失败。
- CI 供应链加固:全部 GitHub Actions 钉到 commit SHA 并接入 dependabot,工作流权限收敛为只读,移除指向上游组织项目板的失效工作流。
- 文档更新:README 中英文版本明确本分支的分发渠道与自更新策略,移除会导致误装上游
mc的安装指引。
已知问题
mcli watch(桶事件监听)在对接 任何已发布的 pgsty/minio 服务端版本时都无法收到事件。根因是服务端侧一处继承自上游的静默流式 flush 回归,与客户端无关,上一个 mcli 版本受影响的程度完全相同;修复已于 2026-07-29 合入服务端 master,但尚未随公开服务端版本交付。详见 SILO 20260618 发布说明 与 PR #34。
另外,本分支继承了上游未修复的历史缺陷;上游仓库已归档,这些问题今后只可能在本分支修复。其中最严重的是 minio/mc#5139:mirror --remove --watch 在源端删除对象的 非当前版本 时,可能误删目标端的现存对象。在版本化桶上组合使用 --remove --watch 时请务必谨慎。
关联提交
- 9603ee3:fix: redact SUBNET secrets in HTTP debug logs
- f6ae2b0:fix: disable self-update in Pigsty builds
- c05a6e4:build: update Go deps and toolchain to 1.26.5
- 1f105aa:build: use local fork artifacts for containers
- 1182da5:ci: pin fork integration test dependencies
- 9ee207f:docs: clarify Pigsty fork distribution channels
- 0686cd8:fix: isolate SUBNET debug redaction
- ad10a2a:build: complete local Docker context isolation
- 5f54221:docs: update mc README and cn version
- 02c0305:build: migrate release packaging to nFPM
- 4c4dcc4:build: harden release provenance and package metadata
8 - Silo 20260618 发布
发布日期: 2026-06-18 · 版本: RELEASE.2026-06-18T00-00-00Z
这是 pgsty/minio 社区分支的一次例行安全与依赖维护更新。该版本加固 LDAP STS 限流,补齐 S3 Select 超大记录限制,移除废弃的 ReadMultiple 节点间 storage-REST API,将 Go 构建基线升级到 1.26.4,并刷新 Go 模块依赖以吸收第三方安全修复。
说明
已知问题:本版本与自 RELEASE.2025-12-03T12-00-00Z 以来的所有早期社区版本一样,带有一个继承自上游的静默流式 flush 回归,会导致 mc watch / 桶事件通知监听以及 S3 Select keepalive 失效。该问题没有 workaround。修复已于 2026-07-29 合入 master,但尚未随公开服务端版本交付;实现见 PR #34。
主要变更
- 移除废弃的
ReadMultiplestorage-REST API:旧的节点间/rmpl端点不再保留兼容路径,而是连同 route、handler、client wrapper、storage interface、xlStorage 方法、生成数据类型和相关 metric 一并移除。上游 multipart 处理迁移到ReadParts之后不应再有生产调用者,但滚动升级时仍应让集群运行一致版本。 - 补齐 S3 Select 超大记录限制:JSON Lines 输入现在走有界 reader 路径,因此在支持 SIMD 的 CPU 上也会一致拒绝超大记录,不再绕过限制。S3 Select stream error 现在会保留预期错误码,并将 JSON parser 错误包装为
JSONParsingError。 - 加固 LDAP STS 限流源地址分桶:限流现在仅按源 IP 分桶,避免按用户名共享的 bucket 被单一客户端耗尽并锁定合法用户。受信代理处理现在从右到左解析
X-Forwarded-For,拒绝全网段 trusted-proxy CIDR,忽略 RFC 7239Forwarded,并明确记录X-Real-IP的部署约定。 - 刷新 Go 运行时与模块基线:release、hotfix、goreleaser 与 old-CPU Docker 构建现在都使用
golang:1.26.4-alpine;go.mod更新到 Go1.26.4;依赖刷新覆盖 NATS、Prometheus、Azure SDK、Apache Thrift、gRPC、OpenTelemetry、Google API/auth、Gox/*以及相关间接依赖。
直接安全修复
- CVE-2026-42600:移除废弃的
ReadMultiplestorage-REST API,关闭/rmpl暴露的旧节点间文件读取路径。 - CVE-2026-39414:补齐 JSON Lines 输入的 S3 Select 超大记录限制,并保留正确的 S3 Select 错误语义。
- CVE-2026-33419:进一步强化 LDAP STS 限流记账与 trusted-proxy 源 IP 处理。
依赖安全更新
- 将
github.com/Azure/go-ntlmssp从v0.1.0升级到v0.1.1,修复 CVE-2026-32952,避免畸形 NTLM challenge 触发 Go 进程 panic。 - 将
github.com/apache/thrift从v0.22.0升级到v0.23.0,修复 GoTFramedTransport实现中的 CVE-2026-41602。 - 将
github.com/nats-io/nats-server/v2从v2.11.1升级到v2.11.15,吸收 NATS 2.11.x 安全补丁线。重点覆盖 pre-auth WebSocket 与 leafnode 拒绝服务、MQTT 授权、JetStream 管理 API 授权、凭据暴露和请求身份伪造等问题,包括 CVE-2026-27889、CVE-2026-29785、CVE-2026-33217、CVE-2026-33218、CVE-2026-33222 与 CVE-2026-33247。 - 将
github.com/prometheus/prometheus从v0.310.0升级到v0.311.3,吸收 Prometheus 关于 remote-read 拒绝服务、Web UI 存储型 XSS、remote-write 配置 secret 暴露等安全修复,包括 CVE-2026-42154、CVE-2026-44903、CVE-2026-42151 与 CVE-2026-40179。 - 将发布构建基线升级到 Go
1.26.4,并刷新golang.org/x/crypto、golang.org/x/net、golang.org/x/sys、golang.org/x/text、google.golang.org/grpc与 OpenTelemetry 等模块族。即便此前锁定版本已经越过特定公开 advisory 的修复范围,这些更新仍让社区分支继续贴近上游已修复依赖基线。
关联提交
9 - Silo 20260417 发布
发布日期: 2026-04-17 · 版本: RELEASE.2026-04-17T00-00-00Z
本次版本聚焦安全加固与兼容性收敛,集中修复了 OIDC、LDAP STS、S3 Select、对象复制元数据、unsigned-trailer、Snowball 上传链路,以及依赖与 Go 工具链相关的多项安全问题,并同步完成 LDAP TLS 回归修复与社区分叉文档整理。
主要变更
- 身份认证链路收紧:OIDC / WebIdentity 现在只接受来自 IdP
JWKS的非对称签名ID Token,HS256等对称签名 token 不再被接受;LDAP STS 统一隐藏“未知用户”和“密码错误”的区别,降低用户名枚举风险。 - LDAP STS 限流行为更新:限流现在同时按源 IP 与归一化用户名生效,成功请求不再错误消耗额度;默认仅使用 socket peer address 作为源地址,不再信任
X-Forwarded-For、X-Real-IP、Forwarded,如需按真实客户端 IP 限流,需显式配置MINIO_IDENTITY_LDAP_STS_TRUSTED_PROXIES。 - 上传与写入路径更严格:presigned query 参数不能再与
unsigned-trailer的PUT/ multipart 上传组合使用;Snowball auto-extract 在unsigned-trailer路径下也会执行完整签名校验,匿名或伪造签名请求将被拒绝。 - 复制元数据不再可伪造:普通
PUT/COPY请求夹带的X-Minio-Replication-*内部复制头现在会被拒绝或忽略,只有可信复制链路才能写入相关内部元数据。 - S3 Select 错误语义更明确:CSV 和 line-delimited JSON 遇到超大记录时会直接返回
OverMaxRecordSize,不再笼统返回InternalError;依赖旧错误码的客户端或告警规则需要同步调整。 - 运行时与依赖基线升级:修复
ldaps://未正确应用 TLS 配置的回归问题,替换minio/pkg/v3为pgsty/minio-pkg/v3,并锁定若干易引入 breaking changes 的关键依赖;同时升级go-jose、go.opentelemetry.io与 Go1.26.2,统一构建与发布基线。 - 文档与安全说明同步更新:刷新
SECURITY.md、VULNERABILITY_REPORT.md、docs/sts/ldap.md等文档,新增安全通告索引,并将安全说明中的上游minio/minio引用统一切换为pgsty/minio。
修复的 CVE
- CVE-2026-34986:升级
go-jose到v4.1.4,修复 JWT / JOSE 依赖中的已知安全问题。 - CVE-2026-39883:升级
go.opentelemetry.io依赖栈,修复 PATH hijacking 风险。 - CVE-2026-33322:恢复严格的 JWKS-only OIDC JWT 验证路径,阻断 keyring 注入与算法混淆风险。
- CVE-2026-33419:系统性强化 LDAP STS 认证、限流、源地址识别与记账逻辑,涉及 4 个后续修复提交。
- CVE-2026-34204:拒绝不可信请求注入
X-Minio-Replication-*元数据,防止对象被写入异常复制状态。 - CVE-2026-39414:提前拒绝超大 S3 Select 记录,避免异常数据持续缓冲和解析。
- GHSA-hv4r-mvr4-25vw:封堵 unsigned-trailer query auth 绕过。
- GHSA-9c4q-hq6p-c237:加固 Snowball auto-extract 场景中的 unsigned-trailer 认证与签名校验。
- CVE-2026-32280、CVE-2026-32281、CVE-2026-32283:升级 Go 到
1.26.2,吸收上游工具链与标准库安全修复。
关联提交
- c878ca0:fix: pin deps with breaking changes and fix LDAP TLS regression (#15)
- e970ec5:fix: upgrade go-jose to v4.1.4 to patch CVE-2026-34986
- a206510:fix: CVE-2026-39883 upgrade go.opentelemetry.io
- fd65f11:merge: PR #18 upgrade go-jose to v4.1.4 for CVE-2026-34986
- bc087e4:merge: PR #19 upgrade go.opentelemetry.io for CVE-2026-39883
- f1f2239:fix: CVE-2026-33322 restore JWKS-only OIDC JWT verification
- 6619d0c:fix: CVE-2026-33419 harden LDAP STS auth
- fcb8f24:fix: CVE-2026-34204 reject untrusted replication metadata
- c5765dc:fix: CVE-2026-39414 reject oversized S3 Select records
- fa7c579:fix: GHSA-hv4r-mvr4-25vw block unsigned-trailer query auth bypass
- b50ab58:fix: GHSA-9c4q-hq6p-c237 harden Snowball unsigned-trailer auth
- 9a4b3cd:fix: CVE-2026-32280/CVE-2026-32281/CVE-2026-32283 upgrade Go to 1.26.2
- c55b52c:fix: CVE-2026-33419 preserve LDAP STS rate limits on success
- 817a457:fix: CVE-2026-33419 harden LDAP STS rate-limit source IP
- 084a154:fix: CVE-2026-33419 tighten LDAP STS rate-limit accounting
- 16e34f9:docs: refresh security guidance and fork references
10 - Silo 20260325 发布
发布日期: 2026-03-25 · 版本: RELEASE.2026-03-25T00-00-00Z
这是一个以打包、稳定性与安全公告为主的维护版本,重点是完善交付镜像、修复 LDAP TLS 回归,并把已经锁定到安全版本的依赖明确纳入发布说明。
主要变更
- 将
mcli/mc打入 Docker 镜像并增加校验流程,改善镜像开箱体验。 - 修复
ldaps://场景中的 LDAP TLS 回归,确保 TLS 配置能够正确透传。 - 移除从上游继承但社区分支不再使用的 CI/CD 工作流,减轻维护负担。
- 固定若干关键依赖,避免上游 breaking changes 继续向下游扩散。
修复的 CVE
- CVE-2026-24051:发布说明明确将
go.opentelemetry.io/otel/sdk锁定在安全版本v1.42.0,规避 macOS 上因 PATH hijacking 导致的任意代码执行风险。 - CVE-2025-10543:发布说明明确交付了
github.com/eclipse/paho.mqtt.golang v1.5.1,修复超长 UTF-8 字符串编码错误导致的 MQTT 数据包内容异常。 - CVE-2025-58181:发布说明明确交付了
golang.org/x/crypto v0.49.0,修复sshGSSAPI 认证请求可触发的无界内存消耗问题。
关联提交
11 - Silo 20260321 发布
发布日期: 2026-03-21 · 版本: RELEASE.2026-03-21T00-00-00Z
这是一次围绕 Go 1.26.1 与依赖收敛展开的维护版。除了适配更严格的编译与 lint 检查外,这个版本也完成了本轮最关键的一次安全依赖刷新。
主要变更
- 将构建环境从 Go
1.26.0升级到 Go1.26.1。 - 全面刷新直接与间接依赖,收敛新工具链下的兼容性问题。
- 修正 Go 1.26.1 更严格检查暴露出来的一批 lint 与测试问题。
修复的 CVE
- CVE-2026-27137:Go stdlib 从
1.26.0升级到1.26.1,修复crypto/x509对邮箱约束校验不完整的问题。 - CVE-2026-27138:Go stdlib 从
1.26.0升级到1.26.1,修复畸形证书触发crypto/x509panic 的问题。 - CVE-2026-25679:Go stdlib 从
1.26.0升级到1.26.1,修复net/url对 IPv6 host literal 解析不严格的问题。 - CVE-2026-27139:Go stdlib 从
1.26.0升级到1.26.1,修复os中FileInfo可逃逸Root边界的问题。 - CVE-2026-27142:Go stdlib 从
1.26.0升级到1.26.1,修复html/template在meta refresh场景下 URL 未正确转义的 XSS 风险。 - CVE-2026-26958:
filippo.io/edwards25519从v1.1.0升级到v1.2.0,修复MultiScalarMult可能产生错误结果或未定义行为的问题。 - CVE-2025-10543:
github.com/eclipse/paho.mqtt.golang从v1.5.0升级到v1.5.1,修复超长 UTF-8 字符串编码错误导致的 MQTT 报文异常。 - CVE-2026-24051:
go.opentelemetry.io/otel/sdk从v1.38.0升级到v1.42.0,修复 macOS 上通过 PATH hijacking 触发任意代码执行的风险。 - CVE-2026-33186:
google.golang.org/grpc从v1.77.0升级到v1.79.3,修复 HTTP/2:path缺少前导斜杠时的授权绕过问题。
关联提交
12 - Silo 20260314 发布
发布日期: 2026-03-14 · 版本: RELEASE.2026-03-14T12-00-00Z
这个版本完成了向社区维护 Console 分支的切换,并在切换过程中做了一轮较大幅度的依赖更新,为后续 Go 1.26.x 维护版打下基础。
主要变更
- 切换到社区维护的
georgmangold/console v1.9.1,替换不可持续维护的上游 Console 依赖。 - 大幅更新
go.mod中的直接与间接依赖,使 Console 与新工具链组合能够稳定构建。 - 修复
grid_test.go的go vet格式化指令问题,并调整部分测试以适配 Go 1.26 的 HTTP 行为变化。
修复的 CVE
- CVE-2025-47913:
golang.org/x/crypto从v0.37.0升级到v0.46.0,修复ssh/agent在处理异常响应时可能导致客户端 panic 的问题。 - CVE-2025-58181:
golang.org/x/crypto从v0.37.0升级到v0.46.0,修复sshGSSAPI 认证请求可触发无界内存消耗的问题。 - CVE-2025-47914:
golang.org/x/crypto从v0.37.0升级到v0.46.0,修复ssh/agent对畸形身份消息缺乏边界校验导致的 panic 问题。 - CVE-2025-47911:
golang.org/x/net从v0.39.0升级到v0.48.0,修复html.Parse在特制输入下的二次复杂度解析问题。 - CVE-2025-58190:
golang.org/x/net从v0.39.0升级到v0.48.0,修复golang.org/x/net/html可能陷入无限解析循环的问题。
关联提交
13 - Silo 20260214 发布
发布日期: 2026-02-14 · 版本: RELEASE.2026-02-14T12-00-00Z
这是社区分支早期的一个基础设施版本,除了恢复内嵌 Console 与建立 GitHub CI/CD 之外,也把 Go 运行时基线提升到 1.26.0,因此一并消化了上一代工具链中的一批安全问题。
主要变更
- 恢复内嵌 Console,并更新 README 以明确社区维护分支的定位。
- 新增 GitHub CI/CD 流水线,为后续自动构建和多平台分发建立基础。
- 补充文档、Docker、GitHub 仓库与
pig包管理器安装入口,完善发布入口。
修复的 CVE
这些问题随着 Go 从 1.25.5 升级到 1.26.0 一并被修复,包括:
- CVE-2025-68121:
crypto/tls在会话恢复时可能错误接受已变更 CA 配置。 - CVE-2025-61730:TLS 1.3 在跨加密级别 record 中可能错误处理握手消息。
- CVE-2025-61726:
net/url查询参数解析可导致内存耗尽。 - CVE-2025-61728:
archive/zip构建索引时可能触发过高 CPU 消耗。 - CVE-2025-68119:
cmd/go在调用外部 VCS 工具链时可能触发意外代码执行。 - CVE-2025-61731:
#cgo pkg-config:指令可导致任意文件写入。 - CVE-2025-61732:
cmd/cgo文档注释解析差异可能导致代码走私。
关联提交
14 - Silo 20251203 发布
发布日期: 2025-12-15 · 版本: RELEASE.2025-12-03T12-00-00Z
这是目前可追溯到的首个社区版发布,主要目标是建立社区维护分支的打包与分发基线,而不是在此前社区版本之上做增量修复。
主要变更
- 基于
minio/pkger建立社区版打包流程。 - 选择 MinIO 进入 maintenance mode 后的一版上游基线作为社区分支起点。
- 首次产出
apk、deb、rpm等多种平台包,为后续持续发布建立基础。
修复的 CVE
- 这是首个社区版发布,GitHub Release 未单独声明相对更早社区版本的安全修复清单;本页不追溯其相对上游维护模式基线的全部历史 CVE 差异。
关联提交
- d4cd4b4:RELEASE.2025-12-03T12-00-00Z with go 1.25.5