现代电子邮件可以用借来的零件搭建

查看原文 HN 讨论

文章摘要

作者 Andros Fenollosa 在开头就把定位说清楚了:这是一个设计实验,目标不是取代现有的邮件系统(「千万别」),而是为了学习、找乐子,并借此把当代技术盘一遍,看看能不能把邮件的每个环节——发送、接收、网关、密钥等等——全部换掉。这套系统永远不会与 Gmail 或任何传统邮件服务商通信,它只跟自己说话。唯一保留的是地址的形状:user@domain。其他一切都重新发明。

由于这是一套跑在 HTTP 之上的邮件系统,作者给协议起名 HMTP:Hypertext Mail Transfer Protocol(SMTP 里代表 Simple 的 S 把座位让给了代表 HTTP 的 H)。

物料清单。文章的核心论点是:这个设计没有发明任何一项技术,一切都已存在。他列了一张对照表:传输和状态码用 HTTP(全网在用);传输加密用 TLS + Let’s Encrypt;用户发现用 WebFinger(RFC 7033,Mastodon 和联邦宇宙在用);消息投递用 POST 到收件箱(ActivityPub);源头的发件人验证用 Webmention 和 DKIM 的模式;签名用 Ed25519(SSH、Signal);内容加密用 HPKE(RFC 9180,MLS、TLS ECH);能在密钥轮换后存活的身份用签名链 sigchain(ATProto/Bluesky、Keybase);读取和同步用 JMAP(RFC 8620,Fastmail);推送通知用 SSE / WebPush;首次接触同意用消息请求(Signal、Instagram);带哈希的附件按引用传递用内容寻址(Git、IPFS、Matrix)。「唯一新的东西是组装方式。」

选 HTTP 不只是实用主义。它开箱即用地解决了任何新协议迟早要重建的东西:TLS、虚拟主机和 SNI 免费获得;状态码目录现成——202 Accepted(已排队投递)、429 Too Many Requests + Retry-After(速率控制)、404/410(邮箱不存在/已消失)、3xx(邮箱迁移)、413(太大),甚至付费反垃圾邮件的状态码从 1997 年起就预留好了:402 Payment Required;以及现有基础设施:代理、负载均衡器、Nginx、各语言的库。协议不再是一个新服务器,而变成了 HTTP 之上的约定,就像 Webmention 或 Micropub。作者还指出了一个历史反讽:HTTP 头直接继承自邮件头(RFC 822),把邮件搬到 HTTP 上不是绑架,是回家。

一、发现与委派(更好的 MX)。委派用一份静态文档解决:GET https://example.com/.well-known/hmtp/ana 返回一个包含 inbox、keys、devices 的 JSON。inbox 可以位于另一台主机——这就是 MX 记录,但不用碰 DNS。托管在 GitHub Pages 上的静态博客也可以通过提供一个 JSON 文件把邮件委派给服务商。而且它允许 MX 从未做到的事:按用户委派(同一域名的每个邮箱可以在不同服务商)。作者回应了「把发现从 DNS 里拿出来是异端吗」的质疑:今天的邮件已经迈出了这一步——MTA-STS(RFC 8461)就把策略发布在 https://mta-sts.domain/.well-known/mta-sts.txt,正是因为用 Let’s Encrypt 部署 TLS 比部署 DNSSEC 容易。代价是域名必须提供 HTTPS,这是 MX 没有的耦合。

二、能在密钥轮换后存活的身份。身份不能是一把密钥(密钥会丢会过期),它必须是密钥去背书的东西。两个锚点:一是密码学连续性——发现文档发布当前密钥和一条轮换链,每把新密钥由前一把签名,认识你旧密钥的人可以在不信任任何第三方的情况下验证新密钥;二是域名控制作为兜底——如果笔记本被偷、密钥没有签名轮换就丢了,域名可以在没有链的情况下声明新密钥,但要有强制公告期(比如 30 天),期间认识你的服务器会显示「身份由域名重锚,而非由签名重锚」的警告。作者诚实地指出了这个方案的阿喀琉斯之踵:域名不是被拥有的,而是被租用的。如果你停止付费、它过期、别人注册了它,新主人在你的 .well-known 里发布他们的密钥,从那一刻起他们就能接收你的邮件并以你的名义签名,没人能分辨合法继承人和抢注者。这正是 ATProto 试图用 DID 把身份与域名分离来解决的问题,代价是又一层基础设施。

三、带队列的投递(存储转发)。投递是一个 POST 到收件人的 inbox。但关键不在于请求,而在于谁发出请求:你的客户端不直接投递给收件人,而是投递给你自己的服务器(一个经认证的 POST 到你的 outbox),由你的服务器排队、指数退避重试、遵守 Retry-After。这是承认 SMTP 的 MUA/MSA/MTA 分离是对的——邮件那个安静的天才之处在于,如果目标服务器宕机,你的服务器会重试好几天,而你可以忘掉这件事。但作者加了一个 SMTP 从未有过的改进:每条消息携带一个 ID,即其内容的哈希,因此重试是幂等的。接收方按 ID 去重,经典的「因为 ACK 失败导致重复邮件」问题从构造上消失了。文章配了一张 mermaid 时序图展示了完整流程:客户端 POST 到自己服务器拿到 202 queued,己方服务器 GET 对方的 .well-known 拿到 inbox 和密钥,POST 投递,对方宕机无响应,队列指数退避重试(同一 id),对方服务器反向 GET 发件人的签名密钥,验证签名、按 id 去重,返回 201 delivered。

