Postfix, One Way Maildir Replication / Backup Using Inotify And Rsync

After I wrote about Maildir replication, using ChironFS and DRBD, this time I will write how to make maildir replication, using a very well known program utility called rsync. basically, rsync itself, does not do realtime replication process. rsync only perform the synchronization/copy process when needed or scheduled by using the crontab. like cp, rsync is used to copy files from one directory to another directory in one system, or to a directory on another system. and vice versa.

How do we make the process of replication/copy that is almost realtime by using rsync?

we will use the inotify-tools (inotifywait) to monitor changes to system files or directories, in this case is the postfix maildir. Inotify has been included in the mainline Linux kernel from release 2.6.13 (June 18, 2005), and could be compiled into 2.6.12 and possibly earlier releases by use of a patch.

What is inotify?

Inotify is a Linux kernel subsystem that acts to extend filesystems to notice changes to the filesystem, and report those changes to applications. It replaces an earlier facility, dnotify, which had similar goals.

OK, without further ado, let’s continue with the first step, install inotify-tools. on my centos machine, it can be done in the following way.

$ sudo yum -y install inotify-tools

Assume that we have two servers, first server contains a postfix + maildir. second servers is used to backup maildir from the first server. using inotifywait, any changes in the maildir on first server will trigger rsync to update the maildir on the backup server. However, first we will make rsync can do the login automatically to the backup server via ssh using Public Key Based Authentication.

On First server

[first_server] $ ssh-keygen -t dsa -f ~/.ssh/identity && cat ~/.ssh/identity.pub | ssh -l postfix second_server -p 12345 'sh -c "cat - >>~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"'


Let’s try login from first server shell to second server

[first_server ~]$ ssh user@second_server -p 12345
Last login: Mon Jun 27 16:21:09 2011 from first_server
[second_server ~]$

Logout, and create this bash script on first server, save it as synch.sh

#!/bin/sh
BASEDIR="$1"
REMOTE_HOST="$2"
RSYNC_OPTIONS=(-rtlavz -e 'ssh -p 12345' --delete)
RSYNC=(rsync "${RSYNC_OPTIONS[@]}")

# Initial sync
"${RSYNC[@]}" ${BASEDIR}/ ${REMOTE_HOST}:${BASEDIR}

# Wait for events to trigger rsync
inotifywait --format '%e %w' -e close_write -e move -e create -e delete -qmr $BASEDIR | while read EVENT
do
  # Fork off rsync proc to do sync
  "${RSYNC[@]}" ${BASEDIR}/ ${REMOTE_HOST}:${BASEDIR} &
done

Make synch.sh executable and suppose, maildir located at /var/postfix/mail

[first_server]$ chmod 755 synch.sh
[first_server]$ cd /var/postfix
[first_server]$ nohup ./synch.sh /var/postfix/mail postfix@second_server & > /dev/null 2>&1

Let’s try to make the maildir manually on the first server.

[first_server]$ cd /var/postfix/mail
[first_server]$ maildirmake leenoux
[first_server]$ ls
leenoux
[first_server]$ ls leenoux
cur  new  tmp

Now let’ see on second server at /var/postfix/mail

[second_server]$ cd /var/postfix/mail
[second_server]$ ls
leenoux
[second_server]$ ls leenoux
cur  new  tmp

Alright, now try to delete leenoux directory recursively on first server

[first_server]$ cd /var/postfix/mail
[first_server]$ rm -rf leenoux
[first_server]$ ls
[first_server]$

On the second server leenoux maildir was also deleted instantly

[second_server]$ cd /var/postfix/mail
[second_server]$ ls
[second_server]$

Great, and in postfix part, as usual just adjust this parameter

virtual_mailbox_base = /var/postfix/mail

Good luck 🙂

2 Comments

  1. Frank

    Hello,
    nice howto – but one question:
    Starting the sync to background – there should be a mechanism to check if the sync is running. What if the snyc process was terminated? Will be mails replicated from the past during the script was stopped like rsnyc?

    best regards
    Frank

Leave a Reply

Your email address will not be published. Required fields are marked *