imapsync

由于自己手上的邮箱很多,难免会遇见迁移邮件这种情况,当然好久以前就考虑过了,因此入手了永久个人版的 eM Client。eM Client 固然好用,但我希望不用客户端就直接迁移邮件,因此选择试试 imapsync

Official imapsync migration tool ( release 2.261 ) (lamiral.info)

What is imapsync

imapsync 是一款用于在不同 IMAP 邮件系统之间进行邮件迁移和同步的开源工具。它可以在两个 IMAP 帐户之间同步邮件,并将邮件夹,子文件夹,邮件和其他邮件元数据(如已读/未读标记,标签和标记)复制到目标帐户

imapsync 支持许多 IMAP 服务器和服务,包括 Gmail,Yahoo Mail,Microsoft Exchange,Zimbra 等,并且具有各种功能,例如对话模式,只同步某个时间段的邮件,同时复制多个源帐户等

作者官网上提供付费商业支持(可获得 Windows 版本的 imapsync),免费则不提供支持及 Windows 版本的 imapsync

Installation

下面以 Debian 操作系统为例,imapsync 的要求是 Debian 版本 >= 7.x,及支持 Debian 9 Stretch, 10 Buster, 和 11 Bullseye

Prerequisites

  • 伺服器 CPU 任意(作者写的),不要太拉就行,个人推荐 CPU 2核比较合适
  • 伺服器 RAM 至少为 500MB 以上,个人推荐 RAM 为 2GB 比较合适
  • 伺服器 Disk space 至少 100MB 以上,现在基本都能达到
  • Apache2 环境或 NGINX 环境

本文使用 Akamai Cloud (Linode) 的高性能计算实例(Premium 4GB),并由 Akamai Cloud Marketplace 提供的 LAMP Stack 快速搭建 Apache2 环境

Akamai Cloud (Linode)

Akamai Cloud (Premium 4 GB) - Geekbench

Deploy a LAMP Stack through the Linode Marketplace | Linode Docs

如果你有 Hetzner 账号,也可以用 Hetzner 来新建伺服器进行部署 Apache 环境

Hetzner Cloud Referral Link

Hetzner LAMP Deploy

Install dependencies

确保有足够的权限运行下面的命令,以 root 权限 或是通过 sudo 运行

apt install -y            \
  libauthen-ntlm-perl     \
  libcgi-pm-perl          \
  libcrypt-openssl-rsa-perl   \
  libdata-uniqid-perl         \
  libencode-imaputf7-perl     \
  libfile-copy-recursive-perl \
  libfile-tail-perl        \
  libio-socket-inet6-perl  \
  libio-socket-ssl-perl    \
  libio-tee-perl           \
  libhtml-parser-perl      \
  libjson-webtoken-perl    \
  libmail-imapclient-perl  \
  libparse-recdescent-perl \
  libproc-processtable-perl \
  libmodule-scandeps-perl  \
  libreadonly-perl         \
  libregexp-common-perl    \
  libsys-meminfo-perl      \
  libterm-readkey-perl     \
  libtest-mockobject-perl  \
  libtest-pod-perl         \
  libunicode-string-perl   \
  liburi-perl              \
  libwww-perl              \
  libtest-nowarnings-perl  \
  libtest-deep-perl        \
  libtest-warn-perl        \
  make                     \
  time                     \
  cpanminus

Take imapsync and test

#Github是下载源码或是在作者官网下载imapsync源码,作者官网上的源码一般是最新的,其二选一

wget -N https://raw.githubusercontent.com/imapsync/imapsync/master/imapsync

wget -N https://imapsync.lamiral.info/imapsync

#赋予imapsync执行权限

chmod +x imapsync
  
#检查是否缺dependency,是否能够完成imapsync的基本操作

./imapsync

#testalive检测imapsync是否完成测试

./imapsync --testslive

作者提供的测试示例

host1: test1.lamiral.info, user1: test1, password1: secret1

host2: test2.lamiral.info, user2: test2, password2: secret2

imapsync \
   --host1 test1.lamiral.info --user1 test1 --password1 secret1 \
   --host2 test2.lamiral.info --user2 test2 --password2 secret2

Bash Script

上述步骤可以直接写成脚本,如下示例

#!/bin/bash

# Define color codes for printing
GREEN="\033[0;32m"
RED="\033[0;31m"
RESET="\033[0m"

