标签 Golang 下的文章

Go 安全新提案:runtime/secret 能否终结密钥残留的噩梦?

本文永久链接 – https://tonybai.com/2025/12/05/proposal-runtime-secret

大家好,我是Tony Bai。

“如果你的服务器被攻破,攻击者能否拿到内存中残留的私钥,进而解密过去两年的所有通信记录?”

这是一个让所有安全工程师夜不能寐的问题。为了防止这种情况,现代加密协议(如 TLS 1.3, WireGuard)都强调前向保密 (Forward Secrecy):使用临时的、一次性的密钥,并在使用后立即销毁。

然而,在 Go 语言中,“立即销毁”这个看似简单的动作,却是一个巨大的技术难题。由于垃圾回收 (GC)、堆栈复制、以及缺乏对内存的底层控制,Go 程序很难保证敏感数据被彻底擦除。

针对这一痛点,Go 社区大神 Jason A. Donenfeld(WireGuard作者,ID: zx2c4) 发起了一项长达数年的提案——引入 runtime/secret 包。近日,该提案已进入实现阶段,有望在Go 1.26版本中落地,并彻底改变 Go 处理敏感数据的方式。

img{512x368}

核心痛点:为什么 memset(0) 在 Go 中不够用?

在 C 语言中,我们可以调用 explicit_bzero 来擦除内存。但在 Go 中,情况要复杂得多:

  1. 隐式拷贝:Go 的切片操作、函数传参、甚至简单的赋值,都可能在堆或栈上留下数据的副本。你擦除了一份,却可能漏掉了其他三份。
  2. GC 的不确定性:垃圾回收器何时运行?被回收的内存是否会被立即归零?这些都是未知的。
  3. 堆栈扩容:当 goroutine 栈空间不足时,Go 运行时会分配一个更大的新栈,并将旧栈的数据拷贝过去。旧栈中的敏感数据就此残留,且不再被追踪。
  4. 编译器优化:简单的“写入零值”操作可能会被编译器视为“死代码”而优化掉。

正如 WireGuard 的 Go 实现中遇到的尴尬局面:为了擦除一个 AEAD 对象中的密钥,开发者不得不使用反射 (Reflection) 这种“旁门左道”来重置其内部字段,既不优雅也不可靠。

提案及演进:从 SetZeroOnGC 到 secret.Do

这项提案的讨论过程,简直是一部 Go 运行时机制的“解剖学教程”。

早期尝试:SetZeroOnGC

最初的设想是让用户标记某个对象,告诉 GC 在回收它时必须将其内存归零。

但这无法解决栈上数据的残留问题,也无法处理那些在函数调用过程中产生的临时副本。

中期探索:自定义分配器与 SetFinalizer

有人提议使用 memguard 等库,通过 mmap 分配不受 GC 管理的内存。

但这需要重写所有加密库的 API,使其接受自定义分配器,工程量巨大且不兼容现有生态。

最终方案:runtime/secret 包

经过反复权衡,Go 团队和社区最终汇聚到了一个基于动态作用域的解决方案上。提案的核心 API 极其简洁:

package secret

// Do 执行函数 f。
// 当 secret.Do 返回时:
//   - 清除函数 f 执行期间创建的所有栈帧(stack frames)。
//   - 清除所有可能包含secret的寄存器。
//   - 在secret模式下栈增长时,清除旧的栈。
//   - secret模式下,在 f 执行期间分配的所有堆对象,会被标记为“敏感”,并在 GC 回收时被安全擦除。
//   - 如果函数出现panic,则将该panic提升为来自 secret.Do 的异常。这会从回溯中移除有关secret函数的任何信息。

func Do(f func())

这个设计不仅解决了堆内存的问题,更关键的是,它提供了一个“安全沙箱”。在这个沙箱内,你可以放心地进行加密计算,Go 运行时会负责清理你在栈上留下的所有痕迹。

使用场景:WireGuard 与 TLS

