SkimMail
Lướt nhanh mọi hộp thư. Trình đọc email đọc-trước (read-first), đa tài khoản, tự host, nhẹ — lõi IMAP + OAuth Gmail/Outlook — đóng gói thành một file binary Go duy nhất nhúng sẵn React SPA. Không cần dịch vụ ngoài.
Giấy phép: Business Source License 1.1 (phần mềm độc quyền; chuyển sang AGPL năm 2030) · Bảo mật: SECURITY.md · Tài liệu: Wiki
Mọi thứ bên dưới đều đã phát hành. Mail đa tài khoản, egress riêng cho từng tài khoản, rules và cảnh báo, thông báo, sao lưu & khôi phục, plugin, remote access và đa người dùng — tất cả đã có trong bản hiện tại; AI Triage là tính năng lớn duy nhất còn nằm trong roadmap. Chi tiết từng bản phát hành:
CHANGELOG.md.
Tính năng
Đọc
- Đọc IMAP đa tài khoản — thêm account bằng host/port + app-password. OAuth cho Gmail & Outlook (XOAUTH2 qua IMAP) là tùy chọn và dùng app credentials Google/Azure của riêng bạn.
- Hộp thư hợp nhất xuyên mọi tài khoản, gom luồng (threading) nhẹ, giao diện 3 khung với khung đọc cô lập. Ảnh từ xa vẫn bị chặn cho tới khi bạn yêu cầu — và khi đó SkimMail tải ảnh, không phải trình duyệt của bạn, đi qua đúng egress của tài khoản đó, nên máy chủ người gửi không thấy bạn.
- Nhóm tài khoản — gom nhiều tài khoản vào các nhóm có tên + màu, đọc mail theo từng nhóm.
- Thời gian thực: mail mới đẩy qua IMAP IDLE → WebSocket, kèm poll dự phòng để mail vẫn về nếu IDLE rớt — backend đồng bộ cả khi không có client mở.
- Tìm kiếm 2 tầng — full-text cục bộ nhanh (SQLite FTS5) + tùy chọn fallback phía server để tìm cả mail ngoài phạm vi đã cache.
- Đọc nhanh — tạm ẩn (snooze), ghim (pin), Đã gắn sao trên mọi tài khoản, bundles chia hộp thư, chọn nhiều + thao tác hàng loạt, chuyển vào thư mục bất kỳ có nút hoàn tác, sender VIP / mute liệt kê và gỡ được ngay trong Settings, hủy đăng ký 1 chạm (RFC 8058), và một danh sách rút gọn hủy đăng ký xếp hạng những người gửi hàng loạt mà bạn hầu như không đọc — chọn theo chính header List-Unsubscribe của người gửi, nên thư bảo mật tài khoản không bao giờ bị đưa vào.
- Bàn phím trước hết (kiểu Superhuman) + chế độ Focus/triage + command palette (⌘K) + PWA (cài được, chạy offline phần vỏ) + đa ngôn ngữ (English / Tiếng Việt / 中文, giao diện sáng & tối).
- Server keywords — những cờ mà các mail client khác của bạn đã đặt được hiện thành chip chỉ-đọc. Mặc định tắt: phần lớn hộp thư không có cờ nào, và một hàng chip rỗng còn tệ hơn là không có hàng nào.
- Chế độ an toàn khi chụp màn hình — mọi địa chỉ, tên, tiêu đề, dòng xem trước và tên tệp đính kèm hiển thị đều được thay bằng dữ liệu giả trông như thật, và thân thư không render chút nào, nên bạn có thể báo lỗi hay viết bài với một hộp thư thật ngay trên màn hình. Mặc định tắt, theo từng thiết bị.
Mỗi tài khoản một đường ra riêng
- Egress theo từng tài khoản. Định tuyến mail của mỗi tài khoản qua proxy
SOCKS5, proxy HTTP, tunnel WireGuard nhúng, hoặc một relay
serverless bạn tự triển khai — dán một file vào Cloudflare Workers, hoặc chạy
skimmail relaytrong container. Công việc và cá nhân không buộc phải dùng chung một IP ra. Các trình đọc mail khác thường để việc này cho công cụ ngoài (wireproxy, VPN theo ứng dụng, một container thứ hai); ở đây nó chỉ là một ô trong tài khoản. - Bằng chứng, không chỉ là cấu hình. Mỗi kết nối báo về địa chỉ IP công khai mà nó thực sự đi ra — proxy, tunnel, relay và cả Direct — và SkimMail cảnh báo khi hai tài khoản đáng lẽ tách biệt lại đi ra từ cùng một địa chỉ. Nút Test mở một kết nối thật qua egress đó và báo độ trễ.
- Fail-closed. Tắt một kết nối không bao giờ đẩy các tài khoản của nó về kết nối trần: chúng chuyển sang degraded và dừng đồng bộ cho tới khi bạn chủ động chọn Direct — nên một egress đã tắt không thể âm thầm lộ IP nhà bạn.
Tự động hoá & vận hành
- Rules & Signals — khớp mail đến theo người gửi, tiêu đề (chữ thường hoặc regex), tài khoản hoặc nhóm, hoặc "trông giống mã một lần", rồi báo về một kênh, hiện toast trong app, gửi push, hoặc gắn tag mà bạn bấm vào để lọc. Mail chứa mã một lần có chip OTP để copy mã; bản thân mã không bao giờ được lưu.
- Thông báo, sáu kênh — webhook thường, Telegram, Slack, Discord, Microsoft Teams hoặc Google Chat, thêm bao nhiêu tuỳ bạn, mỗi kênh có nút Send test riêng — cộng thêm Web Push về trình duyệt và điện thoại (khoá VAPID chuẩn do SkimMail tự sinh; không cần tài khoản Firebase), kèm giờ yên lặng, quyền riêng tư nội dung và công tắc theo từng tài khoản.
- Sức khoẻ đồng bộ — tài khoản liên tục lỗi sẽ tự dừng thay vì dội vào nhà cung cấp; một bảng hiển thị mọi tài khoản theo Stopped / Degraded / Paused với Resume, Retry, Stop một chạm, và cảnh báo bắn ra khi một tài khoản ngừng đồng bộ, một proxy/tunnel chết, hoặc một đăng nhập OAuth sắp hết hạn.
- Sao lưu & khôi phục — bản chụp mã hoá của toàn bộ instance (tài khoản, mail và cấu hình), khôi phục được lên bất kỳ máy chủ SkimMail nào, kể cả máy dùng database khác — cộng thêm sao lưu theo lịch về thư mục cục bộ hoặc bất kỳ lưu trữ tương thích S3 nào (MinIO, Cloudflare R2, Backblaze B2, Wasabi, AWS S3).
- Remote access không cần mở cổng — đưa SkimMail ra ngoài qua Cloudflare Tunnel hoặc Tailscale, kèm mã QR để mở trên điện thoại. Các chương trình đó và engine WireGuard là plugin tải về theo nhu cầu, đối chiếu với một chỉ mục đã ký và ghim SHA256; cài, cập nhật và gỡ chúng ngay tại Settings ▸ Plugins.
- Sync về xa tới đâu, và giữ offline những gì — độ sâu sync theo từng tài khoản (mặc định 30 ngày, hoặc toàn bộ lịch sử), đặt chung ở Settings ▸ Sync và ghi đè được cho từng hộp thư. Thân thư bạn đã mở được cache ở máy nên đọc lại không tốn gì, kèm prefetch nền có thể tắt nếu bạn không muốn nó đọc trước.
- Thư của bạn nằm ở đâu, và nằm bao lâu — thân thư đã cache nằm trong một blob store do bạn chọn: hệ thống tệp tại máy, hoặc bất kỳ bucket tương thích S3 nào, đổi qua lại ngay ở Settings ▸ Storage với nút kiểm tra kết nối thật và một lượt migration chạy tiếp được nếu bị ngắt. Phần lưu giữ nằm ở Settings ▸ Security: mức đang dùng, trần dung lượng, giữ thân thư bao nhiêu ngày, và lệnh purge thủ công. SQLite là cơ sở dữ liệu mặc định, còn PostgreSQL và MySQL đã được compile sẵn trong mọi bản phát hành — không cần dựng lại.
- Cấu hình trong trình duyệt, không phải trong file text — URL công khai, app OAuth và chế độ đăng nhập là các thiết lập ngay trong app, còn thứ gì đặt bằng biến môi trường vẫn thắng và hiện ra ở đó dưới dạng khoá, kèm tên biến cần xoá. Tự cập nhật trong app cài bản mới chỉ bằng một cú bấm trên các bản cài binary/apt, còn Settings ▸ Logs cho xem log trực tiếp, đổi log level lúc chạy và cấu hình xoay vòng.
Bảo mật & đa người dùng
- Đa người dùng tách biệt thật sự —
AUTH_MODE=userscho mỗi người tài khoản, mail và thiết lập của riêng mình, người khác không thấy được, với vai trò owner, operator hoặc viewer; tạo bằngskimmail user add. Instance một người vẫn đơn giản y như trước. - Lớp bảo mật — một mã claim dùng một lần chặn ngay lần đăng nhập đầu tiên; credential, token OAuth và nội dung thư đã cache đều mã hoá at-rest (AES-256-GCM); cùng với rate-limit + lockout đăng nhập, 2FA, khoá màn hình khi rảnh do server cưỡng chế và phủ lên mọi tab đang mở chứ không chỉ tab bạn vừa chạm, kiểm tra CSRF/Origin, chống SSRF, bản phát hành và chỉ mục plugin đều được ký, và audit log chỉ ghi thêm.
- Của bạn, và vẫn cứ là của bạn — một binary Go duy nhất với React SPA nhúng bên trong, SQLite tích hợp sẵn (PostgreSQL và MySQL tuỳ chọn; MySQL là thử nghiệm), đồng bộ nền luôn-bật, và không phone-home. Community Edition miễn phí; key Sponsor và Pro được xác minh hoàn toàn offline, và key hết hạn không bao giờ lấy đi thứ bạn đã thêm.
Yêu cầu
Chỉ cần Docker — SQLite tích hợp sẵn, không cần dịch vụ ngoài.
(Build từ mã nguồn hoặc đóng góp? Xem README.dev.md.)
Bắt đầu nhanh
Không cần mã nguồn — tải file compose đã publish (nó pull sẵn image dựng sẵn):
curl -fsSLO https://lyquyduong.github.io/skimmail/docker-compose.yml
docker compose up -d # → http://localhost:8080 (SQLite + filesystem)
Hoặc chạy image thuần (distroless + non-root; dữ liệu ở volume /data):
docker run -d --name skimmail -p 8080:8080 -v skimmail-data:/data \
-e AUTH_MODE=passphrase ghcr.io/lyquyduong/skimmail:latest
Một image, một gói. WireGuard egress nhúng, PostgreSQL, MySQL và S3 đều nằm
trong bản build mặc định — engine WireGuard là một plugin ghim SHA256 mà SkimMail
tự tải lần đầu bạn thêm tunnel, nên không phải cài thêm gì và không phải chọn
image thứ hai. Bản riêng skimmail-wg đã ngừng từ 1.7.0; nếu bạn còn gói apt đó,
apt remove skimmail-wg là an toàn.
Cài trên Ubuntu / Debian (apt)
curl -fsSL https://lyquyduong.github.io/skimmail/apt/skimmail.gpg \
| sudo tee /usr/share/keyrings/skimmail.gpg >/dev/null
echo "deb [signed-by=/usr/share/keyrings/skimmail.gpg] https://lyquyduong.github.io/skimmail/apt stable main" \
| sudo tee /etc/apt/sources.list.d/skimmail.list
sudo apt update && sudo apt install skimmail # chạy như systemd service → http://localhost:8080
Cấu hình ở /etc/default/skimmail; dữ liệu ở /var/lib/skimmail; log nằm trong
systemd journal (sudo journalctl -u skimmail -f) và file xoay vòng tại
/var/log/skimmail/skimmail.log — level, xoay vòng, truncate và trình xem
realtime nằm ở Settings ▸ Logs. Nâng cấp qua apt upgrade. Mọi kênh phát hành
(image, .deb, apt repo) đều ship từ GitHub — xem DISTRIBUTION.md.
Đăng nhập lần đầu
Mở http://localhost:8080. Trước khi cho bạn tạo bất cứ thứ gì, SkimMail hỏi một mã claim dùng một lần đã in ra lúc khởi động đầu tiên — đây là thứ ngăn người truy cập trước chiếm mất instance của bạn:
sudo journalctl -u skimmail | grep 'claim code' # apt (cần sudo: journal chỉ root đọc được)
docker compose logs skimmail | grep 'claim code' # docker compose (tên service; container thật tên skimmail-skimmail-1)
docker logs skimmail 2>&1 | grep 'claim code' # docker run (chỉ chạy nếu bạn đã truyền --name skimmail như trên)
Mất mã? Tạo mã thay thế — mã cũ hết hiệu lực:
sudo -u skimmail skimmail --data-dir /var/lib/skimmail claim-code --rotate
Trên mạng kín, bạn có thể bỏ hẳn cổng này bằng SKIMMAIL_SKIP_CLAIM=1.
Sau đó, chế độ auth mặc định là passphrase: mật khẩu bạn nhập lần đầu tiên sẽ
trở thành passphrase chính — hãy nhớ nó (dùng để đăng nhập lại). Để trống ô
username.
Thêm tài khoản mail
Thêm tài khoản IMAP: email · host (vd imap.gmail.com) · port 993 · bảo mật
TLS · app password.
Gmail dùng được app password riêng (không phải mật khẩu thường) — hai cú bấm, không cần Cloud project. Outlook.com và Hotmail thì không: Microsoft không cấp app password cho tài khoản cá nhân và đã tắt xác thực cơ bản, nên những hộp thư đó buộc phải dùng OAuth.
Muốn bật nút "Thêm bằng Google/Microsoft", hãy đặt OAuth credentials bên dưới. Không bắt buộc phải có
BASE_URLcông khai — instance không có thì hoàn tất đăng nhập bằng cách dán địa chỉ mà trình duyệt đáp xuống.
Bấm ↻ Sync (hoặc đợi poll nền). Sau đó mail mới đẩy về thời gian thực qua WebSocket.
Sử dụng
- Tìm kiếm — gõ vào ô search (Enter). Khi chọn 1 account, nút "Search server ↗" còn tìm trên máy chủ mail và cache kết quả.
- Nhóm — tạo nhóm tài khoản ở Settings → Groups; chọn 1 nhóm để chỉ đọc mail của các tài khoản trong nhóm đó.
- Bundles — lọc danh sách theo Primary / Newsletter / Transactional / Notifications. 💤 Snoozed xem mail đang tạm ẩn.
- Chọn nhiều — tick các dòng để bulk read / archive / delete.
- Khung đọc — 🗄 Archive · 🗑 Delete (có Undo) · 💤 Snooze · 📌 Pin · ✉️ Unsubscribe · ★ VIP · 🔇 Mute.
- Bàn phím —
?hiện toàn bộ phím tắt:j/kdi chuyển ·Enter/omở ·earchive ·#delete ·ssnooze ·xchọn ·Spacexem nhanh ·/tìm kiếm ·fchế độ Focus ("Get to Zero") ·Escđóng. - Tag — tự gắn tag ngay trong danh sách thư hoặc khung đọc, hoặc để rule làm
hộ; bấm chip tag để lọc, hoặc gõ
tag:tênvào ô tìm kiếm. Gỡ tag ra cũng dễ như gắn vào, và một rule mới có thể áp lên thư đã có sau khi cho bạn xem trước nó sẽ chạm vào bao nhiêu thư. - Ảnh — banner ảnh bị chặn có Show images, kèm Always hoặc Never from this sender (đều đảo ngược được; công tắc cho cả instance nằm ở Settings ▸ Bảo mật).
- PWA — cài từ thanh địa chỉ trình duyệt; phần vỏ app chạy offline.
- Ngôn ngữ / giao diện — đổi EN / VI / 中 và sáng/tối ở sidebar.
Cấu hình
Cấu hình qua biến môi trường (12-factor) — xem .env.example.
Từ 1.9.0 phần lớn thiết lập cũng sửa được ngay trong app (Settings), và giá trị
đặt bằng biến môi trường luôn thắng, hiện ở đó dưới dạng khoá. Tham chiếu đầy đủ —
mọi biến, các mặt phẳng cấu hình và thứ gì đè lên thứ gì — nằm ở
wiki ▸ Cấu hình.
| Biến | Mặc định | Mục đích |
|---|---|---|
AUTH_MODE |
passphrase |
passphrase (một mật khẩu chung) hoặc users (tài khoản có tên + phân quyền). Từ 1.10.0 users là đa người dùng thật: mỗi người sở hữu hộp thư của mình và không thấy của người khác, vai trò là owner, operator hoặc viewer. Tạo bằng skimmail user add. Còn một giá trị thứ ba, none, tắt hẳn xác thực; nó đòi thêm SKIMMAIL_ALLOW_AUTH_NONE=1 trong environment của tiến trình, vì auth.mode ghi được từ cả UI lẫn CLI nên một phiên bị chiếm không được phép tự hạ cấp cả instance. |
DATA_DIR |
./data |
SQLite DB, master key, blobs |
LISTEN_ADDR |
:8080 |
địa chỉ lắng nghe |
BASE_URL |
– | URL công khai — cần cho flow OAuth redirect, WebSocket và PWA. Không có nó OAuth vẫn chạy qua flow dán tay. |
TRUST_PROXY |
false |
tin X-Forwarded-* sau reverse proxy |
TRUSTED_PROXIES |
– | danh sách CIDR (phân tách dấu phẩy) được tin là chặng proxy khi TRUST_PROXY=true (mặc định: chỉ loopback/private) |
TRUSTED_ORIGINS |
– | origin được phép thêm cho CORS/CSRF (phân tách dấu phẩy) |
BACKGROUND_POLL_INTERVAL |
5m |
chu kỳ poll dự phòng cho mọi account |
MAX_CONCURRENT_SYNCS |
4 |
số mailbox đồng bộ cùng lúc tối đa |
SYNC_RATE_PER_MIN |
10 |
số lượt sync khởi động mỗi phút (stagger) |
SYNC_DEPTH_DAYS |
30 |
cửa sổ sync header (0 = toàn bộ lịch sử) |
GOOGLE_CLIENT_ID / _SECRET |
– | OAuth app Gmail (tùy chọn) |
MICROSOFT_CLIENT_ID / _SECRET |
– | OAuth app Outlook (tùy chọn) |
Bảo mật
Credential, token OAuth và nội dung thư đã cache được mã hoá at-rest
(AES-256-GCM). Lần đăng nhập đầu tiên bị chặn bởi mã claim dùng một lần. Server áp
rate-limit + lockout đăng nhập, kiểm tra CSRF/Origin, chống SSRF cho fetch ra
ngoài, security headers nghiêm ngặt + iframe email cô lập, khoá màn hình khi rảnh
do server cưỡng chế, và audit log append-only (GET /api/audit). Xem
SECURITY.md để biết tư thế bảo mật đầy đủ và cách báo lỗ hổng.
Gỡ cài đặt (xoá hoàn toàn)
Bản thân việc gỡ cài đặt không xoá dữ liệu — tài khoản, cache mail và master
key mã hoá nằm trong Docker volume hoặc /var/lib/skimmail. Các bước đánh dấu
⚠ bên dưới xoá chúng vĩnh viễn (không khôi phục được nếu không có backup).
Docker Compose
docker compose down -v # ⚠ dừng + xoá container VÀ volume dữ liệu
docker rmi ghcr.io/lyquyduong/skimmail:latest 2>/dev/null
rm docker-compose.yml # file compose đã tải về
Docker (docker run)
docker rm -f skimmail
docker volume rm skimmail-data # ⚠ toàn bộ dữ liệu
docker rmi ghcr.io/lyquyduong/skimmail:latest
APT (Ubuntu / Debian)
sudo apt purge skimmail # dừng service, xoá binary, unit systemd
# và /etc/default/skimmail
sudo rm -rf /var/lib/skimmail # ⚠ dữ liệu — apt cố tình giữ lại
sudo rm -rf /var/log/skimmail # file log + các bản đã xoay
sudo userdel skimmail # system user được tạo lúc cài
# gỡ repo APT + key đã thêm:
sudo rm -f /etc/apt/sources.list.d/skimmail.list /usr/share/keyrings/skimmail.gpg
sudo apt update
Binary thủ công (tarball) — dừng tiến trình (hoặc unit systemd bạn tự tạo),
rồi xoá binary và thư mục dữ liệu (DATA_DIR, mặc định ./data cạnh binary).
Cho lập trình viên
Build từ mã nguồn, chế độ dev (hot reload), thiết lập VS Code, build tags, tests và
bố cục dự án nằm ở README.dev.md.
Giấy phép & các bậc
SkimMail là phần mềm độc quyền (proprietary). Được cấp phép theo
Business Source License 1.1 (Licensor: Solutions101 (S101)). Mã nguồn là
private; chỉ binary đã build được phân phối cho người dùng.
SPDX: BUSL-1.1.
Ba bậc (tier)
- Community Edition — Miễn phí, 10 tài khoản / 1 tài khoản đăng nhập / 3 proxy / 2 nhóm / 5 GB lưu trữ (không cần license key)
- Sponsor Edition — Lời cảm ơn dành cho người ủng hộ qua GitHub Sponsors / backer (25 tài khoản / 3 tài khoản đăng nhập / 5 proxy / 5 nhóm / 15 GB)
- Pro Edition — License key trả phí; không giới hạn tài khoản/proxy/nhóm/dung lượng + dịch vụ AI Triage trong tương lai
Chi tiết: COMMERCIAL-TERMS.md. Giải thích đầy đủ (EN + VI):
docs/LICENSING.md. Thắc mắc về giấy phép: xem SECURITY.md.
Chuyển đổi giấy phép (2030)
Sau ngày 23/07/2030, SkimMail sẽ tự động chuyển sang AGPL-3.0-or-later. Trước ngày đó, mã nguồn vẫn là độc quyền.
Ghi chú khác
- Thương hiệu: tên "SkimMail" không nằm trong phạm vi giấy phép mã nguồn (xem
TRADEMARK.md) - Thư viện bên thứ ba: danh sách giấy phép trong
NOTICE - Quyền riêng tư: không phone-home; dữ liệu thu thập cho Pro/Sponsor là tùy chọn (xem
PRIVACY.md) - Đóng góp: cần ký CLA
- Thao tác với license key: xem
LICENSE-SIGNING.md(chỉ dành cho maintainer)