ymawky: Linux를 위한 순수 ARM64 어셈블리 웹 서버

ymawky: Linux를 위한 순수 ARM64 어셈블리 웹 서버

ymawky는 최소 시스템 프로그래밍의 고성능 실험입니다

ymawky는 전체가 ARM64 어셈블리로 작성된 웹 서버로, 시스템 호출(system calls)에만 전적으로 의존하여 C 표준 라이브러리(libc 없음) 없이 작동하도록 설계되었습니다. 원래 macOS용으로 개발되었으나, 정적 콘텐츠와 Common Gateway Interface (CGI) 스크립트를 통한 동적 콘텐츠를 모두 처리하는 fork-per-connection 서버로서 Linux로 포팅되었습니다.

핵심 기술 아키텍처

시스템 호출 전용 실행

nymawky는 고수준 라이브러리를 완전히 우회하여 ARM64 어셈블리를 통해 Linux 커널과 직접 상호작용합니다. 이 접근 방식은 libc의 오버헤드를 제거하고 웹 서버가 네트워크 소켓 및 파일 시스템과 어떻게 상호작용하는지 생생하게 보여줍니다.

연결 처리

서버는 fork-per-connection 모델을 채택합니다. PID 고갈을 방지하기 위해 서버는 MAX_PROCS 제한(기본값 256)을 구현하며, 제한에 도달하면 503 Service Unavailable 응답을 반환합니다.

요청 처리 및 HTTP 지원

nymawky는 다음을 포함하여 HTTP/1.0 및 HTTP/1.1의 상당 부분의 하위 집합을 구현합니다:

  • 지원되는 메서드: GET, PUT, DELETE, OPTIONS, HEAD, 및 POST (CGI를 통해).
  • Range 요청: Range: bytes=에 대한 완전한 지원(접미사 및 개방형 범위 포함)을 통해 비디오 스크러빙과 같은 기능을 가능하게 합니다.
  • 원자적 업로드(Atomic Uploads): PUT 요청은 임시 파일(www/.ymawky_tmp_<pid>)에 작성된 후 성공적으로 완료되었을 때만 이름을 변경하므로, 동시 업로드가 손상된 파일을 남기지 않도록 보장합니다.
  • MIME 감지: 웹 에셋, 이미지, 폰트, 문서, 비디오, 오디오 및 아카이브를 아우르는 포괄적인 파일 확장자 목록을 기반으로 자동 Content-Type 할당을 수행합니다.

CGI를 통한 동적 콘텐츠

CGI 구현

nymawky는 구성 가능한 디렉토리(기본값 cgi-bin/)에 위치한 CGI 스크립트를 통해 동적 콘텐츠를 지원합니다. 서버는 QUERY_STRING 환경 변수를 설정하고 스크립트의 출력 및 Status: 헤더를 클라이언트로 다시 전달함으로써 이러한 스크립트를 실행합니다.

CGI 제한 및 보안

CGI 지원은 현재 실험적입니다. 서버는 PATH_INFO를 지원하지 않으며, 모든 경로를 문자 그대로의 파일 경로로 취급합니다. CGI 스크립트는 독립적인 실행 파일이므로 자체적인 입력 파싱 및 오류 처리를 담당해야 합니다. 저자는 CGI 스립트가 다른 요청에 적용되는 엄격한 타임아웃 설정을 갖추고 있지 않아 프로세스를 중단시킬 가능성이 있다고 언급했습니다.

보안 및 안전 조치

직접 작성한 어셈블리 프로젝트임에도 불구하고, ymawky는 일반적인 웹 취약점을 완화하기 위해 여러 내장 보호 기능을 포함하고 있습니다:

  • 경로 탐색(Path Traversal) 방지: 서버는 문서 루트 외부로 탐색을 시도하는 .. 시퀀스를 차단하지만, 파일 이름 내의 여러 개의 마침표는 허용합니다(예: ohwell...txt는 허용됨).
  • DoS 완화: Slowloris 방식의 공격을 방지하기 위해 서버는 읽기 사이의 RECV_TIMEOUT (10초)과 전체 헤더 수신을 위한 HEADER_REQ_TIMEOUT_SECS (10초)를 강제합니다.
  • 파일 시스템 제약: 서버는 PATH_MAX (4096 바이트)를 초과하는 경로를를 차단하고, 처음 16바이트 이내에 경로가 없는 요청을 거부하며, 심볼릭 링크를 포함하는 경로를 거단하기 위해 O_NOFOLLOW_ANY를 사용합니다.
  • 업로드 제약: PUT 요청은 MAX_BODY_SIZE (기본값 1GiB) 및 과도하게 느린 업로드가 리소스를 점유하는 것을 방지하기 위한 최소 초당 바이트 임계값(PUT_MIN_BPS)에 의해 제한됩니다.

구성 및 배포

설정은 어셈블리 시점에 config.S를 통해 처리됩니다. 주요 구성 가능한 파라미터는 다음과 같습니다:

  • DOCROOT: 정적 파일용 디렉토리 (기본값 www/).
  • CGI_DIR: 실행 가능한 CGI 스크립트용 디렉토리 (기본값 cgi-bin/).
  • ERR_DIR: 커스텀 HTML 오류 페이지용 디렉토리 (기본값 err/).
  • Timeouts: 연결 지속성을 제어하기 위한 RECV_TIMEOUTPUT_GRACE_SECS에 대한 조정 가능한 설정.

빌드 요구 사항

nymawky를 컴파일하려면 시스템에 gccbinutils가 설치되어 있어야 합니다. 프로젝트는 스트립된 바이너리(stripped binaries)를 위한 make 명령과 디버깅 심볼이 포함된 바이너리를 위한 make debug 명령을 제공합니다.

Sources