四、用已有的密钥签名和加密。消息是一个签名对象而非松散文本,包含 id(sha256:…)、from、to、date、in_reply_to、sealed(用 HPKE 加密的主题和正文)、signature。这带来几件事:静态存储的真实性——存下来的邮件带着自己的密码学证明,转发保留原始签名,即使经过多层转发也无法伪造发件人;无需 DKIM 的发件人验证——接收服务器 GET from 域名的 .well-known 检查密钥能否验签,这与 Webmention 的验证是同一个动作,证据从源头取得;端到端加密——发现文档发布加密密钥(X25519),主题和正文一起用 HPKE 封装,信封(from、to、id、date)保持可见用于路由和过滤,其余只有收件人可读。作者特意点名:「PGP 把主题留在明文里的错误拖了几十年,那些元数据出卖过不止一个人。我们在这里不重复。」还有线索重建——in_reply_to 用内容哈希引用,对话无需启发式即可重建;以及附件——放在消息之外,文件用一次性密钥加密,发件人的服务器存一个不透明 blob,{hash, url, size, key} 引用放在被封装的正文里,所以 E2E 也覆盖附件(这是 Matrix 的模式)。哈希是加密后 blob 的哈希,任何服务器都能验证完整性却读不到任何内容。收件人的服务器在投递时镜像它而非在阅读时——没人知道你何时打开附件,发件人在镜像确认后可以删除原件。「不再有 base64 撑爆邮箱,而且成本沿途翻转了:谁发送,谁托管。」

作者也诚实地指出了签名整条消息的代价,这一点 DKIM 很清楚:传输途中没人能碰它。而邮件列表恰恰靠这个活着——它们要给分发的消息加 List-Id、退订链接这些头。DKIM 让你选择签哪些头不是偶然。在 HMTP 里,列表不会修改你的消息,而是发布一条新消息,由列表签名,通过哈希引用原件。读者会看到谁写的和谁分发的,各带各的签名。

五、分层反垃圾。三层防御:身份成本——以 ana@example.com 签名需要在 example.com 提供密钥文档,身份锚定在域名上而域名要花钱,这是自签名身份没有的女巫成本;不过作者承认,一个域名给你无限的子域和邮箱,所以成本减缓的是大规模创建独立身份,而非创建地址,「我们在根级别工作」。首次接触同意——陌生发件人进不了收件箱,他们落在一个「请求」箱里,首条消息可见(像 Signal 的消息请求),你接受后线程就永远打开。「陌生人可以敲你的门,这是邮件的本质属性,但他们不能塞满你的客厅。」可选的陌生人邮资——服务器可以用 402 回应首次接触,按邮箱可配置,冷发垃圾邮件的成本不再是零。

作者对第二层做了非常诚实的自我批评,因为它背负着三十年的历史反证:挑战-响应系统在九十年代被试过并以两种方式失败。一是请求箱可能最终变成新的垃圾箱,问题只是搬到了另一个房间;二是致命的那个——非人类写的邮件(购买确认、发票、银行,所有来自 no-reply@ 的东西)永远通不过挑战,而那些邮件占了真实流量的大部分。他的辩护是:这里的同意是被动的,没人要解验证码或点链接,首条消息完整到达、公开等着,你一下就能决定;如果是你发起的接触,线程一出生就是打开的;对于你自己要求的机器邮件(在某个网站注册后会给你发发票),接受一次即永久。「它消除垃圾邮件吗?不。没有任何同意系统能消除它,只能重新排序。这个赌注是:一个把消息摆在明处的请求箱,比一个盲目决定什么能进你邮箱的统计过滤器更划算。」

六、读取也被规范化。邮件把发送(SMTP)和读取(IMAP/POP)标准化成了两个分离的世界。作者说不需要发明任何东西:在 JSON/HTTP 上读取、同步和搜索邮箱已经由 IETF 解决并标准化了,它叫 JMAP。HMTP 定义投递,读取就是 JMAP 加一种新对象类型,客户端推送用 SSE 或 WebPush,完整周期(发送、投递、读取、同步)都留在 HTTP 上。

结论与原型。作者把每个问题的替代方案列了一遍:声誉与社会许可(SPF、DKIM、DMARC、反向 PTR、黑名单、几个月的 IP 预热)被每条消息上的密码学验证取代——一个签名加一个对发件人 .well-known 的 GET,「一个可以被验证的属性不需要声誉」;发件人伪造从构造上不可能;邮件委派变成 .well-known 里的静态文档;内容隐私默认端到端加密(「那个从来没人抽空配置好的 PGP」);垃圾邮件靠首次接触同意、锚定在域名上的昂贵身份和可选的 402 邮资;重试重复靠内容哈希 id 幂等解决;线程用可验证的图;轻量邮箱靠按引用的加密附件(谁发送谁托管,带重附件的垃圾邮件消耗的是垃圾邮件发送者的磁盘空间而非你的);基础设施简单熟悉(一切走标准 HTTPS,在同一个 Nginx 和同一张证书后面);密钥轮换(DKIM 的运维噩梦)变成一条命令——因为没人钉住你的密钥,新的立刻被信任,被偷的也同样快地作废。

作者用 Python 写了一个可运行的原型:github.com/tanrax/hmtp,全部在单个文件里。原型覆盖了完整传输:签名投递、源头验证、端到端加密、首次接触同意、去重、线程、带指数退避的队列、一条命令轮换密钥。它刻意省略了外围部分:签名轮换链(接收方在每次投递时实时取你的密钥而非钉住,所以链只有在节点缓存密钥后才开始有回报)、402 邮资、按引用的附件、JMAP 读取。README 里有快速上手(两分钟内发出第一封给自己的邮件)、两个节点在本机交换加密邮件的演示,以及从 DNS 到 systemd 的完整生产指南。他提醒这是一个设计实验,密码学未经审计,不要用它保护任何人依赖的秘密。

