Last-Modified: 2003/02/20 15:55
データのリモートバックアップ
定期的なデータのバックアップも管理者の重要な仕事の1つです。バックアップを取りたいマシンにDATなどがある場合には,図6のようにtarコマンドを使用したり,専用のコマンドを使用することで簡単に作業を行うことができます。
# tar cvpf /dev/sa0 /
図6 tarを用いて/dev/sa0にフルバックアップを取る例
しかし予算の都合などでバックアップ装置が省略されているマシンも多数あるでしょう。
ここではこのようなマシンのデータをネットワーク経由でバックアップする方法について解説します。
tarを用いる方法
まず,標準で用意されているtarコマンドを用いる方法を見てみましょう。
tarコマンドは,多くのファイルを1つにまとめた書庫(アーカイブ)を作成,管理するためのコマンドで,
tar オプション アーカイブ対象となるファイル名またはディレクトリ名
という書式で使用します。オプションには表1に示すようなものが指定可能です。
| 機能指定オプション(オプションの先頭に指定する) | |
|---|---|
| c | アーカイブファイルを作成する |
| x | アーカイブファイルから元のファイルを復元する |
| t | アーカイブファイルの中身を見る |
| その他のオプション(2番目以降に指定する) | |
| v | コマンドが作業状況を報告する |
| p | アーカイブファイルの作成時にオーナーやパーミッション情報を保持する |
| f | アーカイブファイルの名前を指定する |
表1のオプションのうち,アーカイブファイル名を指定する-fオプションの引数には,図7のようにアーカイブを作成するホストを指定できます。ところが,この方法は,現在のネットワークでは機能しないことが多々あります。
# tar cf remote_host:/dev/rmt0 ./
図7 tarの機能を用いてカレントディレクトリのアーカイブをリモ−トホストに作成する例
tarコマンドは,-fオプションでホスト名が指定された際,リモートホストのrmtコマンドをrshを用いて起動します2)。しかし,現在のネットワークではセキュリティ上の問題からrshを始めとするr系コマンド3)を許可していない場合がほとんどです。では,どのようにすればtarを用いてリモートバックを行えるのでしょうか?
r系コマンドをよりセキュアなものに置き換えるツールとしてSSHがあり,このうちsshコマンドは,rshコマンドと同様にリモートホストでコマンドを実行する機能を持ちます。このsshコマンドとtarコマンド,およびddコマンドを図8のように組み合わせることで,リモートホストにバックアップを作成することが可能になります。
# tar cvpf - / |dd bs=1024 | \ ssh remote_host "dd bs=1024 of=/backup/remote_host.tar.gz"
図8 sshとtarを用いてフルバックアップをリモ−トホストに行う例
また,図9のように標準出力をリダイレクトすることで,バックアップ装置のあるホスト側からリモートバックアップを行うことも可能です。
# ssh remote_host "(cd /etc;tar czpf - ./)" \ > /backup/remote_host/etc.tar.gz
図9 sshコマンドとtarを用いてリモートホストの/etcのバックアップを行う例
なお,ここでは説明を簡単にするため,リモートホスト側sshdがrootでのログインを許可している(sshd_configのPermitRootLoginがyesになっている)ものと仮定しています。また,この方法では毎回パスフレーズを入力する必要があります。 パスフレーズの入力を省略する方法については「バックアップを自動化する方法」の項で取り上げていますので,そちらを参照してください。
rsyncを用いる方法
tarを用いてバックアップを行った場合,バックアップ対象が1つのファイルとなってしまい,ファイル単位で管理を行いたいときなどに不便なことがあります。 このような場合にはrsyncを用いると良いでしょう。
rsyncをバックアップ元,バックアップ先双方のマシンにインストールしたうえで,
rsync オプション [ホスト名:]バックアップ元のファイル名またはディレクトリ名 [ホスト名:]バックアップ先のファイル名またはディレクトリ名
という書式で用いることで,リモートとローカルのファイル/ディレクトリを高速に同期することが可能となります。
rsyncで使用可能なオプションを表2に示します。
| -v | --verbose | 転送情報を詳しく表示 |
| -q | --quiet | 転送情報を表示しない |
| -c | --checksum | 常にチェックサムを行う |
| -a | --archive | アーカイブモード |
| -r | --recursive | ディレクトリで再帰的に実行する |
| -R | --relative | 相対パス名を使う |
| -u | --update | アップデートのみ許可 |
| -l | --links | ソフトリンクを維持する |
| -p | --perms | パーミッションを維持する |
| -o | --owner | オーナーを維持する |
| -g | --group | グループを維持する |
| -D | --devices | デバイスを維持する |
| -t | --times | タイムスタンプを維持する |
| -x | --one-file-system | 再帰的に実行された時にファイルシステムをまたがない |
| -e | --rsh=COMMAND | rsh の代替を指定 |
| --rsync-path=PATH | リモートのマシーンで rsync のコピーへのパスを指定 | |
| -C | --cvs-exclude | システム間で転送したくない広範囲のファイルを除外 |
| --delete | 送信側にないファイルを削除 | |
| --delete-excluded | 受信側にある exclud ファイルも削除 | |
| --force | ディレクトリが空でなくても削除 | |
| -z | --compress | 受信ファイルを圧縮 |
| --exclude=PATTERN | パターン一致するファイルを除外 | |
| --exclude-from=FILE | ファイルに記述されたパターンと一致するファイルを除外 | |
| --include=PATTERN | パターン一致するファイルを除外しない | |
| --include-from=FILE | ファイルに記述されたパターンと一致するファイルを除外しない | |
| --version | rsyncのバージョンを表示する | |
| --daemon | rsyncをデーモンとして走らせる | |
| -h | --help | ヘルプを表示する |
図10は,リモートホストの/homeのバックアップを行う例です。
# rsync -auz --delete --exclude-from=~/.rsync/excludes \ -e ssh remote_host:/home/ /backup/hostname/home/
図10 rsyncコマンドを用いてリモートホストの/homeのバックアップを行う例
ここではアーカイブモードで更新されたファイルのみを圧縮をかけて転送し(-auzオプション),--deleteオプションでバックアップ元で消去されたファイルをバックアップ先でも消去するように指定します。加えて,--exclude-fromオプションでバックアップを行う必要のないファイルの一覧を記したリスト(~/.rsync/excludes)を指定して,Webブラウザのローカルキャッシュなど不要なファイルをバックアップしないようにしています。また,rsyncはデフォルトではrshコマンドを用いてリモートホストのrsyncを呼び出しますので,ここでは-eオプションでrshの代わりにsshを用いるように指定しています。
なお,rsyncはバックアップ元としてディレクトリを指定した際,ディレクトリ名の末尾に'/'があるかないかで,その挙動を少し変えます。
具体的には「/foo/bar」のようにバックアップ元のディレクトリ名の末尾に'/'を付けなかった場合には,バックアップ先として指定したディレクトリ下のbarの中にバックアップファイルを作成するようになり,「/foo/bar/」のように末尾に'/'を付けた場合には,バックアップ先として指定したディレクトリ直下にバックアップファイルを作成するようになります。
さらに図11のように,バックアップ元のディレクトリ名の末尾に'/'を付けずに--deleteオプションを指定すると,バックアップ先ディレクトリ/backup/baz以下に存在するbar以外のすべてのファイル,ディレクトリを削除してしまうので注意が必要です。
# ssh remote_host "ls -F /foo/bar" # ←バックアップ元ディレクトリの内容確認 a b c/
# rsync -a --delete -e ssh remote_host:/foo/bar/ /backup/baz/
:
# ls -F /backup/baz # ←バックアップ先ディレクトリの内容確認
a # ←┐
b # ←┼ バックアップ先ディレクトリ直下にファイルが作成される
c/ # ←┘
# rsync -a --delete -e ssh remote_host:/foo/bar /backup/baz/
:
# ls -F /backup/baz
bar/ # ← 元からあったファイルは削除されbarディレクトリが作成される
# ls -F /backup/baz/bar
a
b
c/
図11 バックアップ元ディレクトリ名の末尾の'/'の有無によるrsyncの挙動の違い
バックアップを自動化する
バックアップは定期的に行ってこそ意味のあるものなのですが,そのためにわざわざ人間が計算機の前に貼り付いているのもばかばかしい話です。
ここではまずバックアップを自動化するための下準備として,SSHのパスフレーズ入力を省略する方法を解説し,その後コマンドを定期的に実行するcronデーモンを用いて定期的に自動バックアップを行う方法について解説します。
SSHのパスフレーズ入力を省略する
tarおよびrsyncの項では,SSHを経由したバックアップの取りかたを述べました。しかし,そのままではコマンドを実行するたびにパスフレーズの入力を要求され,作業を自動化するには適しません。
この問題を解決するためには,sshdの設定をPremitRootLogin fourced-command-onlyにしてrootの鍵のパスフレーズを空にする,など何種類かの方法が考えられますが,ここでは,ホストベース認証と呼ばれるホスト単位で認証を行うしくみを用いる方法を紹介することにします。
ホストベース認証はデフォルトでは無効になっています。これを有効にするには,接続先の「sshd_config」にリスト2の設定を,接続元の「ssh_config」にリスト3の設定をそれぞれ行う必要があります。
PasswordAuthentication no HostbasedAuthentication yes RhostsAuthentication no IgnoreRhosts no PermitRootLogin yes
リスト2 ホストベース認証のための接続先のsshd_configの内容
HostbasedAuthentication yes PreferredAuthentications hostbased,publickey,password
リスト3 ホストベース認証のための接続元のssh_configの内容
リスト2では安全性を高めるために,ホストベース認証にはSSH2プロトコルのみを使用するようにし,パスワード認証,rhost認証はそれぞれ拒否するようにしています。
上記の設定に加えて接続元のマシンではsshコマンド4)がsetuidされている必要もあります。
ホストベース認証を有効化したら,次いで接続先のrootのホームディレクトリに図12のように.shostsと.ssh/known_hostsを作成します。
% scp /etc/ssh/ssh_host_rsa_key.pub remote_host:
% slogin remote_host
:
& su -
# echo 'backup_host' >> .shosts
# chmod 0644 .shosts
# mkdir .ssh
# chmod 0755 .ssh
# cat /somewhere/ssh_host_rsa_key.pub >> .ssh/known_hosts
# chmod 0644 .ssh/known_hosts
# ^D
& ^D
:
%
図12 .sloginおよびknown_hostsの作成例
.shostsには接続元のホスト名を記述し,.ssh/known_hostsには接続元ホストの公開ホスト鍵を登録します。図12では一般ユーザの権限で接続元ホストbackup_hostの公開ホスト鍵/etc/ssh/ssh_host_rsa_key.pubを接続先remote_hostの自分のホームディレクトリ/somewhere/にscpで転送し,その後,remote_hostにログインしてrootになり,.shostsの作成後,転送しておいた公開ホスト鍵を.ssh/known_hostsに登録しています。
以上の設定を行うことで,パスフレーズを入力することなくバックアップ作業を行えるようになったはずです。次のcronの設定を行う前に実際にパスフレーズなしでバックアップ作業が行えることを確認してください。
cronの設定を行う
パスフレーズの入力を省略できるようになったことで,自動バックアップの下準備は整いました。 最後にcronの設定を行い,自動バックアップの環境を完成させましょう。
cronの設定ファイルは,歴史的経緯により,おもにシステム全体の処理を記述する「/etc/crontab」ファイルと,設定ファイルと同名の「crontab」コマンドによって作成される,ユーザが各自行いたい処理を記述するファイル群とに分かれています。どちらを使うかはOSや管理者のポリシーによりますが,本稿では/etc/crontabを用いることとします。
crontabファイルは,処理をいつ行うかの指定を1行ごとに列挙する方式で記述し,それぞれの行には,
処理を実行したい分 時 日 月 曜日 ユーザ コマンド [コマンドの引数…]
と,フィールドをスペースかタブで区切った書式で記述します5)。分,時,日,月,曜日のフィールドにはそれぞれ表3に示すような書式を用いることがきます。
| フィールド | 書式 |
|---|---|
| 分 | 0〜59 |
| 時 | 0〜23 |
| 日 | 1〜31 |
| 月 | 1〜12またはJan, Feb.... |
| 曜日 | 0〜6(0:日曜...6:土曜)またはSun,Mon... |
| 特殊表記 | |
| * | フィールドが取り得る全ての値 |
| */4 | 4回に1回 |
| 1,2 | 1と2 |
| 1-3 | 1から3 |
また,ユーザフィールドにはコマンドをどのユーザの権限で実行するかを指定します。たとえば毎週月曜〜金曜日の午前9時〜午後5時の間,2時間おきにroot権限でremote_hostの/homeをrsyncでバックアップする場合には,リスト4のように記述することになります。
0 9-17/2 * * 1-5 root /usr/local/bin/rsync -auz --delete -e /usr/bin/ssh remote_host:/home/ /backup/remote_host/home/ (実際には一行)
リスト4 crontabの設定
なお,cronなどのデーモンが参照する環境変数PATHは,通常,必要最小限しか設定されていません。不要なトラブルを避けるため,コマンドフィールドにはフルパスでコマンドを書くようにすると良いでしょう。
また,cronは指定されたコマンドを並列に実行します。バックアップのような完了するまでに時間を要する処理を実行するときは,実行間隔を十分に長く取る,コマンド側で排他制御を行うなど,同じ処理が重複して同時に動かないようにする配慮が必要になります。
