ここでは、サーバがランサムウェアなどの被害にあった際やハードディスクに障害があった際に、復旧するのの必要なデータを別のLinuxサーバ(以降、バックアップサーバと記載)へバックアップする手順を紹介します。
バックアップのトリガーは、各運用サーバ側になり、必要なデータ等をバックアップサーバへsftpを使用して安全にバックアップします。
以下バックアップサーバ側の作業を【バックアップサーバ側】、バックアップを取得したい運用サーバ側を【運用側】と記載しておきます。お間違いのないように。
【バックアップサーバ側】sftp用のユーザを作成
まず、バックアップサーバで、sftpアカウント(ここでは、sftp-user001)を作成します。こちらのアカウントを使用して、各サーバからバックアップサーバへ接続します。パスワードも設定しておきます。
# useradd sftp-user001
# passwd sftp-user001
その後、作成したsftpアカウントでログインし、sshの証明書認証でログインできるようにするための準備を行います。なお、証明書認証時には、パスフレーズなしで接続するようにします。
# su - sftp-user001
$ssh-keygen -t rsa -b 4096
全てエンター(パスフレーズなし)
$ cd .ssh/
$ cp id_rsa.pub authorized_keys
$ chmod 600 authorized_keys
【バックアップサーバ側】ユーザ限定の保存領域の準備
バックアップサーバで保存領域やアクセスするユーザの準備を行います。
実際にファイルを読み書きするディレクトリを作成する
# mkdir /backup1
SFTP専用ユーザーのグループを作成する
# groupadd sftponly
SFTP専用ユーザーのグループを設定を変更する
# usermod -G sftponly sftp-user001
ユーザがグループに所属しているか確認する
$ id sftp-user001
SFTP専用ユーザが読み書きするディレクトリを作成する
下記の例では、接続すると test ディレクトリのみが表示されるようになる。
# cd /backup1
# mkdir web-server
# chown sftp-user001:sftp-user001 web-server
次に、SFTP専用ユーザをchrootに閉じ込める設定をsshの設定で行います。
# vi /etc/ssh/sshd_config
PermitRootLogin no
PasswordAuthentication no
Subsystem sftp internal-sftp
Match Address 10.0.0.1
PasswordAuthentication yes
Match group sftponly
ChrootDirectory /backup1
X11Forwarding no
AllowTcpForwarding no
ForceCommand internal-sftp
ここでは、ルートのログインは拒否にして、パスワード認証も拒否にしています。(証明書認証でログインする為)しかし、ローカル(10.0.0.1)に該当する場合のみ、パスワード認証を許可しています。このあたりは皆さまの運用に合わせて適時変更ください。
sftponlyグループに所属する場合は、chrootで/backup1に閉じ込めています。
# systemctl restart sshd
最後にsshdのサービスを再起動して、設定を反映します。
sftp-user001の秘密鍵(id_rsa)を別サーバへコピーしておき、コマンドでのsftpで接続できるかの動作確認は、以下を実施します。(※1)
# sftp -oIdentityFile=id_rsa sftp-user001@バックアップサーバのIPアドレス
ここまで準備ができましたら、次はバックアップしたいサーバ側の設定になります。
【運用側】バックアップデータを取得するサーバでの接続準備
まず、バックアップサーバで作成した、sftp-user001ユーザの秘密鍵(id_rsa)をこのサーバの管理者ユーザ(root)の.ssh/配下にid_rsaとして配置します。
# vi .ssh/id_rsa
# chmod 600 id_rsa
秘密鍵を配置できましたら、バックアップサーバへパスワードなしで接続できるか確認します。コマンドの書式は、ssh -i 秘密鍵 ユーザ名@接続するサーバ名 になります。
# ssh -i ~/.ssh/id_rsa sftp-user001@バックアップサーバのIPアドレス
バックアップサーバ側のsshdのsftpの設定が正しく出来ていれば、
This service allows sftp connections only.
Connection to バックアップサーバのIPアドレス closed.
と表示されて、アクセス拒否されます。※1のコマンドを実行して、sftpで接続できればOKです。
このあたり、sshで接続していろいろなコマンドを実行されても困りますので、sftpのコマンドのみ実行できるように制限しています。バックアップサーバは外部からアクセスされるサーバになるので、rootでsshでログイン不可とか証明書認証のみアクセス許可についても設定し、セキュリティを高めています。せっかく取得したバックアップが壊されても困りますので。
【運用側】バックアップを取得するシェルの作成
まずはバックアップを取得する為の準備をします。以下のコマンドを実行します。
# mkdir /usr/backup
# chmod 700 /usr/backup
次に、バックアップシェルを作成し、実行権限を付与します。
# vi /usr/local/sbin/system_backup.sh
# chmod 700 /usr/local/sbin/system_backup.sh
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ファイルとして準備します。
# vi /usr/backup/sftp_bat
sftp_batファイルの中身は以下になります。
cd web-server
put *.tar.gz
bye
具体的には、sftpで接続した後、web-serverディレクトリに移動して、圧縮したバックアップファイルをputしています。
最後にcronにて自動実行するように設定します。
# crontab -e
0 23 * * 6 /usr/local/sbin/system_backup.sh > /dev/null 2>&1
【バックアップサーバ側】バックアップファイルのローテートスクリプト
取得したバックアップファイルはそのままでは、上書きされてしまい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で定期的に実行するように設定しておきましょう。
今回はここまでです。最後までお読みいただきありがとうございました。