ymawky: A Pure ARM64 Assembly Web Server for Linux
ymawky: A Pure ARM64 Assembly Web Server for Linux
ymawky is a high-performance experiment in minimal systems programming
ymawky is a web server written entirely in ARM64 assembly, designed to operate without the C standard library (no libc) by relying exclusively on system calls. Originally developed for macOS, the project has been ported to Linux as a fork-per-connection server that handles both static content and dynamic content via Common Gateway Interface (CGI) scripts.
Core Technical Architecture
Syscall-Only Execution
nymawky bypasses high-level libraries entirely, interacting directly with the Linux kernel via ARM64 assembly. This approach eliminates the overhead of libc and provides a raw look at how a web server interacts with network sockets and the file system.
Connection Handling
The server employs a fork-per-connection model. To prevent PID exhaustion, the server implements a MAX_PROCS limit (defaulting to 256), returning a 503 Service Unavailable response when the limit is reached.
Request Processing and HTTP Support
nymawky implements a significant subset of HTTP/1.0 and HTTP/1.1, including:
- Supported Methods: GET, PUT, DELETE, OPTIONS, HEAD, and POST (via CGI).
- Range Requests: Full support for
Range: bytes=(including suffix and open-ended ranges), enabling features like video scrubbing. - Atomic Uploads:
PUTrequests are written to a temporary file (www/.ymawky_tmp_<pid>) and renamed only upon successful completion, ensuring that concurrent uploads do not leave corrupted files. - MIME Detection: Automatic
Content-Typeassignment based on a comprehensive list of file extensions covering web assets, images, fonts, documents, video, audio, and archives.
Dynamic Content via CGI
CGI Implementation
nymawky supports dynamic content through CGI scripts located in a configurable directory (defaulting to cgi-bin/). The server executes these scripts by setting the QUERY_STRING environment variable and forwarding the script's output and Status: header back to the client.
CGI Limitations and Security
CGI support is currently experimental. The server does not support PATH_INFO, treating all paths as literal file paths. Because CGI scripts are independent executables, they are responsible for their own input parsing and error handling. The author notes that CGI scripts lack the strict timeout settings applied to other requests and could potentially hang the process.
Security and Safety Measures
Despite being a hand-written assembly project, ymawky includes several built-in protections to mitigate common web vulnerabilities:
- Path Traversal Prevention: The server blocks
..sequences that attempt to traverse outside the document root, while still allowing multiple periods within a filename (e.g.,ohwell...txtis permitted). - DoS Mitigation: To prevent Slowloris-style attacks, the server enforces a
RECV_TIMEOUT(10 seconds) between reads and aHEADER_REQ_TIMEOUT_SECS(10 seconds) for the total header reception. - File System Constraints: The server rejects paths exceeding
PATH_MAX(4096 bytes), rejects requests without a path within the first 16 bytes, and usesO_NOFOLLOW_ANYto reject paths containing symlinks. - Upload Constraints:
PUTrequests are limited byMAX_BODY_SIZE(default 1GiB) and a minimum bytes-per-second threshold (PUT_MIN_BPS) to prevent excessively slow uploads from occupying resources.
Configuration and Deployment
Configuration is handled via config.S at assembly time. Key configurable parameters include:
- DOCROOT: The directory for static files (default
www/). - CGI_DIR: The directory for executable CGI scripts (default
cgi-bin/). - ERR_DIR: The directory for custom HTML error pages (default
err/). - Timeouts: Adjustable settings for
RECV_TIMEOUTandPUT_GRACE_SECSto control connection persistence.
Build Requirements
To compile ymawky, the system must have gcc and binutils installed. The project provides a make command for stripped binaries and make debug for binaries with debugging symbols.