SSD Nodes Learn
ガイド Matt Connor著者 Matt Connor ・更新日 2026-07-24

Resticの使い方。VPSのデータを安全に外部へバックアップする方法

Resticを使ってVPSのデータを暗号化・重複排除しながら外部ストレージへ自動保存する手順を解説します。Ubuntu 24.04でのインストールから、SFTPを利用したリポジトリ作成、systemd timerによる定期実行、リストア検証まで、実用的な手順を網羅しています。

同一サーバーへのバックアップがバックアップにならない理由

Resticは、暗号化および重複排除されたファイルのsnapshotを、別の場所(2台目のVPS、自宅のマシン、またはS3互換のオブジェクトストレージなど)のリポジトリへ送信する、オープンソースの無料バックアップツールです。このガイドでは、Ubuntu 24.04へのインストールから、SFTP経由のリポジトリ作成、初回バックアップ、nightlyのsystemd timerの設定、保持ポリシー(retention policy)、そして動作を確認するためのリストア手順までを解説します。バックアップ先は別のマシンである必要があります。同じサーバー内にあるコピーは、サーバーが故障した際に同時に失われるためです。

バックアップ対象のサーバー内にある backup/ ディレクトリは、誤操作によるファイルの削除からのみ保護します。ディスクの故障には対応できません。データと同じディスクに保存されているためです。root権限を持つ攻撃者にも対応できません。攻撃者はまずコピーを削除するからです。VPS自体を削除してしまうようなアカウント操作のミスにも対応できません。世界で最も非効率なデータセンター では、データと同じアレイ上に backup_final_v2_REAL という名前のtarballが置かれていることを冗談として扱っていますが、実際にそのようなミスを経験した人は非常に多いため、この冗談は現実味を帯びています。バックアップ先は「サーバーの外」にすることが原則であり、Resticはその原則を守るための最も簡単な方法です。

Resticの4つの基本概念

Repository. resticがデータを書き込む場所です。restic独自の形式のディレクトリであり、暗号化されたblobで構成されます。resticのみがこれを読み取れます。手動で編集しないでください。resticのコマンドと -r アドレスを使用して操作します。

Snapshot. バックアップしたファイルのある時点の状態を示すものです。バックアップを実行するたびにsnapshotが作成されます。各snapshotは単独でリストア可能です。各snapshotは、その時点のデータの完全なコピーとして機能します。

Deduplication. resticはファイルをコンテンツベースのchunkに分割し、repositoryに存在しないchunkのみをアップロードします。初回バックアップではすべてがアップロードされますが、それ以降は変更された分のみがアップロードされます。例えば、20 GBのデータのうち50 MBが変更された場合、夜間のsnapshotのコストは約50 MBで済みます。そのため、多数のsnapshotを保持しても容量を圧迫しません。

Encryption by default. resticのrepositoryは常に暗号化(AES-256)されています。すべてのコマンドの実行にrepositoryのパスワードが必要です。バックアップホストやストレージプロバイダーは、暗号化されたblobしか見ることができません。重大な注意点として、パスワードを紛失すると、設計上、データは永久に復元できなくなります。パスワードのコピーは、このサーバーとは別の場所に保管してください。この重要性は、以下のセクションでも繰り返し述べます。

Ubuntu 24.04 に restic をインストールする

sudo apt update && sudo apt install -y restic
restic version

Ubuntu 24.04 では restic 0.16.4 がインストールされます。現在の最新リリースは 0.19.1 です。LTS (long term support) リリースはパッケージのバージョンを固定するため、このような差が生じます。ただし、本ガイドでは 0.16.4 で十分です。速度向上のために最新リリースが必要な場合は、restic プロジェクトの GitHub releases ページから公式の single-binary をダウンロードしてください。bunzip2 で解凍し、/usr/local/bin/restic にインストールします。restic のインストール手順はこれだけです。

SFTPを使用して別のサーバーにリポジトリを作成する

転送先となるマシンが必要です。一般的には、2台目の小型VPSが適しています。SSHサーバーと十分な空きディスク容量があれば、どのようなマシンでも使用可能です。ResticはSFTP(SSH経由のファイル転送)を使用するため、バックアップホスト側に特別なソフトウェアをインストールする必要はありません。このガイドでは、バックアップホストをユーザー名 restic10.0.0.12 とします。ユーザー名を backup にしないでください。UbuntuやDebianでは、すべてのインストールにおいて backup (uid 34, login shellなし) という予約済みシステムアカウントが存在します。そのため、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 init
created 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 init

init 以降の手順は、どちらの転送先でも同一です。このガイドの残りの部分はSFTPのアドレスを使用していますが、ご自身の環境に合わせて読み替えてください。

除外設定を用いた初回バックアップ

ファイルシステム全体ではなく、再インストールできないデータをバックアップしてください。OSは再インストールで復元できますが、設定やデータは復元できません。一般的な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 を使用した nightly 実行

コマンドのたびに repository のアドレスを入力するのは非効率です。また、手動でのバックアップは、1ヶ月も経てば実行されなくなります。これら両方の問題は、1つの script と 1つの timer で解決できます。script 内で restic が読み取る 2つの environment variables、RESTIC_REPOSITORYRESTIC_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 check
sudo chmod 700 /usr/local/bin/restic-backup.sh

forgetcheck の行については、次の 2つのセクションで説明します。次にスケジュールについてです。script を実行する 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.target

timer を enable にした後、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 -f

systemctl list-timers を使用すると、次回の実行時刻を確認できます。また、手動で入力する代わりに、unit files のペアを生成することも可能です。

ToolGenerate the backup service and timer

