【backup】rsyncでローカルのコンテンツをバックアップサーバに転送する


先日、珠玉のエロ画像をどうにかして死守しなければと思った (っ´∀`)っ ゃー です、こんばんは。

前回のエントリーで、sambaの共有ディレクトリ以外をローカルでバックアップしたのですが、やはり珠玉のエロ画像もバックアップしたいし、ローカルに取ったバックアップだけじゃ、そのハードディスクが死んでしまったら目もあてられないので、バックアップサーバを1台作ってそこにrsyncで転送することにしました。

rsyncで転送する利点としては、

1) 初回転送時だけ時間がかかるが、2回目以降は差分のみの転送なので動きが軽い
2) パスフレーズなしの鍵を使ったsshと組み合わせることで、安全かつ楽に転送ができる

でしょう。以下、intra1サーバ(エロ画像ディレクトリがある方。以下バックアップ元)
からバックアップサーバへバックアップを取る作業のメモ書きです。

■■ バックアップ元で鍵を作成する

ホームディレクトリの下に「.ssh」ディレクトリがなければ作成してください。
「.ssh」ディレクトリのパーミッションは700にしてください。

[root@intra1 ~]# cd .ssh/
[root@intra1 .ssh]# ssh-keygen -t rsa -f rsync
Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase):    ← エンターを空打ちします
Enter same passphrase again:    ← ここでもエンターを空打ちします
Your identification has been saved in rsync.
Your public key has been saved in rsync.pub.
The key fingerprint is:
17:4c:63:65:b5:54:a5:d0:0f:ea:f1:61:0c:07:e5:03 root@intra1.example.com

■■ バックアップサーバへ鍵を送る

[root@intra1 .ssh]# scp rsync.pub root@backup:/root/.ssh/
The authenticity of host 'backup (192.168.0.200)' can't be established.
RSA key fingerprint is f6:87:ab:5a:e4:7c:6c:ec:91:71:3f:28:9c:01:c6:0d.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'backup,192.168.0.200' (RSA) to the list of known hosts.
root@backup's password:
rsync.pub                                                    100%  237     0.2KB/s   00:00

■■ バックアップサーバで鍵を登録する

[root@backup ~]# cd .ssh/
[root@backup .ssh]# cat rsync.pub > authorized_keys

■■ バックアップ元からバックアップサーバへログインしてみる

[root@intra1 .ssh]# ssh -i ./rsync backup

ここでパスフレーズなしでログインできれば、ひとまずはOK。

■■ バックアップサーバ側にて、鍵ログインで行えるコマンドを制限する

[root@backup .ssh]# vi authorized_keys

ssh-rsa AAAAB3NzaC1yc2E~~~
で始まる行を

command="ls" ssh-rsa AAAAB3~~~
に変更する。

■■ 再度バックアップ元からバックアップサーバへログインしてみる

[root@intra1 .ssh]# ssh -i ./rsync backup
anaconda-ks.cfg  backup  bin  install.log  install.log.syslog
Connection to backup closed.

バックアップサーバの/rootディレクトリでlsコマンドを実行した結果が
バックアップ元で表示されれば、ひとまずはOK。

■■ バックアップサーバにおいて、rsyncのみを許可する

バックアップ元からなんでもかんでもコマンドを実行できてしまったら、バックアップ元サーバが何らかの手段で乗っ取られた場合、即ちバックアップサーバも自在に操られる手段を提供してしまうことになります。よって、バックアップサーバではrsyncのみを許可することにしましょう。まずは、コマンドレベルでの制限を行うスクリプトを書いてやります。

[root@backup .ssh]# cd ~/bin/
[root@backup bin]# touch validate-rsync.sh
[root@backup bin]# chmod 700 validate-rsync.sh
[root@backup bin]# vi validate-rsync.sh
#!/bin/bash
case "$SSH_ORIGINAL_COMMAND" in
  *&*)
    echo "Rejected"
  ;;
  *;*)
    echo "Rejected"
  ;;
  rsync --server*)
    $SSH_ORIGINAL_COMMAND
  ;;
  *)
    echo "Rejected"
  ;;
esac

■ authorized_keys ファイルを修正する

[root@backup bin]# cd ~/.ssh/
[root@backup .ssh]# vi authorized_keys

ここを
command="ls" ssh-rsa AAAAB3N~~~

こうする
command="/root/bin/validate-rsync.sh" ssh-rsa AAAAB3N~~~

■ sshd_configを修正する

[root@backup .ssh]# cd /etc/ssh/
[root@backup ssh]# cp -p sshd_config sshd_config.orig
[root@backup ssh]# vi sshd_config

ここを
#PermitRootLogin yes

こうする
#PermitRootLogin yes
PermitRootLogin forced-commands-only

■ sshdをreloadする

[root@backup ssh]# /etc/init.d/sshd reload
Reloading sshd:                                            [  OK  ]

■■ 再度バックアップ元からバックアップサーバへログインを試みる

[root@intra1 ~]# ssh -i ./.ssh/rsync backup
Rejected
Connection to backup closed.

接続が拒絶されたので、OK。

■■ バックアップ元からバックアップサーバへrsyncの試験をする

■ バックアップサーバで適当なディレクトリを作る

[root@backup ~]# mkdir tmp
[root@backup ~]# cd tmp/

■ バックアップ元からrsyncで転送をかける

[root@intra1 ~]# cd tmp/
[root@intra1 tmp]# touch hoge
[root@intra1 ~]# rsync -auzv --delete -e 'ssh -i /root/.ssh/rsync' /root/tmp/ root@backup:/root/tmp/
building file list ... done
./
hoge
sent 95 bytes  received 40 bytes  270.00 bytes/sec
total size is 0  speedup is 0.00

■ ファイルが転送されたことをバックアップサーバで確認

[root@backup tmp]# ll
total 0
-rw-r--r--  1 root root 0 Feb  3 03:48 hoge

■ バックアップ元でファイルの更新をしてからrsyncで転送をかける

[root@intra1 tmp]# echo hoge > hoge
[root@intra1 tmp]# rsync -auzv --delete -e 'ssh -i /root/.ssh/rsync' /root/tmp/ root@backup:/root/tmp/
building file list ... done
hoge
sent 108 bytes  received 40 bytes  98.67 bytes/sec
total size is 5  speedup is 0.03

■ 更新されたファイルがバックアップサーバにあることを確認する

[root@backup tmp]# ll
total 4
-rw-r--r--  1 root root 5 Feb  3 03:51 hoge
[root@backup tmp]# cat hoge
hoge

■ バックアップ元で何もファイルの更新をせずにrsyncで転送をかける

[root@intra1 tmp]# rsync -auzv --delete -e 'ssh -i /root/.ssh/rsync' /root/tmp/ root@backup:/root/tmp/
building file list ... done
sent 62 bytes  received 2
 0 bytes  54.67 bytes/sec
total size is 5  speedup is 0.06

■ バックアップサーバにあるファイルに何も更新がかかっていないことを確認する

[root@backup tmp]# ll
total 4
-rw-r--r--  1 root root 5 Feb  3 03:51 hoge

■ バックアップ元でファイルを削除してからrsyncで転送をかける

[root@intra1 tmp]# rm -f hoge
[root@intra1 tmp]# rsync -auzv --delete -e 'ssh -i /root/.ssh/rsync' /root/tmp/ root@backup:/root/tmp/
building file list ... done
deleting hoge
./
sent 44 bytes  received 20 bytes  128.00 bytes/sec
total size is 0  speedup is 0.00

■ バックアップサーバでもファイルが削除されたことを確認する

[root@backup tmp]# ll
total 0

■■ 本番運用準備

■ バックアップサーバ側での受け入れ態勢を作る

[root@backup ~]# mkdir -p /home/backup/intra1/{home,etc,root}

■ 初回バックアップを行う

下記コマンドの例では、ローカルのバックアック領域とISOイメージのディレクトリを除外して転送しています。

[root@intra1 ~]# rsync -auzv --delete --exclude=backup --exclude=shared/isos
-e 'ssh -i /root/.ssh/rsync' /home/ root@backup:/home/backup/intra1/home/
[root@intra1 ~]# rsync -auzv --delete -e 'ssh -i /root/.ssh/rsync' /etc/ root@backup:/home/backup/intra1/etc/
[root@intra1 ~]# rsync -auzv --delete -e 'ssh -i /root/.ssh/rsync' /root/ root@backup:/home/backup/intra1/root/

■ バックアップ元でスクリプトを書く

[root@intra1 ~]# cd bin/backup_pg/
[root@intra1 backup_pg]# touch intra1_backup.sh
[root@intra1 backup_pg]# chmod 755 intra1_backup.sh
[root@intra1 backup_pg]# vi intra1_backup.sh
#!/bin/bash
BPATH=root@backup:/home/backup/intra1
HR="============================================================"
echo $HR
echo
echo "intra1 /home backup"
echo
rsync -auzv --delete --exclude=backup --exclude=shared/isos -e 'ssh -i /root/.ssh/rsync' /home/ $BPATH/home/
echo
echo $HR
echo
echo "intra1 /etc backup"
echo
rsync -auzv --delete -e 'ssh -i /root/.ssh/rsync' /etc/ $BPATH/etc/
echo
echo $HR
echo
echo "intra1 /root backup"
echo
rsync -auzv --delete -e 'ssh -i /root/.ssh/rsync' /root/ $BPATH/root/
echo
echo $HR

■■ cronで自動実行の運用にのせる

[root@intra1 ~]# cd /etc/cron.d
[root@intra1 cron.d]# vi intra1_backup
00 06 * * * root /root/bin/backup_pg/intra1_backup.sh | mail -s "[$HOSTNAME] `date` intra1_backup" root

以上で終了です。
ね、簡単でしょ?