文章末尾有一条 2026 年 7 月 29 日的更新:作者在 HN 讨论之后修订了文章——主题现在与正文一起加密传输、附件被 E2E 覆盖并在投递时镜像、文章澄清了消息哈希覆盖什么以及邮件列表如何适配、并承认了首次接触同意的局限。

HN 评论精华

这条讨论有 198 分和 160 多条评论,实质内容相当扎实——有邮件服务商的前员工、开源 SMTP 服务器的作者、以及在这个领域创业的人下场。但需要说明的是,讨论里有一整条支线完全偏离了技术内容,变成了对作者网站上浮动面板和实时访客计数器的批评,并升级成了作者与读者关于「设计愿景 vs 最佳实践」的正面冲突,长度可观。

「首次接触同意」:三十年的历史反证

这是全帖最受欢迎也最受质疑的设计点。amelius 引用了那段「陌生人可以敲你的门但不能塞满你的客厅」并说「我喜欢这个」,还问这套规范能不能同时取代 WhatsApp 这类即时通讯协议。fny 反问:「有什么理由它们不该是同一个东西吗?」xd1936stackghost 都指出 hey.com(37signals 的邮件产品)就是这么运作的。aboardRat4 提到 Deltachat,inigyou 补充说最初的 Delta Chat 字面意义上实现了「WhatsApp over email」,但后来改了设计,用自己的协议和服务器而非邮件。

thesuitonym 提供了一个有意思的事实纠正:「信不信由你,大多数邮件服务器实际上已经是这样设置的,只是对用户完全不可见」,并链接了灰名单(Greylisting)。dizhn 精确地指出这不是同一回事:灰名单与邮件是否合法(非垃圾)无关,它只捕捉那些在被短暂延迟后不按规矩重试的邮件(重试是邮件的一个超好特性,能在你的服务器短暂宕机时保护你不丢失全部来信),其推理是垃圾脚本或软件大概不会正确实现标准或会跳过看起来坏掉的目标。他补充说,楼上真正想要的东西也是可能的,早在 2000 年代初就有人这么做——手动把邮件加白名单,或者让对方用某种可以带外分享的关键词或令牌绕过列表,有点像验证码。

thesuitonym 随后给出了本帖最有分量的经验判断:「这绝对可行,有几家公司这么做,我告诉你:人们讨厌它。」BeetleB 反驳说他这么做了将近十年,只有一个人抱怨过,「我很惊讶人们愿意为了联系我而跳过这些圈套」,并附上了自己 2018 年的方案说明。thesuitonym 回敬:「我很高兴它对你有用,但绝大多数人不是你,他们讨厌它。」BeetleB 只回了三个字:「需要引用。」

PaulRobinson 给出了最完整的历史证词:「我们」在九十年代末试过这个。他在 ISP 时代写过 exim 配置来做这件事,有两种方式。一是「收件人在你于此 URL 认证自己是合法发件人之前不会收到这条消息」——结果导致人们收不到他们在意的 no-reply 地址来的邮件(银行、电商等)。二是「此发件人给你发了一封邮件,主题是这个,第一段是这个。点这里加白名单,点这里加黑名单」——首次设置时产生了大量用户不喜欢的翻搅。他指出即使在今天的 SMTP/IMAP 世界里把它烤进协议也是可行的,但会遭到邮件服务商的抵制,因为他们中有些人靠把数据卖给营销机构赚钱——「你知道的,比如 Google、Microsoft、Yahoo」。他还提到多年来包括 IETF 层面在内有过其他方案,包括数字邮资(发件人付费发邮件,你的服务器收钱,可以拒收未贴邮票/未付费的邮件),但这是常见的网络效应问题:在被广泛支持之前它不会「粘住」。「被采纳的东西基本上就是 Google 喜欢的东西,句号。」

philipwhiuk 用一句话概括了怀疑:「是啊,『请求』文件夹就变成新的收件箱文件夹了。邮件客户端已经会高亮/过滤你联系人里的人了。」jancsika 用一个精妙的魔术类比表达了同样的意思:魔术师有两摞牌,一摞高的「垃圾邮件」牌和一摞小的「收件箱」牌。他把两摞分开,为新的「请求」牌腾出位置。为了开始这一摞,他用一只手从收件箱那摞里拿起五张「请求」牌,同时用另一只手不着痕迹地把整摞垃圾邮件牌推到他刚腾出的位置上,然后把手里那五张从背后传到另一只手亮出来,洗进现在已经很高的「请求」牌堆里。「铛铛!」他还给「如果是我重新设计邮件,我会长时间认真思考不同用例和工作流,从一份 RFC 开始」配了第二个魔术:魔术师把 17 摞乱七八糟的牌扫下桌子,然后展示他捡起的前 15 张牌如何能更容易地排成三摞。瞧!所有人鼓掌。观众往帽子里放钱的时候,迂腐的人留下来看着魔术师把剩下的牌捡起来,等下一场观众到来时,桌上已经有 18 摞乱牌了。

Multicomp 提出了一个自嘲式的扩展:可以加一层「朋友的朋友」信任——Alice 收到 Bob 的邮件,她不认识 Bob 所以进请求箱;但 Charlie 认识 Bob 并说「是的这人是正经的」,而 Alice 配置了信任 Charlie 的邮件推荐最多两度分隔,于是它进了收件箱并附带说明。「然后砰,我们蹩脚地重新记起了 20 年前的信任网。」

teddyh 贴出了本帖最杀伤力的一条:「更多人应该了解他们的历史。这份文本在九十年代末垃圾邮件开始成为问题时流传甚广。所有人和他们的狗都有自己的『终极解法』,他们都以为自己的显然是对的,但它们或多或少同样不可行。」并链接了那份著名的「垃圾邮件解决方案清单」。