カレンダー構文や service に設定可能な hardening directives を含む、これら 2つのファイルの構成パターンについては、VPS 上で systemd service としてプログラムを実行する を参照してください。

バックアップはリストアできるまで信用できません

この言葉を鉄則として捉えてください。毎晩バックアップジョブが正常に終了していても、それはジョブが実行されたことを示すだけで、データが復元できることを証明するものではありません。そのギャップを埋めるには、2つの確認作業が必要です。

1つ目は restic check です。これはスクリプトによって既に毎晩実行されています。リポジトリの構造とインデックスを検証するため、バックアップホストでのサイレントなデータ破損を、リストアが必要になった時ではなく、翌日のジョブ実行時に検知できます。月に一度、以下の詳細な検証を実行してください。これは実際のデータの10%をランダムにダウンロードし、暗号学的に検証します。

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つ目はリストアの訓練です。引き続き上記のルートシェルを使用し、最新のスナップショットから実際のディレクトリを1つ一時的な場所にリストアして、実ファイルと比較します。

restic restore latest --target /srv/restore-drill --include /etc/ssh
diff -r /etc/ssh /srv/restore-drill/etc/ssh

diff に何も出力されなければ、すべてのバイトが完全に復元されたことを意味します。これこそが唯一の確かな証拠です。終了後、/srv/restore-drill を削除してください。この訓練を毎月行い、年に1、2回はフルバージョンを実行してください。最新のスナップショット全体を一時的な VPS にリストアし、アプリケーションがそこから正常に起動するかを確認します。緊急時に確実に動作させるためには、その手順をルーチンとして習得しておく必要があります。

Retention: forget と prune

ポリシーを設定しないと、スナップショットが蓄積され続け、リポジトリのサイズが増大し続けます。スクリプトの forget 行は、毎晩ポリシーを適用します。--keep-daily 7 は過去7日間の各日のスナップショットを1つずつ保持し、--keep-weekly 4 は4週間の各週のスナップショットを1つずつ、--keep-monthly 6 は6ヶ月間の各月のスナップショットを1つずつ保持します。ルールで保護されていないデータはすべて削除されます。

forget 単体では、スナップショットのレコードを削除するだけです。データチャンクは、何らかの処理によって削除されるまでリポジトリ内に残ります。--prune は、どのスナップショットからも参照されていないチャンクを見つけて削除します。これにより、実際にディスク容量が解放されます。Prune はリポジトリの実作業を伴うため、大規模なリポジトリでは forget を毎晩、--prune を毎週実行する構成もあります。一般的な VPS のサイズであれば、毎晩の実行で十分です。

Databases: 先にダンプを作成し、その後にバックアップを取る

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.gz

MariaDB および MySQL の場合は、mysqldump が同様の役割を果たします。このパターンの具体的な例として、Nextcloud のバックアップセクション では、メンテナンスモードを有効にして Postgres をダンプし、一貫したファイルセットとしてコピーします。これは、restic が毎晩サーバーから持ち出すべきデータセットそのものです。SQLite も同様の考え方ですが、より簡潔な手順で行います。Vaultwarden のガイド では、コンテナを数秒間停止して db.sqlite3 のコールドコピーを取得します。restic はそのアーカイブをサーバーから転送します。

FAQ

restic バックアップは暗号化されますか?

はい、常に暗号化されます。すべての restic repository は AES-256 で暗号化されます。暗号化されないモードはありません。すべてのコマンドに repository password が必要です。repository を保存するマシンやプロバイダーは、暗号化された blob のみを保持します。そのため、バックアップホストが侵害されてもファイルが露出することはありません。トレードオフは明確です。パスワードがなければ誰もデータを復元できません。パスワードのコピーはサーバーとは別の場所に保管してください。

restic は増分バックアップを行いますか?

すべての restic snapshot は、ストレージ容量を節約しながら、フルバックアップのように動作します。restic はファイルを chunk に分割し、repository にまだ保存されていない chunk のみをアップロードします。そのため、毎晩の実行では、その日に変更された分に近いデータ量のみが転送されます。従来の増分方式とは異なり、再生すべきチェーンはありません。どの snapshot からでも直接復元でき、古い snapshot を削除しても新しい snapshot に影響しません。

restic バックアップからファイルを復元するにはどうすればよいですか?

restic snapshots を実行して snapshot ID を特定し、次に restic restore <id> --target /some/empty/dir で復元します。一部のみを復元する場合は --include /path を追加してください。latest は ID の代わりに使用できます。restic は、ターゲットの下に元のディレクトリ構造を再作成します。例えば、/etc/ssh を復元すると /some/empty/dir/etc/ssh に配置されます。バックアップの検証は不可欠です。実際に必要になる前に、この手順を練習しておいてください。

restic backup はどのくらいの頻度で実行すべきですか?

サーバーの場合、毎晩の実行が妥当な最小単位です。deduplication により、コストは低く抑えられます。各実行では、前回の実行以降に変更された chunk のみがアップロードされます。変更が激しいデータや、1日分の損失も許されないデータについては、同じタイマーパターンで数時間おきに実行することも可能です。頻度を決定することよりも、restic check を定期的に実行し、月に一度は復元テストを行うことが重要です。検証のないスケジュールは、偽りの安心感しか与えません。

restic repository password を紛失した場合はどうなりますか?

バックアップは復元できなくなります。restic の暗号化にはバックドアもリセット機能もありません。パスワードはバックアップデータそのものと同じくらい重要です。パスワードマネージャーや、バックアップ対象のサーバーとは別の、耐久性のある場所にコピーを保管してください。アクセス権があるうちに、restic key add を使用して同じ repository に2つ目のパスワードを登録し、予備を作成しておくことができます。