想象一下 WireGuard 的握手过程:

func handleHandshake() {
    secret.Do(func() {
        // 1. 生成临时私钥 (在栈上或堆上)
        ephemeralPrivateKey := generateKey()

        // 2. 计算共享密钥 (产生大量中间计算结果)
        sharedKey := computeSharedKey(ephemeralPrivateKey, peerPublicKey)

        // 3. 使用共享密钥进行加密操作
        // ...

        // 函数返回时:
        // - ephemeralPrivateKey 所在的栈帧被立即擦除
        // - sharedKey 等堆对象被标记,GC 回收时自动擦除
    })
}

开发者不需要手动追踪每一个变量,也不需要担心 copy 操作泄露数据。只要在 secret.Do 的闭包内,一切都是安全的。

深水区的挑战:信号、GC 与汇编

虽然 API 设计看似完美,但实现起来却是困难重重。今年的最新讨论揭示了几个令人头秃的底层挑战:

  1. 信号处理 (Signals):如果程序在 secret.Do 执行期间收到系统信号,CPU 寄存器中的敏感数据会被操作系统保存到“信号栈”中。这相当于泄露了数据!

  2. 垃圾回收器 (GC):GC 在扫描内存时,可能会将敏感指针加载到自己的寄存器或栈中。如何确保 GC 线程本身不泄露数据?这是一个极其棘手的工程问题。

  3. 汇编代码:Go 的加密库大量使用了汇编优化。如何确保这些汇编代码在使用完寄存器后正确地将其清零?

当然,目前该提案的开发者 Daniel Morsing 已经逐个克服了上述挑战,比如针对信号处理的问题,他提出了一种巧妙的“影子栈”方案,试图在信号处理返回前拦截并擦除这些数据。Daniel Morsing针对该提案的cl 704615 近期已经被merge,有望在Go 1.26落地。

不过目前,该secret包仅在linux for arm64 and amd64上有实现。

小结:安全是场持久战

runtime/secret 提案的推进,标志着 Go 语言在系统级安全领域迈出了重要一步。它不仅回应了高安全等级应用(如金融、国防)的需求,也体现了 Go 团队在面对复杂底层问题时的务实与坚持。

虽然已经被merge,但历史经验告诉我们,距离该功能成熟可能还有一段路要走,后续仍在会有一些问题和实现细节需要解决,但它所传达的信号是明确的:Go 正在成为编写安全基础设施的首选语言之一。

对于我们普通开发者而言,虽然我们未必会在业务代码中直接 import 这个包(runtime/secret),但关注这个提案的进展,不仅能让我们见证 Go 语言如何填补安全拼图中至关重要的一角,更能让我们在“围观”其解决信号处理、GC 交互等硬核挑战的过程中,完成一次对 Go 运行时底层机制的深度认知升级。当这一基础设施最终就位时,我们将能以更强的信心,站在更坚固的安全基石之上构建应用。

资料链接:https://github.com/golang/go/issues/21865


聊聊你眼中的 Go 安全基石

runtime/secret 提案的推进,为 Go 在高安全等级场景的应用补上了一块关键的拼图。你在日常的 Go 开发中,是否也曾为如何安全地处理密钥、Token 等敏感数据而感到困扰?除了内存残留问题,你认为 Go 在安全方面还有哪些亟待完善的“深水区”?

或者,你对 secret.Do 这种通过“安全沙箱”来解决问题的方式有何看法?它是否是你心中理想的解决方案?

欢迎在评论区分享你的实战经验、安全痛点,或对 Go 语言安全生态的任何期待与建议! 让我们一起探讨,共同构建一个更安全的 Go 世界。

如果这篇文章让你对 Go 的底层安全有了新的认识,别忘了点个【赞】和【在看】,并分享给更多关注 Go 安全的同伴!


