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:
Here is what happened at that time (on the SuperMicro platform):
About 240 accounts were used and the Users folder (all mail here) weighed about 200 GB.
What happened (Dell PowerEdge 2850 platform)
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:
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.
If everything went smoothly, then the muscle will start, and it remains only to set the root password
Create a user for exim
Create a database:
DB structure:
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
Create a certificate for SSL connections:
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:
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
and edit /etc/mail/mailer.conf
After installation, go to edit the config. I configured the config for three different manuals, here are their sources:
Here's what happened:
Check the config:
OK, no errors were found. We do log rotation for Exim:
We check recognition of local users:
And nonlocal
Great, you can run
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
And customizable (also configured via the above links)
Run the daemon:
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:
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:
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
and ACL'ah rule acl_check_data
Run spamd and restart Exim
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:
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
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
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.
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:
- The number of accounts was limited to 250 accounts;
- 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:
- Installing an Exim-based mail server under FreeBSD
- Exim and courier-imap bundle
- A bunch of exim and dovecot with the postfixadmin web interface
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.
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.