死而未僵的软件:relayd(8) 与 httpd(8) 的持续演进

Lobsters Hottest 新闻

摘要

一篇博客文章,详细介绍了 OpenBSD 的 relayd(8) 和 httpd(8) 守护进程正在进行的复兴与现代化,包括使 imsg 消息系统现代化以及处理待定补丁的努力,作者称 LLM 是促使自己回归 C 语言编程的动因。

<p><a href="https://lobste.rs/s/i6e5wp/dead_software_walking_ongoing_evolution">评论</a></p>
查看原文
查看缓存全文

缓存时间: 2026/07/31 18:50

# 死软件行走:relayd(8) 和 httpd(8) 的持续演进 来源:https://rsadowski.de/posts/2026/dead-software-walking-relayd-and-httpd/ ## 从为什么开始(https://rsadowski.de/posts/2026/dead-software-walking-relayd-and-httpd/#start-with-why) 正如我在我的 OpenBSD 7.8 亮点(https://rsadowski.de/posts/2025/openbsd-78/#daemons)文章中提到的那样,`relayd(8)` 和 `httpd(8)` 的开发曾经停滞不前。许多补丁出现在 `tech@` 邮件列表上,来自不同的贡献者,但很少有被提交到代码仓库中。主要原因很简单:OpenBSD 的资深开发者们对这些守护进程不再感兴趣。你可以称之为势头,或者时机问题。 大约在同一时间,kirill@(https://kirill.korins.ky/)和我开始更积极地研究这些守护进程。我们俩都经常使用它们,并且有现实世界的用例。我为使用 OpenBSD 的客户提供支持,这些客户的设置通常涉及复杂的 `httpd(8)` 和 `relayd(8)` 配置。这种实际需求在多个层面上激励了我。 但最大的动机过去是,现在仍然是 LLM。 多年来,我的职业是编写现代 C++ 代码。最终,我离开了开发工作,专注于解决方案架构、平台工程和团队建设。我很少写实际代码,主要是声明式的 YAML。我唯一做的编码工作是为 OpenBSD ports(7) 阅读和移植代码。 然后 LLM 出现了。当科技老哥们(https://en.wikipedia.org/wiki/Tech_bro)声称“编程已经被解决”时,我意识到了一件事:我想挑战自己,重新开始写代码。我认为,在这种知识正在被外包的时代,拥有这些知识比以往任何时候都更重要!**C** 一直是最让我望而生畏的语言。**C++** 和 **Rust** 会替你完成那些困难的思考。**C** 不会。这正是我想要的:那种挑战。 所以我决定开始为 `relayd(8)` 和 `httpd(8)` 做贡献。 > 战胜自己,胜过赢得千场战役。——佛陀 ## 纪律胜过动力(https://rsadowski.de/posts/2026/dead-software-walking-relayd-and-httpd/#discipline-beats-motivation) 我特意用这个标题写了这一节。我们谈论的是开源。即使我做出了贡献的决定,它也可能在几周后以挫败告终。“我为什么要这样对自己?”但我认为我现在已经过了那个阶段。这种痛苦实际上感觉很好。 起初,我被动地通读了代码库,并对很多部分感到沮丧。也许这就是 **C** 代码的写法。也许是缺少注释。也许是某些地方设计不佳。真正的意大利面条式代码。或者也许只是我自己的问题。时间会证明一切。 我与一些 OpenBSD 守护进程维护者进行了交谈,并决定开始现代化手工打造的 imsg 消息系统。我首先专注于 `relayd(8)`。`httpd(8)` 会紧随其后。做这项工作是一种理解代码库的好方法。 我的下一步是翻阅 2024 年到 2026 年的 `tech@` 邮件列表存档。我收集了所有未处理的补丁和问题。我想我已经解决了大部分。如果有人还有未处理的事项,请联系我。 relayd 和 `httpd(8)` 最初由 Reyk Floeter(reyk@)开发。他现在已经从 OpenBSD 退休。我祝他一切顺利。Reyk 还维护了一个 GitHub 镜像:https://github.com/reyk/relayd。我也浏览了那里的旧问题。所有问题都可以关闭、修复,或者已经不再相关。 那个镜像启发了我创建自己的镜像。我想让新的和年轻的贡献者更容易上手。我也想接触 OpenBSD 邮件列表之外的社区。而且,我在一个 CVS 树的 git 镜像上工作。(CVS 和我永远不会成为朋友。我的职业生涯始于 SVN,那已经够痛苦了。不要再有版本控制的痛苦了。) 开发主要发生在 Gothub 实例上。其他位置保持同步: `` 主要:https://rsadowski.gothub.org/ 镜像:https://codeberg.org/rsadowski/relayd 镜像:https://github.com/sizeofvoid/relayd `` `httpd(8)` 也是如此。我写了一份详细的 README.md,涵盖了你需要知道的一切。 ## httpd(8) 和 relayd(8) 中的成就(https://rsadowski.de/posts/2026/dead-software-walking-relayd-and-httpd/#achievements-in-httpd8-and-relayd8) 一切应该以积极的语气结束。让我们看看 OpenBSD 团队在 `httpd(8)` 和 `relayd(8)` 中取得了哪些成就: ### relayd(8)(https://rsadowski.de/posts/2026/dead-software-walking-relayd-and-httpd/#relayd8) #### 现代化与代码质量(https://rsadowski.de/posts/2026/dead-software-walking-relayd-and-httpd/#modernization-and-code-quality) - **将 imsg 系统转换为使用新的更安全的 getter(imsg\_get\_data、imsg\_get\_type、imsg\_buf\_get)** - 在整个 imsg 负载读取过程中添加了适当的错误处理 - 与 bgpd 保持一致,统一了日志记录和注释风格 - 将 HTTP 起始行逻辑移入专门的函数,以改进代码组织 - 添加了适当的 knfmt 格式化 #### 安全改进(https://rsadowski.de/posts/2026/dead-software-walking-relayd-and-httpd/#security-improvements) - **将默认 TLS 密码组从“HIGH:\!aNULL”切换为“secure”** - **在 CA privsep 引擎中添加了对 ECDSA 的支持** - 以 HTTP 400 响应拒绝重复的 Content-Length 头 - 拒绝 obs-fold 头,以防止解析器差异(RFC 9112 5.2) - 通过 ID 检查将 IMSG\_CTL\_PROCFD 限制为父进程 - 对敏感密码数据使用 explicit\_bzero #### 错误修复与稳定性(https://rsadowski.de/posts/2026/dead-software-walking-relayd-and-httpd/#bug-fixes-and-stability) - **修复了导致崩溃的 relayd 重载竞态条件** - 移除了多个内存泄漏(X509\_dup、config\_purge、tls\_cfg) - 修复了 NULL 检查和边界测试 - 为 OpenSSL 失败添加了适当的错误处理 - **在 TLS 失败时排空 OpenSSL 错误队列** #### 新特性(https://rsadowski.de/posts/2026/dead-software-walking-relayd-and-httpd/#new-features) - 添加了对 MKCALENDAR HTTP 方法的支持 - **支持多监听器的 TLS** - 支持多个可解析地址 - **允许证书、密钥和 OCSP stapling 的显式路径** - 为 HTTP 健康检查设置 User-Agent - 正确响应没有正文的 HTTP 响应 ### httpd(8)(https://rsadowski.de/posts/2026/dead-software-walking-relayd-and-httpd/#httpd8) #### 现代化与代码质量(https://rsadowski.de/posts/2026/dead-software-walking-relayd-and-httpd/#modernization-and-code-quality-1) - 将 proc.c 转换为新的 imsg API,与 relayd 保持一致 - 使令牌顺序更易于为未来的配置选项扩展 - 与 bgpd 保持一致,统一日志记录 - 移除了冗余代码和空函数 - 添加了适当的 knfmt 格式化 - 将内置逻辑移入专门的函数 #### 安全改进(https://rsadowski.de/posts/2026/dead-software-walking-relayd-and-httpd/#security-improvements-1) - **将默认 TLS 密码组从“compat”切换为“secure”** - **拒绝 CL.TE 请求分帧,以防止请求走私攻击** - **以 HTTP 400 拒绝 obs-fold 头(RFC 9112 5.2)** - **在同时存在 Content-Length 和 Transfer-Encoding 头时报错** - 启动时随机重新链接以提供额外保护 - 通过 ID 检查将 IMSG\_CTL\_PROCFD 限制为父进程 - 添加“no banner”选项,以隐藏响应中的服务器标识 #### 错误修复与稳定性(https://rsadowski.de/posts/2026/dead-software-walking-relayd-and-httpd/#bug-fixes-and-stability-1) - 修复了 HTTP 请求中的后缀范围处理 - 修复了 server\_http\_time() 以正确生成 GMT 时间 - 按照手册规范对 timegm(3) 进行错误检查 - 修复了使用分块传输编码的上传 - 修复了 location 中 fcgiparams 被发送两次的问题 - 在 dispatch\_parent 中进行适当的错误处理 - 通过 bufferevent 正确排空 abort 响应 - 修复了 scan-build 发现的死存储问题 - 在复制数据之前验证 return\_uri\_len #### 新特性(https://rsadowski.de/posts/2026/dead-software-walking-relayd-and-httpd/#new-features-1) - **添加自定义 HTTP 头支持** - 在 location 中继承 gzip-static,以改进配置继承 - 将服务器标志扩展为 64 位整数,以提供更多标志选项 - **为静态文件添加缓存控制** 我个人最喜欢的内容用**粗体**标出。 老实说,我的待办事项清单越来越长了。但这没关系。让我们看看今年剩余时间会怎样。如果你有任何想法或反馈,请分享。你知道在哪里能找到我们。

相似文章

使用 M4 减少重复

Lobsters Hottest

本文解释了如何使用 m4 宏处理器,通过创建自定义宏来减少 OpenBSD 的 httpd 配置中的重复代码。

OpenSMTPD 是未来的邮件服务器

Lobsters Hottest

Peter N. M. Hansteen 描述了他转向 OpenSMTPD 的过程,因为 OpenBSD 7.9 放弃了 exim,他认为 OpenSMTPD 是 21 世纪的邮件服务器。

为套接字接口喝彩

Hacker News Top

这篇文章回顾了1983年发布的BSD 4.2套接字接口的历史影响,该接口标准化了网络访问,为现代在线服务铺平了道路。