邮资与身份成本的经济学

BeetleB 提出了本帖最完整的替代方案:「我不想复制邮件,我想修好它。发邮件不该免费。给一个人发邮件应该真的真的便宜(比如一分钱的零头的零头),但你发得越多就指数级更贵。人们不该在没有你事先批准的情况下给你发邮件(批准可以随时撤销)。收件人应该能加收附加费。我应该能对烦人的人收很多钱,对朋友几乎不收。给我发烦人东西的人应该付更多钱来买我的注意力。突然之间,不加思考地转发那篇蠢文章(甚至没读过他们发的那篇文章)就会被三思了。」

dfabulich 给出了最有力的经济学反驳:「问题在于创建假身份的成本。只要创建假身份有一个固定成本(随身份数量线性增长),就没有办法对『同一个人』发更多邮件收指数级更高的费用。他们只会创建新身份来发新邮件。」他指出有人意识到这点后会开始设想如何禁止假身份(禁止真正匿名的邮件),但那需要一个中心化的身份认证机构,而系统里的许多参与者正在积极避免这一点。「如果你想要一个没有垃圾邮件的中心化消息发送机构,那你就该直接用一个流行的中心化消息应用。每个消息应用都被一个中心化机构控制,有好有坏;普遍共识是垃圾邮件在中心化消息应用上的问题小得多。但中心化权威是对抗垃圾邮件的极高代价。」他描述了今天的现状:邮件客户端读邮件并试图分类,给每封邮件一个垃圾分数、超过阈值就隔离;我们只按顶级域名追踪邮件身份,而域名确实有成本;邮件可以用 DKIM/SPF 签名,我们可以惩罚不签名的邮件。「我们没有『中央权威』,但有非常流行的邮件服务,遵循幂律分布,那已经足够接近了。如果 Gmail 认为你的域名声誉太低,你想给 Gmail 上的任何人发邮件就得买个新域名。没有一个官方的中心化权威,我认为这大概就是它能达到的最好状态了。」

BeetleB 部分同意但反击:「Google 不该来决定这个。你作为个人应该控制过滤。」

inigyou 补充了声誉机制的模糊假阳性问题:假设一百万 Gmail 用户带邮件确认地订阅了你的通讯,两个月后你发一封,其中一千人会被激怒并举报为垃圾邮件,尽管他们明确订阅过。「砰,你现在被 Gmail 封了。」他还对 BeetleB 的阶梯定价给出了一个直接的攻击:「我是 10000 个人,每人发 1 条消息,就拿到了每条消息的便宜价格。」BeetleB 回应:「你忘了对每个没把你放进批准列表的收件人收的那 5 分钱。」

choilive 提供了一个现实数据点:发邮件本来就不免费,只是成本对普通人被补贴/隐藏了,而且便宜到可以白送——对于做事务性邮件的人来说,AWS SES 的成本约每封 0.0001 美元,「已经是你说的那个一分钱的零头的零头了」。

miki123211 提出了一个不需要微支付的替代设计:把问题一分为二。首先要求所有消息包含一个 Automated: 0|1 头,最终对不包含它的服务商降权/封禁,就像现在对 DKIM、SPF、DMARC 那样;对 Automated: 1 的消息,要求经收件人服务商中介和验证的知情同意。「对每条消息都要求预批准是不现实的,因为很多人真心想要来自半陌生人的人对人接触;另一方面,不带验证的同意要求是无效的,因为假装同意太容易了。这个设计把垃圾邮件问题拆成两个更可解的子问题:检测把自动消息标为非自动的说谎发件人(用现代 AI + 基础统计分析很容易),以及为诚实的自动发件人验证同意(只需要一个协议)。」BeetleB 追问:「你怎么处理把它设成 0 的恶意行为者?」

raggi 则给出了一条行动派的回应:「老实说我们就该直接干。Maddy 和 Stalwart 的并发足够便宜、可扩展性足够好,它们可以轻松地在服务端基于本地和全局启发式的组合延迟 SMTP 接受。我们也可以轻松开始产出一个可审计的全局启发式,今天就开始原型化这个方案。随着时间推移社区将不得不决定如何与『卡巴尔』合作,或者更确切地说,卡巴尔将不得不学会重新与社区接触。直接开始。」

「为什么是 HTTP」以及协议层面的技术批评

thesuitonym 给出了本帖最简洁的否定:「『让我们在 HTTP 之上设计邮件的继任者』——你可以在这儿打住了,我听够了。不是所有东西都是超文本。」作者 andros 亲自回敬了一句带刺的话:「通常,消息灵通的人只读标题。」beej71 替 HTTP 辩护:「而且 HTTP 传输的东西远不止超文本。就能力而言,对这个用例它似乎是个合理的选择。」inigyou 追问:「为什么,加这一层带来什么好处?你完全可以直接开个 socket 往里发 JSON,你不需要这一层。但如果这层带来好处,那你就该用,只是你得解释清楚好处是什么。」beej71 回答:既然是邮件,我们大概想发几种不同类型的内容,而 MIME 已经烤进 HTTP 了;另外与邮件风格的头共通也很好。

