Migrating from MDaemon to Exim + Dovecot

I welcome you, residents of Habr.

Recently, a situation arose at work: it was necessary to pick up a new mail server and transfer to it all current accounts and the structure of their mail folders from the old server. This need arose for several reasons:
  1. The number of accounts was limited to 250 accounts;
  2. Recently, the mail server began to freeze so that it only helped hard reset (at one time, I noticed that before that HDD was used quite stubbornly);

Here is what happened at that time (on the SuperMicro platform):
  • PC: Intel® Xeon® CPU X3440 2.53GHz 2.53GHz, RAM 4GB, HDD 1TB
  • OS: Windows Server 2008 Enterprise Service Pack 2
  • MTA: Alt-N MDaemon (SMTP (S) / POP (S) / IMAP (S) server, SpamD, WorldClient)

About 240 accounts were used and the Users folder (all mail here) weighed about 200 GB.

What happened (Dell PowerEdge 2850 platform)
  • PC: CPUx2 Intel® Xeon® E5430 2.66GHz 2.67GHz, 4GB RAM, 408GB HDD (RAID: 0)
  • OS: FreeBSD 9.0
  • MTA: Exim + DoveCot + SpamAssassin

Well, now everything is in order.

1. Installing FreeBSD, Exim, DoveCot, SpamAssassin
1.1. Installing FreeBSD
The choice fell on FreeBSD 9.0. There were no problems with the installation. I downloaded the iso image from ftp, cut it to disk and booted from it. The installation process begins (sorry, without screenshots).

We wait for a while, then a window for starting the installation of the system appears. Click the Install button, select the keyboard layout of interest, the encoding, or just click No. Next, select the components of interest for installation. I left everything that was selected, except for games (why do we need games on the server, Exim is also a good toy), added ports and continued on. Partitioning the disks was done manually, according to the following scheme:

# Device        Mountpoint     FStype   Size
/dev/mfid0p2    /              ufs      20G
/dev/mfid0p3    /var           ufs      50G
/dev/mfid0p4    /home          ufs      328G
/dev/mfid0p5    none           swap     4G


In / home contains all maildir'y.

After marking, wait for the installation of the system, enter the password for root. Next, configure the network, users and reboot (there is no need for a detailed description of the installation, since all this can be found on the Internet).

After installation, respectively, configuration, installation of any sudo, perl, etc.

1.2. Installing Exim I will dwell
on the installation of Exim in more detail.
To begin with, we will determine the tasks and the necessary conditions:

1) The format of the mailboxes is maildir;
2) SMTP authorization;
3) Support for SPF, DKIM (in the future, has not yet twisted);
4) Support quote (so far only in the appendfile, then the dovecot quota plugin);
5) MySQL support;
6) SSL support.

Let's start by installing MySQL 5.1.
echo "DEFAULT_MYSQL_VER=51" >> /etc/make.conf
cd /usr/ports/databases/mysql51-server
make install clean
# Установка баз Mysql
mysql_install_db
# Старт демона
echo 'mysql_enable="YES"' >> /etc/rc.conf
echo 'mysql_db_dir="/var/db/mysql"' >> /etc/rc.conf 
/usr/local/etc/rc.d/mysql start

If everything went smoothly, then the muscle will start, and it remains only to set the root password
mysqladmin -u root password my_password

Create a user for exim
pw useradd exim -s /sbin/nologin -b /var/mail/mqueue -g mail

Create a database:
mysqladmin -u root -p create database exim_db

