ymawky: 一款用於 Linux 的純 ARM64 組合語言 Web Server
ymawky: 一款用於 Linux 的純 ARM64 組合語言 Web Server
ymawky 是一個極簡系統程式設計的高性能實驗
ymawky 是一款完全使用 ARM64 組合語言編寫的 Web server,旨在透過完全依賴系統呼叫(system calls)來運作,而不使用 C 標準函式庫(no libc)。最初是為 macOS 開發的,該專案已被移植到 Linux,作為一個「一連線一 fork」的伺服器,可同時處理靜態內容與透過 Common Gateway Interface (CGI) 腳本處理的動態內容。
核心技術架構
僅使用系統呼叫執行
nymawky 完全繞過了高階函式庫,透過 ARM64 組合語言直接與 Linux 核心進行互動。這種方法消除了 libc 的開銷,並提供了觀察 Web server 如何與網路 socket 和檔案系統互動的原始視角。
連線處理
伺服器採用一連線一 fork 的模型。為了防止 PID 耗盡,伺服器實作了 MAX_PROCS 限制(預設為 256),當達到限制時,會回傳 503 Service Unavailable 回應。
請求處理與 HTTP 支援
nymawky 實作了 HTTP/1.0 與 HTTP/1.1 的重要子集,包括:
- 支援的方法:GET, PUT, DELETE, OPTIONS, HEAD, 以及透過 CGI 進行的 POST。
- Range 請求:完整支援
Range: bytes=(包括後綴與開放式範圍),可實現如影片跳轉(video scrubbing)等功能。 - 原子性上傳:
PUT請求會先寫入暫存檔(www/.ymawky_tmp_<pid>),並僅在成功完成後才進行重新命名,以確保併發上傳不會留下損壞的檔案。 - MIME 偵測:根據涵蓋 Web 資產、圖片、字體、文件、影片、音訊與壓縮檔的完整副檔名列表,自動分配
Content-Type。
透過 CGI 提供動態內容
CGI 實作
nymawky 支援透過位於可配置目錄(預設為 cgi-bin/)中的 CGI 腳本提供動態內容。伺服器透過設定 QUERY_STRING 環境變數,並將腳本的輸出與 Status: 標頭回傳給客戶端來執行這些腳本。
CGI 限制與安全性
CGI 支援目前仍處於實驗階段。伺服器不支援 PATH_INFO,將所有路徑視為字面路徑。由於 CGI 腳本是獨立的可執行檔,它們需要自行負責輸入解析與錯誤處理。作者指出,CGI 腳本缺乏應用於其他請求的嚴格超時設定,可能會導致程序掛起。
安全與防護措施
儘管這是一個手寫組合語言專案,ymawky 仍包含幾項內建防護機制,以減輕常見的 Web 漏洞:
- 路徑遍歷防護:伺服器會阻擋試圖遍歷至文件根目錄之外的
..序列,但仍允許檔名中包含多個點(例如,ohwell...txt是允許的)。 - DoS 緩解:為了防止 Slowloris 類型的攻擊,伺服器在讀取之間強制執行
RECV_TIMEOUT(10 秒)以及針對總標頭接收的HEADER_REQ_TIMEOUT_SECS(10 秒)。 - 檔案系統限制:伺服器會拒絕超過
PATH_MAX(4096 bytes)的路徑,拒絕在首 16 位元組內沒有路徑的請求,並使用O_NOFOLLOW_ANY來拒絕包含符號連結(symlinks)的路徑。 - 上傳限制:
PUT請求受MAX_BODY_SIZE(預設 1 GiB)與最小每秒位元組數閾值(PUT_MIN_BPS)的限制,以防止過於緩慢的上傳佔用資源。
配置與部署
配置是在組合語言編譯時透過 config.S 處理的。關鍵的可配置參數包括:
- DOCROOT:靜態檔案的目錄(預設
www/)。 - CGI_DIR:可執行 CGI 腳本的目錄(預設
cgi-bin/)。 - ERR_DIR:靜態 HTML 錯誤頁面的目錄(預設
err/)。 - 超時設定:可調整
RECV_TIMEOUT與PUT_GRACE_SECS以控制連線持久性。
編譯需求
要編譯 ymawky,系統必須安裝有 gcc 與 binutils。該專案提供 make 指令來產生精簡過的二進位檔,以及 make debug 來產生帶有除錯符號的二進位檔。