philipwhiuk 对发现机制提出了直接的成本对比:旧版本是「DNS 查询 MX 记录」;新版本是「DNS 查询 A 记录」+「HTTP 请求 .well-known/htmp/known_hosts」。「不太确定这为什么被认为是改进?」他还追问「同一域名的每个邮箱在不同服务商」为什么有用甚至算「好」。rzerowan 认为这是为终端用户的灵活性和便利:改 DNS 记录比往网页上加一行文本再打默认端点更麻烦,就像 Let’s Encrypt 用 .well-known 端点做了最简单的设置,用户可能除了最初的 A 记录之外没有 DNS 访问权。inigyou 反问:「为什么一个比另一个更麻烦?DNS 也只是一个文本文件。而且你可能根本没有 Web 服务器。为什么邮件服务器要被要求同时是 Web 服务器?如果那个域名的 Web 服务器已经是一套完全独立的系统,你现在强制它与邮件系统绑定了?」stackskipton 更直接:「这不是个好主意,事实上我会说它很糟糕。我们有 MX 记录,不如就用它们。如果不用,就用 SRV 记录。要求邮件服务器介入域名的根是个糟糕的主意。」8organicbits 则站在作者这边补充了事实依据:邮件今天已经在用一个到 https://mta-sts.<domain>/.well-known/mta-sts.txt 的 HTTP 请求(RFC 8461),「依赖 HTTPS/TLS 而非 DNSSEC 正是你看到这种做法流行起来的一个主要原因」。这引出了一段关于 DANE 的支线:winstonwinston 说 MTA-STS 很糟糕,应该用 DANE;tptacek 回击:「所以基本上是所有人?DANE 几乎没有采用率。我觉得到现在可能字面意义上只有 Microsoft 在用。」8organicbits 用自己 2024 年的调查数据补充:Cloudflare 用 DANE 的域名比 Microsoft 还多,但 DANE 确实没有被广泛采用,Google 不支持最为显著,因为用他们服务的域名数量巨大。

AKSF_Ackermann 提出了一条精准的技术批评:「内容寻址的邮件会破坏邮件列表,因为它们需要能加 subscribe/unsubscribe/list id 之类的头。DKIM 允许你挑选签哪些头是有原因的。」(作者在更新版文章里专门回应了这一点。)kamma4434 反问:「我们还需要邮件列表吗?」ninalanyon 一句话终结:「Linus Torvalds 需要它们。就我而言这足以成为它们存在的理由。」

jerf 给出了本帖最具体的实现层建议:他建议重新考虑完全保留当前格式,而且「你不会想把整封邮件嵌进 JSON。太多过去、现在和未来的解析器倾向于在做任何事之前先把整个 JSON 文档解码进内存,所以你会强迫整封邮件文档在规模上被驻留内存,这会给你带来大问题」。他推荐两种替代:一个定义邮件包含哪些部分的 JSON 头,后接一个正常的 MIME 文档(这在 HTTP 里对其他使用该格式的东西也完全正常);或者顶层继续是 MIME 文档,规定第一部分必须是包含头的 JSON 文档。「用 JSON 替换头总体上是个好主意。」zahlman 质疑:即便你的系统一次把一整封邮件读进内存,也不意味着它会同时加载大量邮件。jerf 的回应值得一记:「在思考这样一个标准时,思考『你的』系统是致命错误。你必须思考所有系统。而且是的,世界上确实有同时加载大量邮件的系统。显然有。很多。不仅如此,如果一个新标准无法捕获其中一些,它将永远是个毫无价值的小众标准,因为那些恰恰是你需要让其支持新标准的节点。」

baudehlo(Haraka——一个流行的开源 SMTP 服务器——的作者)指出文章漏掉了 SMTP 一个最根本的问题:缺少按收件人的响应。「虽然你或许可以强制每次请求只有一个收件人。我们在 Haraka 里写了个插件来模拟那个,你对每个后续收件人返回 400(临时失败)。缺点是有些来源就是不重试。」

syhol 对身份设计提出了异议:「我不同意『域名控制作为兜底』,正如作者所说『域名不是被拥有的,而是被租用的』,我想把『如果你丢了私钥就得重新开始』这件事正常化。我讨厌我们不断把这么多权威交给域名,那是个如此巨大的弱点。作者自己甚至把密钥轮换链从初始实现里省略了。」

mrsssnake 提出了「用户名是你的公钥,密码是你的私钥」的老想法(类似 .onion 地址的工作方式),端到端加密和账户所有权开箱即得,需要好记的地址就在上面建别名。jcgl 给出了本帖最有力的一条概念性反驳:「为了任何应当被广泛采用的东西,把身份与密码系统紧耦合应当被彻底摒弃。首先,这类系统总是要求无限期存活的秘密。轮换密钥(或者整个密码系统——想想未来可能的量子计算机)就是改变身份。因此改密钥就是破坏此前的身份。任何要求用户思考长期秘密的东西都是对用户不友好的,会导致脆弱的系统。其次,公钥即地址的人体工学站不住脚。你能想象把 .onion 地址印在广告牌和名片上吗,更别说口头分享了?绝对不行。」他的结论是:「说到底,身份和命名是根本上属于人的关切。如果你试图用纯技术方案绕开这一点,你最终得到的只是一个无法充分反映身份对人们意味着什么的系统。好的系统支持这一点(DNS、邮件);坏的系统与之对抗(加密货币、nostr)。」

「你永远替换不掉邮件」:网络效应派

8organicbits 提出了最务实的一条:网络效应让邮件很难被替换,几乎每个上网的人都有邮箱地址。「如果这能包含一条迁移路径,与 SMTP 向后兼容,我认为它成功的机会会大得多。」他还指出现代邮件已经依赖 HTTP(MTA-STS 用 HTTPS/TLS 改善传输加密、Web Key Directory 用 HTTP 分发公钥),「个人认为这些对 SMTP 的渐进改进比替代品更有希望,但无论怎么建,我们都值得更好的邮件」。

