В этой статье будет рассмотрен способ переноса почты между разными серверами с помощью утилиты IMAPSync через примитивный интерфейс пользователя.
На сервере назначения необходимо иметь ящик с нужным логином и паролем. Перед использованием Imapsync нужно обязательно установить его (https://imapsync.lamiral.info/#install).
По причине запрета организацией использовать пароли от почтовых ящиков сотрудников в скрипте процесс миграции передаем пользователю. Для этого разработан web-интерфейс пользователя, который состоит из модуля формы (gis.html) и модуля запуска скрипта imapsync (gis.php). Заполнение серверов imap можно автоматизировать анализируя содержимое поля с названием почтового ящика. Использование Fetchmail как плагина roundcube не рассматривается, т.к. мною не был найден подробный связный разбор этого вопроса.
Web-интерфейс состоит из полей с информацией о почтовых ящиках, области вывода выполнения операции и кнопок управления (gis.html).
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
<script>
//запуск скрипта sh из командной строки linux
function isexe() {
var ta = document.getElementById('output');
document.getElementById('output').value += 'Start import, please wait...\n';
var source = new EventSource('gis.php');
source.addEventListener('message', function(e) {
if (e.data !== '') {
ta.value += e.data + '\n';
}
}, false);
source.addEventListener('error', function(e) {
source.close();
}, false);
}//isexe
//кнопка Выполнить
function Complete() {
document.cookie = "mail1="+document.maildata.mail1.value;
document.cookie = "pass1="+document.maildata.pass1.value;
document.cookie = "mail2="+document.maildata.mail2.value;
document.cookie = "pass2="+document.maildata.pass2.value;
document.cookie = "msrv1="+document.maildata.msrv1.value;
document.cookie = "msrv2="+document.maildata.msrv2.value;
//alert(document.cookie); // показываем все куки
isexe();
document.cookie = "mail1="+document.maildata.mail1.value+"; max-age=0";
document.cookie = "pass1="+document.maildata.pass1.value+"; max-age=0";
document.cookie = "mail2="+document.maildata.mail2.value+"; max-age=0";
document.cookie = "pass2="+document.maildata.pass2.value+"; max-age=0";
document.cookie = "msrv1="+document.maildata.msrv1.value+"; max-age=0";
document.cookie = "msrv2="+document.maildata.msrv2.value+"; max-age=0";
}//Complete
function ShowCookie() {
alert(document.cookie); // показываем все куки
}
</script>
</head>
<body>
<H1>Миграция почтового ящика</H1>
<FORM NAME="maildata">
<TABLE>
<TR><TD><B>Исходный почтовый ящик:<B></TD>
<TD><INPUT NAME="mail1" SIZE=20 VALUE=""
<TR><TD><B>Пароль:<B>
<TD><INPUT TYPE="password" NAME="pass1" SIZE=20 VALUE=""
<TR><TD><B>IMAP сервер:<B></TD>
<TD><INPUT NAME="msrv1" SIZE=20 VALUE=""<TD>
<TR><TD><B>Конечный почтовый ящик:<B></TD>
<TD><INPUT NAME="mail2" SIZE=20 VALUE=""
<TR><TD><B>Пароль:<B>
<TD><INPUT TYPE="password" NAME="pass2" SIZE=20 VALUE=""
<TR><TD><B>IMAP сервер:<B></TD>
<TD><INPUT NAME="msrv2" SIZE=20 VALUE=""<TD>
</TABLE>
<p>Результат выполнения:<br/><textarea id="output" style="width: 50%; height: 25em;"></textarea></p>
<INPUT TYPE="button" VALUE="Выполнить" onClick="Complete();">
<INPUT TYPE="reset" VALUE="Сброс">
<INPUT TYPE="button" VALUE="Показать cookie" onClick="ShowCookie();">
</FORM>
</body>
</html>
Модуль запуска скрипта imapsync (gis.php).
<?php
ob_end_flush();
ini_set("output_buffering", "0");
ob_implicit_flush(true);
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
//вывод в область сообщений
function echoEvent($datatext) {
echo "data: ".implode("\ndata: ", explode("\n", $datatext))."\n\n";
}//echoEvent
echoEvent("Start!");
//формируем строку запуска скрипта imapsync с параметрами
$strexe = "/bin/bash /home/user/imapsync/startimapsync.sh "
.htmlspecialchars($_COOKIE["mail1"]).' '
.htmlspecialchars($_COOKIE["pass1"])." "
.htmlspecialchars($_COOKIE["mail2"])." "
.htmlspecialchars($_COOKIE["pass2"])." "
.htmlspecialchars($_COOKIE["msrv1"])." "
.htmlspecialchars($_COOKIE["msrv2"]);
echoEvent($strexe);
//запускаем sh скрипт из командной строки linux
$proc = popen($strexe,'r');
//могут быть ограничения php, поэтому достаточно вывести результат окончания миграции
while (!feof($proc)) {
echoEvent(fread($proc, 4096));
}
echoEvent("Finish!");
?>
Скрипт миграции почтового ящика (startimapsync.sh) принимает параметры командной строки: логины и пароли, imap-сервера исходного и конечного ящиков соответственно.
#!/bin/bash
#переход в каталог откуда был запущен данный скрипт
cd `dirname $0`
#запуск imapsync с нужными параметрами
/home/user/imapsync/./imapsync \
#сервер начального почтового ящика, логин, пароль
--host1 $5:993 --user1 $1 --password1 $2 \
#сервер конечного почтового ящика, логин, пароль
--host2 $6:993 --user2 $3 --password2 $4 \
#использование шифрования при подключении к серверу
--ssl1 --ssl2 \
#сопоставление папок
--automap \
#первой синхронизируем папку входящих
--folderfirst INBOX \
#сопоставление папок
--regextrans2 "s/&BB4EQgQ,BEAEMAQyBDsENQQ9BD0ESwQ1-/Sent/" \
--regextrans2 "s/&BBoEPgRABDcEOAQ9BDA-/Trash/" \
--regextrans2 "s/&BCEEPwQwBDw-/Junk/" \
--regextrans2 "s/&BCcENQRABD0EPgQyBDgEOgQ4-/Drafts/" \
#правильно принимаем не прочитанные письма во Входящих
--regexflag 's/\\Unseen//g' \
#Сравнение полученных и отправленных писем по параметру Идентификационный номер
--useheader Message-Id
Переход на новую почтовую систему немыслим без переноса уже существующей почты, так как у многих пользователей там скопилось немало ценной информации, зачастую заботливо разложенной по достаточно сложной структуре директорий. Все это требуется не только сохранить, но перенести с наименьшими неудобствами. А если ящиков много, то безусловно хочется автоматизировать эту процедуру. Справиться с этой задачей нам поможет imapsync – простая, но в тоже время мощная утилита для миграции почтовых ящиков по протоколу IMAP.
Основное преимущество imapsync – это то, что ее не нужно устанавливать на почтовый сервер и, скажем больше, мы не советуем этого делать. Почему? Утилита написана на Perl и для работы требует достаточно много библиотек и зависимостей, засорять которыми сервер очень не хотелось бы, тем более что задача, по сути, одноразовая.
Поэтому лучше всего использовать отдельный ПК на Linux, виртуалку или контейнер. Из DEB-систем поддерживаются Debian и Ubuntu, хотя утилита будет работать в любой системе, если вы, конечно, обеспечите ей все необходимые библиотеки. В нашем случае будет использоваться рабочий ПК на Debian.
Прежде всего откроем /etc/apt/sources.list и убедимся, что у репозиториев подключен раздел contrib, если это не так, то в каждую строку после
main
необходимо добавить
contrib
После чего не забываем обновить список пакетов:
apt update
После чего обращаемся на сайт разработчика за инструкциями по установке. Для Debian они выглядят следующим образом:
apt install \
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
Впечатляет? Самое лучшее что можно сделать – это скопировать данное заклинание в терминал и нажать Enter. Потом еще раз посмотреть на предлагаемый набор пакетов и убедиться в правильности своего решения о том, что тащить все это “добро” на почтовый сервер не нужно.
После того, как мы скачали все необходимые зависимости перейдем в домашнюю директорию и скачаем саму утилиту:
cd
wget -N https://raw.githubusercontent.com/imapsync/imapsync/master/imapsync
И сразу сделаем ее исполняемой:
chmod +x imapsync
Официальная инструкция также советует скопировать файл в /usr/bin, однако мы не видим в этом особого смысла.
Использование утилиты достаточно просто. Но, прежде всего, стоит ознакомиться с терминологией: сервер-источник именуется как host1, сервер-приемник – host2 и все опции с индексом 1 относятся к источнику, а с индексом 2 – к приемнику, например, user1 или password2.
В простейшем случае перенос ящика будет выглядеть так:
./imapsync \
--host1 imap.yandex.ru \
--user1 user@mydomain.ru \
--password1 "Pa$$word1" \
--host2 mk-61.it-31,ru \
--user2 user@it-31.ru \
--password2 "Pa$$word1"
Мы применили перенос каждой опции на новую строку исключительно для удобочитаемости команды, в реальности можете смело писать все в одну строку. Сами опции в особых комментариях не нуждаются, сначала мы указываем хост-источник и параметры доступа к почтовому ящику на нем, затем хост-приемник и параметры учетной записи, в которую мы переносим почту.
Если все сделано правильно, то очень скоро мы увидим в терминале лог переноса писем.
Скорость синхронизации зависит от многих факторов, но основное значение будет играть количество сообщений, а не их размер. Средняя скорость переноса с Яндекса на тестовый сервер у нас получилась около 2,5 сообщений в секунду.
При этом imapsync – умная утилита, она заботливо переносит не только структуру, но и статус писем. Если какие-то письма были помечены как непрочитанные в старом ящике, то они также станут непрочитанными в новом. Также вы можете запускать синхронизацию несколько раз, скачиваться будут только новые или измененные письма.
Теперь давайте посмотрим на результат. Было:
Стало:
В целом – очень неплохо, с учетом того, что мы просто перенесли ящик 1:1.
После первого переноса в директории откуда мы запускали утилиту появится папка LOG_imapsync, в которой содержатся логи переноса. Советуем внимательно их изучить. На основе полученной информации вы можете изменить сопоставление папок в источнике и приемнике или исключить некоторые из них из синхронизации.
Для исключения следует использовать опцию –exclude, которая поддерживает регулярные выражения. Скажем, уберем из синхронизации папку Спам и Корзину:
--exclude 'Spam|Trash'
Если вам нужно явно указать соответствие папок, то добавьте опцию:
--f1f2 Outbox=Sent
В данном случае мы указываем, что содержимое папки Outbox ящика-источника следует поместить в папку Sent ящика-приемника.
Еще одной полезной опцией является указание возраста писем, допустим мы хотим перенести корреспонденцию только за текущий год, не проблема, указываем:
--maxage 365
В итоге будут синхронизированы только письма не старше 365 дней.
А что делать с остальными? А можно перенести их в другой, архивный ящик, в этом нам поможет другая опция:
--minage 365
Теперь мы перенесем только письма с возрастом старше одного года.
Также эти опции можно комбинировать, они сочетаются по принципу И:
--maxage 730 --minage 365
Такая конструкция перенесет письма только за прошлый год (не старше двух лет и не моложе года).
А если указать наоборот?
--maxage 365 --minage 730
То мы перенесем все письма за текущий год, и те, которые старше двух лет (не старше 1 года и не моложе 2 лет).
Подобных опций достаточно много и все они перечислены в документации, поэтому советуем подробно с ней ознакомиться. Там же имеются готовые советы и рецепты для многих публичных служб и почтовых серверов.
С синтаксисом немного разобрались, но как быть, если ящиков много? Конечно же автоматизировать, для этого в официальной документации приведен пример скрипта:
#!/bin/sh
{ while IFS=';' read h1 u1 p1 h2 u2 p2 fake
do
imapsync --host1 "$h1" --user1 "$u1" --password1 "$p1" \
--host2 "$h2" --user2 "$u2" --password2 "$p2" "$@"
done
} < file.txt
Данный скрипт не блещет изысканными решениями и прост как табуретка. На его вход подается файл file.txt, который следует создать в одной директории со скриптом и из которого берутся адреса и учетные данные для узлов источника и приемника. Сам файл file.txt должен содержать строки:
host1;user1_1;password11_1;host2;user2_1;password2_1;
host1;user1_2;password11_2;host2;user2_2;password2_2;
host1;user1_3;password11_3;host2;user2_3;password2_3;
host1;user1_4;password11_4;host2;user2_4;password2_4;
Дополнительные опции вы можете указать после “$@” или передать интерактивно при запуске скрипта, тогда они войдут в переменную $@.
Это достаточно примитивный, но при этом полностью рабочий скрипт. С более продвинутыми вариантами скриптов вы можете ознакомиться в Wiki Zimbra. Ну и помните, что в Linux нет догм и единых способов решения задачи, вы всегда можете выбрать тот, который наиболее подходим именно вам.
#!/bin/cat # $Id: INSTALL.Ubuntu.txt,v 1.23 2022/10/13 00:16:33 gilles Exp gilles $ This documentation is also located online at https://imapsync.lamiral.info/INSTALL.d/ https://imapsync.lamiral.info/INSTALL.d/INSTALL.Ubuntu.txt ======================================================================= Installing imapsync on Ubuntu 16.04 or higher ======================================================================= Here is the command to install imapsync dependencies, you need root privilege to run them. This command installs standard Ubuntu packages: sudo apt-get install \ libauthen-ntlm-perl \ libclass-load-perl \ libcrypt-openssl-rsa-perl \ libcrypt-ssleay-perl \ libdata-uniqid-perl \ libdigest-hmac-perl \ libdist-checkconflicts-perl \ libencode-imaputf7-perl \ libfile-copy-recursive-perl \ libfile-tail-perl \ libio-compress-perl \ libio-socket-inet6-perl \ libio-socket-ssl-perl \ libio-tee-perl \ libjson-webtoken-perl \ libmail-imapclient-perl \ libmodule-scandeps-perl \ libnet-dbus-perl \ libnet-ssleay-perl \ libpar-packer-perl \ libproc-processtable-perl \ libreadonly-perl \ libregexp-common-perl \ libsys-meminfo-perl \ libterm-readkey-perl \ libtest-fatal-perl \ libtest-mock-guard-perl \ libtest-mockobject-perl \ libtest-pod-perl \ libtest-requires-perl \ libtest-simple-perl \ libunicode-string-perl \ liburi-perl \ libtest-nowarnings-perl \ libtest-deep-perl \ libtest-warn-perl \ make \ time \ cpanminus In case you want to update the Perl module Mail::IMAPClient, a major module for imapsync, the following command installs it "manually": sudo cpanm Mail::IMAPClient After installing the dependencies, imapsync should be working. You don't have to be root to test and use imapsync. Take the compressed tarball called imapsync-2.xxx.tgz where 2.xxx is the version number. Untar the tarball where you want: cd tar xzvf imapsync-2.xxx.tgz Go into the directory imapsync-2.xxx cd imapsync-2.xxx A dependencies test that shows also the basic example: ./imapsync A live test showing imapsync job: ./imapsync --testslive Now the install command (need root priviledges again): cp imapsync /usr/bin/ That's finished for the installation part. You can use imapsync. Now go to read http://imapsync.lamiral.info/#doc start with the tutorial. ======================================================================= After installing the dependencies ======================================================================= You don't have to be root to test and use imapsync. Take imapsync either on github: wget -N https://raw.githubusercontent.com/imapsync/imapsync/master/imapsync or be on the cutting edge with the upstream site: wget -N https://imapsync.lamiral.info/imapsync Add execution permission to the downloaded script: chmod +x imapsync Check the dependencies and print also the basic example: ./imapsync Perform a live test showing imapsync job: ./imapsync --testslive Now install imapsync on the system (need root priviledges again): cp imapsync /usr/bin/ That's finished for the installation part. You can now use imapsync without knowing where it is located on the system: imapsync Now go read the menu http://imapsync.lamiral.info/#doc and start with the tutorial https://imapsync.lamiral.info/doc/TUTORIAL_Unix.html Feedback is welcome! ======================================================================= ======================================================================= создадим файл «mails.csv», в котором каждая строка будет иметь вид: old_login|old_pass|new_login|new_pass| Здесь «old_login» и «old_pass» — логин и пароль пользователя на старом сервере, а «new_login» и «new_pass» — логин и пароль пользователя на новом сервере. Если вы мигрируете в Google Suite то вам надо будет зайти в настройки безопасности -> «Основные настройки» -> «Приложения, не обладающие надежной защитой» и на время миграции разрешить приложения, не обладающие надёжной защитой. Без этой настройки может не получится подключиться к IMAP. После этого остаётся написать небольшой скрипт, который последовательно выполнит imapsync для каждого из наших пользователей. Примерный листинг скрипта: #!/bin/bash cd `dirname $0` for line in `cat mails.csv | grep -v ^#`; do M_USER=`echo ${line} | cut -d '|' -f1` M_PASS=`echo ${line} | cut -d '|' -f2` N_USER=`echo ${line} | cut -d '|' -f3` N_PASS=`echo ${line} | cut -d '|' -f4` echo "Processing ${M_USER}..." ./imapsync \ --host1 mail.company.com --user1 ${M_USER} --password1 ${M_PASS} \ --host2 imap.gmail.com:993 --user2 ${N_USER} --password2 ${N_PASS} --ssl2 if [ $? -ne "0" ]; then echo ${M_USER} >> mail_errors fi done После выполнения скрипта в файл «mail_errors» будут записаны логины пользователей, для которых перенос почты не удался. Обычно это связано либо с большим объёмом почты (превышение квоты), либо с наличием спецсимволов в паролях. Поэтому лучше заранее проверить размеры ящиков и хотя бы на время миграции установить на ящики пароли, не содержащие символов, которые при подстановке в команды оболочки могут быть интерпретированы не правильно (например знак доллара или обратный слэш). В последних ревизиях mailsync появилась поддержка аккаунтов GMail и MS Exchange. Однако в силу ряда причин у автора этих строк не было возможности протестировать этот функционал.
Свежие комментарии