行尸走肉:relayd(8) 与 httpd(8) 的持续演进
Dead Software Walking: The ongoing evolution of relayd(8) and httpd(8)

原始链接: https://rsadowski.de/posts/2026/dead-software-walking-relayd-and-httpd/

由于开发者兴趣转移,OpenBSD 的 `relayd(8)` 和 `httpd(8)` 的开发一度陷入停滞。作者出于对精通 C 语言的渴望,以及对“编程已被大语言模型解决”这一论调的挑战,主动承担起这些守护进程的现代化工作。 凭借实践经验和专业架构知识,作者对这些工具进行了系统性的重构。工作重点包括重构遗留的 `imsg` 代码、提升安全性、修复长期存在的错误以及增强功能。关键的安全更新包括:改用“安全”默认 TLS 密码套件、强化 HTTP 解析以防止请求走私,以及实施更严格的进程控制。 为了降低新贡献者的参与门槛,作者改进了文档,并打破了传统的仅限 CVS 的工作流,建立了易于访问的 Git 镜像(Gothub、Codeberg 和 GitHub)。这项振兴工作已经显著提升了这两个守护进程的稳定性和功能,未来还将有更多更新计划。通过拥抱 C 语言的复杂性并投身于规范的开源贡献,作者成功地焕新了这些此前面临停滞风险的关键基础设施。

Hacker News 最新 | 过往 | 评论 | 提问 | 展示 | 招聘 | 提交 登录 Dead Software Walking:relayd(8) 和 httpd(8) 的持续演进 (rsadowski.de) 13 点,tylerius 发布于 4 小时前 | 隐藏 | 过往 | 收藏 | 1 条评论 | 帮助 graemep 8 分钟前 [–] 据我所知,OpenBSD httpd 的编写与 OpenBSD 的其他项目一样,都专注于安全性?我原以为现在比以往任何时候都更需要它。relayd 也是如此。 回复 考虑申请 YC 2026 年秋季批次!申请截止日期为 7 月 27 日。 指南 | 常见问题 | 列表 | API | 安全性 | 法律 | 申请 YC | 联系 搜索:
相关文章

原文

Start with WHY #

As I mentioned in my OpenBSD 7.8 highlights post, development of relayd(8) and httpd(8) had stalled. Many diffs appeared on the tech@ mailing list from different contributors, but few were committed into the repository. The main reason was simple: Established OpenBSD developers weren’t interested in these daemons anymore. Call it momentum, or timing.

Around the same time, kirill@ and I started working on these daemons more actively. We both use them regularly and have real-world use cases. I support customers with OpenBSD setups that often involve complex httpd(8) and relayd(8) configurations. This practical need motivated me on many levels.

But the biggest motivation is and was LLMs.

For many years, I wrote modern C++ code professionally. Eventually, I moved away from development work and focused on solution architecture, platform engineering, and building teams. I wrote little actual code, mostly declarative YAML. The only coding I did was reading and porting code for OpenBSD ports(7).

Then LLMs arrived. As tech bros claimed “coding is solved”. I realized something: I wanted to challenge myself to code again. I think that at a time when this knowledge is being outsourced, it’s more important than ever to have it! C has always been the language that intimidated me most. C++ and Rust handle the hard thinking for you. C doesn’t. That’s exactly what I wanted: that kind of challenge.

So I decided to start contributing to relayd(8) and httpd(8)().

It is better to conquer self than to win a thousand battles. – Buddha

Discipline beats motivation #

I wrote this section with this title intentionally. We’re talking about open source. Even though I made the decision to contribute, it could have ended in frustration weeks later. “Why am I doing this to myself?“But I think I’m past that point now. The pain actually feels good.

At first, I read through the codebase passively and was discouraged by many parts. Maybe it’s just how C code is written. Maybe it’s the lack of comments. Maybe it’s poor design in places. Real spaghetti code. Or maybe it’s just me. Time will tell.

I talked to the some OpenBSD daemon maintainers and decided to start modernizing the handcrafted imsg message system. I’m focusing on relayd(8) first. httpd(8) will follow. Working on this is a great way to understand the codebase.

My next step was to go through the tech@ mailing list archives from 2024 to 2026. I collected all open diffs and issues. I think I’ve addressed most of them. If anyone has something pending, please reach out.

