크라우니터미널 v2 — PowerTerminal 기반 terminal.crowny.org 재구축
개요
다운로드 폴더의 PowerTerminal 패키지(MIT v1.9.90, server.js 1,296줄 + index.html 3,923줄)를 정독하고 그 디자인·내용 그대로 terminal.crowny.org(:9840)에 재구축. 기존 crowny-terminal(v1 서비스 오케스트레이터)은
legacy-v1/에 보존, 한선씨 자산(2,478줄)은 동반 체계로 승계.
무엇을 했는지
- 스캐폴드: PowerTerminal server.js/public/banner.json/LICENSE 이식, 구버전 아카이브(legacy-v1/), npm 의존성(node-pty prebuilt·express·ws·qrcode-generator·ccusage·@xterm 3종) 설치. node-pty darwin-arm64 실동작 확인.
- P0 보안 교정 (핵심): PowerTerminal은
isLocal()(127.0.0.1)이면 토큰·관리자 전부 무비번 통과 → 게이트웨이가 127.0.0.1로 프록시하므로 그대로 올리면 전 인터넷이 로컬 취급 = 공개 RCE. isLocal(req) 3중 판정(루프백 IP + XFF 없음 + Host 로컬)으로 교정. 게이트웨이는 XFF를 항상 주입(lib/proxy.한선 실측)함을 확인.
실측: 공개 무토큰 GET → 302 /pair, API 401 · 토큰 → 200 · 관리자 비번조회 원격 → 403.
- 크라우니화: 포트 9840(SSOT) · cloudflared 터널 제거(공개=고정 도메인, QR 외부열이 terminal.crowny.org 사용) · GitHub(gh 로그인/clone/repo 생성) 제거+무해 스텁(git push 미사용, crowny-hub 대체) · 배너 로컬 전용 · xterm CDN→/vendor 자체호스팅 · 기본 언어 ko · 데이터 ~/.crownyterminal/ · 브랜딩 👑 크라우니터미널.
- 게이트웨이 WS 갭 발견 + 서비스 내 해법: 티옴타게이트웨이 웹소켓프록시(lib/proxy.한선)는 101 업그레이드만 전달하고 양방향 프레임 파이프 미구현("단순 루프" 주석만) → 공개 wss는 첫 프레임 후 정지(실측). 게이트웨이=공유 인프라 무접촉 원칙에 따라 서비스 내 폴백 구현: https 접속은 증분 폴링(
GET /api/term/poll?id&off 절대오프셋 + POST /api/term/input(40ms 배칭+즉시 재폴) + POST /api/term/resize), 프론트 PollWS 클래스(WS 동일 인터페이스). 로컬/LAN은 WS 유지. 지식셀 #27530 공유.
- LaunchAgent 교체: org.crowny.terminal → server.js. 구 데몬 종료, 새 서버 기동.
검증 실측 (전부 PASS)
- 로컬 200 / vendor 4종 200 / 세션 API 정상
- 보안: XFF무토큰 401 · XFF토큰 200 · 관리자 원격 403 · 공개 무토큰 302→/pair
- WS 종단(로컬): 실제 PTY echo 42 왕복 PASS (배포 후 회귀 재확인 PASS)
- 공개 HTTPS: 무토큰 302 · 토큰 200 · vendor 200 · WS 업그레이드 101
- 공개 폴링 E2E PASS: 게이트웨이 경유 세션 생성→input(echo POLL_$((76)))→poll에서 POLL_42 수신
관련 파일
/Users/ef/crowny-terminal/server.js (+pt-server.js.orig 원본 보존)
/Users/ef/crowny-terminal/public/index.html · public/admin.html
/Users/ef/crowny-terminal/server.한선 · public/index.한선 (동반 — sonnet 위임 산출)
/Users/ef/crowny-terminal/legacy-v1/ (v1 오케스트레이터 보존)
- 원본 패키지:
~/Downloads/PowerTerminal/
잔여 이슈
- 게이트웨이 WS 릴레이 미구현 — 인프라 세션이 lib/proxy.한선 웹소켓프록시에 양방향 파이프를 구현하면 공개도 WS 전환 가능(폴백은 그대로 병존 안전). 이슈 제안만, 무단 수정 안 함.
- v1 오케스트레이터(services/.yml·모달 SDK) 미가동 — 서비스 페이지 크라우니코드 모달 연동이 필요해지면 legacy-v1 참조해 v2에 승계.
- 크라우니디자인 중앙CSS 미적용 — 사용자 "패키지 디자인 그대로" 지시. 레지스트리 등록만.
- 사용량바(/api/usage)는 ~/.claude/.credentials.json OAuth 사용 — 로컬에서만 유효.