[local-eml] 로컬 이메일 관리 도구
배경
내가 쓰는 메일 계정 중 하나는 저장 용량이 1GB다. 처음엔 넉넉해 보였지만, 첨부파일 몇 번 주고받다 보면 금방 차오른다. 용량이 가득 차면 결국 오래된 메일을 지워야 하는데, "이건 나중에 다시 볼 것 같은데…" 싶은 메일을 지우는 건 영 찜찜한 일이다.
거기에 더해 웹메일의 기본 검색과 페이지네이션도 내 취향은 아니었다. 원하는 메일을 찾으려면 페이지를 한참 넘겨야 했다.
어차피 대부분의 메일 시스템은 메일을 .eml 파일로 내려받을 수 있으니, 오래된 메일을 전부 내 PC로 옮겨두고 로컬에서 검색해서 읽으면 되지 않을까? 이렇게 하면 계정 용량은 비우면서도 메일은 하나도 잃지 않는다.
그렇게 만든 것이 Local Eml이다.
어떤 도구인가
Local Eml은 .eml 파일을 내 PC에 보관하고 읽는 개인용 아카이브 뷰어다. 브라우저에서 http://localhost:7878 을 열어 사용하고, 모든 데이터는 내 PC를 벗어나지 않는다.
중요한 건 Thunderbird나 Outlook 같은 이메일 클라이언트가 아니라는 점이다. 메일을 쓰거나 보내거나 답장할 수 없고, 서버의 메일함을 건드리지도 않는다. IMAP 연결도 복사본만 가져오는 읽기 전용이다. 평소 메일은 쓰던 클라이언트에서 그대로 보고, 오래 남겨두고 싶은 메일만 Local Eml에 옮겨두는 방식이다.
기술 스택
백엔드는 Go로 작성했다. 프론트엔드(Vue 3 + Vite)는 빌드 결과물을 Go의 embed로 바이너리에 통째로 넣었기 때문에, 배포물은 단일 실행 파일 하나다. 별도의 런타임도, 도커도 필요 없다.
저장소는 SQLite를 사용했다. 드라이버는 modernc.org/sqlite라는 순수 Go 구현체를 골랐는데, CGO가 필요 없어서 크로스 컴파일이 아주 편해진다. Makefile에서 GOOS/GOARCH만 바꿔주면 Linux, macOS, Windows 바이너리가 전부 나온다.
설치하면 kardianos/service를 통해 백그라운드 서비스로 등록되어 부팅 시 자동으로 시작된다. 브라우저만 열면 언제든 내 메일 라이브러리가 떠 있는 셈이다.
검색
이 프로젝트를 시작한 이유의 절반이 검색이었기 때문에, 검색에는 공을 좀 들였다.
전문 검색은 SQLite에 내장된 FTS5를 사용한다. 보낸 사람, 제목, 본문을 한 번에 검색하고, 한글을 비롯한 CJK 언어도 잘 검색된다.
그리고 한국인이라면 익숙할 초성검색도 넣었다. ㅎㄱ만 입력해도 한국이 걸리는 그 검색이다. 받는 메일이 대부분 한글이다 보니 이 기능이 체감상 가장 유용하다.
메일이 많아져도 괜찮을까 싶어 가상 메일 10만 건을 만들어 측정해보았다.
| 작업 | 메일 1만 건 | 메일 10만 건 |
|---|---|---|
| 목록 탐색 / 페이지 이동 | 1 ms 미만 | 1 ms 미만 |
| 검색 (일반적인 검색어) | 1 ms 미만 | 약 2 ms |
| 초성검색 | 약 5 ms | 약 50 ms |
| 대화별로 묶은 목록 | 약 85 ms | 약 0.9초 |
목록 탐색과 전문 검색은 10만 건에서도 사실상 즉시 응답한다. 웹메일에서 검색 결과를 기다리며 느꼈던 답답함이 여기엔 없다.
가져오기
.eml 파일이나 폴더, .zip 압축 파일을 끌어다 놓으면 된다. 파일 해시로 중복을 걸러내기 때문에 같은 메일을 여러 번 넣어도 두 번 들어오지 않는다.
파일을 일일이 내려받기 귀찮다면 IMAP으로 메일함에서 직접 복사본을 가져올 수도 있다. IMAP 프로필에 "새 메일을 백그라운드에서 받아오기"를 켜두면 마지막 동기화 이후 도착한 메일만 주기적으로 자동 수신한다. 이때 필요한 IMAP 비밀번호는 AES-256-GCM으로 암호화해서 저장하고, 암호화 키는 별도 파일(~/.local-eml/keys/secret.key, 권한 0600)에 분리해 보관한다. 토글을 끄면 저장된 비밀번호도 함께 삭제된다.
백업이 걱정된다면 라이브러리 전체를 .zip 하나로 내려받거나 AWS S3 버킷에 올릴 수 있다. 이미 올라간 파일은 건너뛰기 때문에 여러 번 실행해도 안전하다.
보안
메일은 민감한 데이터이기 때문에 몇 가지 원칙을 지켰다.
- 서버는
127.0.0.1에만 바인딩되어 네트워크에 전혀 노출되지 않는다 - HTML 메일은 격리된 iframe 안에서 표시되고, 외부 이미지는 기본적으로 차단된다 (추적 픽셀 방지)
- S3 시크릿 키와 세션 토큰은 저장하지 않고 매번 다시 입력받는다
설치
# Linux / macOS
curl -fsSL https://raw.githubusercontent.com/hwhang0917/local-eml/main/scripts/install.sh | sh
# Windows (PowerShell)
irm https://raw.githubusercontent.com/hwhang0917/local-eml/main/scripts/install.ps1 | iex
설치가 끝나면 브라우저에서 http://localhost:7878 을 열면 된다.
마치며
시작은 "1GB 용량이 부족하다"는 단순한 불만이었지만, 만들고 나니 생각보다 쓰임새가 많다. 계정 용량 걱정 없이 메일을 지울 수 있고, 검색은 빠르고, 무엇보다 내 메일이 내 PC에 파일로 남아 있다는 안심이 있다.
다만 회사 메일에 사용할 생각이라면 사내 보안 정책에 어긋나지 않는지 먼저 확인하자.
메일함 용량 경고에 시달리고 있다면 한번 사용해보길 바란다. 저장소는 여기에 있다!