你的Go技能,是否也卡在了“熟练”到“精通”的瓶颈期?

  • 想写出更地道、更健壮的Go代码,却总在细节上踩坑?
  • 渴望提升软件设计能力,驾驭复杂Go项目却缺乏章法?
  • 想打造生产级的Go服务,却在工程化实践中屡屡受挫?

继《Go语言第一课》后,我的《Go语言进阶课》终于在极客时间与大家见面了!

我的全新极客时间专栏 《Tony Bai·Go语言进阶课》就是为这样的你量身打造!30+讲硬核内容,带你夯实语法认知,提升设计思维,锻造工程实践能力,更有实战项目串讲。

目标只有一个:助你完成从“Go熟练工”到“Go专家”的蜕变! 现在就加入,让你的Go技能再上一个新台阶!


想系统学习Go,构建扎实的知识体系?

我的新书《Go语言第一课》是你的首选。源自2.4万人好评的极客时间专栏,内容全面升级,同步至Go 1.24。首发期有专属五折优惠,不到40元即可入手,扫码即可拥有这本300页的Go语言入门宝典,即刻开启你的Go语言高效学习之旅!


商务合作方式:撰稿、出书、培训、在线课程、合伙创业、咨询、广告合作。如有需求,请扫描下方公众号二维码,与我私信联系。

MinIO 开源版突发“安乐死”:维护模式开启,社区愤怒,你的数据还安全吗?

本文永久链接 – https://tonybai.com/2025/12/04/minio-enter-maintenance-mode

大家好,我是Tony Bai。

“这个项目目前处于维护状态,不接受新的更改。”

近日,GitHub 上拥有近 60k Star、Go 语言生态中最著名的开源对象存储项目——MinIO,悄然修改了其 README。这一行看似平淡的声明,标志着 MinIO 开源版实际上已经被宣判了“死刑”。

曾经,MinIO 是自建 S3 兼容存储的首选,是开源界的宠儿。如今,它转身拥抱了企业级市场和 AI 浪潮,留下了一脸错愕的社区用户和无数依赖它的开源项目。这究竟是一场无奈的求生,还是一次蓄谋已久的“收割”?

突如其来的“维护模式”

MinIO 官方在没有任何预警的情况下,将其开源仓库置于“维护模式”。这意味着:

  • 功能冻结:不再接受任何新功能或改进。
  • 社区关门:不再接受 Pull Request,现有的 Issue 和 PR 也不会被积极审查。
  • 安全补丁随缘:关键的安全修复“可能”会根据具体情况进行评估,不再有保证。

官方建议很明确:“对于企业支持和积极维护的版本,请参阅MinIO AIStor。”,而AIStor则是MinIO的企业版对象存储产品。

这一举动在 Hacker News 上引发了轩然大波。用户感到被背叛,一位评论者愤怒地写道:“太恶心了。构建一个产品,通过开源获得动力,等你做完了就完全抛弃它。我为曾经推广这个项目感到羞耻。”

为何“背叛”?—— 商业化的必然与 AI 的诱惑

MinIO 的转向并非无迹可寻。从更换为更严格的 AGPL 协议,到此次事实上的闭源,其背后的逻辑清晰而冷酷:

开源无法变现的困境

MinIO 作为一个高性能、单二进制文件的存储服务,太容易“被集成”了。云厂商、集成商可以轻松地将其打包进自己的产品中获利,而 MinIO 公司却难以从中分一杯羹。AGPL 协议虽然意在限制云厂商的“白嫖”,但也未能从根本上解决其商业化难题。

AI 浪潮的巨大诱惑

MinIO 的新产品名为 AIStor。这不仅仅是一个改名,更是一次战略转型。在 AI 时代,数据存储是基础设施的核心。MinIO 试图通过重新包装,将自己定位为 AI 基础设施的关键组件,从而向更有付费能力的企业客户(尤其是 AI 公司)靠拢。

正如一位 HN 用户指出的:“他们在上一轮融资中估值 10 亿美元,要想成功退出,必须有深口袋的买家(如 Nvidia, Dell 等)。现在的开源版本只会拖累他们的财报。”

