Skip to content

Warky-Devs/WkMailSync

Repository files navigation

WkMailSync

Mail synchronization and backup tool in Go. Syncs IMAP→IMAP, IMAP→EML, Maildir→EML/Zip, or bulk-exports all users from a Virtualmin server.

Features

  • IMAP→IMAP sync with deduplication
  • IMAP→EML or IMAP→Zip export
  • Local Maildir as source
  • Virtualmin integration — enumerate domains/users via local CLI, SSH, or HTTP API
  • Zip output — one archive per user
  • Date range filtering
  • Subdirectory organization with auto-detected IMAP separator
  • Dry-run mode
  • Charset fallback, malformed MIME handling, auto-reconnect

Build

git clone https://github.com/Warky-Devs/WkMailSync.git
cd WkMailSync
go build ./cmd/WKMailSync

Requires Go 1.24+.

Quick Start

# IMAP → IMAP
./WKMailSync -src-host src.example.com -src-user u@src.com -src-pass p1 \
             -dest-host dst.example.com -dest-user u@dst.com -dest-pass p2

# IMAP → EML files
./WKMailSync -src-host src.example.com -src-user u@src.com -src-pass p1 \
             -output-dir /backup/mail

# IMAP → Zip
./WKMailSync -src-host src.example.com -src-user u@src.com -src-pass p1 \
             -output-dir /backup -output-format zip

# Maildir → EML files
./WKMailSync -config maildir.yaml

# Maildir → Zip
./WKMailSync -config maildir-zip.yaml

# Config file
./WKMailSync -config config.yaml

Maildir examples

maildir.yaml — export a local Maildir to EML files:

maildir_source:
  path: "/home/user/Maildir"
  user: "user"
  domain: "example.com"

output_dir: "/backup/mail"
dry_run: false

maildir-zip.yaml — same but compressed:

maildir_source:
  path: "/home/user/Maildir"
  user: "user"
  domain: "example.com"

output_dir: "/backup"
output_format: "zip"

Date filtering works with Maildir too:

maildir_source:
  path: "/home/user/Maildir"

output_dir: "/backup/mail"
date_from: "2024-01-01"
date_to: "2024-12-31"

Config File

source:
  host: "mail.example.com"
  port: "993"
  username: "user@example.com"
  password: "secret"
  use_tls: true
  insecure_tls: false

# IMAP destination (optional — omit if using output_dir)
destination:
  host: "mail2.example.com"
  port: "993"
  username: "user@example.com"
  password: "secret"
  use_tls: true

output_dir: "/backup/mail"   # omit for IMAP destination
output_format: "eml"         # eml (default) | zip
subdirectory: ""             # e.g. "Archive" → Archive/INBOX, Archive/Sent
date_from: "2024-01-01"      # optional
date_to: "2024-12-31"        # optional
dry_run: false

Maildir Source

Read directly from a local Maildir directory instead of IMAP:

maildir_source:
  path: "/home/user/Maildir"
  domain: "example.com"
  user: "user"

output_dir: "/backup/mail"
output_format: "zip"

Virtualmin Integration

Enumerate all domains and users, then sync each user's Maildir.

Local (run on the Virtualmin server itself):

virtualmin:
  mode: "local"
  domain: ""             # optional: filter to one domain
  maildir_base: ""       # optional: default /home/%s/homes/%s/Maildir

output_dir: "/backup/mail"
output_format: "zip"

SSH (run remotely):

virtualmin:
  mode: "ssh"
  ssh:
    host: "server.example.com"
    port: "22"
    username: "root"
    key_file: "/home/user/.ssh/id_rsa"
    # password: "secret"   # alternative to key_file

output_dir: "/backup/mail"
output_format: "zip"

API (Webmin HTTP API):

virtualmin:
  mode: "api"
  api:
    host: "server.example.com"
    port: "10000"
    username: "admin"
    password: "secret"
    use_tls: true
    insecure_tls: false
    ssh:                          # for reading mail over SFTP
      host: "server.example.com"
      username: "root"
      key_file: "/home/user/.ssh/id_rsa"

output_dir: "/backup/mail"
output_format: "zip"

CLI Flags

Flag Default Description
-config YAML config file
-src-host Source IMAP host
-src-port 993 Source IMAP port
-src-user Source username
-src-pass Source password
-src-tls true TLS for source
-src-insecure false Skip cert verification
-dest-host Destination IMAP host
-dest-port 993 Destination IMAP port
-dest-user Destination username
-dest-pass Destination password
-dest-tls true TLS for destination
-dest-insecure false Skip cert verification
-output-dir Output directory (EML/Zip)
-output-format eml eml or zip
-subdirectory Destination subdirectory prefix
-date-from Sync messages from date
-date-to Sync messages up to date
-dry-run false Preview without changes

Date Formats

YYYY-MM-DD · YYYY-MM-DDTHH:MM:SS · YYYY-MM-DD HH:MM:SS · RFC3339

Output Structure

EML: output_dir/FolderName/YYYYMMDD_HHMMSS_Subject_From.eml

Zip: output_dir/username_YYYYMMDD_HHMMSS.zip with FolderName/YYYYMMDD_HHMMSS_Subject_From.eml inside

Package Structure

cmd/WKMailSync/main.go     — CLI entry point
pkg/config/                — Config structs + YAML loading
pkg/source/                — MailSource interface, IMAP + Maildir implementations
pkg/output/                — MailOutput interface, EML + Zip + IMAP implementations
pkg/sync/                  — SyncEngine (source → output, filtering, dedup, stats)
pkg/connector/             — VirtualminConnector interface, local/SSH/API implementations

Troubleshooting

Connection refused / TLS error — check host, port, use_tls, try insecure_tls: true for self-signed certs.

Malformed MIME / charset errors — handled automatically with raw fallback copy.

Virtualmin CLI not foundlocal mode requires virtualmin binary in PATH on the target machine.

License

MIT

About

IMAP Mail backup tool

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors