regorov
@regorov
Системный администратор

Как при помощи imapsync перенести всю электронную почту с mail.ru на свой почтовой сервер debian 8 + iredmail?

Доброе время суток!!!
Задача: Перейти с biz.mail.ru (mail.ru с использованием корпоративного домена) на собственный сервер debian 8 + iredmail (LDAP). Кол-во электронных почтовых ящиков 105.

Выполнено: Установлен, настроен и протестирован iRedMail на Debian 8. Все исправно работает: A, MX, TXT (DKIM) записи прописаны корректно, SSL настроен, короче все работает и письма ходят.

Осталось только "БЕЗБОЛЕЗНЕННО", то есть не тревожа пользователей перенести все почтовые ящики в рабочем ритме. В итоге было найдена тулза imapsync
Довольно интересная и простая утилита с возможностью переноса сразу нескольких почтовых ящиков.
Проста в использовании (по моему мнению), так как написана на Perl, кроме библиотек больше ничего не надо устанавливать, работает как "однострочник", но можно все необходимые параметры занести в скрипт и запустить. А так же можно настроить, что бы синхронизировал с учетом имеющихся уже дубликатов, то есть переносил только вновь появившиеся письма (но есть НО), хороший FAQ, в общем стоящая вещь.

После изучения мануала запустил на синхронизацию 4 почтовых ящиков (в среднем по 1.5к писем во входящих, и некоторое кол-во в остальных папках). Приятно удивил процесс:
0. Происходит коннект
1. Считал имеющиеся папки на первом электронном ящике (откуда переносим)
2. Считал имеющиеся папки на втором электронном ящике (куда переносим)
3. Сопоставил их и выдал несоответствие, затем создал отсутствующие папки на втором электронном ящике, для корректного переноса почты (но есть второе НО)
4. Начал перенос, перенос происходит поэтапно, сначала одна папка - чтение заголовков, перенос самого "тела" и т.д.
5. Выдает итоговый вывод на экран - что, куда, зачем и почему.
Все происходит красиво, относительно быстро, НО

Теперь НО:
1. При сопоставление папок на почтовых ящиках, а как нам известно - откуда переносим это mail.ru и куда переносим это iredmail выдает на экран такое:
++++ Listing folders
All foldernames are presented between brackets like [X] where X is the foldername.
When a foldername contains non-ASCII characters it is presented in the form
[X] = [Y] where
X is the imap foldername you have to use in command line options and
Y is the uft8 output just printed for convenience, to recognize it.

Host1 folders list:
[&BB4EQgQ,BEAEMAQyBDsENQQ9BD0ESwQ1-] = [Отправленные]
[&BBoEPgRABDcEOAQ9BDA-] = [Корзина]
[&BCEEPwQwBDw-] = [Спам]
[&BCcENQRABD0EPgQyBDgEOgQ4-] = [Черновики]
[INBOX]

Host2 folders list:
[Drafts]
[INBOX]
[Junk]
[Sent]
[Trash]

Folders in host2 not in host1:
[Trash]
[Sent]
[Junk]
[Drafts]

Это говорит о том что при сопоставлении папок совпали только INBOX, остальные будут созданы, нам это не подходит, так как придется в ручную переносить из созданных папок в существующие, получилось вот так:
c20ccea1a531485fb90f36e3f85ad898.jpg
В руководстве нашел опцию --regextrans2, что бы в ручную сопоставить наименование папок. Как бы я не старался ничего не получается, все равно создаются папки и туда переносятся соответствующие письма. Не работающие варианты сопоставления:
--regextrans2 's,^drafts,Drafts,' \
--regextrans2 's,^sent,Sent,' \
--regextrans2 's,^spam,Junk,' \
--regextrans2 's,^trash,Trash,'     # тут не нужно ставить обратный слэш так как является последним аргументом

либо
--regextrans2 's,^Черновики,Drafts,' \
--regextrans2 's,^Отправленные,Sent,' \
--regextrans2 's,^Спам,Junk,' \
--regextrans2 's,^Корзина,Trash,'

либо
--regextrans2 's,^&BCcENQRABD0EPgQyBDgEOgQ4-,Drafts,' \
--regextrans2 's,^&BB4EQgQ,BEAEMAQyBDsENQQ9BD0ESwQ1-,Sent,' \
--regextrans2 's,^&BCEEPwQwBDw-,Junk,' \
--regextrans2 's,^&BBoEPgRABDcEOAQ9BDA-,Trash,'

Ни один из вариантов не работает, все равно создает папки.

2. Второе НО
С этим я встретился, когда решил перенести другой ящик (все ящики рабочие и пользователи работали с ними). После сопоставлений папок, считывание заголовков, во время уже непосредственного переноса писем он зависал на первом же письме из папки INBOX из остальных он успешно переносил, это меня поставило в тупик !?!?!? Я создал два тестовых ящика, на одном, с которого будет перенос почты, создал несколько тестовых писем в каждой папке (Входящие, Отправленные, Спам, Удаленные, Черновики) Начал перенос и опять "зависон", интересно то что при переносе без ручного сопоставления папок, перенос папки INBOX осуществляется в конце процесса. Начал изучать, как оказалось все заголовки он удачно читал и стопарился на переноси именно тела письма, которое не прочитано
Вопрос - Какой папки не хватает?:
Host1 folders list:
[&BB4EQgQ,BEAEMAQyBDsENQQ9BD0ESwQ1-] = [Отправленные]
[&BBoEPgRABDcEOAQ9BDA-] = [Корзина]
[&BCEEPwQwBDw-] = [Спам]
[&BCcENQRABD0EPgQyBDgEOgQ4-] = [Черновики]
[INBOX]