社区的反击与法律迷局

MinIO 的做法也引发了法律层面的争议。

  • 贡献者的权利:MinIO 曾要求贡献者签署 CLA(贡献者许可协议)。这意味着 MinIO 公司拥有代码的版权,他们确实有权改变许可证或停止开源。
  • AGPL 的约束:但对于那些没有签署 CLA 的早期贡献者,或者包含在代码库中的第三方 AGPL 代码,MinIO 是否有权单方面“私有化”?这是一个复杂的法律问题。

更有趣的是,MinIO 过去曾因 AGPL 许可问题积极“维权”,甚至公开指责其他公司违反协议。如今,它自己却试图摆脱开源的束缚,这种双重标准让社区感到讽刺。

历史的镜像 —— Redis 与 Valkey 的启示

MinIO 的剧变,让人不由得想起了 2024 年初震动开源界的另一场“地震”——Redis 修改开源协议事件

当时,Redis Inc. 宣布不再遵循开源定义,转而采用限制性更强的 SSPL 协议。这一举动激怒了整个社区和云厂商,Linux 基金会迅速集结了 AWS、Google、Oracle 等巨头,基于 Redis 旧版本 fork 出了 Valkey。如今,Valkey 已经展现出取代 Redis 的蓬勃生命力。

MinIO 与 Redis 的异同:

  • 相同点:两者都面临“云厂商困境”。AWS 直接拿 Redis 做 ElastiCache,拿 MinIO 做兼容 S3 的服务,却无需向原厂付费。原厂为了生存,不得不通过协议(AGPL/SSPL)或停止维护来“筑墙”。
  • 不同点:Redis 选择了“掀桌子”(改协议),引发了激烈的对抗和即时的 Fork(Valkey);而 MinIO 选择了“冷处理”(维护模式),这更像是一种温水煮青蛙式的告别。

MinIO 会迎来它的“Valkey 时刻”吗?

目前来看,难。对象存储的复杂度和维护成本远高于内存缓存,且市场上已经存在成熟的替代品(如 SeaweedFS, Ceph, Garage)。MinIO 社区或许不会像 Redis 那样迅速集结出一个统一的 Fork,而是会走向分裂和迁徙

对于开发者而言,Redis 和 MinIO 的连续“暴雷”是一个明确的信号:在基础设施选型时,除了关注技术指标,更要评估其背后的治理模式。由单一商业公司绝对控制的“开源”项目,始终悬着一把达摩克利斯之剑。

自救指南 —— 寻找 MinIO 的替代品

对于现有的 MinIO 用户来说,现在是时候寻找备胎了。社区推荐了几个值得关注的替代方案:

SeaweedFS (Go)

  • 特点:基于 Haystack 论文实现,擅长处理海量小文件,自带 File 和 S3 接口。
  • 适用场景:需要高性能小文件存储的场景。
  • 评价:功能丰富,甚至有点“过度”,但性能强悍。

Ceph (C++)

  • 特点:存储界的瑞士军刀,功能极其强大,但也极其复杂。
  • 适用场景:大规模、生产级、需要块存储和文件存储的场景。
  • 评价:如果你有运维团队,Ceph 是永远不会错的选择。

Versity Gateway (Go)

  • 特点:基于文件的 S3 网关,可以在开发测试环境作为 MinIO 的直接替代品,后端直接对接文件系统。

RustFS (Rust)

  • 特点:野心勃勃的新晋选手,试图在性能和易用性上直接对标甚至超越 MinIO。
  • 适用场景:极客尝鲜、非生产环境的测试与评估。
  • 评价:社区评价两极分化。一方面,它展现了强大的潜力;另一方面,用户反馈其目前稳定性欠佳,且项目要求签署 CLA(贡献者许可协议),这让不少刚被 MinIO 伤过心的开发者担心它未来会重演“养肥再杀”的剧本。“潜力巨大,但需谨慎观望。”

