borgbackupでバックアップを管理
borgbackupは高速・重複排除・暗号化つきのバックアップツールです
rsyncでバックアップを取ることもできますが、その場合世代管理が面倒です。
borgbackupをつかえばディスク効率よく世代管理も可能です。
レポジトリの初期化
最初にインストールします
brogbackupでは最初にバックアップ用のレポジトリを生成する必要があります。
公式ページの、Usage borg initに詳しいことが書いてあります。
必須のオプションである -e --encryptedは暗号化の方法を指定します。指定する値はつぎのようになっています。
- none(そのまま保存)
- authenticated(改ざん検知)
- repokey(改ざん検知・暗号化・キーをレポジトリ内に配置)
- keyfile(改ざん検知・暗号化・キーファイル使用)
none指定時以外は、使用するキーに対するパスフレーズを設定し記憶しておかなければいけません。キーとパスフレーズがセットで存在しないとレポジトリの復元ができない仕組みなっています。
またキーをレポジトリ内に保存する場合は、パスフレーズでキーを復元できますが、レポジトリが破損する万が一の自体に備えてレポジトリキーのバックアップをとっておくことが推奨されます。
その際のコマンドは次の通りです。
デフォルトではHash/MACはSHA-256を利用しますが、それぞれのキーワードの後に-blake2を付与すると(例:repokey-blake2)、BLACKE2bアルゴリズムを使います(noneを除く)。
CPUにSHA-256のハードウェアアクセラレータが無い場合は、-blake2をつけた方が早くなる可能性が高いです。
基本的な部分ではSHA-256よりBLACKE2bの方が高速なのですが、アクセラレータがある場合はそれを使った処理の方が早いと思います。
lscpuのflagsの出力中に、sha_ni があればアクセラレータが使えます。
次のバックアップ生成用のコマンドである borg createを実行するたびに、レポジトリの中に複数の世代のバックアップが蓄積されますが、それを確認するには、borg listを使います。
バックアップの生成
初期化したレポジトリに対してバックアップを作成します。
$ borg create [レポジトリのパス]::[バックアップ名] [保存対象] ... $ borg create /srv/borg::bkup-$(hostname)-$(date +%Y%m%d%H%M%s) ~/doc
バックアップ名は、一意な名前を使います。バックアップ対象を示す文字列とタイムスタンプ等で構成します。もし上書きしたい事があれば一度削除してから作り直します。レポジトリ上には他のマシンのデータも保存することができるので、hostnameなどを付けておくと後で使い勝手がよくなります。
保存対象は通常はディレクトリを指定すると思いますが、スペースで区切って複数指定可能です。
デフォルトではワーニング未満のメッセージは表示されませんが、--progress または --list オプションをつけると実行の状態が表示されます。
初回バックアップの次のバックアップは、差分バックアップとなり、初回よりも高速に処理が終了します。
差分がどのように取られているか確認したい場合は、--stats オプションをつけると表示されます。
復元
バックアップを復元するには、borg extractを使います。
$ borg extract [レポジトリのパス]::[バックアップ名] [対象ディレクトリ] $ borg extract /srv/borg/::bkup-20260106
対象ディレクトリを省略した場合は、カレントディレクトリにバックアップが復元されます。
削除
削除は、borg deleteコマンドを使います。単に削除しただけえはディスクスペースは回復しませんので、必要に応じて borg compact を使います。
$ borg delete [レポジトリのパス]::[バックアップ名] $ borg delete /srv/borg/::bkup-20260106 $ borg compact [レポジトリのパス] $ borg compact /srv/borg
borg prune
prune は日本語で「剪定」などと訳されますが、borg prune は世代管理をするのに便利なコマンドです。
次のようにオプションを指定すると、日別7つ、週別4つ、月べつ6つでバックアップを残す形でborg deleteをしてくれます。
$ borg prune ¥ --keep-daily 7 ¥ --keep-weekly 4 ¥ --keep-monthly 6
直近の日別のバックアップを7つ、週別のバックアップを4つ、月別のバックアップを6つ残して削除します。
削除しないバックアップのリストを、日・週・月別に保持してどれにも当てはまらないものは削除されるというイメージだと思います。
バックアップはそれぞれの期間内で一番新しいバックアップを対象とします。週はISO 8601に基づくとのことでしたので、月曜はじまり~日曜おわりの期間となります。
borg prune コマンドは、borg compact を実行しないので、必要に応じて実行する必要があります。
サンプルスクリプト
公式ページ[Quick Start]に載っていたサンプルスクリプトを転載します。
sample.sh
#!/bin/sh # 都度コマンドラインに入力しなくてもいいように、レポジトリの環境変数が用意されています # ここではsshでリモート環境にバックアップを保存する設定となっています。 export BORG_REPO=ssh://username@example.com:2022/~/backup/main # 同様にパスフレーズも環境変数へセットしておけます export BORG_PASSPHRASE='XYZl0ngandsecurepa_55_phrasea&&123' # some helpers and error handling: info() { printf "¥n%s %s¥n¥n" "$( date )" "$*" >&2; } trap 'echo $( date ) Backup interrupted >&2; exit 2' INT TERM info "Starting backup" # Backup the most important directories into an archive named after # the machine this script is currently running on: # hostnameを使ってレポジトリのデータにタグ付けしています # あとでこれで識別して borg pruneを実行します borg create ¥ --verbose ¥ --filter AME ¥ --list ¥ --stats ¥ --show-rc ¥ --compression lz4 ¥ --exclude-caches ¥ --exclude 'home/*/.cache/*' ¥ --exclude 'var/tmp/*' ¥ ¥ ::'{hostname}-{now}' ¥ /etc ¥ /home ¥ /root ¥ /var backup_exit=$? info "Pruning repository" # Use the `prune` subcommand to maintain 7 daily, 4 weekly and 6 monthly # archives of THIS machine. The '{hostname}-*' matching is very important to # limit prune's operation to this machine's archives and not apply to # other machines' archives also: borg prune ¥ --list ¥ --glob-archives '{hostname}-*' ¥ --show-rc ¥ --keep-daily 7 ¥ --keep-weekly 4 ¥ --keep-monthly 6 prune_exit=$? # actually free repo disk space by compacting segments info "Compacting repository" borg compact compact_exit=$? # use highest exit code as global exit code global_exit=$(( backup_exit > prune_exit ? backup_exit : prune_exit )) global_exit=$(( compact_exit > global_exit ? compact_exit : global_exit )) if [ ${global_exit} -eq 0 ]; then info "Backup, Prune, and Compact finished successfully" elif [ ${global_exit} -eq 1 ]; then info "Backup, Prune, and/or Compact finished with warnings" else info "Backup, Prune, and/or Compact finished with errors" fi exit ${global_exit}
リモートの設定
リモートでborgbackupを利用する環境を作っていきます。
ここではレポジトリは /srv/bkupに設定しています。
まずborg用のユーザーを作成します。通常ユーザーと同じように設定します。
# useradd borg -m # passwd borg ... # mksir /srv/bkup # chown borg:borg /srv/bkup # chmod 700 /srv/bkup
クライアント側で、borg用の鍵を作成します。
おそらくsshキーは生成済みだと思いますが、専用にしておいた方がいいです。
/etcのファイルをバックアップ対象にすることも考えていますので、クライアント側はrootで各種コマンドを実行する前提でいます。
公開鍵をコピーします。
コピーしたあと、コマンドを制限するために、サーバー側のauthorized_keysを編集します。
atuthorized_keys
command="borg serve", restrict ssh-ed25519 .....commandはコマンドの強制、restrictは端末の要求を拒否します。
ちなみに、.sshディレクトリの所有者とグループはborg、権限は700、.authorized_keysファイルの所有者とグループはborg、権限は600になっていないと ssh自体が動かないのでうまくいかない場合は見直してください。
さらに、サーバー側でユーザー名とパスワードでのシェルログインをふさいでおきます。これはsshd_configに記述します。
鍵認証の時は、コマンド強制、パスワードログインはさせないこのセットでセキュリティを担保します。
/etc/ssh/sshd_config
...
# 特定のユーザーにマッチした時
Match User borg
# パスワード認証を拒否
PasswordAuthentication no
ssh -i ~/.ssh/borg_key borg@borg.server.domain コマンドを実行してパスワードを求められずに、This account is currently not availableとでて切断されればOKです。
sshのキーはデフォルトではなく、指定しないといけないので、その設定を環境変数に入れます。
テスト接続をしてみます。この時点でレポジトリはまだ作成していませんが、borgのエラーメッセージが返ってくるかチェックします。
うまく設定されていないと、Got unexpected RPC data format from client といったメッセージが返ってきます。
# borg info borg@borg.server.domain:/srv/bkup /srv/bkup is not a valid repository. Check repo config.
以降は、指定ディレクトリをscp風に指定するだけです。
{hostname}や{now:%Y%m%d}はborgで使える変数展開で、$(hostname)-$(date +%Y%m%d)に相当します。
運用上の注意点
borgのバックアップ中にファイルに編集が加えられていたりすると、中途半端な状態でファイルがコピーされることがあります。
それを防ぐためには、先日紹介したBTRFS(B-Tree ファイルシステム)でとったスナップショットをコピー元にします。
また、MariaDBなどのデータベースのテーブルデータの場合は、ファイルは完全でも複数ファイル間の一貫性が失われることがあるので、これらのしくみは使わずMariaDB Backupなどを使って作成したファイルをバックアップするようにします。
