- 기존 OpenBSD 개발자들의 관심이 줄면서 정체됐던 relayd(8)와 httpd(8) 개발이 실제 운영 수요를 가진 기여자들의 참여로 다시 활발해짐
- LLM이 코딩 지식을 대신하는 시기일수록 직접 C를 익히고 도전해야 한다는 판단에서 출발해, relayd(8)의 수제 imsg 체계부터 현대화함
- 2024~2026년
tech@메일링 리스트의 미반영 패치와 기존 GitHub 미러의 오래된 이슈를 대부분 정리하고, 신규 기여자를 위한 Git 미러와 README도 마련함 - relayd(8)는 안전한 imsg API와 TLS·요청 파싱 보안을 강화하고 재로딩 충돌을 수정했으며, httpd(8)는 요청 스머글링 방어, 사용자 정의 헤더, 정적 파일 캐시 제어 등을 추가함
- 두 데몬의 보안·안정성·확장성이 함께 나아졌지만 작업 과정에서 백로그도 늘어나 아이디어와 피드백을 계속 받고 있음
관심을 잃은 프로젝트를 다시 살린 배경
- OpenBSD 7.8 주요 변경점에서 다뤘듯
relayd(8)와httpd(8)개발은 정체된 상태였음- 여러 기여자가
tech@메일링 리스트에 패치를 보냈지만 저장소에 반영된 것은 거의 없었음 - 기존 OpenBSD 개발자들이 두 데몬에 더 이상 관심을 두지 않은 것이 주된 원인이었음
- 여러 기여자가
kirill@와 함께 두 데몬을 정기적으로 사용하며 실제 활용 사례를 다뤄온 경험을 바탕으로 적극적인 개발을 시작함- 복잡한
httpd(8)·relayd(8)구성으로 OpenBSD 고객을 지원해야 하는 실무 수요도 직접적인 동력이 됨
- 복잡한
LLM 시대에 C로 돌아간 이유
- 가장 큰 계기는 LLM의 등장이었음
- 과거에는 현대적인 C++ 코드를 전문적으로 작성했지만, 이후 솔루션 아키텍처와 플랫폼 엔지니어링, 팀 구축으로 옮겨가며 실제 코드를 거의 쓰지 않게 됐음
- 주로 선언형 YAML을 작성하고 OpenBSD
ports(7)를 위해 코드를 읽고 포팅하는 정도에 머물렀음
- “코딩은 해결됐다”는 주장과 달리, 지식이 외부로 위임되는 시기일수록 직접 그 지식을 갖추는 일이 더 중요하다고 판단함
- C++와 Rust는 어려운 판단 일부를 대신하지만 C는 그렇지 않다는 점을 도전 과제로 삼아
relayd(8)와httpd(8)에 기여하기로 결정함
동기보다 규율로 이어간 기여
- 오픈소스 기여는 몇 주 만에 좌절로 끝날 수 있지만, 초기의 고통스러운 단계를 지나 꾸준히 작업할 수 있는 상태에 도달함
- 처음에는 코드베이스를 수동적으로 읽으며 여러 부분에서 낙담함
- 부족한 주석과 일부 좋지 않은 설계, 복잡하게 얽힌 코드가 원인이었으며, 이것이 C 코드의 특성인지 개인의 경험 부족 때문인지는 아직 알 수 없음
- OpenBSD 데몬 유지보수자들과 논의한 뒤 수제로 만든 imsg 메시지 체계를 현대화하기로 함
- 먼저
relayd(8)에 집중한 뒤httpd(8)로 범위를 넓힘 - 현대화 작업 자체를 코드베이스를 이해하는 수단으로 활용함
- 먼저
미반영 패치와 오래된 이슈 정리
- 2024~2026년
tech@메일링 리스트 기록을 검토해 미처리 패치와 이슈를 수집했으며 대부분 처리한 것으로 판단함 - 두 데몬은 현재 OpenBSD에서 은퇴한 Reyk Floeter가 처음 개발했음
- Reyk가 관리하던 relayd GitHub 미러의 오래된 이슈도 검토함
- 모든 이슈는 종료하거나 수정할 수 있는 상태이며, 일부는 더 이상 유효하지 않음
신규 기여자를 위한 Git 미러
- 기존 GitHub 미러에서 착안해 신규·젊은 기여자의 진입을 돕고 OpenBSD 메일링 리스트 밖의 커뮤니티와도 접점을 만들기 위한 별도 미러를 구축함
- CVS 트리를 Git 미러로 사용하며, 개발은 Gothub 인스턴스에서 먼저 진행하고 나머지 저장소로 동기화함
- Primary: https://rsadowski.gothub.org/
- Mirror: https://codeberg.org/rsadowski/relayd
- Mirror: https://github.com/sizeofvoid/relayd
httpd(8)에도 같은 방식을 적용하고 필요한 정보를 담은 상세README.md를 작성함
relayd(8)의 현대화와 코드 품질
- imsg 체계를 더 안전한
imsg_get_data,imsg_get_type,imsgbuf_get접근자로 전환함 - imsg 페이로드를 읽는 전체 과정에 적절한 오류 처리를 추가함
bgpd와 일관되도록 로깅과 주석을 표준화함- HTTP 시작 줄 처리를 전용 함수로 분리해 코드 구성을 개선함
knfmt형식을 적용함
relayd(8)의 보안 강화
- 기본 TLS 암호군을
HIGH:!aNULL에서secure로 변경함 - CA 권한 분리(privsep) 엔진에 ECDSA 지원을 추가함
- 중복
Content-Length헤더는 HTTP 400 응답으로 거부함 - RFC 9112 5.2에 따라 파서 차이를 막기 위해
obs-fold헤더를 허용하지 않음 - 프로세스 ID를 검사하고
IMSG_CTL_PROCFD를 부모 프로세스로 제한함 - 민감한 비밀번호 데이터 삭제에는
explicit_bzero를 사용함
relayd(8)의 버그와 안정성 개선
- 충돌을 유발하던 재로딩 경쟁 조건을 수정함
X509_dup,config_purge,tls_cfg와 관련된 여러 메모리 누수를 제거함- NULL 검사와 경계 검사를 바로잡음
- OpenSSL 실패에 적절한 오류 처리를 추가함
- TLS 실패 시 OpenSSL 오류 큐를 비우도록 변경함
relayd(8)에 추가된 기능
MKCALENDARHTTP 메서드를 지원함- 여러 리스너에서 TLS를 사용할 수 있게 됨
- 이름 해석이 가능한 여러 주소를 지원함
- 인증서와 키, OCSP staple의 경로를 명시적으로 설정할 수 있음
- HTTP 상태 확인 요청에
User-Agent를 설정함 - 본문이 없는 HTTP 응답을 올바르게 처리함
httpd(8)의 현대화와 코드 품질
proc.c를 새로운 imsg API로 전환해relayd(8)와 일관성을 맞춤- 향후 구성 옵션을 쉽게 확장할 수 있도록 토큰 순서를 변경함
bgpd와 일관되도록 로깅을 표준화함- 중복 코드와 빈 함수를 제거함
knfmt형식을 적용함- 내장 기능 처리를 전용 함수로 분리함
httpd(8)의 보안 강화
- 기본 TLS 암호군을
compat에서secure로 변경함 - 요청 스머글링 공격을 막기 위해 CL.TE 요청 프레이밍을 거부함
- RFC 9112 5.2에 따라
obs-fold헤더에 HTTP 400으로 응답함 Content-Length와Transfer-Encoding헤더가 동시에 존재하면 오류로 처리함- 추가 보호를 위해 부팅 시 무작위 재링크를 수행함
- 프로세스 ID를 검사하고
IMSG_CTL_PROCFD를 부모 프로세스로 제한함 - 응답에서 서버 식별 정보를 숨기는
no banner옵션을 추가함
httpd(8)의 버그와 안정성 개선
- HTTP 요청의 suffix range 처리를 수정함
server_http_time()이 GMT 시각을 올바르게 출력하도록 고침- 매뉴얼 명세에 따라
timegm(3)의 오류를 검사함 chunked transfer-encoding을 사용하는 업로드 문제를 해결함- location의
fcgiparams가 두 번 전송되지 않도록 수정함 dispatch_parent에 적절한 오류 처리를 추가함- 중단 응답을
bufferevent를 통해 올바르게 비우도록 변경함 scan-build가 발견한 불필요한 저장을 제거함- 데이터를 복사하기 전에
return_uri_len을 검증함
httpd(8)의 신규 기능과 남은 작업
- 사용자 정의 HTTP 헤더를 지원함
- 더 나은 구성 상속을 위해 location에서
gzip-static을 상속함 - 더 많은 플래그 옵션을 수용하도록 서버 플래그를 64비트 정수로 확장함
- 정적 파일에 대한 캐시 제어를 추가함
- 작업을 진행할수록 백로그가 늘어났으며, 향후 개발을 위한 아이디어와 피드백을 계속 받고 있음