1 điểm bởi GN⁺ 2 giờ trước | 1 bình luận | Chia sẻ qua WhatsApp
  • Quá trình phát triển relayd(8) và httpd(8), vốn bị đình trệ khi các nhà phát triển OpenBSD hiện tại giảm quan tâm, đã sôi động trở lại nhờ sự tham gia của các contributor có nhu cầu vận hành thực tế
  • Xuất phát từ nhận định rằng trong thời kỳ LLM thay thế kiến thức lập trình, càng cần trực tiếp học C và thử thách bản thân, công việc bắt đầu bằng việc hiện đại hóa hệ thống imsg thủ công của relayd(8)
  • Trong giai đoạn 2024~2026, hầu hết các bản vá chưa được phản hồi trên mailing list tech@ và các issue cũ trên GitHub mirror hiện có đã được xử lý; đồng thời cũng chuẩn bị Git mirror và README cho contributor mới
  • relayd(8) đã tăng cường API imsg an toàn, bảo mật TLS và phân tích request, đồng thời sửa xung đột khi reload; httpd(8) bổ sung phòng thủ request smuggling, header tùy chỉnh, kiểm soát cache cho file tĩnh, v.v.
  • Bảo mật, độ ổn định và khả năng mở rộng của cả hai daemon đều được cải thiện, nhưng backlog cũng tăng lên trong quá trình làm việc nên vẫn tiếp tục đón nhận ý tưởng và phản hồi

Bối cảnh hồi sinh một dự án đã mất đi sự quan tâm

  • Như đã đề cập trong các thay đổi chính của OpenBSD 7.8, việc phát triển relayd(8)httpd(8) đang ở trạng thái đình trệ
    • Nhiều contributor đã gửi bản vá lên mailing list tech@, nhưng hầu như không có bản vá nào được đưa vào repository
    • Nguyên nhân chính là các nhà phát triển OpenBSD hiện tại không còn quan tâm đến hai daemon này nữa
  • Dựa trên kinh nghiệm cùng kirill@ sử dụng hai daemon này thường xuyên và xử lý các trường hợp dùng thực tế, tác giả đã bắt đầu phát triển tích cực
    • Nhu cầu thực tiễn phải hỗ trợ khách hàng OpenBSD với các cấu hình httpd(8)·relayd(8) phức tạp cũng là động lực trực tiếp

Vì sao quay lại với C trong thời đại LLM

  • Tác nhân lớn nhất là sự xuất hiện của LLM
    • Trước đây tác giả từng viết mã C++ hiện đại một cách chuyên nghiệp, nhưng sau đó chuyển sang kiến trúc giải pháp, kỹ thuật nền tảng và xây dựng đội ngũ, nên gần như không còn viết code thực tế
    • Chủ yếu chỉ viết YAML dạng khai báo và dừng ở mức đọc, port code cho OpenBSD ports(7)
  • Trái với tuyên bố “việc lập trình đã được giải quyết”, tác giả cho rằng càng trong thời kỳ tri thức bị ủy thác ra bên ngoài, việc tự mình sở hữu tri thức đó càng quan trọng hơn
  • C++ và Rust thay thế một phần các quyết định khó, nhưng C thì không; xem đó là một thử thách, tác giả quyết định đóng góp cho relayd(8)httpd(8)

Duy trì đóng góp bằng kỷ luật hơn là động lực

  • Đóng góp mã nguồn mở có thể kết thúc trong thất vọng chỉ sau vài tuần, nhưng sau khi vượt qua giai đoạn đau đớn ban đầu, tác giả đã đạt đến trạng thái có thể làm việc đều đặn
  • Ban đầu tác giả đọc codebase một cách thụ động và nản lòng ở nhiều chỗ
    • Nguyên nhân là thiếu chú thích, một số thiết kế chưa tốt và mã đan xen phức tạp; hiện vẫn chưa rõ đó là đặc tính của mã C hay do thiếu kinh nghiệm cá nhân
  • Sau khi thảo luận với các maintainer daemon của OpenBSD, tác giả quyết định hiện đại hóa hệ thống thông điệp imsg được làm thủ công
    • Trước hết tập trung vào relayd(8), sau đó mở rộng phạm vi sang httpd(8)
    • Bản thân việc hiện đại hóa được dùng như một cách để hiểu codebase