# List of dependencies
dependencies=(
  libauthen-ntlm-perl
  libcgi-pm-perl
  libcrypt-openssl-rsa-perl
  libdata-uniqid-perl
  libencode-imaputf7-perl
  libfile-copy-recursive-perl
  libfile-tail-perl
  libio-socket-inet6-perl
  libio-socket-ssl-perl
  libio-tee-perl
  libhtml-parser-perl
  libjson-webtoken-perl
  libmail-imapclient-perl
  libparse-recdescent-perl
  libproc-processtable-perl
  libmodule-scandeps-perl
  libreadonly-perl
  libregexp-common-perl
  libsys-meminfo-perl
  libterm-readkey-perl
  libtest-mockobject-perl
  libtest-pod-perl
  libunicode-string-perl
  liburi-perl
  libwww-perl
  libtest-nowarnings-perl
  libtest-deep-perl
  libtest-warn-perl
  make
  time
  cpanminus
)

# Check and install missing dependencies
missing_dependencies=()
for dependency in "${dependencies[@]}"; do
  if ! dpkg -s "$dependency" >/dev/null 2>&1; then
    missing_dependencies+=("$dependency")
  fi
done

if [ "${#missing_dependencies[@]}" -gt 0 ]; then
  echo -e "${RED}Missing dependencies:${RESET} ${missing_dependencies[@]}"
  echo -e "${GREEN}Installing missing dependencies...${RESET}"
  apt update
  apt install -y "${missing_dependencies[@]}"
else
  echo -e "${GREEN}All dependencies are already installed.${RESET}"
fi

# Download imapsync script to /usr/local/bin and add execute permission
imapsync_path="/usr/local/bin/imapsync"

# Remove existing imapsync file if present
if [ -f "$imapsync_path" ]; then
    echo -e "${GREEN}Removing existing imapsync file...${RESET}"
    rm "$imapsync_path"
fi

# Prompt the user to choose a download source
echo "Please choose the source to download imapsync:"
echo "1. Download from GitHub"
echo "2. Download from imapsync official website"
read -p "Enter your choice (1 or 2): " choice

# Depending on user choice, set the download URL
if [ "$choice" == "1" ]; then
    download_url="https://raw.githubusercontent.com/imapsync/imapsync/master/imapsync"
elif [ "$choice" == "2" ]; then
    download_url="https://imapsync.lamiral.info/imapsync"
else
    echo -e "${RED}Invalid choice.${RESET}"
    exit 1
fi

# Download the latest imapsync file and add execute permission
wget -N -P /usr/local/bin "$download_url" && chmod +x "$imapsync_path"

echo -e "${GREEN}Dependency installation and imapsync download are complete.${RESET}"

Start to use

Command Line Arguments

中括号 [] 里是参数后所接的数据类型

--host1 [str]:源或“来自”IMAP服务器的主机名或IP地址。
--port1 [int]:连接到 host1 上的端口号。可选,默认端口是知名端口 IMAP/143 或 IMAPS/993。
--user1 [str]:登录 host1 的用户名。
--password1 [str]:user1 的密码。

--host2 [str]:“目标”IMAP服务器的主机名或IP地址。
--port2 [int]:连接到 host2 上的端口号。可选。
--user2 [str]:登录 host2 的用户名。
--password2 [str]:user2 的密码。

--showpasswords :在输出中显示密码而不是“MASKED”。只需阅读即可重新启动完整运行日志中使用的命令行,或调试密码。这根本不是一个安全的做法!
--passfile1 [str] : user1 的密码文件。 它必须包含密码在第一行。 此选项避免显示命令行上的密码就像 --password1 一样。
--passfile2 [str] :user2 的密码文件。

Common Imap Server

icloud: imap.mail.me.com

Microsoft 365 / Outlook: outlook.office365.com

Gmail: imap.gmail.com

Yahoo: imap.mail.yahoo.com

Yandex: imap.yandex.com

Common Command Line

#未指定子文件夹的情况下将[user1]根目录所有mail同步至[user2]中根目录

imapsync \
     --host1 [host1] --user1 [user1] --password1 [password1] \
     --host2 [host2] --user2 [user2] --password2 [password2]
#用 --subfolder 参数指定子文件夹,将[user1]中[subfolder1]目录的mail同步至[user2]中[subfolder2]目录

imapsync \
     --host1 [host1] --user1 [user1] --password1 [password1] --subfolder1 [subfolder1] \
     --host2 [host2] --user2 [user2] --password2 [password2] --subfolder2 [subfolder2]
imapsync \
     --host1 [host1] --user1 [user1] --passfile1 [password1 path] --subfolder1 [subfolder1] \
     --host2 [host2] --user2 [user2] --passflie2 [passflie2 path] --subfolder2 [subfolder2]

Using Online "X" Service