abdullahkhalids 提出了一个具体的十年迁移路径:NewEmailServer 能用 Email 或 NewEmail 两种协议收发;发送前检查一个类似 DNS 的目录看收件人是否在另一台 NewEmailServer 上,是则走 NewEmail,否则走 Email。完全向后兼容,一旦 Google/Microsoft 转向 NewEmail,其余会很快跟进。montagg 指出这基本就是 iOS Messages 对 SMS 做的事,并给出了一条重要的方法论提醒:「注意到这并没有导致所有人都用 iOS Messages 作为通信协议,但它确实让用户在没用它时知道,带着某种内在的社会压力。在处理任何网络效应和既有用户行为——尤其是像邮件这样根深蒂固的——时,我强烈建议在使用『只需要』(just)这个词时保持审慎,因为这些是互相强化的效应。想象一个解法与实现一个解法有天壤之别。」他认为思路方向是对的,但缺的那部分是推动力:正面压力(经济、产品意义、说服)或负面压力(经济、社会、监管)。inigyou 则给了个冷水回复:「我想 Gmail 做过这个!Gmail 可以给 Email 或 Gmail 收发消息。Google 和 Microsoft 之间也用某种专有协议对话。我们不该讨论 EEE(拥抱、扩展、消灭)的最佳方式,因为 EEE 及其后果对互联网开放性是一场灾难,我们不想扩大它的传播。」

rbanffy 给出了本帖最长也最被认同的怀疑论:「没有人在另一套标准之上重新发明邮件这个事实,是个很好的指示,说明当前的技术栈没有某些人希望的那么坏。」他用 CMS 做类比:在他的前一段人生里,每个人都基于稍有不同的方法重新发明内容管理系统,因为他们觉得现有的 CMS 太臃肿。「它从提供页面开始,然后你想要多套模板,然后你想要无障碍,然后你想用 LDAP 认证,然后你想把 LDAP 组用作你的组,然后你需要把组绑到角色上,因为组对组织是一回事而角色对 CMS 是另一回事,然后你意识到关系数据库不那么匹配,然后你意识到附上一些逻辑会很方便,而文档数据库不再是个好主意,然后你需要多个内容数据存储,然后你需要在上面加新的工作流,然后……」他的总结是:「魔鬼藏在边角情形里。它们已经被不同的当事人用不同的方式解决了几十年,而且并不总有文档(『因为那只是个简单的东西,就那一次,我们修好了』)。除非你在场,否则你注定会犯同样的错误。」他最后开了个玩笑:「为什么不投入精力去迁移那些跑着几乎每笔银行交易的 COBOL 代码呢?那应该很容易 ;-)」

HumblyTossed 附和:「邮件是那种『就是能用』的技术,但这么多人似乎觉得它需要被『修好』。它总体上非常可靠,人们应该接受这一点并心存感激。事情本可以更糟——它本可以像其他那么多技术一样被屎化。」HDBaseT 反驳:「只有当你用 Google 或 Microsoft 收邮件时它才真的『非常可靠』,因为它们是现代邮件的仲裁者。」inigyou 补充了一个重要的不对称:「自托管接收也非常可靠。只有当你从自己的服务器发送时才可能有黑名单问题。但今天这么多应用是只接收的——每一个网站注册。」

dredmorbius 给出了一段更平衡的判断:「我从八十年代就在用邮件。我……见过很多考虑不周的修复它的提案。邮件有极其大量的锁定,这个事实并不意味着它没坏,只是说明它恰好处在一个该死的局部最优里,要到达任何更可取的状态都有大量的爬山要做。就像演化不是目的论的、无法识别某个它想演化向的期望状态,而必须通过适应度的逐步增量提升前进一样,协议和标准也是如此。这不是说 SMTP 加上那些零碎没有解决某些问题,有时甚至很优雅。但从那里跳到『它没那么坏』……那步子相当大。我读了文章也在读评论。有些想法我喜欢,有些我质疑。我会说这个提案看起来比我见过的许多别的提案考虑得更周到。」

citizenpaul 提出了政治经济学层面的判断:「问题不在于让它跑起来。问题在于邮件此刻是一个被俘获的系统,真正的工作是大服务商控制的各种声誉管理流程,否则你无法给他们收发邮件。他们也没有真正的兴趣让你做自己的邮件服务商,所以这只是推石上山,为了什么?为了省下一年不到 100 美元、搭在别人服务商上用自定义域名?还是直接用免费服务商?」calvinmorrison(在服务商工作过)给出了内部视角的纠正:「心理完全不是那样。第一优先级是让邮件流动。第二优先级是安全、垃圾邮件、声誉的渐进改善,而且是很遥远的第二。另一件事是,服务商已经有人在做邮件标准、在生态里工作。所以一旦你在里面,跟那些知道发生了什么、知道工具、不用看手册就凭直觉知道事情怎么运作的人在一起,改变的欲望就变少了。」stackskipton(某大服务商的前邮件首席)也澄清了黑名单的动机:「大多数时候不是服务商在『哈哈哈,去他的小人物』式地拉黑,而是『是啊,他们托管在声誉糟糕的 IP 段上而且垃圾邮件发送者都是彻头彻尾的骗子。我拒绝相信他们说的任何话,句号。』如果你有自己的 /24 或更大,你可以成为邮件服务商。而且这生意利润太低,小企业不值得来颠覆。」

关于 GUI 的支线:也许协议根本不是瓶颈

aboardRat4 提出了一个被作者明确反驳的观点:「最重要的不是协议,是 GUI。目前邮件的 GUI 在所有平台上无一例外都很糟糕。如果/当一个像样的 GUI 出现时,协议会跟上。」作者 andros 不同意:「GUI 不能在协议规范之前或之中构建。事实上这是最不该有权重的部分。」他还说 JMAP 灵活、成熟、易于与当前技术连接,是更好的选择。inigyou 用一个二选一逼问:「你有两个系统。一个有超棒的证书轮换和糟糕的 UI。一个有糟糕的证书轮换和超棒的 UI。哪个会占领世界,哪个永远只有 10 个用户?」作者回答这是伪二分法,两者长期都活不下来,「就像问你想要一辆引擎好但方向盘糟的车,还是操控好但引擎糟的车?」inigyou 的回复堪称本帖最佳一句反驳:「开丰田的人比开法拉利的人多。」

dewey 也不同意 GUI 论:「当邮件是一个开放协议、上面建了成千上万不同的应用时,你怎么能这么说?终端 UI、Web 界面、聊天界面等等——这本该是那种人人都有一个 GUI 的情况。」inigyou 简短作答:「而且它们都很烂。」

不过 aboardRat4 在被 isaachinman(在这个领域创业,做 marcoapp.io)追问「你到底讨厌现在的 GUI 什么」时,给出了本帖最具体的一份产品需求清单:没有一个对 managesieve 有好的(或任何)支持,而没有 managesieve 或其他自动打标机制,邮件就只是一大堆垃圾;即便 Gmail 也不支持在移动端 App 里编辑过滤器,「2026 年了,这很荒谬」,而且它们的过滤器严格弱于 Sieve;没有一个有「从一封消息快速生成过滤规则」的功能;没有一个能从邮件列表大致自动生成论坛式界面;除了 Delta Chat 之外没有一个支持把消息线性地一条条往下显示而非一次一条——而「一次一条」也很重要:给老板写信时他把消息当文档写,给女朋友写信时他常常想要一行回复;过度引用管理得很糟,Gmail 把前一条消息藏在一个按钮下(很慢),但大多数时候根本不需要过度引用,应该有「不引用」和「自动剥除引用」的按钮。isaachinman 的回复很短:「会把这些需求快速通道处理进 Marco。」

ccamrobertson 从另一个方向提出了对首次接触同意的产品级担忧:「我喜欢今天的邮件运作起来更像一个邮箱而不是 WhatsApp 或 Telegram。虽然数字(或纸质)垃圾邮件很讨厌,我不喜欢把每个发件人都扔进一个『未读』箱直到我批准的想法。我在 X 和 Telegram 这类应用里一直会漏掉未读。作为第一步我会聚焦在类似广泛的 S/MIME 支持上。不幸的是我怀疑最大的邮件服务商没有动力这么做,因为那会打乱他们的商业模式。」

TheOtherHobbes 除了「未知请求会被埋在垃圾里,这是我们已有的问题但更糟」之外,还提出了一个具体的工作流需求:「我不想要一条无限的线程对话。我想能按主题拆分——也许还能归档和导出——不同的对话。我最近处理一些法律事务,需要把某段对话的副本转给律师。结果这异常困难,因为邮件客户端会引用之前的对话。你想要一条关于某个特定主题的干净的评论与回复线索,而你得不到。」

关于网站本身:一场关于「设计愿景」的正面冲突

需要如实记录的是,本帖有相当长的一条支线完全离开了协议设计,变成了对作者网站的批评以及作者的回击。

gostsamo 起头,态度其实相当克制:「不幸的是我在某个时刻停止阅读了,因为虽然想法可能有意思,但包装无法忍受。那个讨人厌的实时访客计数器严重干扰我的屏幕阅读器。我不在乎有多少人在读这篇文章、每 3 秒更新一次,而且不只是数字,还有随机选择的表情符号进入我的语音流。如果你有网站,请不要让你的访客承受这种东西。」作者 andros 立刻道歉并为屏幕阅读器隐藏了计数器,gostsamo 也道谢并说「错误总会发生」。

但接下来的交锋就没那么友好了。jeffbee 说:「『我有个改变现代生活基本体验之一的想法』和『我的网站讨人厌又有敌意』这个组合,对我来说不太成立。」作者回应说整个网站是无障碍的,他投入了充分时间,这是个小疏忽,「但我不会称之为敌意」。hju22_-3 反驳:「就字面而言?也许。就精神而言?嗯。奇怪的是你在别处拒绝批评。无障碍不只是一个勾选框,而是要考虑和测试实际使用。」

flexagoon 提出了移动端的问题:面板「一直盖住半个页面」。作者说往下滚它们就都会消失,并问是不是禁用了 JavaScript。zahlman 详细描述了禁用 JS 后的行为:顶部和左侧栏保持装饰性且不打扰,但访客计数器浮在页面右下方上方很远的位置;随着页宽收窄,左侧栏和计数器换边,顶部的一堆内容又被加进底部新的一栏;最终侧边组件之间的水平空间变得无关,它们变成额外的底栏;到那时可能 40% 的垂直空间被用于导航和其他闪亮玩具。「这真的很烦人,而且整个体验在不同宽度下不一致。」作者的回复带了明显的火气:「如果你想消除任何摩擦,我建议启用 JavaScript。或者你可以用终端模式读它:curl -H "Accept: text/markdown" [URL]。」以及后来的:「至于其他几点,那些是设计选择。谢谢你的反馈。附言:未来的互动请像其他所有人一样私下给我发消息。这里不是讨论这个的合适地方。」

