Linuxサーバで別のLinuxサーバに安全にバックアップを取得する方法

ここでは、サーバがランサムウェアなどの被害にあった際やハードディスクに障害があった際に、復旧するのの必要なデータを別のLinuxサーバ(以降、バックアップサーバと記載)へバックアップする手順を紹介します。

バックアップのトリガーは、各運用サーバ側になり、必要なデータ等をバックアップサーバへsftpを使用して安全にバックアップします。

以下バックアップサーバ側の作業を【バックアップサーバ側】、バックアップを取得したい運用サーバ側を【運用側】と記載しておきます。お間違いのないように。

【バックアップサーバ側】sftp用のユーザを作成

まず、バックアップサーバで、sftpアカウント(ここでは、sftp-user001)を作成します。こちらのアカウントを使用して、各サーバからバックアップサーバへ接続します。パスワードも設定しておきます。

その後、作成したsftpアカウントでログインし、sshの証明書認証でログインできるようにするための準備を行います。なお、証明書認証時には、パスフレーズなしで接続するようにします。

【バックアップサーバ側】ユーザ限定の保存領域の準備

バックアップサーバで保存領域やアクセスするユーザの準備を行います。

次に、SFTP専用ユーザをchrootに閉じ込める設定をsshの設定で行います。

ここでは、ルートのログインは拒否にして、パスワード認証も拒否にしています。(証明書認証でログインする為)しかし、ローカル(10.0.0.1)に該当する場合のみ、パスワード認証を許可しています。このあたりは皆さまの運用に合わせて適時変更ください。

sftponlyグループに所属する場合は、chrootで/backup1に閉じ込めています。

最後にsshdのサービスを再起動して、設定を反映します。

sftp-user001の秘密鍵(id_rsa)を別サーバへコピーしておき、コマンドでのsftpで接続できるかの動作確認は、以下を実施します。(※1)

# sftp -oIdentityFile=id_rsa sftp-user001@バックアップサーバのIPアドレス

ここまで準備ができましたら、次はバックアップしたいサーバ側の設定になります。

【運用側】バックアップデータを取得するサーバでの接続準備

まず、バックアップサーバで作成した、sftp-user001ユーザの秘密鍵(id_rsa)をこのサーバの管理者ユーザ(root)の.ssh/配下にid_rsaとして配置します。

秘密鍵を配置できましたら、バックアップサーバへパスワードなしで接続できるか確認します。コマンドの書式は、ssh -i 秘密鍵 ユーザ名@接続するサーバ名 になります。

バックアップサーバ側のsshdのsftpの設定が正しく出来ていれば、

This service allows sftp connections only.
Connection to バックアップサーバのIPアドレス closed.

と表示されて、アクセス拒否されます。※1のコマンドを実行して、sftpで接続できればOKです。

このあたり、sshで接続していろいろなコマンドを実行されても困りますので、sftpのコマンドのみ実行できるように制限しています。バックアップサーバは外部からアクセスされるサーバになるので、rootでsshでログイン不可とか証明書認証のみアクセス許可についても設定し、セキュリティを高めています。せっかく取得したバックアップが壊されても困りますので。

【運用側】バックアップを取得するシェルの作成

まずはバックアップを取得する為の準備をします。以下のコマンドを実行します。

次に、バックアップシェルを作成し、実行権限を付与します。

system_backup.shのファイルの中身は以下になります。

#!/bin/sh

cd /usr/backup

date >> ./log.txt
tar czf $(hostname)_user.tar.gz /usr/local
tar czf $(hostname)_etc.tar.gz /etc
tar czf $(hostname)_home.tar.gz /home

sftp -oIdentityFile=~/.ssh/id_rsa -b ./sftp_bat sftp-user001@バックアップサーバのIPアドレス

date >> ./log.txt
echo "" >> ./log.txt

このプログラム中に記載のある、sftpを行う処理(コマンド)をbatファイルとして準備します。

sftp_batファイルの中身は以下になります。

cd web-server
put *.tar.gz
bye

具体的には、sftpで接続した後、web-serverディレクトリに移動して、圧縮したバックアップファイルをputしています。

最後にcronにて自動実行するように設定します。

【バックアップサーバ側】バックアップファイルのローテートスクリプト

取得したバックアップファイルはそのままでは、上書きされてしまい1世代分しか残りません。複数世代を残しておきたい場合は、次のバックアップが動く前に別領域へ移動させます。また、ずっと移動させると今度はバックアップの容量が大きくなるので、一定期間が過ぎると削除するようにします。

バックアップサーバ側で、以下のようなシェル(/usr/local/sbin/backup_rotation.sh)を作成します。

#!/bin/sh

DATE=`date '+%Y%m'`
DAY=`date '+%d'`

# 年月のディレクトリとその下に1-5のディレクトリ作成
if [ ! -d /backup1/backup_old/$DATE ];then
        mkdir -m 700 /backup1/backup_old/$DATE
        mkdir -m 700 /backup1/backup_old/$DATE/1
        mkdir -m 700 /backup1/backup_old/$DATE/2
        mkdir -m 700 /backup1/backup_old/$DATE/3
        mkdir -m 700 /backup1/backup_old/$DATE/4
        mkdir -m 700 /backup1/backup_old/$DATE/5
fi

# バックアップファイルを実行する日にちを判定して別ディレクトリに移動
cd /backup1/web-server

if [ $DAY -ge 1 ] && [ $DAY -le 7 ];then
        mv ./*.tar.gz /backup1/backup_old/$DATE/1/
elif [ $DAY -ge 8 ] && [ $DAY -le 14 ];then
        mv ./*.tar.gz /backup1/backup_old/$DATE/2/
elif [ $DAY -ge 15 ] && [ $DAY -le 21 ];then
        mv ./*.tar.gz /backup1/backup_old/$DATE/3/
elif [ $DAY -ge 22 ] && [ $DAY -le 28 ];then
        mv ./*.tar.gz /backup1/backup_old/$DATE/4/
else
        mv ./*.tar.gz /backup1/backup_old/$DATE/5/
fi

# 古いバックアップファイルとディレクトリを削除
cd /backup1/backup_old

find ./ -name '*.tar.gz' -mtime +30 -exec rm -f {} \;
find ./ -type d -name '202???' -mtime +90 -exec rm -rf {} \;

こちらのファイルを作成しましたら、実行権限を付与して、crontabで定期的に実行するように設定しておきましょう。

今回はここまでです。最後までお読みいただきありがとうございました。