チュートリアル
VPSを暗号化オフショアストレージへバックアップする方法
サーバーをデプロイしたその日にバックアップを用意する人は、ほとんどいません。それはいつも後からやって来ます — アップグレード中にディスクが満杯になった後、間違ったディレクトリで削除してしまった後、マイグレーションのせいで一見正常に起動するのに答えがおかしいデータベースが残った後、誰かに侵入された後。重要なマシンを稼働させることと、そのマシンより長生きするコピーを持つことのあいだにあるこの隙間こそが、セルフホスティングにおいて最も危険な期間であり、ほとんどの人はそれに気づかないまま何か月も過ごします。長いあいだ何も起きず、そしてある日すべてが一度に起きるからです。この隙間を埋めるのは難しくも高くもありません。難しく感じさせているのは、「バックアップ」という言葉が四つの異なるものを指すのに使われ、そのうち悪い日にもまだそこにあるのはたった一つだけだ、という事実です。
バックアップではない四つのもの
そのどれもが本当に役立ち、備えておく価値があります。しかしそのどれもバックアップではなく、そうではないと思い込むことこそが、人々が安全だと思っていたデータを失う最も多い原因です。この区別は重箱の隅をつつく話ではありません — これらはどれも、バックアップが最も必要になるまさにその状況で機能しなくなるのです。
- RAIDは稼働時間を守るものであって、バックアップではありません。アレイはディスクが1台故障してもオフラインにならずに耐えます — 当社のストレージサーバーがRAID-6で稼働し、同時に2台の故障まで許容しているのもそのためです。しかし削除されたディレクトリ、失敗したアップグレード、誰かに暗号化されてしまったファイルツリー、あるいはドロップされたテーブルからは守ってくれません — そのどれもが、すべてのディスクへ同じ瞬間に忠実に書き込まれてしまうからです。
- スナップショットは「元に戻す」機能であって、バックアップではありません。データと同じストレージ上に存在し、たいてい同じマシンのrootから見え、ボリュームやホストを破壊するものは何であれスナップショットも道連れにします。ロールバックは速い一方、マシンそのものが失われれば無力です。
- 同期はレプリケーションであって、バックアップではありません。同期ツールは遠隔側を手元側に一致させるために存在するので、削除や破損はネットワークが許す限りの速さでコピー側にも伝播します。Nextcloud、Dropbox、rclone syncはいずれも設計上こうふるまいます。
- バージョン履歴とゴミ箱は便利機能であって、バックアップではありません。これらはアプリケーションの機能であり、アプリケーションのデータベース内に保持され、保持期間も日単位です。壊れた原因がそのアプリケーション自身であれば、履歴も道連れになります。
- 同じサーバー上のコピーはオフサイトではありません。障害の原因がマシン自体、プロバイダーアカウント、ハイパーバイザー、あるいは差し押さえであれば、そのマシン上のすべてのファイルは、どのディレクトリに置かれていようと同じ障害ドメインの中にあります。
バックアップとは、空間的に分離し、時間的に分離し、そして管理権限の面でも分離しているコピーのことです。空間的に分離しているのは、火災や差し押さえが両方を同時に道連れにしないためです。時間的に分離しているのは、被害を忠実に写し取ったコピーではなく、被害が起きる前の状態に戻れるようにするためです。管理権限の面で分離しているのは、稼働中のマシンから盗まれた認証情報がそこに届かないようにするためです。この三つのうちどれか一つでも欠けているものは、バックアップの衣装をまとった便利機能にすぎません。
3-2-1ルールと、2026年を生き抜くための拡張版
古くからのルールは、データを3つのコピーで持ち、2種類の異なるストレージに分け、そのうち1つをオフサイトに置く、というものです。これがいまだに通用するのは、本質的にテープの話ではなく、相関のない障害についてのルールだからです。それ以来、正当な理由があって2つの項目が付け加えられました。どちらも、このルールが書かれた当時にはまだ一般的でなかった出来事が理由になっています。
- 3つのコピー。稼働中のデータに加えて、さらに2つ。コピーが2つしかないと、あと1回の障害で単一障害点になってしまい、単一障害点というものは、最初の問題を直そうと思っているうちに限って壊れるものです。
- 2種類のストレージ。異なるハードウェア、異なるソフトウェア、できれば異なるプロバイダー。同じホスト上の2つのボリュームは、ハイパーバイザーもコントロールパネルもアカウントも共有しています — つまり、そのアカウントを失う原因もすべて共有しているということです。
- 1つはオフサイトへ。物理的に別の場所にあり、自分のインフラが落ちても道連れにならないインフラの上に置きます。これが、火災、盗難、差し押さえ、そして予告なしのアカウント閉鎖に効くコピーです。
- 1つはイミュータブル、またはオフラインに。ランサムウェアも乗っ取られたrootも、真っ先にバックアップを探しに来ます。自分のサーバーが書き込める送信先は、自分のサーバーが消せる送信先でもあります。追記専用の認証情報、あるいはプル型の設計にしておけば、それが大惨事から単なる不便へと変わります。
- 検証していないリストアはゼロに。一度もリストアしたことのないバックアップは、単なる仮説にすぎません。これは人々が最も省略しがちで、最も後悔する項目です。なぜなら、2年間ずっと成功を報告し続けてきたバックアップジョブが、その2年間ずっと使い物にならないアーカイブを書き続けていた、ということが起こり得るからです。
何をバックアップすべきか:マシン全体ではなく状態
直感的にはサーバー全体をイメージ化したくなります。しかしそれはたいてい間違った形です:イメージバックアップは容量が大きく、遅く、一部分だけを選んでリストアするのが面倒なうえ、その中身の大半は1分もあれば再インストールできる素のOSです。再生成できないのは状態のほう — つまり、あなたが何かをしたからこそ存在しているものです。
- データベースはコピーではなくダンプで。エンジンが書き込んでいる最中にコピーしたデータベースファイルは、破損したファイルであり、リストアできるかもしれないし、間違ってリストアされるかもしれず、しかもどちらなのか教えてはくれません。エンジン自身のダンプツールを使うか、サービスを停止するか、あるいはファイルシステムのスナップショットを取ってそこからダンプしましょう。
- アプリケーションのデータディレクトリ。アップロードされたファイル、メディア、生成されたアセット — データベースが指し示すファイルツリーです。データベースとまったく同じ時点で取得しなければ、そこに存在しないファイルを記述する索引をリストアすることになります。
- 設定ファイルと、自分の手で編集したもの。ウェブサーバーとリバースプロキシの設定、systemdユニット、cronのエントリ、ファイアウォールのルール、そして夜中の2時に加えた二十個の細かい修正 — どうせ覚えてはいません。
- シークレットと鍵は、別扱いでより慎重に。TLS証明書とその秘密鍵、SSHのホスト鍵、APIトークン、そして何より重要なウォレットファイルとシード。これらには、レンタルしたマシンの上だけにとどまらない、専用の暗号化されたコピーがふさわしいものです。
- コンテナの定義とボリューム。composeファイルと環境変数ファイル、そして名前付きボリューム — これこそ忘れられがちな部分です。コンテナ自体はいくらでも簡単に作り直せますが、そのボリュームはそうはいかないからです。
- インストールそのものではなく、何がインストールされているかの一覧を。パッケージ、バージョン、そして何がどこで動いているかの短い目録があれば、ルートファイルシステム全体のイメージよりも速く、小さくリストアできます。
境界線は単純です:スクリプトやパッケージマネージャーから10分で再生成できるなら、バックアップする必要はありません — 代わりに手順を書き留めておきましょう。あなたやユーザーが何かをしたからこそ存在しているものなら、コピーが必要です。この原則は小さなサイトから、ウォレットとデータベースがすべてであり残りは再インストールできるBTCPayインスタンス、そしてファイルツリーとそのデータベースを一緒に取得しなければどちらもほとんど価値を持たないNextcloudサーバーまで、そのまま当てはまります。
送信先のサイジングと、実際にかかるコスト
たいていの人はこれをひどく過大評価します。最初のフルコピーの容量を計算し、それを保持したい日数分だけ単純に掛け算してしまうからです。しかし最近のバックアップツールはそういう動き方をしません。データをチャンクに分割し、重複のないチャンクだけを1回だけ保存し、圧縮できるものは圧縮します — だからこそ、ほとんど変化していないサーバーの2回目のスナップショットはほぼ無料同然になり、毎日30回分のスナップショットも最初の30倍には遠く及びません。
- 通常のペースで変化するサーバーに一般的な保持ポリシーを設定するなら、稼働中の状態のサイズに加えて、履歴分として30〜50パーセントを見込んでおきましょう。
- 容量の増加を左右するのは頻度よりも保持期間のほうです。2日分保持する1時間ごとのスナップショットは、3年分保持する毎日のスナップショットより安上がりです。実際にどこまで過去に遡ることがあり得るかを決めたうえで、そこまでを自動的に間引きましょう。
- すでに圧縮済みのデータは、もう一度圧縮しても縮みません。動画、写真、アーカイブ、暗号化されたバイナリはほぼ元のサイズのまま落ち着くので、メディア中心のサーバーに必要なのは巧妙な設定ではなく、正味の容量です。
- データベースはダンプ間での重複排除の効きが悪いものです。わずかに異なるデータベースの圧縮済みダンプは、まったく別のバイト列になってしまうからです。圧縮せずにダンプし、圧縮そのものはバックアップツールに任せれば、ストレージコストは大きく下がります。
- 遅いのは最初のアップロードだけです。それ以降は毎晩の実行が差分だけを転送し、たいていのサーバーではその量はメガバイト単位にすぎません。ここでの転送量は無制限なので、最初の1回にかかるのは予算の問題ではなく忍耐の問題です。
実際のところ、これはスタック全体の中でも最も安い保険です。ストレージサーバーは$7.99/moからでRAID-6上の1 TBが手に入り、これはVPSインスタンス数台分の状態が占める容量をゆうに上回ります。STO-2なら$12.99/moで容量が2倍になります。メディアライブラリや長期保持で容量が本当にものを言う場面には、STO-4が$22.99/moで4 TBを、STO-8が$39.99/moで8 TBを用意しています。送信先はrsync、SFTP、S3互換APIを話すので、主要なバックアップツールはどれもプラグインなしで接続でき、ボリュームは保存時にAES-256で暗号化され、独自の鍵の持ち込みにも対応しています — とはいえ次の節で述べる通り、データはどのみち送信元を出る前に暗号化しておくべきです。
ツールの選び方:それぞれが本当に向いていること
ここで思い悩む必要はありません。3つのツールで事実上すべてのケースをカバーできますし、どれも無料であり、ツール同士の違いよりも「使っているか使っていないか」の違いのほうがずっと重要です。ベンチマークではなく、自分の課題の形で選びましょう。
- restic — たいていのサーバーに対するデフォルトの推奨です。クライアント側で暗号化され、重複排除を行い、デーモン不要の単一の静的バイナリで、SFTP、S3互換エンドポイント、普通のディレクトリにネイティブに書き込めます。追記専用モードは、乗っ取られたサーバーが消せない送信先を作る最も簡単な道です。
- BorgBackup — 重複排除と圧縮に優れ、低速な回線でも非常に効率的で、成熟し実績も豊富です。リモートリポジトリを使うには送信先に専用のエージェントが必要になりますが、これはストレージの消費を目に見えて軽くしてくれることと引き換えの小さな制約です。
- rclone — 本質的にオブジェクトストア間でデータを移動する作業や、バージョン管理された履歴ではなくミラーが欲しい場合に適したツールです。直接使うならcryptレイヤーと組み合わせ、素の同期は削除も伝播させてしまうことを忘れないでください。
- データベースには、必ずネイティブのダンプツールを使いましょう。mysqldump、pg_dumpおよびそれらに相当するツールは、エンジンが確実に読み戻せる一貫性のある論理コピーを作ります。ファイルにダンプしてから、resticやBorgにそのファイルを拾わせましょう — ダンプを、気の利いたファイル単位のコピーで代用しようとしてはいけません。
- プロバイダーのスナップショットは、あくまで高速なローカル層として扱いましょう。リスクのあるアップグレードの前後で素早くロールバックするために使い、3つのコピーの1つとして数えてはいけません。
ステップバイステップ:一度の作業で動く暗号化バックアップを作る
- 01送信先をデプロイし、まず固める保護対象のサーバーとは異なるリージョンにストレージサーバーを置きます。鍵認証のみのSSH、専用のユーザー、そして書き込み元のマシンと認証情報を使い回さないことが条件です。
- 02ツールに触る前に、状態のリストを決める生き残らせるべきすべてのパスとすべてのデータベースを書き出しましょう。今テキストファイルに10分かけておけば、誰もリストに入れていなかった1つのディレクトリをリストアの最中に発見する事態を防げます。
- 03暗号化されたリポジトリを初期化する強力なリポジトリパスワードを生成し、SFTPまたはS3経由でリポジトリを初期化し、そのパスワードはバックアップ対象のサーバー以外の場所に保管しましょう。鍵が壊れたマシンの上にしか存在しないリポジトリは、復旧できません。
- 04先にデータベースをダンプし、それからアーカイブする各データベースをステージング用ディレクトリにダンプし、そのダンプとファイルツリーの両方に対して1回のバックアップを実行するラッパースクリプトを用意します。この順序こそが、データベースとそのファイルの整合性を保つ鍵です。
- 05最初のバックアップを実行し、終わるまで見守る最初の1回は時間がかかります。接続が切れても止まらないよう、ターミナルマルチプレクサの中で実行し、かかった時間を記録しておきましょう — これでリストアにかかる時間の目安も同時にわかります。
- 06保持期間を設定し、自動的に間引く日次7つ、週次4つ、月次6つ程度のスナップショットで、たいていのサーバーには十分です。同じジョブの中で間引きも設定しておかないと、リポジトリはいずれ動かなくなる日まで肥大化し続けます。
- 07スケジュールを組み、失敗したら必ず気づけるようにする毎晩のタイマーまたはcronのエントリに加え、ジョブが成功を報告しなかったときのアラートを用意します。何も知らせてこないバックアップジョブは、気づくまでの何か月ものあいだ、バックアップジョブが存在しないのと見分けがつきません。
- 08今日のうちに、別のマシンでバックアップから何かをリストアするアーカイブの一覧表示ではありません — 実在する1つのファイルと1つのデータベースを、使い捨てのサーバーへ実際にリストアするのです。これを一度やり遂げるまで、あなたが手にしているのはバックアップスクリプトであって、バックアップではありません。
サーバーを殺したものからコピーを生き延びさせる
ここが、バックアップと単なる「攻撃者にとっての多少の不便」とを分ける部分です。サーバーがバックアップを削除できる認証情報を持っていれば、乗っ取られたroot、ランサムウェアの実行、あるいは不具合のあるスクリプトが、同じ1分の間に両方のコピーへ届いてしまいます。この解決策は、より強いパスワードの問題ではなく、構造の問題です。
- 送信元からは追記専用の認証情報を使いましょう。resticもBorgも、書き込み側のマシンが新しいスナップショットを作れても、既存のものを削除・間引きできないモードをサポートしています。間引きは、別の場所から、スケジュールに沿って、別の鍵で実行します。
- 可能な場所ではプル型の設計を優先しましょう。送信元がプッシュするのではなく、送信先が送信元へ取りに行く形にすれば、送信元はそもそもアーカイブへの認証情報を一切持たずに済みます。
- SSH鍵やリポジトリのパスワードをサーバー間で使い回してはいけません。1台のマシンが乗っ取られたときに失うべきは、そのマシン1台分のバックアップだけであり、保有インフラすべてであってはなりません。
- 少なくとも1つのコピーは、異なる管轄、異なる障害ドメインに置きましょう。リージョンを分散させるのは過剰反応ではありません — それはハードウェアの障害で済むか、全損になるかの分かれ目です。
- リポジトリの鍵はインフラの外に完全に保管しましょう。パスワードマネージャー、ハードウェアトークン、金庫の中の紙。リポジトリが守っているマシン以外であれば、どこでも構いません。
- 不自然なほど速く成功するようになったバックアップには注意しましょう。以前は20分かかっていたジョブが40秒で終わるようになったなら、たいていは空のディレクトリかマウントされていないディレクトリをバックアップしているだけであり、それでも成功だけは報告し続けます。
リージョンの選択は些細な詳細ではなく、ここでは本物の決断です。バックアップと本番サーバーが同じ1回の行動で差し押さえられてしまうようなことがあってはならないからです。自分が動かしているものにとってそれが重要であるなら、設置場所を意図的に選ぶことに数分をかける価値があります。送信先を送信元とは異なる法域に置くこと自体が、この作業の目的なのですから。
リストア:誰もリハーサルしない部分
リストアは、たいてい退屈な理由で失敗します。そして最悪のタイミングで失敗します — なぜなら、たいていの人がリストアを試すのはそのときだけだからです。以下の失敗はどれも、訓練の最中なら数分で見つかりますが、実際の障害の最中には何時間もかかります。
- リポジトリのパスワードが、死んでしまったサーバーの上にしかなかったため、アーカイブ自体は無傷なのに永久に読めなくなっている。
- データベースはリストアできたが、ファイルツリーは3時間後の実行分から来ていたため、アプリケーションが実在しないファイルのレコードを表示してしまう。
- バックアップが対象としていたディレクトリが、いつの間にかマウントされなくなっていたため、1年間毎晩、空のフォルダを律儀にアーカイブし続けていた。
- リストアの順序 — データベースが先かファイルが先か、サービスを止めるべきか動かしたままにするか — を誰も知らなかったため、中途半端にリストアされた状態を破棄してやり直す羽目になった。
- 利用できる回線でのリストアには11時間かかるが、それは誰も計測しておらず、復旧計画は1時間で済む前提で組まれていた。
- ファイルの所有者とパーミッションが誤った状態で戻ってきたため、すべてのファイルは揃っているのにアプリケーションが起動を拒否する。
- テストしたことがあるのは最新のスナップショットだけだったが、いま復旧しようとしている破損は6週間前から始まっていた。
年に2回の訓練が、そのすべてを解決します。使い捨てのVPSをデプロイし、本物のリポジトリからそこへリストアし、サービスを起動し、データを確認し、マシンを破棄します。かかるのは数ドルと1時間程度ですが、これによってバックアップシステム全体が、信じているだけのものから確かめられた事実に変わります。ランブックを開いた状態で一度実行し、ランブックが嘘をついていた箇所はすべて直しましょう。
プライバシーの層:バックアップは匿名性を台無しにしうる
これはオフショア運用に特有の問題であり、最初のアップロードの後ではなく前に考えて初めて、正しく対処できます。バックアップとは、あなたのインフラの完全で索引化された長期保存コピーが、どこか別の場所に存在している状態です。それは元のものとまったく同じだけセンシティブでありながら、その存在をずっと忘れやすいのです。
- ファイル名とディレクトリ構造は、中身が暗号化されていてもメタデータとして残ります。resticやBorgのクライアント側暗号化は名前もカバーしますが、素のrsyncミラーはカバーしません。ディレクトリの一覧だけで、そのサーバーが何であり誰が運用しているかを特定できてしまうことは少なくありません。
- 送信先のアカウントも物語の一部です。本名のカードでレンタルしたバックアップの保管庫は、送信元のマシンをどれほど注意深くクリーンに保っていようと、その保管庫が抱えるすべてに本名を結びつけてしまいます。
- バックアップの通信は、2つのアドレスのあいだで持続的・定期的・大容量に発生するリンクです。これはサーバーが生み出すパターンの中でもとりわけ読み取りやすいものの一つであり、毎晩必ず送信先を指し示します。
- 古いスナップショットは、それを生んだ判断よりも長生きします。1年前に保存をやめたものでも、保持設定で間引かれていなければアーカイブの中に残り続けます。これは復旧にとっては良い性質ですが、露出という観点では悪い性質です。
- ログとシェル履歴も、他のすべてと一緒に巻き込まれます。稼働中のマシンでは注意深く扱っていたはずのIPアドレス、コマンド、認証情報が、アーカイブの中には平然と含まれていることがよくあります。
対処法はごく普通のものです。名前も中身も両方暗号化するツールを使いましょう。送信先も、送信元と同じやり方でレンタルします — 身元を一切尋ねてこなかったホストから、暗号資産の残高でチャージして。支払いの痕跡まで断ちたいならMoneroでチャージすることを使いましょう。通信のパターンそのものが気になるなら、WireGuardトンネル経由で転送しましょう。そして、本番環境に施したのと同じ最初の10分間の強化を、ストレージ用のマシンにも適用しましょう。すべてのコピーを抱えたマシンは、元のマシンより価値の低い標的では決してなく、むしろしばしばより高い標的なのですから。
データを失う原因になるミス
- RAID、スナップショット、あるいは同期フォルダをバックアップだと信じ込み、それが実際にはどのカテゴリだったのかを、それが重要になった当日に思い知らされる。
- 唯一のコピーを、保護対象そのものと同じサーバー、同じアカウント、同じプロバイダーの上に置いてしまう。
- データベースをダンプせずに稼働中のファイルをそのままコピーしてしまい、微妙に、しかも静かに壊れたアーカイブをリストアすることになる。
- ファイルツリーとデータベースを異なる時刻にバックアップしてしまい、リストア時にどちらも互いに一致しない。
- リポジトリのパスワードを、そのリポジトリが保護しているマシンの上に保管してしまう。
- 送信元に送信先への削除権限をフルに与えてしまい、1回の侵害でアーカイブごと道連れになる。
- 間引きを一切行わないまま放置し、送信先が満杯になって、毎晩のジョブが何週間も静かに失敗し続けていたことに気づく。
- 公開データにすぎない何百ギガバイトものブロックチェーンデータをバックアップする一方で、ウォレットファイルはどのアーカイブにも含まれていない。
- 失敗時のアラートは設定していても不在時のアラートは設定しておらず、ジョブがまったく動かなくなっても何も報告されない。
- 最新のスナップショットしかテストしておらず、実際の障害の最中になって、破損がそれより前から始まっていたと発覚する。
バックアップは、あなたが設定するものの中で最もつまらない部類でありながら、それが欠けていたときだけ取り返しがつかない唯一のものです。サーバー上の他のすべては、パッケージマネージャーと午後のひとときがあれば組み直せますが、状態だけはそうはいきません。一度の作業に時間をかけましょう:生き残らせるべきものを書き出し、データベースをダンプし、暗号化したアーカイブを別の国のストレージサーバーへ送り、スケジュールに沿って間引き、沈黙をアラートで検知し、そしてターミナルを閉じる前に何か本物をリストアしてみてください。そのあとは放っておけばいいのです。良いバックアップシステムの尺度とは、大惨事をちょっとした厄介な1時間に変えてくれるその朝が来るまで、自分がそれを設定したことすら忘れていられる、ということです。