rsync + cron + ssh でセキュアな自動リモートバックアップ (2006/11/21)
現時点でできる限りのセキュリティを考慮に入れた自動リモートバックアップシステムを rsync + cron + ssh で作成してみました.各条件は,次のものとします.
[local.jp, local] バックアップしたいディレクトリ. /etc : 設定ファイル等. /home : NFSで提供しているユーザデータ. /usr/local : NFS共有データ. バックアップしたくないディレクトリ. /home/data : あまり重要でないデータなどが膨大. [remote.jp, remote] バックアップ用のディレクトリは /backup.
local, remote共に同じLAN上にいるものとします.セキュアなリモートバックアップのために,sshの公開鍵認証,暗号化通信を用います.もちろんremoteでNFSマウントしたものに対して,バックアップを行ってもよいのですが,NFSマウントしたディレクトリに対してremoteのrootでもroot権限を与えなくてはならない欠点があります.そこで,sshを利用することにしました.
rootアカウント用のsshのRSA秘密鍵,公開鍵をlocal上で作成します.
local# ssh-keygen -t rsa -N "" -f /root/.ssh/rsync
local上では,秘密鍵/root/.ssh/rsyncと公開鍵/root/.ssh/rsync.pubが作成されます.
一方,remoteでは,rootでのsshでのアクセスをコマンド限定で許可します.そして,sshデーモンを再起動させます.
remote# vi /etc/ssh/sshd_config ... #PermitRootLogin no PermitRootLogin forced-commands-only ... remote# /etc/init.d/ssh restart
local上で作成した公開鍵をremote上に持ってきて,/root/.ssh/rsync.pubにコピーします.この公開鍵を/root/.ssh/authorized_keysに追加します.
remote# cat /root/.ssh/rsync.pub >> /root/.ssh/authorized_keys
公開鍵には,コマンドを指定する必要があります.このコマンドを次のようにして調べます.-vvオプションは,デバッキング用のオプションです.この時点では,エラーで終了するはずです.
local# rsync -vv -az -e "ssh -i /root/.ssh/rsync" \ /etc root@remote:/backup/ opening connection using ssh -i /root/.ssh/rsync -l root \ remote rsync --server -vvlogDtprze.iLs . /backup/ ...
この結果より,ssh のコマンドで指定するべきは"vv"を除いた"rsync --server -logDtprze.iLs . /backup/"ということが分かります.(追記 2008/10/20) "-logDtprz"から"-logDtprze.iLs"に修正しました.
実はこの部分は気にいらない点の一つです.一度実行してみないとコマンドが分からないし,rsyncのこの仕様が今後維持されるかどうか分からないためです.
調べたコマンドauthorized_keysに追加します.また,アクセスをlocal.jpに制限します.その他いろいろのオプションを追加します.このオプションの詳細は,sshのmanのAUTHORIZED_KEYS FILE FORMATで確認できます.各オプションの間にはカンマを入れ,カンマの間にはスペースを入れません.
remote# vi /root/.ssh/authorized_keys command="rsync --server -logDtprze.iLs . /backup/",\ from="local.jp",no-port-forwarding,no-X11-forwarding,\ no-agent-forwarding,no-pty ssh-rsa \ ...
以上の操作を持って,実際に転送できるかどうかを確かめます.
local# rsync -az -e "ssh -i /root/.ssh/rsync" \ /etc root@remote:/backup/ ... local# rsync -az -e "ssh -i /root/.ssh/rsync" \ /usr/local root@remote:/backup/ ... local# rsync -az --exclude="/home/data" \ -e "ssh -i /root/.ssh/rsync" \ /home root@remote:/backup/ ...
ここで,--exlude="/home/data"がきちんと動作するかどうかが心配だったのですが,転送元の処理であるため,きちんと動作するようです.これで,それぞれのバックアップディレクトリ/backup/etc, /backup/local, /backup/homeができます.最初は,/backup/usr/localとしたかったのですが,別のRSA秘密鍵と公開鍵のペアを作成しないといけないので,あきらめました.
なお,rsync用の秘密鍵でrootで遠隔ログインができないかどうか確かめておきましょう.
一ヶ月に一度は,転送元にないファイルを消す,すなわち,転送元と転送先を完全に一致させるrsyncの--deleteオプションを使いたいと思いました.しかし,
local# rsync -az --delete -e "ssh -i /root/.ssh/rsync" \ /etc root@remote:/backup/ ...としても,コマンドプロンプトが返ってきません.そこで,
local# rsync -vv -az --delete -e "ssh -i /root/.ssh/rsync" \ /etc root@remote:/backup/ opening connection using ssh -i /root/.ssh/rsync -l root \ remote rsync --server -vvlogDtprze.iLs --delete . /backup/ ...で確かめると,sshで実行されるコマンドに--deleteを加える必要があります.そこで,--delete用のRSA秘密鍵と公開鍵を作るところから始めます.
local# ssh-keygen -t rsa -N "" -f /root/.ssh/rsync-delete ... remote# cat /root/.ssh/rsync-delete.pub \ >> /root/.ssh/authorized_keys remote# vi /root/.ssh/authorized_keys ... command="rsync --server -logDtprze.iLs --delete . /backup/",\ from="local.jp",no-port-forwarding,no-X11-forwarding,\ no-agent-forwarding,no-pty ssh-rsa \ ...
これで,--deleteオプションも秘密鍵rsync-deleteを利用すれば可能になりました.ここで,次のようにバックアップ用のスクリプトの作成をしました.
local# cat $SCRIPTDIR/backup.sh #!/bin/sh # auto-backup script using rsync PATH=/usr/bin:/usr/sbin:/bin:/sbin if [ `date +%d` = "01" ] ; then rsync -az --delete -e "ssh -i /root/.ssh/rsync-delete" \ /etc root@remote:/backup/ rsync -az --delete --exclude="/home/data" \ -e "ssh -i /root/.ssh/rsync-delete" /home root@remote:/backup/ rsync -az --delete -e "ssh -i /root/.ssh/rsync-delete" \ /usr/local root@remote:/backup/ elif [ `date +%w` = "1" ] ; then rsync -az -e "ssh -i /root/.ssh/rsync" /etc root@remote:/backup/ rsync -az --exclude="/home/data" \ -e "ssh -i /root/.ssh/rsync" /home root@remote:/backup/ rsync -az -e "ssh -i /root/.ssh/rsync" /usr/local root@remote:/backup/ elif [ `date +%w` = "3" -o `date +%w` = "5" ] ; then rsync -az --exclude="/home/data" \ -e "ssh -i /root/.ssh/rsync" /home root@remote:/backup/ rsync -az -e "ssh -i /root/.ssh/rsync" /usr/local root@remote:/backup/ fi
月の始めに転送元と転送先のディレクトリを一致させます.月曜日に/etc, /home, /usr/localに関して更新があったものをバックアップします.水曜日と金曜日に,/home, /usr/localに関して更新があったものをバックアップします.これを,localの/etc/cron.daily/からシンボリックリンクを張ります.
local# cd /etc/cron.daily local# ln -s $SCRIPTDIR/backup.sh backup
確か/etc/cron.daily/のファイル名にドットを含むものは実行されなかったので,注意しましょう.
しかし,この方法はこれからも利用できるかどうかが不安です.結局,同じLAN上にあることもありeSATAの外付けHDDでバックアップする予定です.
梅原 大祐 / UMEHARA Daisuke umehara@kit.ac.jp Last modified: 2020/05/01 15:37