Garage (Rust)

  • 特点:轻量级、自包含、专注于在异构硬件和地理分布的网络上运行。
  • 适用场景:自托管、家庭实验室、中小规模集群。
  • 评价:“非常稳固,简单可靠,没有风险投资背景。”

小结:开源的尽头是商业,还是背叛?

MinIO 的故事,是开源软件商业化困境的又一个注脚。它提醒我们:

  • 没有免费的午餐:由 VC 支持的开源项目,最终都要面临盈利的压力。当增长遇到瓶颈,社区往往是被牺牲的第一个对象。
  • 选择开源项目需谨慎:除了代码质量,项目的治理结构、CLA 协议、背后的商业模式,都是选型时必须考虑的风险因素。

MinIO 虽已“离去”,但开源精神不死。也许下一个更好的 MinIO,正在某个 GitHub 的角落里悄然生长。

资料链接:https://news.ycombinator.com/item?id=46136023


还在为“复制粘贴喂AI”而烦恼?我的新专栏 AI原生开发工作流实战 将带你:

  • 告别低效,重塑开发范式
  • 驾驭AI Agent(Claude Code),实现工作流自动化
  • 从“AI使用者”进化为规范驱动开发的“工作流指挥家”

扫描下方二维码,开启你的AI原生开发之旅。


你的Go技能,是否也卡在了“熟练”到“精通”的瓶颈期?

  • 想写出更地道、更健壮的Go代码,却总在细节上踩坑?
  • 渴望提升软件设计能力,驾驭复杂Go项目却缺乏章法?
  • 想打造生产级的Go服务,却在工程化实践中屡屡受挫?

继《Go语言第一课》后,我的《Go语言进阶课》终于在极客时间与大家见面了!

我的全新极客时间专栏 《Tony Bai·Go语言进阶课》就是为这样的你量身打造!30+讲硬核内容,带你夯实语法认知,提升设计思维,锻造工程实践能力,更有实战项目串讲。

目标只有一个:助你完成从“Go熟练工”到“Go专家”的蜕变! 现在就加入,让你的Go技能再上一个新台阶!


商务合作方式:撰稿、出书、培训、在线课程、合伙创业、咨询、广告合作。如有需求,请扫描下方公众号二维码,与我私信联系。

如发现本站页面被黑,比如:挂载广告、挖矿等恶意代码,请朋友们及时联系我。十分感谢! Go语言第一课 Go语言进阶课 AI原生开发工作流实战 Go语言精进之路1 Go语言精进之路2 Go语言第一课 Go语言编程指南
商务合作请联系bigwhite.cn AT aliyun.com

欢迎使用邮件订阅我的博客

输入邮箱订阅本站,只要有新文章发布,就会第一时间发送邮件通知你哦!

这里是 Tony Bai的个人Blog,欢迎访问、订阅和留言! 订阅Feed请点击上面图片

如果您觉得这里的文章对您有帮助,请扫描上方二维码进行捐赠 ,加油后的Tony Bai将会为您呈现更多精彩的文章,谢谢!

如果您希望通过微信捐赠,请用微信客户端扫描下方赞赏码:

如果您希望通过比特币或以太币捐赠,可以扫描下方二维码:

比特币:

以太币:

如果您喜欢通过微信浏览本站内容,可以扫描下方二维码,订阅本站官方微信订阅号“iamtonybai”;点击二维码,可直达本人官方微博主页^_^:
本站Powered by Digital Ocean VPS。
选择Digital Ocean VPS主机,即可获得10美元现金充值,可 免费使用两个月哟! 著名主机提供商Linode 10$优惠码:linode10,在 这里注册即可免费获 得。阿里云推荐码: 1WFZ0V立享9折!


View Tony Bai's profile on LinkedIn
DigitalOcean Referral Badge

文章

评论

  • 正在加载...

分类

标签

归档



View My Stats