0

imapsync

Перенос почты между серверами через интерфейс пользователя посредством IMAPSync

В этой статье будет рассмотрен способ переноса почты между разными серверами с помощью утилиты 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 – умная утилита, она заботливо переносит не только структуру, но и статус писем. Если какие-то письма были помечены как непрочитанные в старом ящике, то они также станут непрочитанными в новом. Также вы можете запускать синхронизацию несколько раз, скачиваться будут только новые или измененные письма.

Теперь давайте посмотрим на результат. Было:

migrating-mailboxes-using-imapsync-002.png

Стало:

В целом – очень неплохо, с учетом того, что мы просто перенесли ящик 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. Однако в силу ряда причин у автора этих строк не было возможности протестировать этот функционал.

Свежие комментарии

Подписка

Лучшие статьи

Рубрики

Популярное

webdav
Previous Story

Памятка по использованию WebDAV

Next Story

Перенос папки home на другой диск

Latest from Blog

Fail2ban обязательная защита сервера VPS

В операционной системе Ubuntu 18.04.4 LTS, 20.04.1 LTS Fail2ban ставиться очень просто, если вам нужна только защита SSH и вы используете для настройки фаервола iptables для начинающих: Простое управление брандмауэром с UFW. $

NGINX UPSTREAM

Чтобы наш сервер мог распределять нагрузку, создадим группу веб-серверов, на которые будут переводиться запросы: vi /etc/nginx/conf.d/upstreams.conf * в данном примере мы создаем файл upstreams.conf, в котором можем хранить все наши апстримы. NGINX автоматически

Очереди в Mikrotik

Рассмотрим примеры настройки Simple Queues (Простых очередей), SQ+Mangle (Простые очереди с маркировкой соединений и пакетов) и Queues Tree (Деревья очередей). Цвет иконок: использование доступной полосы. Параметры, на которые стоит обратить внимание: Kind PCQ:Классифицирует

Настройка Nginx в качестве обратного прокси-сервера для развертывания нескольких сервисов на одном сервере с помощью Docker

Чтобы легко начать работу с этой статьей, вам потребуются следующие знания. Но вы можете обойтись и без них. Мы использовали domain.ru в качестве примера доменного имени в статье. Убедитесь, что вы изменили
Go toTop