Last-Modified: 2003/02/20 15:55

NetworkingTips

データのリモートバックアップ

定期的なデータのバックアップも管理者の重要な仕事の1つです。バックアップを取りたいマシンにDATなどがある場合には,図6のようにtarコマンドを使用したり,専用のコマンドを使用することで簡単に作業を行うことができます。

# tar cvpf /dev/sa0 /

図6 tarを用いて/dev/sa0にフルバックアップを取る例

しかし予算の都合などでバックアップ装置が省略されているマシンも多数あるでしょう。
ここではこのようなマシンのデータをネットワーク経由でバックアップする方法について解説します。

tarを用いる方法

まず,標準で用意されているtarコマンドを用いる方法を見てみましょう。

tarコマンドは,多くのファイルを1つにまとめた書庫(アーカイブ)を作成,管理するためのコマンドで,
tar オプション アーカイブ対象となるファイル名またはディレクトリ名
という書式で使用します。オプションには表1に示すようなものが指定可能です。

表1 tarの代表的なオプション
機能指定オプション(オプションの先頭に指定する)
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に示します。

表2 rsyncの代表的なオプション
-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に示すような書式を用いることがきます。

表3 crontabの各フィールドの書式
フィールド 書式
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は指定されたコマンドを並列に実行します。バックアップのような完了するまでに時間を要する処理を実行するときは,実行間隔を十分に長く取る,コマンド側で排他制御を行うなど,同じ処理が重複して同時に動かないようにする配慮が必要になります。

1) SoftwareDesign 2003年2月号 pp.14-30, 「ネットワーク管理者必携! ネットワークの基本ワザ」より一部加筆の上,転載

2) FreeBSD 4.3Release以降のtarでは環境変数TAR_RSHを用いることでrsh以外のコマンドを使用することも可能です。

3) rsh, rlogin, rcp, rexecなど

4) OpenSSH3.3以降の場合はssh-keysignコマンドです。

5) crontabコマンドによりユーザ別のcrontabを作成する場合は「分 時 日 月 曜日 コマンド [コマンドの引数…]」という書式になります。