ResticでVPSを別サーバーへバックアップする方法
ResticでVPSのデータを暗号化・重複排除し、別サーバーやS3互換ストレージへ保存します。Ubuntu 24.04での設定、毎晩のsystemdタイマー、保持ポリシー、復元テストまで解説します。
同じサーバー上のバックアップがバックアップにならない理由
Resticは、ファイルの暗号化および重複排除済みのスナップショットを別の場所にあるリポジトリへ送信する、無料のオープンソースバックアップツールです。送信先には、2台目のVPS、自宅のマシン、またはS3互換オブジェクトストレージを指定できます。このガイドでは、Ubuntu 24.04でのインストールから、SFTP経由のリポジトリ、最初のバックアップ、毎晩実行するsystemdタイマー、保持ポリシー、そして全体が機能することを確認するリストア手順まで設定します。コピーは同じサーバー上に置かず、別のマシンに保存する必要があります。同じサーバー上のコピーは、サーバーの障害とともに失われるためです。
バックアップ対象のサーバー上にbackup/ディレクトリを作成しても、防げるのは誤ってファイルを削除する事故だけです。そのディスク上にあるため、ディスク障害には耐えられません。root権限を持つ攻撃者が最初にコピーを削除するため、侵害にも耐えられません。VPS自体を削除してしまうアカウント操作のミスにも耐えられません。世界で最も非効率なデータセンターは、データと同じアレイ上にbackup_final_v2_REALという名前のtarballを置くことを冗談にしています。その冗談が通じるのは、多くの人が実際に同じことをしてきたからです。バックアップはサーバーの外部に置くのが原則です。Resticは、その原則を最も簡単に実践できる方法です。
Resticを理解する4つの要点
リポジトリ。 Resticがデータを書き込む場所です。Restic独自形式のディレクトリで、暗号化されたblobが格納されており、Resticだけが読み取れます。手動で編集せず、Resticのコマンドと-rアドレスを介して操作します。
スナップショット。 バックアップしたファイルを、ある時点で取得した状態の記録です。バックアップを実行するたびにスナップショットが作成され、各スナップショットを個別に復元できます。各スナップショットは、その時点のデータ全体のコピーとして機能します。
重複排除。 Resticはファイルをコンテンツ定義チャンクに分割し、リポジトリにまだ存在しないチャンクだけをアップロードします。最初のバックアップではすべてをアップロードします。それ以降の実行では、変更されたデータに相当する量だけをアップロードします。20 GBのデータで50 MBだけが変更された場合、毎晩作成するスナップショットのコストは約50 MBです。そのため、数十個のスナップショットを保持しても容量をあまり消費しません。
デフォルトで暗号化。 Resticのリポジトリは常に暗号化されています(AES-256)。すべてのコマンドでリポジトリのパスワードが必要です。バックアップホストやストレージプロバイダーに見えるのは、暗号化されたblobだけです。重大な点は、パスワードを失うとデータが永久に失われることです。これは意図した設計です。パスワードのコピーを、このサーバー上ではない場所に保管してください。この点は重要なので、以下でもう2回取り上げます。
Ubuntu 24.04 に restic をインストールする
sudo apt update && sudo apt install -y restic
restic versionUbuntu 24.04 では restic 0.16.4 がインストールされます。現在の upstream リリースは 0.19.1 です。この差は、LTS(長期サポート)リリースではパッケージのバージョンが固定されるために生じます。ただし、このガイドでは問題ありません。0.16.4 ですべての手順を実行できます。速度向上のために最新リリースを使用する場合は、restic プロジェクトの GitHub releases ページから公式の単一バイナリビルドをダウンロードし、bunzip2 で展開して /usr/local/bin/restic にインストールします。restic のインストールに必要な作業はこれだけです。
SFTP経由で別のサーバーにリポジトリを作成する
保存先のマシンが必要です。通常は2台目の小規模なVPSを使用します。SSHサーバーと空きディスクがあるマシンなら使用できます。ResticはSFTP(SSH経由のファイル転送)に対応しているため、バックアップホストにソフトウェアをインストールする必要はありません。このガイドでは、バックアップホストを10.0.0.12、ユーザー名をresticとします。このユーザー名にbackupを使用しないでください。UbuntuとDebianは、すべてのインストール環境にbackup(uid 34、ログインシェルなし)という予約済みのシステムアカウントを作成します。そのため、adduser backupは失敗し、ssh backup@...はnologinに配置されます。
夜間ジョブはバックアップ対象サーバー上でrootとして実行されるため、rootにはバックアップホストへの鍵認証によるログインが必要です。午前3時に入力する人がいないため、パスフレーズなしの専用鍵を作成し、コピーします。
sudo ssh-keygen -t ed25519 -f /root/.ssh/id_ed25519 -N "" -C "web1-restic"
sudo ssh-copy-id -i /root/.ssh/id_ed25519.pub restic@10.0.0.12
sudo ssh restic@10.0.0.12 true && echo key login works鍵認証に慣れていない場合は、SSH鍵管理の基本で仕組み、権限、後から鍵を失効させる方法を説明しています。
次に、リポジトリのパスワードを作成します。rootだけが読み取れるファイルに強力なパスワードを生成します。
openssl rand -base64 32 | sudo tee /root/.restic-password
sudo chmod 600 /root/.restic-password先に進む前に、そのパスワードをパスワードマネージャーにコピーしてください。このVPSが停止しても、リポジトリとこのパスワードがあればすべて復元できます。パスワードがなければ、リポジトリから何も復元できません。
リポジトリを初期化します。
sudo restic -r sftp:restic@10.0.0.12:/srv/restic/web1 --password-file /root/.restic-password initcreated restic repository 9f3c2a1b0d at sftp:restic@10.0.0.12:/srv/restic/web1別の保存先として、S3互換オブジェクトストレージも使用できます。2台目のマシンを運用したくない場合に適しています。S3互換バケットなら同じ方法で使用できます。変更するのはアドレスと2つの認証情報変数だけです。
export AWS_ACCESS_KEY_ID=your-key-id
export AWS_SECRET_ACCESS_KEY=your-secret-key
sudo -E restic -r s3:https://s3.example.com/web1-backups --password-file /root/.restic-password initinit以降は、どちらの保存先でも同じです。このガイドの残りではSFTPアドレスを示します。使用するアドレスに置き換えてください。
除外設定を行った最初のバックアップ
再インストールできないデータをバックアップし、ファイルシステム全体は対象にしません。オペレーティングシステムは再インストールで復元できますが、設定とデータは復元できません。一般的な VPS では、/etc、/home、およびアプリケーションが状態を保存する場所(/srv や /var/www など)が対象になります。キャッシュは除外します。キャッシュは容量が大きく、毎日更新され、自動的に再生成されるためです。
sudo restic -r sftp:restic@10.0.0.12:/srv/restic/web1 --password-file /root/.restic-password backup /etc /home /srv --exclude '/home/*/.cache'Files: 4181 new, 0 changed, 0 unmodified
Added to the repository: 731.204 MiB (312.418 MiB stored)
snapshot 5b8a3f2c saved最初の実行ではすべてのデータをアップロードするため、時間がかかります。同じコマンドをもう一度実行すると、重複排除により新しいチャンクだけがアップロードされるため、数秒で完了します。変更されたファイルが数個、追加された MiB が数個あることが報告されます。取得済みの一覧を表示します。
sudo restic -r sftp:restic@10.0.0.12:/srv/restic/web1 --password-file /root/.restic-password snapshots各スナップショットには ID、時刻、および含まれるパスが表示されます。復元にはこれらの ID を使用します。
systemd timerによる夜間実行
すべてのコマンドでリポジトリのアドレスを入力するのは手間がかかります。また、手動で実行するバックアップは1か月以内に実行されなくなります。どちらの問題も、1つのスクリプトと1つのタイマーで解決できます。スクリプトで、resticが読み取る2つの環境変数 RESTIC_REPOSITORY と RESTIC_PASSWORD_FILE を設定するため、スクリプト内の各コマンドを短くできます。
sudo nano /usr/local/bin/restic-backup.sh#!/usr/bin/env bash
set -euo pipefail
export RESTIC_REPOSITORY='sftp:restic@10.0.0.12:/srv/restic/web1'
export RESTIC_PASSWORD_FILE=/root/.restic-password
restic backup /etc /home /srv --exclude '/home/*/.cache'
restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune
restic checksudo chmod 700 /usr/local/bin/restic-backup.shforget と check の行については、次の2つのセクションで説明します。次にスケジュールを設定します。スクリプトを実行する oneshot serviceと、毎晩03:00に起動するtimerを作成します。ここではcronの行よりtimerが適しています。実行ログをjournalに記録でき、Persistent=true により、停止中に実行されなかったバックアップをサーバーの復旧直後に実行できるためです。
# /etc/systemd/system/restic-backup.service
[Unit]
Description=Nightly restic backup
Wants=network-online.target
After=network-online.target
[Service]
Type=oneshot
ExecStart=/usr/local/bin/restic-backup.sh# /etc/systemd/system/restic-backup.timer
[Unit]
Description=Run the nightly restic backup
[Timer]
OnCalendar=*-*-* 03:00:00
RandomizedDelaySec=15m
Persistent=true
[Install]
WantedBy=timers.targettimerを有効にしてから、serviceを手動で1回実行し、動作を監視します。
sudo systemctl daemon-reload
sudo systemctl enable --now restic-backup.timer
sudo systemctl start restic-backup.service
sudo journalctl -u restic-backup.service -fsystemctl list-timers には、次回の実行時刻が表示されます。unit fileのペアは、手動で入力する代わりに生成することもできます。
これら2つのファイルの基礎となる完全なパターンについては、カレンダー構文やserviceに設定できるhardeningディレクティブを含めて、VPSでプログラムをsystemd serviceとして実行する方法で説明しています。
バックアップはリストアするまで噂にすぎません
この文を原則として扱ってください。毎晩バックアップジョブが正常終了していても、ジョブが実行されたことしか証明できません。データを復元できることの証明にはなりません。2つの確認でこの差を埋めます。
1つ目は、restic checkです。この処理はすでに毎晩実行されています。リポジトリの構造とインデックスを検証するため、バックアップホスト上の潜在的な破損を、リストア当日ではなく翌晩に検出できます。月に1回、より詳細なバージョンを実行してください。この処理では、実データのランダムな10分の1をダウンロードし、暗号学的に検証します。
sudo -i
export RESTIC_REPOSITORY='sftp:restic@10.0.0.12:/srv/restic/web1'
export RESTIC_PASSWORD_FILE=/root/.restic-password
restic check --read-data-subset=10%毎回ランダムに対象が選ばれるため、月次実行を続けると、全データをダウンロードせずにリポジトリ全体を確認できます。
2つ目は、リストア訓練です。上記と同じrootシェルで、最新のスナップショットから実際のディレクトリを1つスクラッチ領域にリストアし、稼働中のファイルと比較します。
restic restore latest --target /srv/restore-drill --include /etc/ssh
diff -r /etc/ssh /srv/restore-drill/etc/sshdiff の出力がない場合、すべてのバイトが完全に同一の状態で戻ったことを意味します。これだけが有効な証拠です。完了後に /srv/restore-drill を削除してください。この訓練を毎月実施し、年に1回または2回は完全版も実施してください。最新のスナップショット全体をスクラッチVPSにリストアし、そこからアプリケーションが実際に起動することを確認します。緊急時にこれを実行する必要が生じたとき、すでに何度も実施した手順になっていることが重要です。
保持期間: forget と prune
ポリシーがないと、スナップショットは無期限に蓄積し、リポジトリだけが増え続けます。スクリプトの forget 行は、毎晩ポリシーを適用します。--keep-daily 7 は過去7日間について1日あたり1つのスナップショットを保持し、--keep-weekly 4 は4週間について週あたり1つ、--keep-monthly 6 は6か月について月あたり1つを保持します。ルールで保護されないものはすべて忘れられます。
forget だけではスナップショットの記録を削除するだけです。データチャンクは、何らかの処理で削除されるまでリポジトリに残ります。それを行うのが --prune です。残っているスナップショットから参照されていないチャンクを探して削除します。この時点で、実際にディスク容量が解放されます。Prune はリポジトリに対して実際の処理を行うため、大規模なリポジトリでは forget を毎晩、--prune を毎週実行する方法もあります。一般的な VPS のサイズであれば、毎晩の実行で問題ありません。
データベース: まずダンプし、その後ダンプをバックアップする
Restic はファイルを読み取りながらコピーします。一方、データベースは継続的にファイルへ書き込みます。書き込み途中のライブデータベースファイルを取得すると、書き込み前後のページが混在するため、復元時にデータベースが破損します。標準的な対策は、データベースエンジンに整合性のあるエクスポートをファイルへ作成させ、そのファイルを restic でバックアップすることです。
PostgreSQL の場合は、restic-backup.sh の先頭に、restic backup コマンドより前にダンプの行を追加します。また、ダンプディレクトリをバックアップ対象のパスに含めます。
mkdir -p /var/backups/db
sudo -u postgres pg_dump myapp | gzip > /var/backups/db/myapp.sql.gzMariaDB と MySQL では、mysqldump が同じ役割を果たします。手順全体の例については、Nextcloud のバックアップセクションでメンテナンスモードを有効にし、Postgres をダンプして、ファイルを一貫したセットとしてコピーします。これは、restic が毎晩サーバーから持ち出すべき対象そのものです。SQLite も同じ考え方ですが、より簡単な方法を使います。Vaultwarden ガイドでは、数秒間コンテナを停止して db.sqlite3 のコールドコピーを作成し、そのアーカイブを restic でサーバー外へ転送します。
FAQ
resticのバックアップは暗号化されていますか?
はい、常に暗号化されています。すべてのresticリポジトリはAES-256で暗号化され、暗号化しないモードはありません。すべてのコマンドでリポジトリのパスワードが必要です。リポジトリを保存するマシンやプロバイダーが保持するのは暗号化済みのblobだけなので、バックアップホストが侵害されてもファイルは公開されません。代わりに、パスワードがなければ誰もデータを復元できません。そのため、パスワードのコピーをサーバーから離れた場所に保管してください。
resticは増分バックアップを実行しますか?
resticの各スナップショットは完全バックアップと同じように動作しますが、必要なストレージは増分分だけです。resticはファイルをチャンクに分割し、リポジトリにまだ保存されていないチャンクだけをアップロードします。そのため、毎晩の実行で転送されるのは、おおむねその日に変更された分だけです。従来の増分方式と異なり、再生が必要なチェーンはありません。任意のスナップショットを直接復元でき、古いスナップショットを削除しても新しいスナップショットが壊れることはありません。
resticのバックアップからファイルを復元するにはどうすればよいですか?
restic snapshotsを実行してスナップショットIDを確認し、次にrestic restore <id> --target /some/empty/dirを実行して復元します。--include /pathを追加すると、一部だけを復元できます。IDの代わりにlatestも使用できます。resticは元のディレクトリ構造を復元先の下に再作成するため、/etc/sshを復元すると/some/empty/dir/etc/sshに配置されます。必要になる前にこの手順を試してください。テストしていないバックアップは、存在を確認できない情報にすぎません。
restic backupはどのくらいの頻度で実行すべきですか?
サーバーでは毎晩の実行が現実的な最低頻度です。重複排除により、各実行で前回から変更されたチャンクだけがアップロードされるため、コストも抑えられます。変更の速いデータや、1日分でも失うと大きな損害になるデータは、同じタイマーの構成で数時間ごとに実行できます。頻度は対策の一部にすぎません。定期的にrestic checkも実行し、毎月復元訓練も行ってください。検証のないスケジュールは、誤った安心感を生みます。
resticリポジトリのパスワードを失った場合はどうなりますか?
バックアップは復元できません。resticの暗号化にはバックドアもリセット機能もないため、パスワードはバックアップそのものと同じくらい重要です。パスワードマネージャーと、バックアップ対象サーバー以外の耐久性のある場所にコピーを保管してください。まだアクセスできる間に、restic key addを使用して同じリポジトリに2つ目のパスワードを登録できます。これにより予備のパスワードを用意できます。