relayd and httpd(8) were originally developed by Reyk Floeter (reyk@). He is now retired from OpenBSD. I wish him all the best. Reyk also maintained a GitHub mirror: https://github.com/reyk/relayd. I went through the old issues there too. Everything can be closed, fixed, or is no longer relevant.

That mirror inspired me to create my own. I wanted to make it easier for new and young contributors. I also wanted to reach the community beyond the OpenBSD mailing lists. Also, I work on a git mirror of the CVS tree. (CVS and I will never be friends. I started my career with SVN, which was painful enough. No more version control pain.)

Development happens primarily on the Gothub instance. The other locations are kept in sync:

Primary: https://rsadowski.gothub.org/
Mirror: https://codeberg.org/rsadowski/relayd
Mirror: https://github.com/sizeofvoid/relayd

The same goes for httpd(8). I wrote a detailed README.md that covers everything you need to know.

Achievements in httpd(8) and relayd(8) #

Everything should end on a positive note. Let’s look at what the OpenBSD team has accomplished in httpd(8) and relayd(8):

relayd(8) #

Modernization and Code Quality #

  • Converted the imsg system to use new safer getters (imsg_get_data, imsg_get_type, imsgbuf_get)
  • Added proper error handling throughout imsg payload reading
  • Standardized logging and comments with bgpd for consistency
  • Moved HTTP start line logic into dedicated functions for better code organization
  • Added proper knfmt formatting

Security Improvements #

  • Switched default TLS cipher set from “HIGH:!aNULL” to “secure”
  • Added ECDSA support to the CA privsep engine
  • Reject duplicate Content-Length headers with HTTP 400 response
  • Reject obs-fold headers to prevent parser differentials (RFC 9112 5.2)
  • Restrict IMSG_CTL_PROCFD to parent process with ID checks
  • Use explicit_bzero for sensitive password data

Bug Fixes and Stability #

  • Fixed relayd reload race condition that caused crashes
  • Removed multiple memory leaks (X509_dup, config_purge, tls_cfg)
  • Fixed NULL checks and bounds tests
  • Added proper error handling for OpenSSL failures
  • Drain OpenSSL error queue on TLS failures

New Features #

  • Added support for MKCALENDAR HTTP method
  • Support for TLS with multiple listeners
  • Support for multiple resolvable addresses
  • Allow explicit paths for certificates, keys and OCSP staples
  • Set User-Agent for HTTP healthchecks
  • Handle HTTP responses without bodies correctly

httpd(8) #

Modernization and Code Quality #

  • Converted proc.c to new imsg API for consistency with relayd
  • Made token order more easily extendable for future configuration options
  • Standardized logging with bgpd
  • Removed code redundancy and empty functions
  • Added proper knfmt formatting
  • Move builtin logic into dedicated function

Security Improvements #

  • Switched default TLS cipher set from “compat” to “secure”
  • Reject CL.TE request framing to prevent request smuggling attacks
  • Reject obs-fold headers with HTTP 400 (RFC 9112 5.2)
  • Error out on simultaneous Content-Length and Transfer-Encoding headers
  • Random-relink at boot time for additional protection
  • Restrict IMSG_CTL_PROCFD to parent process with ID checks
  • Add “no banner” option to hide server identification from responses

Bug Fixes and Stability #

  • Fixed suffix range handling in HTTP requests
  • Fixed server_http_time() to emit GMT times correctly
  • Error check timegm(3) per manual specifications
  • Fixed uploads using chunked transfer-encoding
  • Fixed location fcgiparams being sent twice
  • Proper error handling in dispatch_parent
  • Drain abort responses via bufferevent correctly
  • Fixed scan-build dead stores findings
  • Validate return_uri_len before copying data

New Features #

  • Add custom HTTP header support
  • Inherit gzip-static in locations for better configuration inheritance
  • Widen server flags to 64-bit integers for more flag options
  • Add cache controls for static files

My personal highlights are in bold.

Honestly, my backlog has grown. But that’s fine. Let’s see where the rest of the year takes us. If you have ideas or feedback, please share them. You know where to find us.

联系我们 contact @ memedata.com