Host2 folders list:
[Drafts]
[INBOX]
[Junk]
[Sent]
[Trash]

Ответ - Не хватает папки "Не прочитанное" в случае host1 и "new" в случае host2 (new не отображается в веб-морде roundcube, а является папкой в vmail)

Помогите, пожалуйста, решить эти две проблемы:
1. Как корректно сопоставить папки на двух серверах?
2. Как перенести не прочитанные письма? (вариант: сделать все письма прочитанными не подходит, так как у некоторых пользователей кол-во не прочитанных писем доходит до 1000 и более. Пользователи хотят так и оставить)

Заранее благодарю за помощь!!!

P.S.: Прошу прощение за "многа букавак" )))
  • Вопрос задан
  • 7421 просмотр
Решения вопроса 1
regorov
@regorov Автор вопроса
Системный администратор
Решение двух "НО" найдено, спасибо dimonchik2013 за подсказку по первому пункту:

по п1 это пробовал?
serverfault.com/questions/598364/imapsync-doesnt-s...


В итоге работающий скрипт sync_loop_unix.sh выглядит таким образом:
#!/bin/sh
echo Looping on account credentials found in file.txt
echo

{ while IFS=';' read  h1 u1 p1 h2 u2 p2 fake
    do
        { echo "$h1" | egrep "^#" ; } > /dev/null && continue # this skip commented lines in file.txt
        echo "==== Starting imapsync from host1 $h1 user1 $u1 to host2 $h2 user2 $u2 ===="
        ./imapsync --host1 "$h1" --user1 "$u1" --password1 "$p1" \
                    --host2 "$h2" --user2 "$u2" --password2 "$p2" \
                    --ssl1 \
                    --port1 993 \
                    --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
                 "$@"
        echo "==== Ended imapsync from host1 $h1 user1 $u1 to host2 $h2 user2 $u2 ===="
        echo
    done
} < file.txt

А теперь разберем все по полочкам:
1. В файле file.txt находятся данные о почтовых аккаунтах, которые Вы будете синхронизировать, каждая строка это два синхронизируемых между собой почтовых ящика:
host001_1;user001_1;password001_1;host001_2;user001_2;password001_2;
host002_1;user002_1;password002_1;host002_2;user002_2;password002_2;
host003_1;user003_1;password003_1;host003_2;user003_2;password003_2;

Пример:
# вариант с использованием посредника, то есть на другой машине выполняете скрипт
imap.mail.ru;ivanov@blabla.com;P@ssw0rd;imap.newdomain.ru;ivanov@newdomain.ru;P@ssw0rd;
imap.mail.ru;petrov@blabla.com;P@ssw0rd;imap.newdomain.ru;petrov@newdomain.ru;P@ssw0rd;
... и т.д.
# если выполняете скрипт локально на новом почтовом сервере
imap.mail.ru;ivanov@blabla.com;P@ssw0rd;localhost;ivanov@newdomain.ru;P@ssw0rd;
imap.mail.ru;petrov@blabla.com;P@ssw0rd;localhost;petrov@newdomain.ru;P@ssw0rd;
... и т.д.

В моем случае я выполнял скрипт непосредственно локально на новом почтовом сервере.

2. Для того что бы при синхронизации папки Входящие, Отправленные, СПАМ, Карзина, Черновики - правильно сопоставились и письма попали согласно своим папкам, Вам необходимо установить дополнительный модуль Unicode::IMAPUtf7 для Perl:
Скачивается он с CPAN установка очень простая, в README очень подробно описана.
Затем для сопоставления папок Вам необходимо написать в скрипте такие строки:
...
# папка Отправленные
--regextrans2 "s/&BB4EQgQ,BEAEMAQyBDsENQQ9BD0ESwQ1-/Sent/" \
# папка Корзина 
--regextrans2 "s/&BBoEPgRABDcEOAQ9BDA-/Trash/" \
# папка СПАМ
--regextrans2 "s/&BCEEPwQwBDw-/Junk/" \
# папка Черновики
--regextrans2 "s/&BCcENQRABD0EPgQyBDgEOgQ4-/Drafts/" \
...

После этого у Вас не будут дублироваться эти папки.

3. Что бы imapsync правильно воспринимал не прочитанные письма во Входящих, Вам надо добавить строку
...
--regexflag 's/\\Unseen//g' \
...

После всех не "хитрых" манипуляций письма будут корректно переносится.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
Может быть проще переименовать папочки или перенести письма и удалить ненужные папки прямо в maildir'ах на сервере или поискать в своем IMAP-сервере настройку имен для специальных папок? Если такой настройки нет, то тривиально переехать не получится, т.к. если сервер не будет отдавать служебные папочки с теми же именами, все равно в клиентских программах папки задублируются и придется менять их в настройках.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы