자동화&툴 리뷰

Zeroserve: eBPF로 스크립팅하는 무설정 웹 서버 총정리

노동1호 2026. 6. 8. 02:02
Zeroserve: eBPF 기반 무설정 HTTPS 서버 (이미지 출처: Picsum)

Zeroserve: eBPF로 스크립팅하는 무설정 웹 서버 총정리

웹 서버 설정 파일이 너무 길어진 적 있지 않으신가요? nginx의 location 블록, rewrite 규칙, try_files 그리고 한계에 부딪힐 때마다 추가하는 Lua 스크립트까지. 설정 언어와 스크립팅 언어가 분리되어 두 층을 동시에 관리하는 고통. Zeroserve는 이 문제를 단일 eBPF 프로그램으로 해결하는 새로운 무설정 HTTPS 서버입니다.

Zeroserve란?

Zeroserve는 웹사이트 tarball 하나를 HTTP/2와 TLS 1.3으로 제공하는 작고 빠른 무설정 HTTPS 서버입니다. tarball 안에 넣은 eBPF 프로그램이 모든 요청에서 사용자 공간 샌드박스 미들웨어로 실행되며, 요청 재작성, 인증, 속도 제한, 백엔드 리버스 프록시를 처리합니다.

핵심 설계 철학은 선언형 설정 언어와 별도 스크립팅 런타임을 합친다는 점입니다. nginx와 Caddy는 location 블록, rewrite 규칙 같은 선언형 설정 언어를 제공하고, 한계에 도달하면 Lua나 Caddy 플러그인 같은 선택적 스크립팅 런타임을 옆에 붙이는 구조입니다. Zeroserve는 구성 파일 자체가 없으며, eBPF 프로그램 하나가 모든 요청을 보고 라우팅, 헤더, 인증, 속도 제한, 프록시를 결정합니다.

핵심 아키텍처

단일 tarball 배포

전체 사이트는 하나의 tar 파일이며, Zeroserve는 로드 시 path -> byte-range 맵을 만들고 tarball 자체에 바이트 범위 읽기를 수행해 파일을 제공합니다. 어떤 파일도 디스크에 풀리지 않기 때문에 사이트는 단일 파일 안에만 존재하며, 잘못된 location 규칙이 노출할 문서 루트가 없습니다.

패키징과 실행 명령은 다음과 같습니다.

# 디렉터리를 tarball로 패키징zeroserve --pack ./public > site.tar# 서버 실행zeroserve --addr 0.0.0.0:8080 site.tar# 핫 리로드killall -SIGHUP zeroserve

리로드는 같은 프로세스 안에서 사이트, 스크립트, TLS 자료를 원자적으로 교체하고 연결 손실 없이 동작합니다.

사용자 공간 eBPF 스크립팅

.zeroserve/scripts/ 아래에 둔 모든 .c 파일은 패키징 시점에 clang과 llc로 eBPF 오브젝트로 컴파일되고 모든 요청에서 실행됩니다. eBPF는 커널 BPF 서브시스템이나 CAP_BPF 없이 일반 비권한 프로세스 안의 async-ebpf 런타임에서 사용자 공간으로 실행됩니다.

async-ebpf는 uBPF를 내장해 바이트코드를 네이티브 x86-64 머신 코드로 JIT 컴파일합니다. 포인터 케이지(pointer cage)는 JIT 컴파일된 코드의 모든 메모리 접근을 프로그램 전용 아레나로 마스킹해 잘못된 접근을 스크립트 메모리 안에 가둡니다.

느린 스크립트가 다른 연결을 멈추지 않도록 타이머가 JIT 컴파일된 네이티브 코드를 실행 중간에 인터럽트하고 제어를 이벤트 루프로 돌려줄 수 있습니다. 프로그래밍 모델은 파일명 정렬 순서로 실행되는 스크립트 체인이며, 스크립트들은 요청별 메타데이터 맵을 공유합니다.

헬퍼 API

Zeroserve는 풍부한 헬퍼 표면을 제공합니다.

• 요청 메서드, 경로, 쿼리, 헤더, 피어 주소 읽기

• URI 재작성, 헤더 설정 및 삭제

• 암호화/인코딩: SHA-256, HMAC-SHA256, base64, hex, getrandom

• JSON: 요청 본문 파싱, 문서 트리 생성 및 수정, zs_json_respond 응답

• 속도 제한: 피어 IP나 API 키 기반 토큰 버킷 (핫 리로드 후에도 상태 유지)

• AWS SigV4: S3와 AWS 서비스용 서명 헤더 및 presigned URL

• OIDC: Authorization Code + PKCE 기반 relying-party 흐름

성능 벤치마크

8코어 Ryzen 7 3700X에서 zeroserve, nginx 1.26, Caddy 2.11을 같은 콘텐츠와 같은 자체 서명 인증서로 비교한 결과입니다. 모든 서버는 단일 코어에 고정되어 코어당 공정 비교가 가능합니다.

소형 정적 파일 (174B)

서버req/sp99
Zeroserve36,6815.4ms
nginx31,2267.8ms
Caddy12,83022ms

Zeroserve는 단일 코어에서 nginx보다 약 17% 빠르게 소형 파일을 제공했고, 꼬리 지연도 더 낮습니다.

eBPF vs Lua 스크립팅 (완전 동적 JSON)

엔진req/sp99
Zeroserve eBPF 10ms46,9454.5ms
nginx Lua content_by_lua41,2316.4ms
Zeroserve eBPF 2ms 기본값32,3936.7ms

--preempt-timer-interval-ms를 10으로 올리면 스크립팅 처리량이 약 40% 회복되고 결과가 뒤집힙니다. 운영 환경에서는 10ms 사용을 권장합니다.

리버스 프록시 (소형 174B 응답)

프록시req/sp50p99
Zeroserve26,4863.3ms8ms
nginx21,7614.2ms10.5ms
Caddy7,68310.3ms33ms

Zeroserve의 풀링된 io_uring 프록시는 nginx보다 약 22% 앞섰고 Caddy 대비 약 3.4배 처리량을 기록합니다. 다만 100KB 응답 프록시에서는 nginx가 5,882 req/s로 우위입니다. 큰 프록시 응답에는 nginx, 작고 많은 응답에는 Zeroserve가 더 적합합니다.

메모리 사용량

유휴 상태의 단일 Zeroserve 인스턴스는 약 15MB PSS를 사용하며, nginx의 약 6MB보다 많고 Caddy의 약 60MB보다 적습니다. 코어마다 복사본을 실행할 때 같은 바이너리를 매핑해 코드 페이지를 공유하기 때문에 추가 프로세스 비용이 낮습니다.

TLS와 네트워크 기능

Zeroserve의 TLS 계층은 TLS 1.3 전용이며 BoringSSL로 종료됩니다. Encrypted Client Hello(ECH)는 실제 SNI가 평문으로 나타나지 않게 하며, 디렉터리 기반 SNI 인증서 선택과 스크립트에 노출되는 JA4 클라이언트 핑거프린팅을 제공합니다.

네트워크와 디스크 작업은 monoio 런타임을 통해 io_uring으로 제출되어 높은 I/O 처리량을 보입니다.

Zeroserve vs nginx vs Caddy

항목ZeroservenginxCaddy
설정 방식eBPF 프로그램 (코드)선언형 설정 + Lua선언형 설정 + 플러그인
배포 단위단일 tarball디렉터리 + 설정디렉터리 + 설정
핫 리로드SIGHUP 원자적 교체reload (워커 재시작)API
소형 정적 파일36,681 req/s31,226 req/s12,830 req/s
동적 미들웨어43,709 req/s28,653 req/s-
소형 프록시26,486 req/s21,761 req/s7,683 req/s
100KB 프록시3,631 req/s5,882 req/s4,285 req/s
메모리 (PSS)15MB6MB60MB
ECH 지원OX부분
JA4 핑거프린팅OXX

Zeroserve가 적합한 경우: HTML 페이지, 소형 JSON, CSS 같은 정적 사이트, API 호출처럼 작고 많은 응답, 헤더 주입 미들웨어, "Google로 로그인" 뒤의 정적 사이트. nginx가 더 나은 경우: 큰 프록시 응답 (100KB 이상), 이미 운영 중인 nginx 워크로드.

결론

Zeroserve는 "설정 파일"과 "스크립팅 계층"을 하나의 eBPF 프로그램으로 합친 새로운 무설정 HTTPS 서버입니다. 단일 tarball 배포, 사용자 공간 eBPF, 현대적 TLS, io_uring 기반 I/O를 결합해 소형 정적 파일과 미들웨어 워크로드에서 nginx보다 빠른 처리량을 보입니다.

큰 프록시 응답이 아니라면, 정적 사이트에 동적 기능을 얹고 싶은 개발자나 API 게이트웨이를 만들려는 팀에게만 한 번 해볼 만한해 볼 만한 프로젝트입니다. GitHub에서 오픈소스로 공개되어 있으니 관심 있는 분은 직접 빌드해서 벤치마크를 돌려보시길 권합니다.

> 한 줄 요약: Zeroserve = nginx의 속도 + Caddy의 자동 TLS + 사용자 정의 가능한 eBPF 미들웨어