Tuesday, 29 May 2018

Command line option to list suspended accounts/domains – cPanel

How to suspend/unsuspend an account via WHM panel?

From the WHM control panel the server admin can simply manage the account suspension and re-activation. Here is the steps for suspending an account via WHM.
Step I : Login to WHM panel.
Step II : Go to:
Home >> Account Functions >> Manage Account Suspension
From there you can select the account and suspend it simply. There is an option to add your note for suspension reason and also you can prevent re-sellers from un-suspending the account from their WHM panel. See the image below for more details.
suspend1
You can also un-suspend an account from here.

How to suspend/unsuspend an account via command-line?

Back-end scripts are available to do the same in a WHM/cPanel server. We can simply suspend and un-suspend accounts via command-line using those cPanel scripts. Here I am listing those scripts for suspending and un-suspending cpanel accounts.
To suspend an account:
/scripts/suspendacct user-name
To unsuspend an account:
/scripts/unsuspendacct user-name

How to list suspended accounts from the WHM panel?

At the section where you managing the suspention of an account, you can see that already suspended account is shaded with red color. In WHM there is a direct option to list all suspended accounts. Do follow the below pasted steps for that.
Step I : Login to WHM panel.
Step II : Go to:
Home >> Account Functions >> List Suspended Accounts 
If you want, you can unsunpend accounts from there directly.

How to list suspended accounts from comman-line?

Here we goes to our topic “command line option to list suspended accounts/domains“. Yes, from the back-end we can simply list suspended accounts by accessing the directory “/var/cpanel/suspended/“. All suspended accounts will be listed there.
Example:
# ll /var/cpanel/suspended
total 72
drwxr-xr-x   2 root root  4096 Jul 24 13:03 ./
drwxr-xr-x. 86 root root 12288 Jul 24 13:09 ../
-rw-r--r--   1 root root    54 May  6 18:30 user1
-rw-r--r--   1 root root     0 Mar 22 23:01 user2
-rw-r--r--   1 root root    54 May  6 18:30 user3
-rw-r--r--   1 root root    54 May  6 18:30 user4
-rw-r--r--   1 root root    54 May  6 18:30 user5
-rw-r--r--   1 root root   152 Jul 24 13:03 user6
-rw-r--r--   1 root root     0 Jun 11 10:04 user7
-rw-r--r--   1 root root    54 May  6 18:30 user8
-rw-r--r--   1 root root    54 May  6 18:30 user9

Monday, 21 May 2018

Apache Virtual Hosting

This tutorial shows how to setup Apache Virtual Hosts in CentOS 6 . This is useful if you want to host more than one website on a single CentOS web server. For instructions on how to setup Apache, PHP, and SQL database on CentOS 7,

Setup folder structure for your websites

We are going to create 2 folders for each website. The first will hold HTML and other content, second - log files.
/var/www/sites/domain1/html
/var/log/httpd/domain1
/var/www/sites/domain2/html
/var/log/httpd/domain2
/var/www/sites/domain3/html
/var/log/httpd/domain3
Log files will be stored in var/log/httpd/... subfolders, which is the default place to store log files in Linux. People often store Apache log files in /var/www/ subfolders, but in CentOS with SELinux enabled this can cause access denied errors. This can be fixed with chcon command, but I prefer to store all my log files in /var/logs... 
You can also place index.html files with some sample text in each html directory which we'll use later for testing.

Create folder structure for virtual host files

Create folders:
/etc/httpd/sites-available
/etc/httpd/sites-enabled
sites-available will hold virtual host config files for websites that are configured, but not necessary enabled. These files are actually ignored when Apache starts, but this system allows to easily disable and enable websites without having to delete or create new virtual host files every time we want to take a site offline and put it back online.
sites-enabled will hold symbolic links to virtual host files inside sites-available that are enabled. They will be loaded when Apache starts.

Add sites-enabled to Apache config

Open file /etc/httpd/conf/httpd.conf and at the very end of the file add following text:
IncludeOptional sites-enabled/*.conf
This will tell Apache to look for virtual host files with extension .conf in sites-enabled directory.

Create Virtual Host files

In directory /etc/httpd/sites-available create config files for each website (domain1.conf, domain2.conf, etc.) with following content:
<VirtualHost *:80>
ServerName www.domain1.com
ServerAlias domain1.com
DocumentRoot /var/www/sites/domain1/html
ErrorLog /var/log/httpd/domain1/error.log
CustomLog /var/log/httpd/domain1/access.log combined
</VirtualHost>
Change domain1 to match your domain names and directories you created previously.
If Apache can't match the requested domain to any of the virtual hosts, the first (alphabetically) virtual host site will be loaded. If you want to have more control over this, you can create a dedicated virtual host (i.e. 00_default) that will be loaded only when no matching virtual host exist. ServerName and ServerAlias should not match any of your domains (i.e.example.com) The name starts with 00 so that it is always the first virtual hosts alphabetically. The site linked to this default virtual host could show an error message, redirect to another domain, etc.

Edit httpd.conf

Edit the main Apache configuration file /etc/httpd/conf/httpd.conf according to your requirements.
In my particular case, I made following changes:
Set webmaster email address:
ServerAdmin administrator@domain.com
Set main document root:
DocumentRoot "/var/www/sites"
Configure main document root:
<Directory "/var/www/sites">
AllowOverride All
Options FollowSymLinks
</Directory>
AllowOverride All - is required if you intend to use .htaccess files for directory level configuration. By default, this is set to None, in which case .htaccess overrides would be ignored.
Options -Indexes - prevents directory listing.

Enable Virtual Hosts

To enable websites, we need to create symbolic links in /etc/httpd/sites-enabled pointing to appropriate config files in sites-available. To do this, run:
ln -s /etc/httpd/sites-available/domain1.conf /etc/httpd/sites-enabled/domain1.conf
For changes to take effect we need to restart Apache:
service  httpd restart
To disable a particular website, simply delete relevant symbolic link (or change the extension) and restart Apache.
Before going live, you can test if everything is working locally. To do this, edit the hosts file on your client machine to point domains configured inside virtual hosts to the CentOS web server's IP address. If everything was setup properly, pointing your web browser to one of the domains should load index.html file from an appropriate /var/www/sites/... directory 

Sunday, 6 May 2018

Zimbra to Zimbra (zcs to zcs) migration

A bit of history for the context

After running a Zimbra mail server in a 500Gb Virtual Machine, for about 4 years, the server started feeling a bit crowded and with  #df -h reporting less than 50Gb of space left, it was time to move to a larger machine.
The version I was (and still am) running is the open source version, there are no migration tools available as part of the package, although you can find plenty of tutorials on the web forums about how to rsync stuff between the old and the new server. I was not comfortable with that. For starters, there would be down time involved, but apart from that I would have to rsync between two identical servers, meaning that the new server would still need to be zimbra 8.6 and running on an identical Centos 6 machine.
There was also the fact that some time ago, the server did a very bad shutdown (due to a power failure), and the database had been corrupted, and every so often a problem or two would crop up in the logs. This became very evident when an upgrade to 8.7.1 failed miserably, and the only thing that saved the day was the backup from the previous night ! I was afraid that most likely, an rsync migration would also transfer the problematic data, and that it would be back to haunt me down the road.
Since I was going to have to go through all the aches and  pains of  a server migration  I wanted to end up not only with more space,  but also to move to a newer O.S., and a newer release, so rsync was out of the question.

zmmailbox and cli to the rescue

If you have spent any time at all administering a Zimbra mail server, you are definitely familiar with the zmprov command. You might have used it to reset a forgotten admin password, or to list all the accounts using a forwarding address or to really do any other thing you could do from within the web interface ! You might be a bit less familiar with zmmailbox.
Like zmprov, zmmailbox is also a very powerful command, and can be used to do something as thrivial as creating a mail folder, but it can also export whole mailboxes in “tgz” format, including any folder structure the user might have …. AWESOME !! The only downside is that each mailbox needs to be exported separately, and you cannot use “*” or any wildcards. We are running on Linux however, so we can write  bash scripts to do all the heavy lifting for us :).

Preparing the new server

You can follow my guide about how to install Zimbra 8.7.1 on Centos 7 here. If you already know how to do it, just go ahead and install the new server. Basically you will need to install a server with the same settings you used for your old server, but with a different I.P. Address. Remember to setup named, and the zone file accordingly, along with the /etc/hosts file. You do not need to create all the domains inside the server. Just create your main one, we will import the others automatically. Remember that if you intend to install a “letsencrypt” certificate later on, your server name needs to be the same as your http://webmail name. Normally I like to use webmail.domain.com

Switching over to the new server

In order to have virtually zero down time, we will proceed as follows :-
  1. Set the DNS TTL Entries pertinent to the mail server to the shortest possible time (Ideally this is done a day before to make sure the ttl propagates accordinly)
  2. Prepare a fully working new server
  3. Import all existing domains from the old server.
  4. Import all existing accounts, passwords, distribution lists, and aliases from the old server
  5. Move all DNS Pointers and firewall port forwards to the new server (or leave the DNS Pointers as they are, and simply swap the servers’ I.P. Addresses old to new, and new to old. (More about this later)
  6. Make sure that new mail is arriving  on the new server.
  7. Make sure users are able to connect and use the new server.
  8. Export Mailbox data from the old server, and import it to the new while the new server is running

Before you go any further …

Most of the commands executed during export, and more importantly during import, may take hours. These should be run directly from  a console session. If you have absolutely no choice then to run the commands remotely, make sure you use the “screen” command, so that if the connection gets interrupted, you can connect back to your screen, without disrupting any running scripts

The export part

Before we begin the export part, we need  to make sure we have enough storage space, which can be accessed from both “old” and “new” servers. The old server did not have any space left but the new server had vitually 1Tb of free space. The way to go, in my case was to remote mount an NFS share from the new server, on the old server and use it as the intermediate storage. Other ways include external usb drives, a network attached storage etc. The choice is really up to you. The steps that follow are generic, and assume the intermediate storage is located at /migration/zimbra. If your path is different you will need to modify the scripts accordingly. To keep things organised, we will create separate folders for all the different migration files. Also make sure the path is readable / writable to Zimbra user. In this case I would recommend
# chmod 777 /migration
# chmod 777 /migration/zimbra
# chown zimbra:zimbra /migration
# chown zimbra:zimbra /migration/zimbra

Step 1. Export all domains

# su - zimbra
# cd /migration/zimbra
# mkdir domains
# cd domains
# zmprov gad | tee -a domains.txt
The command should last only a few seconds, depending on the number of domains on the server. A quick cat domains.txt will show us the available domains
# cat domains.txt
domain1.com
domain2.com

Step 2. Export all accounts

Go back to /migration/zimbra
Create a new directory called accounts and export the admin accounts
# cd /migration/zimbra
# mkdir accounts
# cd accounts
# zmprov gaaa | tee -a admins.txt
Again a quick “cat admins.txt” should list the domain admins, the same ones you see during execution of the “tee – a” command.
Next we export all the users
# zmprov -l gaa | tee -a users.txt

Step 3. Export all account details

Go back to /migration/zimbra
Create a new directory called account_details, and export all account details from Zimbra.
# cd /migration/zimbra
# mkdir account_details
# cd account_details
# for user in `cat ../accounts/users.txt`; do zmprov ga $user  | grep -i Name: | tee -a $user.txt ; done

Step 4. Export all account passwords

Go back to /migration/zimbra
Create a new directory called passwords, and export all shadow passwords
# cd /migration/zimbra
# mkdir passwords
# cd passwords
# for user in `cat ../accounts/users.txt`; do zmprov -l ga $user userPassword | grep userPassword: | awk '{ print $2}' | tee -a $user.shadow; done

Step 5. Export all distribution lists

Go back to /migration/zimbra
Create a new directory called distribution_lists, and export all distribution lists
# cd /migration/zimbra
# mkdir distribution_lists
# cd distribution_lists
# zmprov gadl | tee -a distribution_lists.txt
# for list in `cat distributinlist.txt`; do zmprov gdlm $list > $list.txt ;echo "$list"; done

Step 6.  Export all aliases

Go back to /migration/zimbra
Create a new directory called aliases and export all mail aliases
# cd /migration/zimbra
# mkdir aliases
# cd aliases
# for user in `cat ../accounts/users.txt`; do zmprov ga  $user | grep zimbraMailAlias | awk '{print $2}' | tee -a $user.txt ;echo $i ;done
This process will take some time, depending on the number of accounts. Since most accounts won’t actually have aliases, we will end up with a lot of unnecessary empty text files, which we will delete using “find . -type f -empty | xargs -n1 rm -v”
# find . -type f -empty | xargs -n1 rm -v
So far we have exported everything from our old server, except the mailboxes themselves and any filters the users might have created. We also have the following backup folder structure :-

Step 7. Restore all domains to the new server

The first step in the restoration process starts by restoring all domains. If you have already created the main domain on the new server, you can delete it from /migration/zimbra/domains/domains.txt
The next part assumes that the data we just just exported in the above section is available or copied (in the same directory structure) on the new server. If you have to copy the data, ensure that you issue a chown  -R zimbra:zimbra in /migration/zimbra to make sure, user zimbra has full acess to all the files and directories.
Let me also remind you again that any interruption during the the execution of these scripts could result in database corruption, these commands should be run either from a console or via a screen session. You have been warned.
Let’s begin. Login as zimbra user and issue the following commands :-
# cd /migration/zimbra/domains
# for domain in `cat domains.txt `; do zmprov cd $domain zimbraAuthMech zimbra ;echo $domain ;done
A quick visit to https://youserver-ip:7071 should confirm that the domains have been imported successfully.

Step 8. Restore all accounts and passwords

Restoring accounts and passwords requires the use of a small script.  Restoring each account will entail creating the account with a temporary password, and restoring the old password in another step.
Go to /migration/zimbra
create a directory called “scripts”, and cd to it, and open your favourite editor to create a file called restore_accounts.sh
# cd /migration/zimbra
# mkdir scripts
# cd scripts
# vim restore_accounts.sh

Paste this script to your file and save it
#!/bin/bash
PASSWDS="../passwords"
ACCOUNT_DETAILS="../account_details"
USERS="../accounts/users.txt"
for i in `cat $USERS`
 do
 givenName=$(grep givenName: $ACCOUNT_DETAILS/$i.txt | cut -d ":" -f2)
 displayName=$(grep displayName: $ACCOUNT_DETAILS/$i.txt | cut -d ":" -f2)
 shadowpass=$(cat $PASSWDS/$i.shadow)
 zmprov ca $i "TeMpPa55^()" cn "$givenName" displayName "$displayName" givenName "$givenName"
 zmprov ma $i userPassword "$shadowpass"
done
Make the script executable chmod 777 restore_accounts.sh, and execute it
# chmod 777 restore_accounts.sh
# ./restore_accounts.sh
The user accounts, and their relative passwords are now being imported into the new server. You might get an error every now and again saying :-
ERROR: account.ACCOUNT_EXISTS (email address already exists: admin@domain.com, at DN: uid=admin,ou=people,dc=domain,dc=com)
This basically means that the account which is currently being imported already exists. This is true for admin, anti spam and anti virus accounts (you may wish to delete these accounts from /migration/zimbra/accounts/users.txt. Also keep in mind that after the script runs, the admin password of the new server will now be the same as the admin password of the old server . The password you have created during the installation will be overwritten (unless you delete admin@domain.comfrom users.txt)

Step 9. Restore distribution lists

Go to /migration/zimbra and execute the following command to re-create the distribution lists
for lists in `cat  distribution_lists/distribution_lists.txt`; do zmprov cdl distribution_lists/$lists ; echo "$lists -- done " ; done
Next we need to populate the lists, using a very short bash script
Go to /migration/zimbra/distribution_lists and copy and paste the script below to restore_dist_lists.sh
# cd /migration/zimbra/distribution_lists
# vim restore_dist_lists.sh
paste the following script, save and make it executable, and run it.
#!/bin/bash
for list in `cat distribution_lists.txt`
do
    for mbmr in `grep -v '#' ./$list.txt | grep '@'`
    do
        zmprov adlm $list $mbmr
        echo " $mbmr has been added to $list"
    done
done

# chmod 777 restore_dist_lists.sh
# ./restore_dist_lists.sh
You will see members being added to the various distribution lists, as the script goes thru the lists. Depending on the number of distribution lists, and the number of members in each list, this script could take a few minutes to finish

Step 10. Restore all aliases

Next we restore the user aliases.
You guessed it go to /migration/zimbra/aliases
create a new script called restore_aliases.sh paste the script below into it, and make it executable
# cd /migration/zimbra/aliases
# vim restore_aliases.sh
#!/bin/bash
echo "Processing User accounts"
for user in `cat ../accounts/users.txt`
do
    echo $user
    if [ -f "./$user.txt" ]; then
        for alias in `grep '@' ./$user.txt`
        do
            zmprov aaa $user $alias
            echo "$user ALIAS $alias - Restored"
        done
     fi
done

echo "Processing Admin accounts"
for user in `cat ../accounts/admins.txt`
do
    echo $user
    if [ -f "./$user.txt" ]; then
        for alias in `grep '@' ./$user.txt`
        do
            zmprov aaa $user $alias
            echo "$user ALIAS $alias - Restored"
        done
    fi
done
# chmod 777 restore_aliases.sh
# ./restore_aliases.sh

Step 11. Bring the new server online, and take the old server offline

At this point, we have migrated all the user accounts, their passwords, all the distribution lists, and account aliases. For all intents and purposes, we have a fully working server.
For good measure, let’s restart zimbra services
# zmcontrol restart
Wait for the services to restart, and issue a zmcontrol status
#zmcontrol status
Host domain.com
 amavis Running
 antispam Running
 antivirus Running
 ldap Running
 logger Running
 mailbox Running
 memcached Running
 mta Running
 opendkim Running
 proxy Running
 service webapp Running
 snmp Running
 spell Running
 stats Running
 zimbra webapp Running
 zimbraAdmin webapp Running
 zimlet webapp Running
 zmconfigd Running

Login to the web interface, and check that the number of accounts on the new server is the same as the number of accounts on the old server. There could be a minor discrepancy, if you have used a different domain name when you created the new server, this is due to the spam, galsync, and antivirus accounts which will lead to the number of accounts on the new server to be slightly higher than on the old one.
Once happy with what you see, login using a normal user account, and check to see if you can send emails to your domain, using the test server. Since it is running its own DNS server, and it believes it is the mail server for your domain.com, emails to any account on the server should be delivered immediately.
Check /var/log/zimbra.log for any anomalies.
If all seems well, it is time to take server live.
There are two ways to do this.
  • Change all DNS records and port forwarding on your firewall to the new server I.P
  • Wait for the DNS records to propagate before continuing with the migration
or
  • Disconnect the new server from the network
  • Change its I.P. Address to that of the old server
  • Modify its /etc/hosts/etc/named.conf and /var/your_zone_file accordingly
  • Restart the zimbra services (this is necessary if you mess around with DNS records)
  • Make sure the server is still able to send / receive emails to and form its own domain
  • Disconnect the Old mail server from the Network
  • Connect the new server to the network (which will now be live)
  • Change the IP address of the Old server to an unused I.P. Address
  • Modify its /etc/hosts/etc/named.conf and /var/your_zone_file accordingly
  • Restart zimbra services
  • Connect it back to the network, to continue the migration of the mailbox data
The second method, seems more complicated, but it will guarantee ZERO downtime. Believe it or not, it could be the fastest method to switch over to the new server.
Once the switch over is complete, any users logging in to the server using IMAP or Webmail will be greeted with an empty mailbox, but any new emails arriving to the domain, will be delivered to the new server.
In the final few steps we will export the mailbox data from the old server, and import it to the new server.

Step 12. Migrating mailbox data

The next process will be the most time consuming of all the processes. Depending on the amount of data, exporting the data could take as long as a day if not more. Data import will take just as long.
Now that our users can login to the new server and send and receive emails, the pressure is a bit lower. Also if a very important email needs to be accessed, this can be done via the web interface of the old server, using https://old-server-i.p.
Let’s start the data export.
Login to the old server, via console or via a “Screen” session. I am assuming that the backup repository we were using in /migration/zimbra is mounted again on the “old” server using the same path
Login as Zimbra user and goto /migration/zimbra
# su - zimbra
# cd /migration/zimbra 
# mkdir mailbox_data
# cd mailbox_data
# for user in `cat ../accounts/users.txt`; do echo "Exporting mailbox $user" ; zmmailbox -z -m $user getRestURL '/?fmt=tgz' > ./$user.tgz ; done

You will start seeing mailboxes being exported. This is going to take a while, so you might go endeavor in other projects.
In the event that any mailboxes report errors during export, make a note of the problematic accounts, and try to re export them later, by creating a text file :
/migration/zimbra/accounts/problematic_accounts.txt 
and running the following command. The format of the file needs to be exactly like the format inside /migration/zimbra/accounts/users.txt. Use it as reference.
# for user in `cat ../accounts/problematic_accounts.txt`; do echo "Exporting mailbox $user" ; zmmailbox -z -m $user getRestURL '/?fmt=tgz' > ./$user.tgz ; done
Once the mailbox migration complete, let’s also export any user filter settings. We need a bash script for this.
Create a new directory called filters, create a file called export_filters.sh and paste the script below into it.
# mkdir /migration/zimbra/filters
# cd /migration/zimbra/filters
# vim export_filters.sh
# chmod 777 export_filters.sh
#!/bin/bash
mkdir tmp
set -x
clear
for user in `cat ../accounts/users.txt`; 
do
    filter=`zmprov ga $user zimbraMailSieveScript > ./tmp/$user`
    sed -i -e "1d" ./tmp/$user
    sed 's/zimbraMailSieveScript: //g' ./tmp/$user > ./$user;
    rm ./tmp/$user
    echo "Export filter for $user"
done
\rm -rf tmp
Mount, move or copy /accounts/zmigrate to the new server, and go to the /migration/zimbra/mailbox_data directory
# cd /migration/zimbra/mailbox_data
# for mailbox in `cat ../accounts/users.txt`; do zmmailbox -z -m $mailbox postRestURL "/?fmt=tgz&resolve=skip" ./$mailbox.tgz ; echo "$mailbox - done "; done
This process will also take quite a while to complete, the users may use the server freely during the import. When their turn arrives, they will start seeing their mailbox starting to get populated with the emails they left behind on the old server.
If you get any errors, you can re-export, and re-import the problematic accounts by manipulating /migration/zimbra/accounts/users.txt accordingly and re-running the export command. If you get any “broken pipe” type errors it probably means that the tar archive got corrupted during the transfer for some reason or other, and is essentially incomplete.
Finally let’s import the user filters. Go to /migration/zimbra/filters, and create a file called import_filters.sh. Paste the script below into it, save and make it executable.
# cd /migration/zimbra/filters
# vim import_filters.sh
# chmod 777 import_filters.sh
#!/bin/bash
for filter in ./*
do
    if [ "$filter" == "./import_filters.sh" ] ; then
        continue;
    fi


    if [ "$filter" == "./export_filters.sh" ] ; then
        continue;
    fi

    if [ "$filter" == "./tmp" ] ; then
        continue;
    fi

    Filter_String=`cat "$filter"`
    Account=$filter
    zmprov ma $(echo $filter | grep -E -o "\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,6}\b") zimbraMailSieveScript '$Filter_String'
    echo "Process filter $Account"
done
echo "All filter has been import successfully"

Conclusion

That’s it,  your users should be happy using your newly migrated server. The only thing they will find missing are their account signatures. To date I have not yet found an automated reliable way to copy them automatically. What I did in this case was, made the old server available on a temporary sub-domain (old-webmail.domain.com), so that the users could login in to the old server, and essentially copy and paste their signature to the new server. If you feel extremely generous, you could also do it via the admin interface, but you would have to do the process account by account manually, so it could take some time.

Zimbra Server Migration and Zimbra Account Transfer – The Perfect Method

1. Introduction

Zimbra project doesn’t have a cross migration or proper account transfer documentation. All they tell is to do copy the folder /opt/zimbra to your new servers. But if any of those files infected with a rootkit or other malicious scripts , then your new server also will be compromised. So never sync or copy the entire directory of your zimbra installation. Zimbra also tell you to upgrade your production server to the latest version before migration. But improper upgrade may result in entire data lose. With this procedure you can do:
  • Migrate zimbra from one Operating System To another.
  • Migrate zimbra account between any hardware and Operating systems configurations.
  • No interruption on production server like software upgrade or service disable.
  • Migrate zimbra from old version to a new version server
  • Zimbra cross migrations without copying entire directories.

2. Requirement

You need an old server with zmibra account and a new fresh server with the Os you wish. Dont’ create or make any custom configuration or setting in you new server. Please make sure to set your new servers hostname same as the old one.
  • Old server
    • Need ssh root login
    • Need zimbra admin logins
    • Enough HDD space to store backups
  • New server
    • Must be installed with latest stable zimbra
    • Need ssh root logins
    • Need zimbra admin logins
    • Enough HDD space to store backups

3. Presetup

You need to setup an ssh key from the new server’s root account to the old server’s root account.
Reduce the TTL of MX records of your domain to 500 seconds . So that you can easily switch the domain’s IP after migration. Please remember to schedule the migration task on non peek hours.
Create a directory in both new and old server into which we store all required files and data for doing the migration
[root@zimbra ~]# mkdir /backups/zmigrate
[root@zimbra ~]# chown zimbra.zimbra /backups/zmigrate
[root@zimbra ~]# su - zimbra
All operation in your Zimbra server must be performed as Zimbra user itself, otherwise you will get permission and ownership issues in your zimbra server

4. Backup all data from Old server

We are going to copy all data from old server without interrupting the services.

4.1 Find all domains

You need to find all the domains from your old server. We will store the domain list in a file called domains.txt. You need to back all the domains list as follows,
zimbra@zimbra:~$ cd /backups/zmigrate
zimbra@zimbra:/backups/zmigrate$ zmprov gad > domains.txt
zimbra@zimbra:/backups/zmigrate$ cat domains.txt
fun.com
myserver.com
justfortest.com
checkit.com
dieanotherday.com
gnutest.com
foo.com
zimbra.foo.com
zimbra@zimbra:/backups/zmigrate$
Now remove all domains and subdomains related with the main hostname of your server foo.com , from this list (domains.txt) because it was already created in your new server. So there is no need to create a new domain with the same name.

4.2 Find all admin accounts

Most of these servers will have only one admin. But some servers have multiple admins. So it will be good to find all admin accounts. We will store the admins list in admins.txt
zimbra@zimbra:/backups/zmigrate$ zmprov gaaa > admins.txt
zimbra@zimbra:/backups/zmigrate$ cat admins.txt
admin@foo.com
zimbra@zimbra:/backups/zmigrate

4.3 Find all email accounts

Next step is to find all the email accounts hosted in your old server. Get a list of your email accounts and save in the file emails.txt . So from this file we can see how many accounts that need to migrate.
zimbra@zimbra:/backups/zmigrate$ zmprov -l gaa >emails.txt
zimbra@zimbra:/backups/zmigrate$ cat emails.txt
gm@fun.com
forest@fun.com
galsync@fun.com
fax@myserver.com
paul@myserver.com
angela@myserver.com
brooke@myserver.com
hnmobile1@myserver.com
maria@justfortest.com
samantha@justfortest.com
backupmail@justfortest.com
admin@checkit.com
sandra@checkit.com
zimbra@zimbra:/backups/zmigrate$
Please remove all the email accounts from the file /backups/zmigrate/emails.txt with a starting words like spam, virus, ham, galsync . There is no need to restore these accounts. Even if you still need to restore , you can do it. I don’t like spam and virus emails.

4.4 Get all distribution lists

You need to get all the distributions list and store it in a file called distributinlist.txt.
 
zimbra@zimbra:~$ zmprov gadl > /backups/zmigrate/distributinlist.txt
zimbra@zimbra:~$ cat /backups/zmigrate/distributinlist.txt
budgetrtodomainusers@fun.com
healthnowdomainusers@myserver.com
checkit.comdomainusers@checkit.com
northpointessdomainusers@dieanotherday.com
parkatnorthhillsdomainusers@gnutest.com
zimbra@zimbra:~$

4.5 Get all members in distribution lists

In this step we are going to collect all members in each of these distributions. We will create a folder called distributinlist_members and create a file under this folder named distributinlist.txt , then store all the distributions members.
zimbra@zimbra:~$ mkdir /backups/zmigrate/distributinlist_members
zimbra@zimbra:~$ for i in `cat /backups/zmigrate/distributinlist.txt`; do zmprov gdlm $i > /backups/zmigrate/distributinlist_members/$i.txt ;echo "$i"; done
budgetrtodomainusers@fun.com
healthnowdomainusers@myserver.com
checkit.comdomainusers@checkit.com

4.6 Find all email account’s passwords

Now need to find the encrypted password of all of your old email accounts and store it under a folder named userpass/ as follows:
zimbra@zimbra:/backups/zmigrate$ mkdir userpass
zimbra@zimbra:/backups/zmigrate$ for i in `cat emails.txt`; do zmprov  -l ga $i userPassword | grep userPassword: | awk '{ print $2}' > userpass/$i.shadow; done

4.7 Backup all user names , Display names and Given Names

Zimbra will accept a Names and Disaplay names in email accounts during account creation. So we need to restore those data too. We will create a directory called userdata/ which contains these details of each of those email accounts
zimbra@zimbra:/backups/zmigrate$ mkdir userdata
zimbra@zimbra:/backups/zmigrate$ for i in `cat emails.txt`; do zmprov ga $i  | grep -i Name: > userdata/$i.txt ; done

4.8 Now backup all email account

This will take some time to take backup of all email accounts. So you can run this command behind “screen”. A tgz file will be created with each emails name. We will use this files to transfer email accounts.
 
zimbra@zimbra:/backups/zmigrate$ for email in `cat /backups/zmigrate/emails.txt`; do  zmmailbox -z -m $email getRestURL '/?fmt=tgz' > $email.tgz ;  echo $email ; done
gm@fun.com
forest@fun.com
galsync@fun.com
fax@myserver.com
fax2@myserver.com
paul@myserver.com

This tgz files contains
  • Mail
  • Contacts
  • Calendars
  • Briefcase
  • Tasks
  • Searches
  • Tags
  • Folders
All subfolders are included, except Junk and Trash. There is no way to include these in the big dump, but they can be exported separately:

4.9 Now backup alias

Some times your server may have email aliases for certain accounts. So you need to copy those aliases too. We will create a sub folder called alias/ for storing the backup of Alias.
 
zimbra@zimbra:/backups/zmigrate$ mkdir -p alias/
zimbra@zimbra:/backups/zmigrate$ for i in `cat emails.txt`; do zmprov ga  $i | grep zimbraMailAlias |awk '{print $2}' > alias/$i.txt ;echo $i ;done
gm@fun.com
forest@fun.com
Some of your email accounts don’t have alias. So the above created files may be an empty file. Remove those empty files as follows,’\
zimbra@zimbra:/backups/zmigrate$ find alias/ -type f -empty | xargs -n1 rm -v 

4.10 Rsync folder to new server

Now we have all the required data to do the migration process. As a summery :
  • /backups/zmigrate – Have all the backups stored
  • /backups/zmigrate/domains.txt – Contains the domains names
  • /backups/zmigrate/emails.txt – Contains the list of email accounts
  • /backups/zmigrate/distributinlist.txt – Contains the distribution lists
  • /backups/zmigrate/distributinlist_members – Contains the members in each of your distributions
  • /backups/zmigrate/userpass – Contains the encrypted password of your email accounts
  • /backups/zmigrate/userdata – containts the email accounts user informations
  • /backups/zmigrate/alias – Contains all the aliases of your email accounts
Also the parent folder /backups/zmigrate contains a lot of zip file which are the data inside emails.
Now rsync the files as follows,
root@newserver # rsync -avp -e 'ssh -p 22' root@old-server-ip:/backups/zmigrate /backups/

5. Restore in new server

So after finishing the rsync process , we need to restore this in your new server as follows:
All this operations must be carried out as zimbra sudo user itself. Don’t use root account to store the backups
[root@zimbra ~]# su - zimbra
[zimbra@zimbra]$

5.1 Restore all domains

Now create all the domains that we have from the file /backups/zmigrate/domains.txt
[zimbra@zimbra zmigrate]$ for i in `cat /backups/zmigrate/domains.txt `; do  zmprov cd $i zimbraAuthMech zimbra ;echo $i ;done
2c86f244-de9d-4b7c-8e22-2246a8256219
myserver.com
dbf75058-d85e-4d60-8b69-1f148a456eb6
justfortest.com
ee90ffa2-505d-449f-82fd-129acb21cb5e
checkit.com
8b6bf287-f61e-4930-ada0-96b817292556
dieanotherday.com
17d3c73c-14f7-43aa-9fd2-c9be9e29c9e5
You can also verify the domains created from the zimbra admin panel too

5.2 Create email accounts and set the old password

We need to create the email accounts for storing the mails. We also need to set the old passwords too. We already collected the account info and passwords.
To Create email accounts and restore passwords . Please use the following script to create it
#!/bin/bash
#Scrit  for creating the email accounts createacct.sh
USERPASS="/backups/zmigrate/userpass"
USERDDATA="/backups/zmigrate/userdata"
USERS="/backups/zmigrate/emails.txt"
for i in `cat $USERS`
do
givenName=$(grep givenName: $USERDDATA/$i.txt | cut -d ":" -f2)
displayName=$(grep displayName: $USERDDATA/$i.txt | cut -d ":" -f2)
shadowpass=$(cat $USERPASS/$i.shadow)
tmpPass="CHANGEme"
zmprov ca $i CHANGEme cn "$givenName" displayName "$displayName" givenName "$givenName" 
zmprov ma $i userPassword "$shadowpass"
done

5.3 Restore email accounts

Now we are going to restore the emails from the Zip file. This process may take some hours. So it will be good to run behind “screen” command.
[zimbra@zimbra zmigrate]$ for i in `cat /backups/zmigrate/emails.txt`; do zmmailbox -z -m $i postRestURL "/?fmt=tgz&resolve=skip" /backups/zmigrate/$i.tgz ;  ; echo "$i -- finished "; done
gm@fun.com -- finished 
forest@fun.com -- finished 

5.4 Now recreate the distribution lists

It is time to recreate all the distribution lists as follows.
[zimbra@zimbra zmigrate]$ for i in `cat distributinlist.txt`; do zmprov cdl $i ; echo "$i -- done " ; done
2a852fd8-6e66-426e-a76d-15192536042a
budgetrtodomainusers@fun.com -- done 
a0f6ddb3-8525-4194-9397-6cf0a920dda6

5.5 Restore the distribution lists

After creating the distribution lists we need to add all the members inside the distribution lists. We have the distribution lists in the folder distributinlist_members/ and the list is in distributionlist.txt file. Please use the following small script to restore the distribution lists.
[zimbra@zimbra zmigrate]$ cat restoredist.sh 
#!/bin/bash
# add all memebers to each of these distribution lists
for i in `cat distributinlist.txt`
do
 for j in `grep -v '#' distributinlist_members/$i.txt |grep '@'` 
 do
 zmprov adlm $i $j
 echo " $j member has been added to list $i"
 done

done

5.6 Restore Alias accounts

Please use the following script to restore alias. This will add all the aliases in your email accounts.
#!/bin/bash
for i in `cat /backups/zmigrate/emails.txt`
do
 if [ -f "alias/$i.txt" ]; then
 for j in `grep '@' /backups/zmigrate/alias/$i.txt`
 do
 zmprov aaa $i $j
 echo "$i HAS ALIAS $j --- Restored"
 done
 fi
done

6. Conclusion

So now we migrated all our email accounts. It is time for DNS change. You need to shut down the old zimbra services and change the DNS. After that send some test emails and make sure everything is working fine. Next step is to secure your zimbra server. You need to install ssl certificates and firewall in your new zimbra server. Now you have a new server with new packages and files with the same old email accounts and its data.

7. References

https://wiki.zimbra.com/wiki/Zmprov_Examples
https://wiki.zimbra.com/wiki/Zmprov
https://wiki.zimbra.com/wiki/Backing_up_and_restoring_Zimbra_%28Open_Source_Version%29
'https://xmission.com/blog/2015/04/30/zimbra-server-admin-tip-mailbox-password-migration-and-server-settings-comparison'
http://stdout.no/zimbra-open-source-backup-strategy-and-scripts/