「一台跑认证的服务器,内存占用比业务代码还高——这事本身就不对劲。」
这是某位开发者在折腾了 Keycloak 一年后得出的结论。他的解决方案很硬核:用 Rust 重写了一个认证服务,内存控制在 20MB 以内。这篇文章拆解了他对现有工具的不满、技术选型的逻辑,以及从零造轮子的真实成本。
现状:小团队的认证成本困境
这位开发者用 Keycloak 接了近一年的外包项目,从企业级应用到个人 side project。这套系统的吸引力很明确:免费、经过实战检验、能跑起来。
但问题同样突出。
文档是一座迷宫。概念页和配置页堆叠在一起,懂 Keycloak 的人看得懂,新手只想跑个登录流程却处处碰壁。
真正的爆发点是算经济账。DigitalOcean 上能流畅跑 Keycloak 的 droplet,月费超过大多数小项目的承受范围。转投 SaaS 方案如 Clerk 或 Auth0,定价模式是按月按人头收费,且用户凭证要托管到第三方服务器。
他的原文算了一笔具体的资源账:
Keycloak 空闲状态占用约 512MB 内存。Authentik 需要同时跑 server 和 worker,合计约 735MB,还得额外配一个 Redis 实例。Zitadel 相对克制,约 150MB,但仍需要一台配置宽裕的服务器。这些工具的技术栈是 Java、Python 或 Go——带垃圾回收的运行时,开销天生存在。
如果你的 VPS 只有 1GB 内存,认证系统已经吃掉大半,业务代码还没启动。而很多自由职业者和 side project 就运行在 6 美元/月的最低配 droplet 上,根本没有余量。
SaaS 方案解决了基础设施问题,却制造了新的麻烦。Clerk 起步价 25 美元/月,Auth0 起步 23 美元/月,都是按座位随规模递增。更关键的是,用户凭证存放在别人的服务器上,用别人的加密模型。
他认为这个缺口——"认证运行成本"与"小项目实际承受力"之间的落差——正是他新项目瞄准的空间。他甚至提到,最低配服务器跑个 Minecraft 原版服都没问题。
技术选型:为什么非得是 Rust
他的坦白很直接:他想要的是默认就精简的东西,而不是靠调配置压出来的精简。
带垃圾回收的运行时(如 JVM)有不可控的开销——内存峰值、暂停时间、预热成本。对需要表现可预测的认证服务器来说,这是隐患。Rust 没有垃圾回收器,二进制文件启动不到一秒,之后保持稳定。
安全维度同样关键。Rust 的所有权模型(ownership model)在编译阶段就消灭整类内存漏洞,不是在生产环境,不是在事后复盘,是在编译时。
「一旦习惯了这套机制,就很难回头。」
安全架构:从零设计意味着什么
自己造认证服务器,意味着要做很多"陷进去之前并不明显"的决策。这些选择最终塑造了新项目的架构。
零知识加密
用户数据采用 AES-256-GCM 加密,使用双重信封密钥模型——服务器永远不接触明文密钥。主密钥派生自用户密码,结合 Argon2id 和硬件绑定的安全密钥。即使数据库泄露,攻击者拿到的是加密 blob 和加盐哈希,没有用户密码就无法解密。
他的原话是:「服务器永远看不到你的数据是什么样子。」
无会话令牌
新项目完全放弃服务器端会话。访问令牌和刷新令牌都是自包含的 JWT,用 Ed25519 签名。验证只需公钥,无需数据库查询。这意味着水平扩展时不需要粘性会话或共享存储,单台服务器宕机不影响已签发令牌的有效性。
最小权限隔离
每个组件以最小权限运行。令牌签发服务只持有签名私钥,不接触用户数据。用户数据服务只处理加密存储,不能签发令牌。即使某一层被攻破,攻击者拿到的权限也受限。
密码学细节
他列出了具体的技术选型:X25519 用于密钥交换,Ed25519 用于签名,Argon2id 用于密码哈希,AES-256-GCM 用于对称加密,SHA-3-256 用于派生函数。
热门跟贴