flexagoon 继续说:停止滚动后哪怕往上滚一点点(不小心,或者想回看漏掉的东西),它们又会出现,「我认为唯一可能的好 UX 是给个显示/隐藏按钮」。作者不同意:「最低的交互成本是滚动,那是自然、连续、几乎不自主的手势。必须点或按一个按钮要求用户停下、评估标题是否有趣、并决定付出努力去点。」flexagoon 抓住了他自己的话反击:「正是——『几乎不自主』,所以把大型 UI 位移绑在那个不自主手势上,会让体验感觉非常不可预测。」他还对「启用浏览器阅读模式」的建议提出了原则性反对:「阅读模式是个 hack,只有在站点本身不可读时才需要。你不该必须启用它才能读内容。而且如果网站没测过,它也不总是工作良好——比如在你的网站上,它移除了正文里的所有图片。」他最后给出了本帖最尖锐的一句:「刻意用一种不让用户决定他们是否想要它的方式做事,这叫暗黑模式(dark pattern)。它离那些试图诱骗你接受营销通讯的复选框不远。『我们不能给用户一个选项去想他们是否想要我们的邮件!如果他们不想,为什么不直接用他们邮箱的垃圾过滤?』你自己可能不这么看,但巨大的、指向你简历、演讲和课程的链接恰恰就是那个——一个盖住半屏的广告。你有多个人告诉你体验很糟,你也问了为什么,但当人们给你解释时你又反驳回去。当然这没问题,那是你自己的网站,你可以随心所欲、不必迎合任何人。但那并不会让读者体验变得不那么糟。」作者只回了一句:「谢谢你的反馈,我记下了。」

dredmorbius 也报告了移动端的问题并说他很快用了 Firefox/Android 的阅读视图。作者说移动端交互是类似的,「这不是 bug,是设计」,如果他能顺利读完文章他就满意了。dredmorbius 回应:「那就是在移动端。如果那是意图,结果是高度令人恼火的。」作者:「我觉得你太关注你的最佳实践范式,而不够关注我的设计愿景。」dredmorbius:「或者也许恰恰相反。内容是扎实的。呈现方式非常碍事。」作者:「呈现方式是足够的,它只是不合某些口味。」

hju22_-3 写了本帖对此最长的一段回应,指出了「设计愿景」这个挡箭牌的问题,并给出了具体的可用性场景:「取决于视口,你的面板确实碍事,比如在我的屏幕上占三分之一。如果你要隐藏面板,就好好隐藏。顶部和底部自动显示,好吧,不过在移动端它们可以更小。但你至少可以考虑小视口上的 UX。如果我在阅读时想往上滚一点,它们就弹出来,我不得不再往下滚才能藏起来——意思是我得滚到比预期更高的位置,才有足够空间往下滚。另一个常见的用户模式是缓慢持续滚动,一个微小的向上抖动就让它们重新出现,却需要相对巨大的向下滚动才能藏起来。你的站不是唯一这么做的,但这就是糟糕的设计。愿景也好、没愿景也好,那不是理由,只是借口。还有,左撇子怎么办?更容易误点进消息框,键盘会弹出来又得关掉。再加上它体积占了拇指滚动空间的大部分。人们告诉你这很恼人,不合理吗?不。而这还没考虑那些因为各种原因在控制设备上有困难的人——不是要求你『向后弯腰』,而是至少把这些纳入考虑。」

作者的最终回复是四点:「首先,这类『问题』应该像人们通常做的那样私下解释,而不是公开在 Hacker News 上。对我来说这已经大大削弱了你的反馈。其次,这篇文章是被设计成从上往下读的。第三,好设计没有硬性规则,黑白之间有一整片灰色光谱。第四,谢谢你的反馈。虽然看起来不像,但我几天前就记下了它去反思。但你的坚持正在打消我的积极性。」

aboardRat4 用一句话给这条支线做了总结:「它们在我眼前闪烁,让我分心无法阅读,而且容易误点。总的来说,给页面加移动元素零理由。」

其他值得一记的碎片

inigyou 贡献了本帖最简洁的一句总结性观察:「ActivityPub 字面意义上就是 HTTP 上的 SMTP。」astrodust 呼应了文章里的那个历史细节:「这里的反讽是 HTTP 头直接继承自 RFC822 邮件头。」zdw 提出了一个方向相反的思路实验:「我会往相反方向走——HTTP 该变得更像 SMTP。想想看:除了 HTTP 之外,几乎所有其他标准协议(DNS、SMTP 等)是怎么在没有服务端负载均衡的情况下大规模存活的?谢天谢地,由于 happy eyeballs 和相关的客户端重试机制,我们正在往这个方向走。」dinkelberg 一句话点出了作者后来在更新中修正的问题:「复制了 PGP 元数据不加密的错误。」bellowsgulch 给出了最不留情面的一句:「这在每个方面都可测量地更差,哪怕只因为你说了要扔掉所有人现有的邮件栈。不,没人想这么做。」而作者自己在回应社区建议时把定位说得很清楚:「我的目标不是取代任何东西;这是一个(博弈)理论练习。资源和影响力更大的公司试图提供改进的方案却不留痕迹。用标准工具能不能创造一个更好的方案?能!:)」

mrnotcrazy(在这个领域工作)给出了本帖最有智慧的一段收尾观点:「邮件不只是一项技术,它是一个社群。已经有大量替代它的技术尝试,但它们没能撼动邮件,因为它们只聚焦在技术层面——正如你发现的,技术在很大程度上是个已解决的问题,虽然把细节做对可能很难。你需要社群的认同,而社群不只是用户,还包括使用邮件的企业和组织,从 CEO 到教会领袖每一个人。修好邮件是不够的,你必须让社群认同才能带来有意义的改变,而我在这里没看到任何能做到这一点的东西。这不真的是批评,只是我提供的一点洞见。我在这个领域工作,而我们正试图退出,因为管理邮件很糟糕。我很想要新东西取代它,但社群听过太多从未兑现的承诺,那时候你要么需要一个更好的承诺(比看起来难得多),要么需要信誉——而在当前气候下那可能非常困难。这不是无解的问题,那种问题不存在,但有时候解决问题所需的杠杆比你独自能够到的更远,而这就是其中之一。」