2026年6月17日
2026年6月17日
ファイルサーバーのバックアップ設計と実装(rsyncの世代管理・スナップショット・ランサムウェア対策)
ファイルサーバーのバックアップは、コピーの手順より先に「どこまで戻せればよいか」「どれだけの時間で戻すか」を決めると、方式が自然に決まります。そのうえで、バックアップ用のサーバーからファイルサーバーのデータを取りに行く形にし、世代を残し、少なくとも1つはファイルサーバー側から消せない場所に置くのが基本の構成です。この記事では、Linux 上の Samba や NFS で社内向けに共有しているファイルサーバーを例に、要件の決め方、構成の考え方、rsync による世代つきバックアップの実装、権限や属性の扱い、スナップショットとの組み合わせ、復元の確認までを説明します。WordPress のサーバーで、アップロードされたファイルを守る場合にも同じ考え方が使えます。
最初に決める3つのこと
設計の出発点は、次の3つです。
- RPO(どの時点まで戻せればよいか):最大で何時間分の変更を失ってもよいか。1日1回のバックアップなら、最悪で約1日分の作業が失われます。
- RTO(どれだけの時間で戻すか):障害から利用再開までに許される時間。共有全体を戻すのか、1つのフォルダーだけを戻すのかで、必要な仕組みが変わります。
- 保持期間:何日前、何か月前の状態まで戻せる必要があるか。「間違えて上書きしたことに3週間後に気づいた」という場面を想定すると、日次の世代だけでは足りないことが分かります。
これらは利用者や部署の責任者と合意しておきます。技術的に決められるのは方式であり、どれだけ失ってよいかは業務の側の判断だからです。
構成の考え方
3-2-1を基準にする
データを3つ持ち、2種類の媒体に置き、そのうち1つは別の場所に置く、という3-2-1の考え方が基準になります。ファイルサーバー本体のデータ、同じ拠点のバックアップサーバー、クラウドや別拠点のコピー、という3段の構成がよく使われます。
「取りに行く」形にする
ファイルサーバーからバックアップ先へ書き込む形(プッシュ)だと、ファイルサーバーが乗っ取られたり、ランサムウェアに感染したりしたときに、書き込み権限を使ってバックアップまで消されるおそれがあります。バックアップサーバーからファイルサーバーへ接続し、読み取ってくる形(プル)にすると、ファイルサーバー側はバックアップ先の認証情報を持たずに済みます。
消せないコピーを1つ持つ
プルにしても、バックアップサーバー自体が攻撃される可能性は残ります。オブジェクトストレージの削除を防ぐ機能(S3 のオブジェクトロックなど)、追記しかできない設定のリポジトリ、定期的に取り外す外部媒体など、通常の権限では消せないコピーを少なくとも1つ用意しておくと、最悪の場合の逃げ道になります。
RAID はバックアップではない
RAID はディスクの故障に備える仕組みで、誤削除や上書き、暗号化された状態も、そのまま全ディスクに反映されます。RAID を組んでいても、別のバックアップは必要です。
rsync で世代つきのバックアップを作る
rsync の --link-dest を使うと、前回から変わっていないファイルはハードリンクで共有し、変わったファイルだけを新しく保存できます。各世代のディレクトリは、それぞれが丸ごとのコピーに見えるため、戻すときにそのままファイルを取り出せます。
以下はバックアップサーバー側で実行する例です。ファイルサーバーの /srv/share を、日付ごとのディレクトリに取得します。
#!/bin/bash
# /usr/local/sbin/pull-share-backup.sh(バックアップサーバーで実行)
set -euo pipefail
SRC="backup@fileserver.example.lan:/srv/share/"
DEST_BASE="/backup/share"
TODAY="$(date +%Y%m%d)"
LATEST="$DEST_BASE/latest"
KEEP=30 # 日次の世代を30個残す
mkdir -p "$DEST_BASE"
LINK_OPT=()
if [ -d "$LATEST" ]; then
LINK_OPT=(--link-dest="$LATEST")
fi
rsync -aHAX --numeric-ids --delete \
--rsync-path="sudo rsync" \
"${LINK_OPT[@]}" \
"$SRC" "$DEST_BASE/$TODAY.partial/"
# 最後まで成功したときだけ確定させる
mv "$DEST_BASE/$TODAY.partial" "$DEST_BASE/$TODAY"
ln -sfn "$DEST_BASE/$TODAY" "$LATEST"
# 古い世代を名前(日付)の順に削除し、新しいものから KEEP 個を残す
ls -1d "$DEST_BASE"/20[0-9][0-9][0-1][0-9][0-3][0-9] | head -n -"$KEEP" | xargs -r rm -rf --
いくつかの点に理由があります。
-aHAX --numeric-ids:-aで権限・所有者・更新日時を保ち、-Hでハードリンク、-AでACL、-Xで拡張属性を保ちます。--numeric-idsは、バックアップサーバーに同じ名前のユーザーがいなくても、ユーザーIDの数字のまま保存するための指定です。.partialで受けてから名前を変える:途中で失敗した世代を、次回の--link-destの基準にしないためです。- 古い世代は名前で消す:rsync はディレクトリの更新日時も元のファイルサーバーの値にそろえるため、
find -mtimeで古さを判断すると、意図しない世代を消すことがあります。
1日1回の実行は、cron か systemd のタイマーで設定します。同じ日に2回実行すると、同じ名前の世代と衝突するため、1日に複数回取りたい場合は日時まで含めた名前にします。
権限・ACL・拡張属性の扱い
ファイルサーバーのバックアップで問題になりやすいのが、ファイルの中身ではなく権限です。中身は戻ったのに、共有のアクセス権が失われて誰も開けない、という事態は珍しくありません。
Samba で Windows のアクセス権を扱う設定にしている場合、その情報は拡張属性に保存されていることがあります。拡張属性の一部は root でなければ読めないため、ファイルサーバー側では、バックアップ用ユーザーに rsync だけを sudo で実行できる権限を与える構成がよく使われます。
# /etc/sudoers.d/backup-rsync(visudo -f で編集する)
backup ALL=(root) NOPASSWD: /usr/bin/rsync
これは rsync を root で動かせる強い権限なので、SSH の鍵には接続元の制限をかけ、rsync に付属する rrsync のような制限用スクリプトで読み取り専用・対象ディレクトリ限定にしておくと安全です。rrsync の場所はディストリビューションによって異なるため、パッケージの中身を確認してください。
また、Samba の設定ファイル(/etc/samba/smb.conf)、共有のユーザー情報、NFS の公開設定(/etc/exports)も、データとは別にバックアップします。データだけ戻っても、共有の設定を作り直すのに時間がかかるからです。
使用中のファイルとスナップショット
業務時間中に rsync を実行すると、コピー中に書き換えられたファイルが、壊れた状態で保存されることがあります。対策は2つあります。
- 利用の少ない時間帯に実行する:夜間に実行し、その時間に動く処理がないかを確認しておきます。
- スナップショットからコピーする:LVM、ZFS、Btrfs などのスナップショットを撮り、その固定された状態からコピーします。コピーの間にファイルが変わっても、バックアップには一貫した状態が残ります。
ZFS や Btrfs を使っている場合、ファイルサーバー自身に一定期間のスナップショットを残しておくと、誤削除からの復旧が速くなります。Samba の vfs_shadow_copy2 モジュールを設定すると、Windows のエクスプローラーの「以前のバージョン」からスナップショットのファイルを利用者自身が取り出せるようになります。ただし、スナップショットは同じディスク上にあるため、ディスクの故障やサーバーの乗っ取りには無力です。外部へのバックアップの代わりにはなりません。
外部へのコピー
同じ拠点のバックアップサーバーだけでは、火災や盗難、拠点全体の障害に備えられません。restic や BorgBackup のような重複排除・暗号化に対応したツールで、クラウドや別拠点に送るのが一般的です。外に出すデータは、送る前に暗号化しておきます。
BorgBackup の追記専用モードや、オブジェクトストレージのオブジェクトロックを使うと、送り元の権限では過去の世代を消せない構成にできます。ただし、追記専用にすると古い世代の整理を別の安全な端末から行う必要があるなど、運用の手間は増えます。
監視と復元の確認
バックアップは、止まっていることに気づかないのが最大の弱点です。
- スクリプトの終了コードを記録し、失敗したらメールやチャットに通知する
- 最新の世代の日付が古くなっていないかを、別の仕組みで毎日確認する
- バックアップ先のディスク使用量を監視する。ハードリンクで共有しているため、
duの見え方は世代の数ほどには増えません
そして、定期的に復元を試します。1つのフォルダーを戻す、共有全体を別のサーバーに戻す、の2種類を試し、かかった時間を記録しておくと、最初に決めた RTO を満たせるかを判断できます。権限が正しく戻り、利用者のアカウントで開けることまで確認してください(2026年10月現在の一般的な Linux ディストリビューションでの手順として説明しています。パッケージ名やパスは環境に合わせて読み替えてください)。
まとめ
- RPO・RTO・保持期間を業務の側と合意してから方式を決める
- 3-2-1を基準にし、バックアップサーバーから取りに行く形にして、消せないコピーを1つ持つ
- rsync の
--link-destで世代を作り、-aHAX --numeric-idsで権限・ACL・拡張属性を保つ - 使用中のファイルは夜間実行かスナップショットで扱い、共有の設定ファイルも別に保存する
- 失敗の通知と最新世代の監視を入れ、権限まで含めて定期的に復元を試す