Skip to content

Instantly share code, notes, and snippets.

@udibagas
Created December 21, 2015 10:43
Show Gist options
  • Save udibagas/3f5dd94eb486c1c65209 to your computer and use it in GitHub Desktop.
Save udibagas/3f5dd94eb486c1c65209 to your computer and use it in GitHub Desktop.
step by step migrating postfix to zimbra

Langkah migrasi mail server postfix ke zimbra

Migrasi account

Copy script berikut dan beri nama backup.php. Simpan ke server lama.

#!/usr/bin/php

// Postfixadmin (http://postfixadmin.sourceforge.net/) to Zimbra
// (www.zimbra.com) migration script
//
// History:
// Based on work from: Jaros�[34m~Baw Czarniak
// Enhanced by NERvOus (www.nervous.it) on 1-12-2009

<?php
/////////////////////////////////////////////////////////

$user           = "changeme"; // sesuaikan
$pass           = "changeme"; // sesuaikan
$db             = "postfix";
$table_mbox     = "mailbox";
$table_alias    = "alias";
$file           = "exported.sh";

/////////////////////////////////////////////////////////
echo "This script generates a bash script called: $file
The script contains the commands to re-create the mboxes and
aliases on zimbra server.\n\n
";

$mydb = mysql_connect('localhost',$user, $pass) or die ('Error connecting to server');
mysql_select_db($db);
mysql_query("SET CHARACTER SET utf8");
mysql_query("SET NAMES utf8");

$query = "SELECT username,password,name,maildir,quota,domain FROM $table_mbox";
$dane = mysql_query($query) or die ('Error during query for '.mysql_error());

echo "Writing to $file ...\n";
$fh = fopen($file, "w");

fwrite($fh, "#!/bin/sh -x\n\n");

while ($row = mysql_fetch_array($dane, MYSQL_NUM))
{
    $data_mbox = "zmprov ca ".$row[0]." dsfs123hsdyfgbsdgfbsd displayName '".$row[2]."'\n";
    $data_mbox .= "zmprov ma ".$row[0]." userPassword '{crypt}".$row[1]."'"."\n";
    fwrite($fh, $data_mbox);
}
// skip domain aliases, aliases that forward to themselves and aliases
// for which a mbox exists
$query = "SELECT address, trim(trailing ',' from goto) AS dest
                FROM ".$table_alias."
                WHERE address NOT LIKE '@%'
                        AND address NOT IN (SELECT username FROM $table_mbox)
                HAVING address != dest";
$dane = mysql_query($query) or die ('Error during query for '.mysql_error());

$data_alias = "";

while ($row = mysql_fetch_array($dane, MYSQL_NUM)) {
        // multiple dests
        unset($rawdest_r);
        unset($dest_r);
        $rawdest_r = preg_split('/,/', $row[1]);
        foreach ($rawdest_r as $dest) {
                if ($dest != $row[0]) {
                // don't forward to itself
                        $dest_r[] = $dest;
                }
        }
        if (count($dest_r) > 1) {
                // distribution list
                $data_list .= "zmprov cdl $row[0]\n";
                foreach ($dest_r as $dest) {
                        $data_list .= "zmprov adlm $row[0] $dest\n";
                }
        }
        if (count($dest_r) == 1) {
                preg_match('/@(.*)$/', $row[0], $matches);
                $acct_domain = $matches[0];
                preg_match('/@(.*)$/', $dest_r[0], $matches);
                $alias_domain = $matches[0];
                if ($acct_domain == $alias_domain) {
                        // we are adding an alias, not a forward
                        // try to create alias both for a normal
                        // account and for a distribution list. One of the
                        // commands will fail, pity.
                        $data_alias .= "zmprov aaa $dest_r[0] $row[0]\n";
                        $data_alias .= "zmprov adla $dest_r[0] $row[0]\n";
                } else {
                        // we are adding a forward
                        $data_alias .= "zmprov ca $row[0] " . rand_str(11) . "\n";
                        $data_alias .= "zmprov ma $row[0] zimbraprefmailforwardingaddress $dest_r[0]\n";
                }
        }
}

// first create all distribution lists, last all aliases
// We cannot create aliases for distribution lists that do not
// exist yet
fwrite($fh, $data_list . $data_alias);
fclose($fh);


echo "Done.

Now copy exported.sh to zimbra server and run:
# su - zimbra
$ sh ./$file
";


function rand_str($length = 32, $chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890')
{
    // Length of character list
    $chars_length = (strlen($chars) - 1);

    // Start our string
    $string = $chars{rand(0, $chars_length)};

    // Generate random string
    for ($i = 1; $i < $length; $i = strlen($string))
    {
        // Grab a random character from our list
        $r = $chars{rand(0, $chars_length)};

        // Make sure the same two characters don't appear next to each
        // other
        if ($r != $string{$i - 1}) $string .=  $r;
    }

    // Return the string
    return $string;
}

?>

Export account dari server lama menggunakan script backup.php menghasilkan file exported.sh

php backup.php

Contoh output file exported.sh adalah sebagai berikut:

#!/bin/sh -x

zmprov ca support@post.asaba.co.id dsfs123hsdyfgbsdgfbsd displayName 'support'
zmprov ma support@post.asaba.co.id userPassword '{crypt}$1$3e819da4$Nu9P3yrQtDiqLyO1VAEH7.'
zmprov ca roni@post.asaba.co.id dsfs123hsdyfgbsdgfbsd displayName 'Roni Iskandar'
zmprov ma roni@post.asaba.co.id userPassword '{crypt}$1$834f8ff9$LEyCkeK7mZVhOuL7FRPmO/'
zmprov ca root@mailserver.intra.net dsfs123hsdyfgbsdgfbsd displayName 'root'
zmprov ma root@mailserver.intra.net userPassword '{crypt}$1$8a970a7d$4uhUZJCjiPjC4JLw6BlME.'
zmprov ca adi@post.asaba.co.id dsfs123hsdyfgbsdgfbsd displayName 'adi'

Copy file exported.sh ke server baru menggunakan command scp

scp exported.sh root@10.10.1.235:/opt/zimbra

Di server zimbra sebagai root jalankan perintah berikut, tunggu sampai proses migrasi accounrt selesai:

cd /opt/
chmod +x exported.sh
chown zimbra:zimbra exported.sh
su zimbra -l
./exported.sh

Migrasi maildir

Buat symbolic link semua maildir user di server lama ke salah satu maildir user sebagai berikut (jalankan sebagai root):

for domain in `ls /usr/local/virtual`;
do
    for user in `ls /usr/local/virtual/$domain/`;
    do
        ln -s /usr/local/virtual/$domain/$user /usr/local/virtual/post.asaba.co.id/adimaulana@post.asaba.co.id/.$user;
    done
done

Script di atas akan membuat symbolic link semua maildir user untuk semua domain ke dalam 1 user yaitu adimaulana@post.asaba.co.id di folder /usr/local/virtual/post.asaba.co.id/adimaulana@post.asaba.co.id/ dengan nama .{nama_account}. Misal : /usr/local/virtual/post.asaba.co.id/adimaulana@post.asaba.co.id/.support@post.asaba.co.id

Hapus symbolic link .adimaulana@post.asaba.co.id di folder /usr/local/virtual/post.asaba.co.id/adimaulana@post.asaba.co.id/ untuk menghindari recursive pembacaan maildir

rm /usr/local/virtual/post.asaba.co.id/adimaulana@post.asaba.co.id/.adimaulana@post.asaba.co.id

Siapkan file yang berisi daftar account yang akan di migrasi. Beri nama userlist. Letakkan di folder /opt/zimbra/. Contoh filenya sebagai berikut:

aan_k@samafitro.co.id
a.azis@samafitro.co.id
abdul_azis@samafitro.co.id
abdul.kamal@samafitro.co.id
abdullah.abd@samafitro.co.id
abdulrahman@samafitro.co.id
abdurrahman@samafitro.co.id
abdurrohim@samafitro.co.id
abi@samafitro.co.id

Copy script sync.sh berikut ke server zimbra di folder /opt/zimbra/

#!/bin/bash
# sync.sh Script to migrate imap mailboxes under the account migrate1
DATE=`date +%m%d%y_%H:%M`
LOGFILE="imapsync.log"
echo "IMAPSync starting..  $DATE" >> $LOGFILE

# Begin 'for' loop, calling the list of user names already collected
for ACCTNAME in `cat /opt/zimbra/userlist`
do
# Reset the zimbra password temporarily:
zmprov setPassword $ACCTNAME xxxxxxx

# Then migrate:

/usr/bin/imapsync --buffersize 8192000 --nosyncacls --subscribe --syncinternaldates --host1 10.10.2.1 \
--user1 adimaulana@post.asaba.co.id --password1 system --host2 localhost --user2 $ACCTNAME --password2 xxxxxx \
--folderrec INBOX.$ACCTNAME --regextrans2 's/(.*)/INBOX/' --noauthmd5 --nolog --ssl2

echo Done with $ACCTNAME on $DATE >> $LOGFILE

done

# Change the password back to the encrypted one on file.
reset_passwords.sh

echo "" >> $LOGFILE
echo "IMAPSync Finished..  $DATE" >> $LOGFILE
echo "------------------------------------" >> $LOGFILE

Pastikan file sync.sh di atas executable dan bisa dijalankan oleh user zimbra

chmod +x
chown zimbra:zimbra sync.sh

Buat script untuk reset password account di server zimbra dengan memodifikasi file exported.sh dengan menghapus line yang diawali dengan "zmprov ca". Beri nama reset_passwords.sh. Untuk memodifikasi ikuti langkah berikut

cp exported.sh reset_passwords.sh
vim reset_passwords.sh

Untuk menghapus line yang diawali dengan "zmprov ca" di editor vim ketik perintah berikut diikuti enter:

:g/zmprov ca/d

Setelah itu ketik perintah berikut diikuti enter untuk menyimpan file kemudian keluar dari editor vim:

:wq

Contoh scriptnya reset_passwords.sh sebagai berikut:

#!/bin/sh -x

zmprov ma support@post.asaba.co.id userPassword '{crypt}$1$3e819da4$Nu9P3yrQtDiqLyO1VAEH7.'
zmprov ma roni@post.asaba.co.id userPassword '{crypt}$1$834f8ff9$LEyCkeK7mZVhOuL7FRPmO/'
zmprov ma root@mailserver.intra.net userPassword '{crypt}$1$8a970a7d$4uhUZJCjiPjC4JLw6BlME.'
zmprov ma adi@post.asaba.co.id userPassword '{crypt}$1$7e0a5ea5$EOubaopUAQzZWzTXTkw3B.'
zmprov ma gaipsmedan@samafitro.co.id userPassword '{crypt}6XIwoJ1I/3PxY'

Pastikan script reset_passwords.sh executable dan bisa dijalankan oleh user zimbra

chmod +x
chown zimbra:zimbra reset_passwords.sh

Buat file imapsync.log untuk menyimpan log imapsync

touch /opt/zimbra/imapsync.log
chmod 777 /opt/zimbra/imapsync.log
chown:zimbra:zimbra /opt/zimbra/imapsync.log

Jalankan scrypt sync.sh di server zimbra sebagai user zimbra

su zimbra -
./sync.sh

Tunggu hingga proses migrasi selesai. Lama migrasi tergantung besar file dan kecepatan transfer data.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment