Samba4とrsync、シャドウコピーを用いたファイルのバージョン管理が出来るファイルサーバーの構築

ファイルサーバを利用している環境は多いと思うが、よくあるトラブルがファイルを間違えて上書きや削除してしまい、過去のファイルに戻したい、というもの。
それも、数日や場合によっては数ヶ月前のファイルに戻したいという時もあるだろう。rysncとSamba4、そしてクライアントとしてWindowsのシャドウコピー機能を用いれば、これは実現可能となる。

ディスク容量に余裕が無い状態であればおすすめ出来ないが、もしディスクの容量がものすごく余っている状態なのであれば、ファイルサーバのバックアップも兼ねたバージョン管理ファイルサーバを構築すると良いだろう。
今回は同一ディスク上にファイルサーバでの共有先、rsyncやシャドウコピーで利用するバックアップ先を作成したが、実際に運用するのであれば共有先、バックアップ先は別のディスク・機器で提供するを勧める。
検証環境として、OSはCentOS 7、Samba 4、共有ディレクトリは「/samba/share」、スナップショットのベースディレクトリが「/samba」、スナップショットディレクトリの配置先を「/samba/backup」としている。
スナップショットのベースディレクトリ(shadow:basedir)配下に共有ディレクトリ(path)とスナップショットディレクトリの配置先(shadow:snapdir)を置く必要があるので注意。

なお、今回の作成にあたってはこちらの情報を参考にさせていただいた。感謝!

1.前提となるパッケージのインストール

まずは、前提となるパッケージとしてsamba4とrsyncが必要となる()。
以下のコマンドで、rsync、samba4のインストールを行う。

yum install rsync samba

これで、前提となるパッケージのインストールが出来た。

2.rsyncの設定

さて、次にrsyncでバックアップ(及びスナップショット)の生成を行わせ、cronで自動実行させるようにする。
実際には、以下のようなスクリプトを作成すると良いだろう。

get_sambasnap.sh

#!/bin/sh

# 変数設定
# バックアップ対象ディレクトリ
SAMBA_DIR=/samba/share
# バックアップ先ディレクトリ
BACKUP_DIR=/samba/backup
# バックアップ先ディレクトリに作成するスナップショットを保有するディレクトリのPATH
SNAPSHOT_DIR=$(TZ=GMT date +@GMT-%Y.%m.%d-%H.%M.%S)
# 最後にバックアップを取得したディレクトリ名を保持しているファイル
LAST_SNAPSHOT_FILE=$BACKUP_DIR/last_snapshot

if [ ! -e $LAST_SNAPSHOT_FILE ]; then
    rsync -av $SAMBA_DIR $BACKUP_DIR/$SNAPSHOT_DIR
    echo $SNAPSHOT_DIR > $LAST_SNAPSHOT_FILE
else
    LAST_SNAPSHOT_DIR=`cat $LAST_SNAPSHOT_FILE`
    rsync -av --delete --link-dest=$BACKUP_DIR/$LAST_SNAPSHOT_DIR $SAMBA_DIR $BACKUP_DIR/$SNAPSHOT_DIR
    echo $SNAPSHOT_DIR > $LAST_SNAPSHOT_FILE
fi

上記のスクリプトはあくまでも最低限利用する部分のみ記述しているので、後は環境にあわせて編集してもらいたい。
スクリプトはcrontabで1時間間隔で定期実行させるようにすると良いだろう。

もしバックアップファイルのローテーションをさせるようであれば、スクリプトを以下のようにすると良いだろう。

get_sambasnap.sh

#!/bin/sh

# 変数設定
# バックアップ対象ディレクトリ
SAMBA_DIR=/samba/share
# バックアップ先ディレクトリ
BACKUP_DIR=/samba/backup
# バックアップ先ディレクトリに作成するスナップショットを保有するディレクトリのPATH
SNAPSHOT_DIR=$(TZ=GMT date +@GMT-%Y.%m.%d-%H.%M.%S)
# 最後にバックアップを取得したディレクトリ名を保持しているファイル
LAST_SNAPSHOT_FILE=$BACKUP_DIR/last_snapshot
# ローテーションを行う日程
ROTATE_DATE=14

# バックアップを実施する
if [ ! -e $LAST_SNAPSHOT_FILE ]; then
    mkdir -p $BACKUP_DIR/$SNAPSHOT_MONTH
    rsync -av $SAMBA_DIR $BACKUP_DIR/$SNAPSHOT_DIR
    echo $SNAPSHOT_DIR > $LAST_SNAPSHOT_FILE
else
    LAST_SNAPSHOT_DIR=`cat $LAST_SNAPSHOT_FILE`
    mkdir -p $BACKUP_DIR/$SNAPSHOT_MONTH
    rsync -av --delete --link-dest=$BACKUP_DIR/$LAST_SNAPSHOT_DIR $SAMBA_DIR $BACKUP_DIR/$SNAPSHOT_DIR
    echo $SNAPSHOT_DIR > $LAST_SNAPSHOT_FILE
fi

# バックアップのローテーションを行う
LIST=`ls -1 $BACKUP_DIR | grep GMT`
for s in $LIST
do
    DEL_SNAPSHOT_DIRDAY=`echo $s | cut -f2 -d"-" | tr -s "." "/" `
    DEL_SNAPSHOT_DIRTIME=`echo $s | cut -f3 -d"-" |  tr -s "." ":"  `
    DEL_SNAPSHOT_DIR=`date -d "$DEL_SNAPSHOT_DIRDAY $DEL_SNAPSHOT_DIRTIME" "+%s"`
    NOW_TIME=`date -d "9 hours $ROTATE_DATE days ago" "+%s"`
    if [ $DEL_SNAPSHOT_DIR -le $NOW_TIME ]; then
        rm -rf $BACKUP_DIR/$s
    fi
done

3.Samba4の設定

最後に、Samba4の設定を行う。
「/etc/samba/smb.conf」の共有ディレクトリの設定で、「shadow: ~」の設定を記述した共有フォルダ「share」の設定を追記する。

/etc/samba/smb.conf(例)

[share]
        comment = 世代管理ファイルサーバ
        guest account = nobody
        guest ok = Yes
        guest only = yes
        read only = No
        browseable = yes
        writable   = yes
        path = /samba/share
        vfs objects = shadow_copy2
        shadow:basedir = /samba
        shadow:snapdir = /samba/backup
        shadow:sort = desc

後は、以下のコマンドでsambaを起動させるだけだ。

systemctl start smb.service
systemctl start nmb.service

さて、それでは実際にシャドウコピーが取得されているかどうかを確認してみよう。
対象のディレクトリにアクセスし、ファイルを右クリック > プロパティ > [以前のバージョン]タブを開く。

確かにシャドウコピーが取得されている事が確認出来た。
なお、Macでこのファイルサーバにアクセスした場合、シャドウコピーの機能は利用出来ない。
そのため、MacとWindowsの混在環境で利用する場合は、スナップショットを記録しているディレクトリを読み取り専用で公開すると良いだろう。