Xử lý các bản vá chưa được đưa vào và issue cũ

  • Tác giả đã xem lại lưu trữ mailing list tech@ giai đoạn 2024~2026 để thu thập các bản vá và issue chưa xử lý, và cho rằng phần lớn đã được xử lý
  • Hai daemon này ban đầu được phát triển bởi Reyk Floeter, người hiện đã nghỉ khỏi OpenBSD
  • Tác giả cũng xem lại các issue cũ trên relayd GitHub mirror do Reyk quản lý
    • Tất cả issue đều ở trạng thái có thể đóng hoặc sửa, một số không còn hợp lệ nữa

Git mirror cho contributor mới

  • Lấy cảm hứng từ GitHub mirror hiện có, tác giả đã xây dựng một mirror riêng nhằm giúp contributor mới và trẻ dễ tiếp cận hơn, đồng thời tạo điểm kết nối với cộng đồng bên ngoài mailing list OpenBSD
  • CVS tree được dùng làm Git mirror; quá trình phát triển trước tiên diễn ra trên instance Gothub rồi đồng bộ sang các repository còn lại
  • Cách làm tương tự cũng được áp dụng cho httpd(8), đồng thời tác giả viết một README.md chi tiết với các thông tin cần thiết

Hiện đại hóa và chất lượng mã của relayd(8)

  • Chuyển hệ thống imsg sang các accessor an toàn hơn như imsg_get_data, imsg_get_type, imsgbuf_get
  • Bổ sung xử lý lỗi phù hợp cho toàn bộ quá trình đọc payload imsg
  • Chuẩn hóa logging và chú thích để nhất quán với bgpd
  • Tách xử lý dòng bắt đầu HTTP thành hàm riêng để cải thiện tổ chức mã
  • Áp dụng định dạng knfmt

Tăng cường bảo mật cho relayd(8)

  • Đổi bộ mã hóa TLS mặc định từ HIGH:!aNULL sang secure
  • Bổ sung hỗ trợ ECDSA cho engine tách đặc quyền CA (privsep)
  • Từ chối header Content-Length trùng lặp bằng phản hồi HTTP 400
  • Không cho phép header obs-fold theo RFC 9112 5.2 để ngăn khác biệt giữa các parser
  • Kiểm tra process ID và giới hạn IMSG_CTL_PROCFD ở tiến trình cha
  • Dùng explicit_bzero để xóa dữ liệu mật khẩu nhạy cảm

Cải thiện lỗi và độ ổn định của relayd(8)

  • Sửa race condition khi reload từng gây crash
  • Loại bỏ nhiều rò rỉ bộ nhớ liên quan đến X509_dup, config_purge, tls_cfg
  • Sửa kiểm tra NULL và kiểm tra biên
  • Bổ sung xử lý lỗi phù hợp khi OpenSSL thất bại
  • Thay đổi để làm rỗng hàng đợi lỗi OpenSSL khi TLS thất bại

Tính năng được thêm vào relayd(8)

  • Hỗ trợ phương thức HTTP MKCALENDAR
  • Có thể dùng TLS trên nhiều listener
  • Hỗ trợ nhiều địa chỉ có thể phân giải tên
  • Có thể thiết lập rõ ràng đường dẫn của certificate, key và OCSP staple
  • Thiết lập User-Agent cho request kiểm tra trạng thái HTTP
  • Xử lý đúng các phản hồi HTTP không có body

Hiện đại hóa và chất lượng mã của httpd(8)

  • Chuyển proc.c sang API imsg mới để nhất quán với relayd(8)
  • Thay đổi thứ tự token để dễ mở rộng các tùy chọn cấu hình trong tương lai
  • Chuẩn hóa logging để nhất quán với bgpd
  • Loại bỏ mã trùng lặp và hàm rỗng
  • Áp dụng định dạng knfmt
  • Tách xử lý chức năng tích hợp thành hàm riêng

Tăng cường bảo mật cho httpd(8)

  • Đổi bộ mã hóa TLS mặc định từ compat sang secure
  • Từ chối CL.TE request framing để ngăn tấn công request smuggling
  • Phản hồi HTTP 400 với header obs-fold theo RFC 9112 5.2
  • Xử lý lỗi nếu header Content-LengthTransfer-Encoding cùng tồn tại
  • Thực hiện relink ngẫu nhiên khi boot để tăng cường bảo vệ
  • Kiểm tra process ID và giới hạn IMSG_CTL_PROCFD ở tiến trình cha
  • Bổ sung tùy chọn no banner để ẩn thông tin định danh server trong phản hồi

Cải thiện lỗi và độ ổn định của httpd(8)

  • Sửa xử lý suffix range của HTTP request
  • Sửa để server_http_time() xuất đúng thời gian GMT
  • Kiểm tra lỗi của timegm(3) theo đặc tả trong manual
  • Giải quyết vấn đề upload khi dùng chunked transfer-encoding
  • Sửa để fcgiparams của location không bị gửi hai lần
  • Bổ sung xử lý lỗi phù hợp cho dispatch_parent
  • Thay đổi để xả đúng phản hồi bị ngắt thông qua bufferevent
  • Loại bỏ các lần lưu không cần thiết do scan-build phát hiện
  • Xác thực return_uri_len trước khi sao chép dữ liệu

Tính năng mới và công việc còn lại của httpd(8)

  • Hỗ trợ HTTP header tùy chỉnh
  • Kế thừa gzip-static trong location để cấu hình được kế thừa tốt hơn
  • Mở rộng server flag thành số nguyên 64-bit để chứa nhiều tùy chọn flag hơn
  • Bổ sung kiểm soát cache cho file tĩnh
  • Backlog tăng lên khi công việc tiến triển, và tác giả vẫn tiếp tục đón nhận ý tưởng cũng như phản hồi cho quá trình phát triển sau này

1 bình luận

 
Các ý kiến trên Lobste.rs
  • Rất vui khi thấy hỗ trợ HTTP header tùy chỉnh. Trước đây không có tính năng này nên ngay cả cho các mục đích đơn giản cũng không dùng được httpd, giờ được hỗ trợ thì thật tốt

  • Việc phát triển relayd(8) và httpd(8) đã bị đình trệ, nhiều contributor đã gửi patch lên mailing list tech@ nhưng hầu như không được đưa vào repository. Lý do chính là các developer OpenBSD hiện tại không còn quan tâm đến các daemon này nữa, nên rất biết ơn vì đã tiếp quản việc bảo trì

  • Tôi dùng cả hai phần mềm này thường xuyên, nên rất vui khi chúng lại được quản lý đúng cách. Hoàn toàn không biết là việc phát triển đã bị đình trệ
    Có vẻ nhờ cấu trúc phần mềm đơn giản mà việc phát triển có thể được khởi động lại và đưa vào nhiều tính năng, bản sửa lỗi như vậy mà không cần một đội ngũ lớn

  • Các con số sau tên phần mềm từng khiến tôi bối rối một thời gian, rồi mới biết đó là số mục của manual
    1 là chương trình thực thi/lệnh shell, 2 là system call, 3 là library call, 4 là file đặc biệt, 5 là định dạng/quy tắc file, 6 là game, 7 là khác, 8 là lệnh quản trị hệ thống, còn 9 không chuẩn là kernel routine

    • Chỉ cần chạy man 1 man hoặc ngắn gọn là man man để xem man(1). Đặc biệt các trang intro khác nhau trong SEE ALSO rất hữu ích
  • Tò mò không biết các cải tiến này có được đưa vào OpenBSD 8.0 không

  • Không biết link này vốn có được làm để đọc được không. Trên Firefox cho Android thì trông như sau
    https://imgur.com/a/oTimS9R