Kage: Shadow Websites into Script-Free Offline Binaries

Kage는 웹사이트를 스크립트가 없는 브라우징 가능한 미러로 복제하여 "깨진" 오프라인 저장 문제를 해결하도록 설계된 도구입니다. 외부 JavaScript에 대한 의존성이나 깨진 링크를 남기는 경우가 많은 전통적인 "다른 이름으로 저장" 기능과 달리, Kage는 실제 브라우저에서 페이지를 렌더링하고 최종 DOM을 스냅샷으로 찍은 뒤 모든 JavaScript를 제거하여 콘텐츠가 오프라인에서도 기능적으로 유지되고 프라이버시를 보호할 수 있도록 합니다.

Core Functionality: Rendering and Sanitization

Kage는 헤드리스 Chrome 인스턴스를 구동하여 사람이 보는 것과 똑같이 페이지를 캡처함으로써 웹사이트의 영구적인 오프라인 버전을 생성합니다. 프로세스는 특정 파이프라인을 따릅니다: Seed URL $\rightarrow$ Headless Chrome (Render) $\rightarrow$ Final DOM (Snapshot) $\rightarrow$ Strip JS (Sanitize) $\rightarrow$ Localize Assets (Rewrite Links) $\rightarrow$ Disk.

모든 스크립트를 제거함으로써 Kage는 트래킹, 네트워크 호출, 그리고 현대적인 싱글 페이지 애플리케이션에서 흔히 발생하는 "스피너" 효과를 제거합니다. 결과물은 .html 파일과 로컬라이즈된 CSS, 이미지, 폰트를 포함하는 예약된 _kage 디렉토리로 구성됩니다.

Deployment and Usage Options

Kage는 다양한 환경 요구 사항에 맞춰 도구를 설치하고 실행할 수 있는 여러 가지 방법을 제공합니다:

  • Go Installation: go install github.com/tamnd/kage/cmd/kage@latest
  • Prebuilt Binaries: .deb, .rpm, 및 .apk 패키지로 제공됩니다.
  • Docker: Chromium을 번들링한 컨테이너 이미지 (ghcr.io/tamnd/kage)를 통해 로컬 Chrome 설치의 필요성을 없앱니다.

Cloning and Mirroring

kage clone 명령은 정중한 너비 우선 탐색(breadth-first crawl)을 수행합니다. robots.txt를 준수하며 sitemap.xml을 사용하여 시딩(seeding)을 합니다. 주요 기능은 다음과 같습니다:

  • Scope Control: --scope-prefix를 사용하여 크롤링 범위를 사이트의 특정 섹션으로 제한할 수 있습니다.
  • Depth and Page Limits: --max-pages--max-depth를 사용하여 데이터 양을 제어할 수 있습니다.
  • Lazy Loading Support: --scroll 플래그는 스크롤 시에만 로드되는 이미지를 캡처하기 위해 자동 스크롤을 트리거합니다.
  • Idempotency: Kage는 페이지를 기록하는 파일로 키를 지정하여, 프로토콜(HTTP vs HTTPS)에 관계없이 동일한 페이지가 여러 번 가져오지 않도록 보장합니다.

Serving Offline Content

현대적인 브라우저가 보안상의 이유로 file:// 프로토콜을 통한 로컬 파일 로딩을 제한하는 경우가 많기 때문에, kage serve는 링크와 에셋을 올바르게 해석할 수 있도록 로컬 HTTP 서버를 실행합니다.

Packing Mirrors into Portable Artifacts

Kage는 사용자가 디렉토리 기반의 미러를 단일 파일로 압축하여 더 쉬운 공유와 장기 보관을 위해 사용할 수 있게 합니다.

ZIM Archives

Kage는 Kiwix와 같은 프로젝트에서 Wikipedia 및 Stack Overflow를 오프라인으로 저장하기 위해 사용하는 오픈 표준인 ZIM 파일 형식을 사용하여 미러를 패킹할 수 있습니다. ZIM은 문서화된 표준이므로 Kage로 생성된 파일은 모든 ZIM 리더러(Kiwix 데스크톱, Android, 또는 iOS 앱 등)에서 열 수 있어 벤더 종속성을 방지할 수 있습니다.

Self-Contained Binaries

--format binary 플래그를 사용하면 Kage는 웹사이트 아카이브를 Kage 실행 파일의 복본본에 결합합니다. 이를 통해 실행 시 사이트를 오프라인적으로 서비스하는 단일 바이너리가 생성되며, 대상 머신에 외부 의존성이나 ZIM 리더러가 필요하지 않습니다.

더 통합된 경험을 위해 webview 태그와 함께 Kage를 빌드하면, 이 바이너리들이 브라우저 탭 대신 네이티브 OS 창(macOS의 WKWebView, Windows의 WebView2, Linux의 WebKitGTK 사용)에서 사이트를 열 수 있게 됩니다.

Technical Architecture

Kage는 Go로 작성되었으며 여러 전문화된 패키지로 구성됩니다:

  • clone: 크롤링 프론티어, 렌더링 워커, 그리고 재개 상태를 관리합니다.
  • browser: 헤드리스 Chrome 제어 및 DOM 스냅샷을 처리합니다.
  • sanitize: 스크립트, 이벤트 핸들러, 및 URL을 제거합니다.
  • asset: CSS, 이미지, 폰트를 다운로드하고 로컬라이즈합니다.
  • zim: ZIM 리더러 및 라이터의 순수 Go 구현체입니다.

Community Insights and Alternatives\n

Hacker News의 커뮤니티 커뮤니티 논의에서는 웹 아카이빙에 대한 이 접근 방식에 대한 몇 가지 대와안과 고려 사항을을 다음과 같이 강조했습니다:

  • Alternative Tools: 사용자들은 모든 것을 base64 문자열을 사용하여 단일 HTML 파일로 패킹하는 강력한 대안으로 SingleFile을 언급했으며, 전통적인 위키 미러링을 위해 HTTrack을 언급했습니다.
  • Security Concerns: 일부 사용자들은 온라인에서 공유된 바이너리를 실행하는 것이 보안 위험이 될 수 있다고 지언했으나, 한 사용자는 Windows Security가 생성된 바이너리를 잠재적으로 원치하지 않는 소프트웨어로 플래그할 수 있다고 언급했습니다.
  • Comparison to wget: 이 도구구는 본질적으로 JavaScript-heavy한 페이지를 먼저 렌더링한 후 처리할 수 있는 wget --mirror의 더 현대적인 버전입니다.

"Ugly HTML 덤프는 '완벽한' 아카이브보다 더 유용할 때가 있습니다... 10년 전의 피드는 신중하게 보존된 (애플리케이션) 웹사이트보다 오늘날 더 사용하기 쉬운 경우가 많습니다."

이 정서는서는 Kage의 철학학의 우선순위가 복잡한 애플리케이션 상태 보존보다 단순하고 스크립트가 없는 HTML을 우선시하는 데 있음을 강조합니다.

Sources