DB structure:
DROP TABLE IF EXISTS `accounts`;
CREATE TABLE `accounts` (
  `login` varchar(128) COLLATE utf8_bin NOT NULL DEFAULT '',
  `password` varchar(128) COLLATE utf8_bin NOT NULL DEFAULT '',
  `uid` int(11) NOT NULL DEFAULT '1002',
  `gid` int(11) NOT NULL DEFAULT '6',
  `domain` varchar(128) COLLATE utf8_bin NOT NULL DEFAULT 'domain.ru',
  `quota` varchar(16) COLLATE utf8_bin NOT NULL DEFAULT '250M',
  `status` int(11) NOT NULL DEFAULT '1',
  PRIMARY KEY (`login`,`domain`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
DROP TABLE IF EXISTS `aliases`;
CREATE TABLE `aliases` (
  `address` varchar(128) COLLATE utf8_bin DEFAULT NULL,
  `goto` varchar(128) COLLATE utf8_bin DEFAULT NULL,
  `domain` varchar(128) COLLATE utf8_bin DEFAULT 'domain.ru'
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
DROP TABLE IF EXISTS `domains`;
CREATE TABLE `domains` (
  `domain` varchar(128) COLLATE utf8_bin NOT NULL DEFAULT '',
  `status` int(11) NOT NULL DEFAULT '1',
  PRIMARY KEY (`domain`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

The uid and gid fields are the UID and GID of the Exim user in our system. They turned out to be UID = 1002 and GID = 6 for me. For convenience, we make the table fields set by default with these values.
Add Exim Database User
mysql -u root -p
Password: ***
mysql> grant all privileges on exim_newdb.* to exim@localhost identified by 'exim_password';
mysql> \q

Create a certificate for SSL connections:
mkdir -p /etc/ssl/certs
cd /etc/ssl/certs
openssl req -x509 -newkey rsa:1024 -keyout favmail.pem -out favmail.pem -days 9999 -nodes

We answer a bunch of questions, and the certificate is ready.
The preliminary steps for installing Exim have been completed, now you can start installing and configuring it.
Install Exim:
cd /usr/ports/mail/exim
make install clean

We select the options that interest us and remove unnecessary ones. I chose the support maildir, spf, dkim, mysql. We are waiting for the installation to complete. Exim builds with a bunch of dependencies, but it doesn't take that long.
Turn off sendmail
echo 'sendmail_enable="NONE"' >> /etc/rc.conf
/etc/rc.d/sendmail stop

and edit /etc/mail/mailer.conf
cat /etc/mail/mailer.conf
# $FreeBSD: release/9.0.0/etc/mail/mailer.conf 93858 2002-04-05 04:25:14Z gshapiro $
#
# Execute the "real" sendmail program, named /usr/libexec/sendmail/sendmail
#
sendmail        /usr/local/sbin/exim
send-mail       /usr/local/sbin/exim
mailq           /usr/local/sbin/exim -bp
newaliases      /usr/local/sbin/exim -bi
hoststat        /usr/local/sbin/exim
purgestat       /usr/local/sbin/exim


After installation, go to edit the config. I configured the config for three different manuals, here are their sources:

Here's what happened:
cat /usr/local/etc/exim/configure
primary_hostname = domain.ru
hide mysql_servers = localhost/exim_db/exim/exim_password
domainlist local_domains = ${lookup mysql{select domain from domains where domain='${domain}'}}
domainlist relay_to_domains = ${lookup mysql{select domain from domains where domain='${domain}'}}
hostlist   relay_from_hosts = localhost : 127.0.0.1
acl_smtp_rcpt = acl_check_rcpt
acl_smtp_data = acl_check_data
tls_certificate = /etc/ssl/certs/favmail.pem
tls_privatekey = /etc/ssl/certs/favmail.pem
daemon_smtp_ports = 25 : 465
tls_on_connect_ports = 465
qualify_domain = domain.ru
allow_domain_literals = false
exim_user = exim
exim_group = mail
never_users = root
host_lookup = *
rfc1413_hosts = *
rfc1413_query_timeout = 5s
ignore_bounce_errors_after = 2h
timeout_frozen_after = 7d
return_size_limit = 10K
split_spool_directory = true
syslog_timestamp = no
begin acl
acl_check_rcpt:
 acl_check_rcpt:
  accept  hosts = :
  deny    domains       = +local_domains
          local_parts   = ^[.] : ^.*[@%!/|]
  deny    domains       = !+local_domains
          local_parts   = ^[./|] : ^.*[@%!] : ^.*/\\.\\./
  accept  senders=${lookup mysql{SELECT senders FROM whitelist \
          WHERE senders='${quote_mysql:$sender_address}'}}
  deny    message       = HELO/EHLO required by SMTP RFC
          condition     = ${if eq{$sender_helo_name}{}{yes}{no}}
  deny    message       = Go Away! You are spammer.
          condition     = ${if match{$sender_host_name} \
                          {bezeqint\\.net|net\\.il|dialup|dsl|pool|peer|dhcp} \
                          {yes}{no}}
  deny    message       = rejected because $sender_host_address \
                         is in a black list at $dnslist_domain\n$dnslist_text
          hosts         = !+relay_from_hosts
          !authenticated = *
          log_message   = found in $dnslist_domain
          dnslists      = bl.spamcop.net : \
                        cbl.abuseat.org : \
                        dnsbl.njabl.org : \
                        pbl.spamhaus.org
  warn
         set acl_m0 = 25s
  warn
         hosts = +relay_from_hosts
         set acl_m0 = 0s
  warn
         authenticated = *
         set acl_m0 = 0s
  warn
         logwrite = Delay $acl_m0 for $sender_host_name \
                [$sender_host_address] with HELO=$sender_helo_name. Mail \
                from $sender_address to $local_part@$domain.
         delay = $acl_m0
  drop   message     = Rejected - Sender Verify Failed
         log_message = Rejected - Sender Verify Failed
         hosts       = *
         !verify     = sender/no_details/callout=2m,defer_ok
         !condition  =  ${if eq{$sender_verify_failure}{}}
  accept  domains       = +local_domains
          endpass
          message       = unknown user
          verify        = recipient
  accept  domains       = +relay_to_domains
          endpass
          message       = unrouteable address
          verify        = recipient
  accept  hosts         = +relay_from_hosts
  accept  authenticated = *
  deny    message       = relay not permitted
acl_check_data:
  warn  message = X-Spam-Score: $spam_score ($spam_bar)
        hosts   = !+relay_from_hosts
        spam    = nobody:true
  warn  message = X-Spam-Report: $spam_report
        hosts   = !+relay_from_hosts
        spam    = nobody:true
  warn  message = Subject: [***SPAM***] $h_Subject:
        hosts   = !+relay_from_hosts
        spam    = nobody
  deny  message = This message scored $spam_score spam points.
        spam    = nobody:true
        hosts   = !+relay_from_hosts
        condition = ${if >{$spam_score_int}{120}{1}{0}}
  deny message = Blacklisted file extension detected ($mime_filename)
       condition = ${if match \
                    {${lc:$mime_filename}} \
                    {\N(\.exe|\.pif|\.bat|\.scr|\.lnk|\.com|\.vbs|\.cpl)$\N} \
                    {1}{0}}
  accept
begin routers
dnslookup:
  driver = dnslookup
  domains = ! +local_domains
  transport = remote_smtp
  ignore_target_hosts = 0.0.0.0 : 127.0.0.0/8
  no_more
system_aliases:
  driver = redirect
  allow_fail
  allow_defer
  data = ${lookup mysql{select goto from aliases where address='${quote_mysql:$local_part}' and domain='${quote_mysql:$domain}'}}
  user = exim
  group = mail
  file_transport = address_file
  pipe_transport = address_pipe
userforward:
  driver = redirect
  check_local_user
  no_verify
  no_expn
  check_ancestor
  file_transport = address_file
  pipe_transport = address_pipe
  reply_transport = address_reply
  data = ${lookup mysql{select goto from aliases where address='${quote_mysql:$local_part}' and domain='${quote_mysql:$domain}'}}
localuser:
  driver = accept
  domains = ${lookup mysql{select domain from domains where domain='${domain}'}}
  local_parts = ${lookup mysql{select login from accounts where login='${local_part}' and domain='${domain}'}}
  transport = local_delivery
  cannot_route_message = Unknown user
begin transports
remote_smtp:
  driver = smtp
local_delivery:
  driver = appendfile
  maildir_format
  maildir_tag = ,S=$message_size
  directory = /home/mail/$domain/$local_part
  create_directory
  delivery_date_add
  envelope_to_add
  return_path_add
  group = mail
  mode = 0660
  no_mode_fail_narrower
address_pipe:
  driver = pipe
  return_output
address_file:
  driver = appendfile
  delivery_date_add
  envelope_to_add
  return_path_add
address_reply:
  driver = autoreply
begin retry
*                      *           F,2h,15m; G,16h,1h,1.5; F,4d,6h
begin rewrite
begin authenticators
auth_plain:
  driver                     = plaintext
  server_set_id              = $2
  server_prompts             = :
  public_name                = PLAIN
  server_condition           = ${lookup mysql{select login from accounts where login='${quote_mysql:${local_part:$2}}' and password='${quote_mysql:$3}'}{yes}{no}}
auth_login:
  driver                     = plaintext
  public_name                = LOGIN
  server_set_id              = $1
  server_prompts             = Username:: : Password::
  server_condition           = ${lookup mysql{select login from accounts where login='${quote_mysql:${local_part:$1}}' and password='${quote_mysql:$2}'}{yes}{no}}
auth_cram_md5:
 driver                      = cram_md5
 public_name                 = CRAM-MD5
 server_secret               = ${lookup mysql{select password from accounts where login='${quote_mysql:${local_part:$1}}'}{$value}fail} 
 server_set_id               = $1

Check the config:
exim -bV
Exim version 4.77 #0 (FreeBSD 9.0) built 04-Jul-2012 19:16:56
Copyright (c) University of Cambridge, 1995 - 2007
Probably Berkeley DB version 1.8x (native mode)
Support for: crypteq iconv() use_setclassresources PAM Perl Expand_dlfunc OpenSSL Content_Scanning DKIM Experimental_SPF
Lookups (built-in): lsearch wildlsearch nwildlsearch iplsearch cdb dbm dbmnz dnsdb dsearch mysql nis nis0 passwd
Authenticators: cram_md5 dovecot plaintext spa
Routers: accept dnslookup ipliteral manualroute queryprogram redirect
Transports: appendfile/maildir autoreply lmtp pipe smtp
Fixed never_users: 0
Size of off_t: 8
Configuration file is /usr/local/etc/exim/configure

OK, no errors were found. We do log rotation for Exim:
crontab -u exim -e
@daily /usr/local/exim/exicyclog

We check recognition of local users:
exim -bt admin
admin@domain.ru
    router = localuser, transport = local_delivery

And nonlocal
exim -bt user@www.com
user@www.com
  router = dnslookup, transport = remote_smtp
  host ASPMX.L.GOOGLE.com      [173.194.71.27] MX=10
  host ALT2.ASPMX.L.GOOGLE.com [209.85.225.26] MX=20
  host ALT1.ASPMX.L.GOOGLE.com [173.194.77.26] MX=20
  host ASPMX4.GOOGLEMAIL.com   [173.194.78.27] MX=30
  host ASPMX5.GOOGLEMAIL.com   [74.125.130.27] MX=30
  host ASPMX3.GOOGLEMAIL.com   [74.125.127.27] MX=30
  host ASPMX2.GOOGLEMAIL.com   [173.194.69.27] MX=30

Great, you can run
echo 'exim_enable="YES"' >> /etc/rc.conf
/usr/local/etc/rc.d/exim start

Checking Exim authorization. How to do this is described in detail here .
At this point, you can finish configuring Exim.
1.3. Installing Dovecot Install
dovecot also from ports
cd /usr/ports/mail/dovecot
make install clean

And customizable (also configured via the above links)
cat /usr/local/etc/dovecot.conf
base_dir=/var/run/dovecot/
protocols=imap imaps pop3 pop3s
ssl=yes
ssl_cert_file=/etc/ssl/certs/favmail.pem
ssl_key_file=/etc/ssl/certs/favmail.pem
protocol imap {
    listen=*:143
    ssl_listen=*:993
}
protocol pop3 {
    listen=*:110
    ssl_listen=*:995
}
disable_plaintext_auth=no
shutdown_clients=yes
log_timestamp="%b %d %H:%M:%S "
syslog_facility=mail
login_dir=/var/run/dovecot/login
login_chroot=yes
login_user=dovecot
login_process_size=64
login_process_per_connection=yes
login_processes_count=3
login_max_processes_count=3
login_greeting=Dovecot ready
login_log_format_elements=user=<%u> method=%m rip=%r lip=%l %c
login_log_format=%$: %s
first_valid_uid=1002
first_valid_gid=6
mail_access_groups=mail
mail_debug=yes
verbose_proctitle = yes
mail_location=maildir:/home/mail/%d/%n
protocol imap {
    imap_client_workarounds=delay-newmail outlook-idle netscape-eoh tb-extra-mailbox-sep
}
protocol pop3 {
    pop3_uidl_format=%08Xu%08Xv
    pop3_client_workarounds=outlook-no-nuls oe-ns-eoh
}
protocol lda {
    postmaster_address=admin@domain.ru
    auth_socket_path=/var/run/dovecot/auth-master
}
auth default {
    default_realm=domain.ru
    mechanisms=plain
    socket listen {
        master {
            path=/var/run/dovecot/auth-master
            mode=0600
            user=exim
        }
    }
    passdb sql {
        args=/usr/local/etc/dovecot-sql.conf
    }
    userdb sql {
        args=/usr/local/etc/dovecot-sql.conf
    }
    user=root
    verbose=yes
}
plugin {
}
#######################################
cat /usr/local/etc/dovecot-sql.conf
driver=mysql
connect=host=127.0.0.1 dbname=exim_db user=exim password=exim_password!
default_pass_scheme=PLAIN
password_query=select password from accounts where login='%n' and domain='%d'
user_query=select uid, gid from accounts where login='%n' and domain='%d'

Run the daemon:
echo 'dovecot_enable="YES"' >> /etc/rc.conf
/usr/local/etc/rc.d/dovecot start

Check POP (S), IMAP (S) telnet'om or any client. If everything is OK, then you can finish setting up Dovecot.

1.4. Installing SpamAssassin and configuring Exim for it
SpamAssassin can be installed in two ways:

1) perl -MCPAN -e shell;
2) From the ports.

I set out of ports. SpamAssassin is a pearl module, and installing it requires a bunch of dependencies from the same pearl modules. Install them:
cd /usr/ports/security/p5-Digest-MD5
make install clean
cd /usr/ports/www/p5-HTML-Parser
make install clean
cd /usr/ports/dns/p5-Net-DNS
make install clean
cd /usr/ports/japanese/p5-Mail-SpamAssassin
make install clean

During installation, there will be a huge bunch of questions related to the functionality of certain modules.
After installation, configure SpamAssassin. Here is my local.cf, which I’ve been using for several years:
cat /usr/local/etc/mail/spamassassin/local.cf
trusted_networks 192.168.2/24
required_score 5.0
report_safe 0
rewrite_header subject [***SPAM***]
use_bayes 1
bayes_path /usr/local/etc/mail/spamassassin/bayes/
bayes_file_mode 0666
bayes_min_spam_num 1
bayes_min_ham_num 1
bayes_learn_to_journal 1
skip_rbl_checks 0
bayes_auto_learn 0
ok_languages ru en
ok_locales ru_en
score BAYES_00 0.0001 0.0001 -6.0 -6.0
score BAYES_05 0.0001 0.0001 -3.0 -3.0
score BAYES_20 0.0001 0.0001 -1.0 -1.0
score BAYES_50 0.0001 0.0001 1.6 1.6
score BAYES_60 0.0001 0.0001 2.0 2.0
score BAYES_80 0.0001 0.0001 4.0 4.0
score BAYES_95 0.0001 0.0001 6.5 6.5
score BAYES_99 0.0001 0.0001 10.0 10.0
score RDNS_NONE 0.0001 0.0001 3.0 3.0
score SUBJ_FULL_OF_8BITS 0.00
score HTML_COMMENT_8BITS 0.01
score HEADER_8BITS 0.00
score TO_NO_USER 0.01
score FORGED_MUA_OUTLOOK 0.5
score X_AUTH_WARNING 0.01
score SUBJ_HAS_UNIQ_ID 9.99
score HTTP_USERNAME_USED 9.99
score FORGED_YAHOO_RCVD 9.99
score FORGED_JUNO_RCVD 16
score UNWANTED_LANGUAGE_BODY 1.02
score MLM 5.55
score RCVD_NUMERIC_HELO 4.95

I transferred it from my old server to MDaemon, because SpamD is SpamAssassin cut to the disgrace.
Now we add the line to the exim config to the acl line
spamd_address = 127.0.0.1 783

and ACL'ah rule acl_check_data
acl_check_data:
#deny  message = Virus found ($malware_name)
        #malware = *
  warn  message = X-Spam-Score: $spam_score ($spam_bar)
        hosts   = !+relay_from_hosts
        spam    = nobody:true
  warn  message = X-Spam-Report: $spam_report
        hosts   = !+relay_from_hosts
        spam    = nobody:true
  warn  message = Subject: [***SPAM***] $h_Subject:
        hosts   = !+relay_from_hosts
        spam    = nobody
  deny  message = This message scored $spam_score spam points.
        spam    = nobody:true
        hosts   = !+relay_from_hosts
        condition = ${if >{$spam_score_int}{120}{1}{0}}
  accept

Run spamd and restart Exim
echo 'spamd_enable="YES"' >> /etc/rc.conf
/usr/local/etc/rc.d/sa-spamd start
/usr/local/etc/rc.d/exim restart

Done. Now we have a new mail server and we can start migrating users

2. Migrating users from MDaemon to Exim
2.1. Accounts and Aliases


Mdaemon stores all user accounts in DAT files, which are located in its app directory. In fact, this is an ordinary text file and you could parse it directly, but the same MDaemon can export accounts to a CSV file. So, we export all accounts using the menu command: Accounts-> Export-> Export accounts to a text file, separated by commas (yes, a very long name for the menu. Religion did not allow to write “Export to CSV” ). The Accounts.csv file will be created in the app directory, so we need it.
There are accounts, now aliases. Here you have to take the dat file. He is called Alias.dat. We copy it and edit it to the state so that only aliases remain in it, and all comments are in the furnace.
To parse these files and add accounts to the Exim database, I piled a small script on the pearl, here are its contents:
use strict;
use Digest::MD5 qw(md5_hex);
use DBI;
my $dsn='DBI:mysql:exim_db:192.168.2.7';
my $db_user='exim';
my $db_pass='exim_password!';
my $dbh=DBI->connect($dsn, $db_user, $db_pass)
	or die "Cann\'t connect to DB\n";
my $acc_file="c:\\Accounts.csv";
my $alias_file="c:\\Alias.dat";
open(ACFILE, $acc_file);
open(ALIASFILE, $alias_file);
my @line=;
my @alias=;
my @arr;
my @arr1;
my $login;
my $password;
my $mquota;
my $mdir;
my $sq
sub  sql_query
{
	my ($query)=@_;
	#print $query."\n";
	my $sth=$dbh->prepare($query);
	$sth->execute;
	$sth->finish;
}
print "Adding user accounts\n";
foreach my $s(@line)
{
	@arr=split(/,/, $s);
	if ($arr[0] =~ m/Email/g) {
		next;
	}
	$login=$arr[0];
	$password=$arr[5];
	$login =~ s/\"//g;
	$login =~ s/\@domain.ru//;
	if($arr[17]>0)
	{
		$mquota=$arr[17]/1000;
	} else { $mquota=0; }
	$sql=qq(INSERT INTO accounts(login, password, quota) VALUES("$login", $password, $mquota));
	sql_query($sql);
	print $login." added OK\n";
}
print "\nAdding aliases\n";
foreach my $s(@alias)
{
	@arr1=split(/ /, $s);
	$arr1[2] =~ s/\n//;
	$arr1[0] =~ s/\@domain.ru//;
	$arr1[2] =~ s/\@domain.ru//;
	my $goto=$arr1[2];
	my $address=$arr1[0];
	#print $goto."\n";
	$sql=qq(insert into aliases(address, goto) values('$address', '$goto'));
	sql_query($sql);
	print "Alias ".$address." => ".$goto." added OK\n";
}

Well, that's almost it. It remains to drag the user mail.

2.2. Synchronization of mailboxes
To synchronize user mailboxes, I used the utility imapsync, which I was told about at the ENT, when I raised the topic of migration there.
We put imapsync from ports
cd /usr/ports/mail/imapsync
make install clean

Next, I wrote a couple of scripts, although one could do it alone. The first script generates a csv file for imapsync, and the second runs it. Here are their contents
# Creating CSV file for imapsync
#
#!//usr/bin/perl
use strict;
use DBI;
my $dsn="DBI:mysql:exim_db:localhost";
my $db_user="exim";
my $db_password="exim_password";
my $dbh=DBI->connect($dsn, $db_user, $db_password) or die "Cannt connect to DB";
my $f_csv="imap_users.csv";
open(CSV, ">".$f_csv);
my $sql="select login, password from accounts";
my $result=$dbh->prepare($sql);
$result->execute;
while ((my $login, my $password)=$result->fetchrow_array) {
    print CSV $login.";".$password.";".$login.";".$password."\n";
}
print "File $f_csv is created\n";
close(CSV);
$result->finish;
#-------------------------------------------------------------------
# imapsync
#!/usr/bin/perl
my $f_csv="imap_users.csv";
my $src="192.168.2.3";
my $dst="127.0.0.1";
open(CSV, $f_csv);
while() {
    chomp;
    my ($u1, $p1, $u2, $p2)=split(";");
    #print $p1."\n";
    print "Sync user $u1\n";
    my $r_sync=system("imapsync --debug --host1 $src --user1 $u1 --password1 $p1 --host2 $dst --user2 $u2 --password2 $p2");
}
close(CSV);

After launching the latter, we wait a long, long, long time until all 200GB migrate from the old server to the new one.

3. Results
After a few hours, I just finished this article, synchronization went through. I checked several mailboxes with a variety of clients. No changes were noticed, everything was as it was, and it remained. All letters are in place. The only drawback, if you use POP3, then all the letters will be supposedly unread, but it doesn’t matter.
Hope this article helps someone. If you have any questions, ask them in the comments.

Thanks for attention.

Also popular now: