
zlodev 저장소는 로컬 개발 서버 앞에서 동작하는 HTTPS 리버스 프록시다. 자동 생성한 인증서와 사용자 지정 DNS로 https://dev.lo 같은 주소를 제공하며, 터미널 UI(TUI)에서 HTTP 트래픽을 살펴보고 가로채거나 다시 보낼 수 있다. macOS, Linux, Windows를 지원한다.
기능과 설치
zlodev는 서브도메인이나 경로 접두사로 여러 앱에 요청을 전달하고, *.lo를 localhost로 해석하는 DNS를 제공한다. /etc/hosts를 수정할 필요는 없다. 실시간 요청 목록에는 메서드, 경로, 상태 코드, 처리 시간, 본문 크기가 표시된다. 요청과 응답을 조건에 따라 보류하고 편집·수락·폐기할 수 있으며, 완료된 요청 재전송, curl 명령 복사, HTTP Archive(HAR) 내보내기, 검색·필터링, 웹소켓 전달도 지원한다. 중요한 요청은 별표를 붙여 순환 버퍼가 넘쳐도 보존할 수 있다.
개발 서버를 zlodev와 함께 실행하면 TUI를 나눠 서버 로그를 볼 수 있다. 미리 빌드한 바이너리는 외부 의존성이 없는 단일 파일이며, 설치 스크립트로 받을 수 있다.
curl -fsSL https://raw.githubusercontent.com/vandot/zlodev/main/install.sh | sh
소스에서 빌드하려면 Zig 0.15.2가 필요하다. 다른 의존성은 없으며 BoringSSL은 자동으로 소스에서 빌드된다.
git clone https://github.com/vandot/zlodev.git
cd zlodev
zig build -Doptimize=ReleaseSafe
실행 파일은 zig-out/bin/zlodev에 생성된다. Linux에서 루트 권한 없이 80·443 포트를 사용하려면 다음 권한을 부여한다.
sudo setcap cap_net_bind_service=+eip zig-out/bin/zlodev
빌드 옵션은 -Dversion=STRING(기본값 dev), -Dmax-entries=N(요청 순환 버퍼의 최대 항목 수, 기본값 500), -Dstrip=BOOL(디버그 정보 제거, Debug 빌드가 아니면 기본값 true)이다.
시작하기
macOS와 Linux에서는 인증서와 DNS 리졸버를 한 번 설치한다. 설치에는 sudo가 필요하다. zlodev가 개발 서버를 함께 실행하게 하려면 다음과 같이 시작한다.
# 1. 인증서와 DNS 리졸버를 설치한다(최초 1회, sudo 필요).
zlodev install
# 2. 개발 서버를 통합해 zlodev를 시작한다.
zlodev start --command="npm run dev"
앱은 https://dev.lo에서 이용할 수 있고, TUI에는 실시간 트래픽과 개발 서버 로그가 나란히 표시된다. 개발 서버를 별도로 실행하는 기존 방식도 가능하다.
# 1. 인증서와 DNS 리졸버를 설치한다(최초 1회, sudo 필요).
zlodev install
# 2. 개발 서버를 시작한다(예: 3000번 포트).
npm run dev &
# 3. zlodev를 시작한다.
zlodev start
Windows에서는 관리자 권한으로 터미널을 열어 명령을 실행한다. zlodev install로 인증서와 DNS를 설치한 뒤 개발 서버를 시작하고 zlodev start를 실행한다. DNS가 동작하려면 브라우저의 ‘보안 DNS 사용’을 꺼야 한다. Edge에서는 설정의 개인정보·보안 항목에서 해당 옵션을 끈다.
주요 명령은 zlodev install(인증서와 DNS 설치), zlodev install --cert(인증서만 설치), zlodev install --dns(DNS만 설치), zlodev uninstall(인증서와 DNS 제거), zlodev uninstall --cert, zlodev uninstall --dns, zlodev start(프록시·DNS·TUI 시작), zlodev start --dns(로그 모드로 DNS 서버만 시작)이다.
옵션으로 대상 포트(-p=PORT, --port=PORT, 자동 감지 또는 기본값 3000), 수신 주소(-b=ADDR, --bind=ADDR, 기본값 0.0.0.0), 반복 가능한 라우팅 규칙(--route=PATTERN=TARGET), 실행·감시할 개발 서버 명령(--command=CMD), 설정 파일 경로(-c=PATH, 기본값 .zlodev), 최대 요청 본문 크기(--max-body=SIZE, 기본값 10M), TUI 끄기(--no-tui), .local 도메인 사용(-l, --local), DNS 전용 설치·제거·시작(--dns), 인증서 전용 작업(--cert), 강제 재설치(-f, --force), 버전 표시(-v, --version), 도움말(-h, --help)을 지정할 수 있다. SIZE에는 K(KB), M(MB), G(GB)를 붙일 수 있다. 예를 들어 --max-body=50M으로 설정한다.
설정과 라우팅
프로젝트 디렉터리에 .zlodev 파일을 두면 명령행 옵션을 매번 입력하지 않아도 된다.
port=3000 bind=127.0.0.1 route=api=3001 route=/webhooks=8080 command=npm run dev intercept=POST /api no-tui
start를 실행할 때 현재 디렉터리의 .zlodev를 읽는다. -c=PATH로 다른 파일을 지정할 수 있으며, 명령행 인수가 설정 파일 값보다 우선한다. 지원 옵션은 port, p, bind, b, route, max-body, command, intercept, no-tui, local, l, dns다.
서브도메인이나 경로 접두사에 따라 다른 포트로 요청을 보낼 수 있다.
# 서브도메인 라우팅 — 앞에 "/"를 붙이지 않는다.
zlodev start --route=api=3001 --route=dashboard=4200
# api.dev.lo → 127.0.0.1:3001
# dashboard.dev.lo → 127.0.0.1:4200
# dev.lo → 127.0.0.1:3000 (기본값)
# 경로 라우팅 — 앞에 "/"를 붙인다.
zlodev start --route=/api=3001 --route=/admin=8080
# dev.lo/api/* → 127.0.0.1:3001
# dev.lo/admin/* → 127.0.0.1:8080
# dev.lo/* → 127.0.0.1:3000 (기본값)
# 두 방식 혼합
zlodev start --route=api=3001 --route=/webhooks=8080
# 외부 업스트림으로 라우팅
zlodev start --route=api=staging.api.example.com
zlodev start --route=/payments=payments.stripe.com:443
# api.dev.lo → staging.api.example.com:443 (TLS)
# dev.lo/payments/* → payments.stripe.com:443 (TLS)
라우팅 우선순위는 서브도메인 일치, 가장 긴 경로 접두사, 기본 포트 순이다. 외부 경로는 TLS로 연결하고 Host 헤더를 업스트림 호스트 이름으로 바꾼다. 브라우저에서 쿠키가 동작하도록 Set-Cookie의 도메인 속성은 dev.lo로 바꾼다. 포트를 지정하지 않으면 443을 사용한다. -l 로컬 모드에서는 mDNS가 임의의 서브도메인을 지원하지 않으므로 서브도메인 라우팅을 사용할 수 없다.
포트 옵션을 생략하면 .env의 PORT= 값을 먼저 찾고, 프레임워크 설정 파일을 확인한다. 예를 들어 next.config.js는 3000, vite.config.ts는 5173으로 감지한다. 해당 정보가 없으면 3000을 사용한다.
같은 네트워크의 모바일 기기에서 접근하려면 .local 도메인을 사용한다.
zlodev install -l
zlodev start -l
# -> https://yourhostname.local
TUI 없이 스크립트나 CI에서 실행하려면 로그를 표준 오류로 보내는 zlodev start --no-tui를 사용한다.
개발 서버와 트래픽 가로채기
--command를 지정하면 zlodev가 시작될 때 개발 서버를 실행하고, 출력을 요청 목록 아래의 분할 창에 표시한다. .zlodev 설정에 command=npm run dev를 넣어도 된다. l로 로그 창을 표시하거나 숨기고, Tab으로 요청과 로그 창 사이의 포커스를 바꾸며, 로그 창에 포커스가 있을 때 R을 눌러 서버를 다시 시작한다. 로그 창에서는 j·k로 스크롤하고, g·G로 위·아래 끝으로 이동하며, s로 자동 스크롤을 전환한다.
TUI에서 i를 눌러 가로채기 모드를 켜고 패턴을 입력한다. 일치하는 요청은 검사할 수 있도록 보류되고 나머지는 그대로 통과한다. 패턴을 비워 두면 모든 요청과 응답을 가로챈다. /api는 경로에 /api가 포함된 요청, POST는 모든 POST 요청, POST /api는 /api로 향하는 POST 요청과 일치한다. req:/api는 요청만 보류하고 응답은 통과시키며, resp:/api는 응답만 보류하고 요청은 통과시킨다. req: 또는 resp:를 붙이지 않으면 요청과 응답을 모두 가로챈다.
응답을 가로채면 TUI에 두 항목이 나타난다. 원래 요청에는 업스트림 왕복 시간이 표시되고, ↳ 응답 항목에는 상태 열의 RESP와 실시간 보류 시간이 표시된다. 응답 항목에서 e를 눌러 브라우저로 전달되기 전 상태 코드·헤더·본문을 편집할 수 있고, a로 수락하거나 d로 폐기할 수 있다. 응답 항목은 r이나 R로 재전송할 수 없다. 그 위의 원래 요청을 재전송하면 새 응답이 생성된다. 패턴은 대소문자를 구분하지 않는다. i를 다시 누르면 가로채기가 꺼지고 보류된 요청이 모두 해제된다. 기본 패턴은 설정 파일에 다음처럼 지정할 수 있다.
intercept=resp:POST /api
TUI 키 조작
요청 목록에서는 j·k 또는 위·아래 화살표로 이동하고, G로 끝으로, g로 처음으로 이동한다. s는 자동 스크롤, l은 로그 창, Tab은 요청·로그 창 포커스를 전환한다. Enter는 상세 보기, /는 경로·메서드·상태 코드 검색 및 필터, Esc는 필터 해제다. *로 요청을 별표 표시하거나 해제하며 별표 요청은 버퍼가 넘쳐도 남는다. i로 패턴을 입력해 가로채기를 켜거나 끈다. a는 보류 항목 수락, A는 보류 항목 모두 수락, d는 보류 요청을 폐기하거나 완료된 요청을 삭제한다. c는 요청을 curl 명령으로 복사하고, e는 요청·응답 편집, r은 편집 후 재전송, R은 편집 없이 재전송한다. 로그 창에 포커스가 있으면 R은 개발 서버를 다시 시작한다. E는 HAR 파일로 내보내기, C는 모든 요청 지우기, ?는 도움말 표시(닫기는 Esc), q는 종료다.
개발 서버 로그 창에서는 j·k 또는 위·아래 화살표로 스크롤하고, G·g로 끝과 처음으로 이동하며, s로 자동 스크롤을 전환한다. R은 서버를 다시 시작하고 Tab은 요청 창으로 포커스를 옮긴다.
상세 보기에서는 j·k 또는 위·아래 화살표로 스크롤하고, G·g로 아래·위 끝으로 이동한다. n·p 또는 오른쪽·왼쪽 화살표로 다음·이전 요청을 선택하고, b로 본문 표시를 전환한다. a는 보류 항목 수락, d는 보류 항목 폐기 또는 완료 항목 삭제, *는 별표 표시 전환, c는 curl 복사, e는 요청·응답 편집, r은 편집 후 재전송, R은 즉시 재전송, i는 가로채기 전환, s는 자동 스크롤 전환이다. q 또는 Esc를 누르면 목록으로 돌아간다.
편집 보기에서는 Tab·Shift+Tab으로 다음·이전 필드를 선택하고, 왼쪽·오른쪽 화살표 또는 Home·End로 커서를 이동한다. 여러 줄 필드에서는 위·아래 화살표로 줄을 이동하고, Enter로 새 줄을 넣거나 다음 필드로 간다. Ctrl+S는 저장해 편집한 보류 항목을 수락하거나 편집한 요청을 재전송한다. Esc는 편집을 취소한다.
작동 방식과 문제 해결
install을 실행하면 zlodev가 로컬 인증 기관(CA)과 도메인 인증서를 만들고 CA를 시스템 신뢰 저장소에 추가한다. CA는 해당 기기마다 고유하다. DNS 서버는 *.lo 질의를 127.0.0.1로 해석한다. macOS에서는 /etc/resolver/, Linux에서는 systemd-resolved, Windows에서는 NRPT 규칙을 통해 등록한다.
HTTPS 리버스 프록시는 443번 포트에서 TLS 연결을 종료하고 일반 HTTP를 개발 서버로 전달한 뒤, 응답을 TLS로 돌려보낸다. 80번 포트의 일반 HTTP 서버는 모바일 기기용 CA 인증서 다운로드 페이지를 제공하고 다른 요청은 HTTPS로 리디렉션한다. --command를 지정하면 셸 프로세스로 개발 서버를 실행한다. 표준 출력과 표준 오류는 크기가 제한된 순환 버퍼에 저장돼 분할 로그 창에 표시된다. 로그 창에서 R을 눌러 서버를 다시 시작할 수 있으며 zlodev를 종료하면 서버도 정상적으로 종료된다.
443번 포트가 이미 사용 중이면 다른 프로세스가 점유하고 있는지 확인한다.
# macOS
sudo lsof -i :443
# Linux
sudo ss -tlnp | grep :443
# Windows (관리자 권한 터미널)
netstat -an | findstr ":443"
Linux에서 80·443번 포트에 권한 오류가 나면, 루트로 실행하는 대신 파일 기능을 부여한다. 설치 스크립트는 이를 자동으로 설정한다. 직접 빌드했다면 다음을 실행한다.
sudo setcap cap_net_bind_service=+eip $(which zlodev)
이 권한은 특권 포트에 바인딩하는 기능만 허용하며 다른 루트 접근 권한은 부여하지 않는다. 인증서를 신뢰하지 않는 경우 zlodev install -f로 강제 설치를 다시 실행한다.
DNS가 해석되지 않으면 리졸버 설치 여부를 확인한다.
# macOS
cat /etc/resolver/lo
# Linux
resolvectl query dev.lo
# Windows (관리자 권한 PowerShell)
Resolve-DnsName dev.lo
설치되지 않았다면 zlodev install --dns로 DNS를 다시 설치한다. Windows에서는 브라우저의 ‘보안 DNS 사용’을 꺼야 한다. 이 기능이 켜져 있으면 Chromium 계열 브라우저가 시스템 DNS 리졸버를 우회한다.
모바일 기기가 연결되지 않으면 휴대전화가 같은 네트워크에 있는지 확인하고, zlodev start -l로 시작한다. 휴대전화에서 http://yourhostname.local/ca를 열어 CA 인증서를 설치한 뒤 다운로드 페이지의 운영체제별 안내를 따른다.
제거 명령은 다음과 같다.
zlodev uninstall
이 명령은 시스템 신뢰 저장소에서 CA를 제거하고 생성된 인증서와 DNS 리졸버 설정을 삭제한다. zlodev의 라이선스는 MIT다.
댓글 (0)
로그인하면 이 기사에 내 생각을 남길 수 있어요