考虑到用命令行操作不方便,作者弄了个 WebUI 操作界面来简单迁移邮件,当然功能比较有限,这里可以自己搭建一个和作者同款 WebUI

Download Assets

如下脚本只是将 WebUI 所需要的静态资源下载并放在 /var/www/html/imapsync/X/ 路径下中,请根据自己网站目录自行调整

#!/bin/bash

# Create the directory
mkdir -p /var/www/html/imapsync/X/

# Change to the newly created directory
cd /var/www/html/imapsync/X/

# Download the necessary files
wget -N \
https://imapsync.lamiral.info/X/imapsync_form_extra.html \
https://imapsync.lamiral.info/X/imapsync_form.css \
https://imapsync.lamiral.info/X/imapsync_form.js \
https://imapsync.lamiral.info/X/logo_imapsync_Xn.png

# Create a symbolic link
ln -s imapsync_form_extra.html index.html

# Print completion message
echo "Installation complete. Please check the following link:"
echo "http://imapsync.mydomain.com/imapsync/X/imapsync_form_extra.html"
echo "Or the safer link:"
echo "https://imapsync.mydomain.com/imapsync/X/imapsync_form_extra.html"

Apache Configuration

Apache 需要正确配置确保,已经加载了 mod_cgi.so 这个模块。你可以在Apache的配置文件(如 httpd.confapache2.conf)中添加以下行来加载这个模块

LoadModule cgi_module /usr/lib/apache2/modules/mod_cgi.so

如果没有配置文件,可以在 /etc/apache2/sites-available/ 目录下创建一个新的配置文件,如 172-232-184-71.ip.linodeusercontent.com.conf

编辑此配置文件,确保加入以下配置

ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
<Directory "/usr/lib/cgi-bin">
    AllowOverride None
    # Next line "no-gzip 1" is to avoid output buffering, 
    # clients can then see the log during the sync
    SetEnv no-gzip 1
    Options +ExecCGI -MultiViews

    # Choose either one or the other, depending on your Apache version
    # Lines beginning with # are ignored

    # For Apache 2.2
    #Order allow, deny
    #Allow from all

    # Apache 2.4
    Require all granted
</Directory>

示例站点配置如下所示

ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
<Directory "/usr/lib/cgi-bin">
    AllowOverride None
    # Next line "no-gzip 1" is to avoid output buffering, 
    # clients can then see the log during the sync
    SetEnv no-gzip 1
    Options +ExecCGI -MultiViews

    # Choose either one or the other, depending on your Apache version
    # Lines beginning with # are ignored

    # For Apache 2.2
    #Order allow, deny
    #Allow from all

    # Apache 2.4
    Require all granted
</Directory>

<VirtualHost *:80>
      ServerName 172-232-184-71.ip.linodeusercontent.com
   ServerAlias www.172-232-184-71.ip.linodeusercontent.com
      DocumentRoot /var/www/172-232-184-71.ip.linodeusercontent.com/public_html
   ErrorLog /var/log/apache2/error.log
   CustomLog /var/log/apache2/access.log combined
   <files xmlrpc.php>
   order allow,deny
   deny from all
   </files>
RewriteEngine on
RewriteCond %{SERVER_NAME} =www.172-232-184-71.ip.linodeusercontent.com [OR]
RewriteCond %{SERVER_NAME} =172-232-184-71.ip.linodeusercontent.com
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>

如果 apache 非版本 2.4,请根据版本取消相应注释,并注释 apache 2.4

Copy imapsync to cgi-bin

根据上面 Apache 的配置,需要把 /usr/local/bin/imapsync 复制到 /usr/lib/cgi-bin

service apache2 restart 重启 Apache 服务

Check imapsync Status

browser 端上 /cgi-bin/imapsync 下检查是否正常运行

server 端上通过以下命令行检查是否正常运行

wget -nv -S -O-  http://localhost/cgi-bin/imapsync?testslive=1

imapsync 启动测试时日志反馈中出现 200 OK to sync IMAP boxes 状态即正常

imapsync WebUI

The limitation of imapsync

如果使用 NGINX 则还要麻烦一些,前几个月时已经问过作者,不过他也只会 apache,我使用 NGINX 搭建 WebUI 没有成功

Reference

Official imapsync migration tool ( release 2.261 ) (lamiral.info)

imapsync.lamiral.info/INSTALL.d/INSTALL.OnlineUI.txt

imapsync.lamiral.info/INSTALL.d/INSTALL.Debian.txt

Imapsync tutorial (lamiral.info)

imapsync.lamiral.info/examples/imapsync\_example.sh

最后修改:2023 年 10 月 05 日
如果觉得我的文章对你有用,请随意赞赏