簡単にリムーバブル メディアをクラウドにバックアップできます。

簡単にリムーバブル メディアをクラウドにバックアップできます。

USBクラウドまだUSBメモリをお使いですか?フラッシュカード、SDカード、MicroSDカード、ポータブルハードドライブなどでしょうか?

クラウドが普及した現代においても、人々は様々な理由から、バックパックに大量のデータを入れています。IT担当者は、ネットワークに接続できない状況でサーバーやスイッチの緊急復旧作業を行う必要がある場合に備えて、ポータブルメディアを必要とします。また、代替ブート環境(MacのBootcampなど)としてポータブルドライブを使用する人もいます。デジタルメディアを扱う人は、現在作業中のファイルの「ワーキングセット」を持っている場合が多く、作業内容によっては、ポートフォリオ全体を1つのボリュームに保存している場合もあります。これらのファイルの一部はクラウドにアーカイブできますが、現在のプロジェクトでは、ノートパソコンの容量を超えるストレージが必要になる場合があります。さらに、誰もが常にあらゆる場所でクラウドを使用しているわけではありません。

さらに、シングルカードシステムの時代では、Micro-SDカードはどこにでもあります。Raspberry Piを最後にバックアップしたのはいつですか?再現するのが大変な作業を行う場合、バックアップから簡単に復元できると確信できますか?

このチュートリアルでは、外付けメディアへのバックアップを可能な限り簡単に行う方法をご紹介します。目指すのはシンプルです。USBインターフェースに接続するだけで、自動的にバックアップが実行されるのです。ユーザーは、デバイスを接続するだけで、スクリプトの実行やボタンのクリックなどは一切不要です。接続するだけでバックアップが実行され、クラウドストレージに保存されます。バックアップが完了し、安全に取り外せる状態になったら通知が届きます。

どうやって?続きを読む!

udevの魔法

udevはLinux用のデバイスマネージャーです。その便利な機能の一つは、特定のイベントが発生した際に自動的にアクションを実行するようにプログラムできることです。今回はこの機能を利用して、バックアップスクリプトを実行します。

このチュートリアルでは、クラウドバックアップソリューションの種類は指定しません。選択肢が多岐にわたるためです。代わりに、ダミースクリプト(cloud_backup.sh)を呼び出します。このスクリプトを変更することで、B2 API呼び出し、rclone呼び出し、min.ioバケットの操作など、必要な処理を挿入できます。

仕組み

まず、USBデバイスを一意に(または半一意に)識別する方法を見つけます。マウントされると、システムは自動的にデバイスへのシンボリックリンクを作成し、そのシンボリックリンクをバックアップスクリプトに渡します。

USBドライブのRAWイメージをバックアップします。このイメージは、デバイスにマウントしたり、元に戻したりできます。これは、ドライブが暗号化されているかどうかに関わらず、手動操作なしでバックアップが成功するためです。ドライブが暗号化されている場合は、バックアップイメージも暗号化されます。

USBを一意に識別する

私はUSB 3.0とUSB 2.0ポートを豊富に備えたDebian 11デスクトップシステムを使用しています。この例ではGorilla 32GB USBを使用していますが、USBサムドライブ、外付けハードドライブ、フラッシュカードなど、どのデバイスでも基本的な使い方は同じです。USBポートを備えたLinuxシステムであれば、どれでも動作するはずです。他のLinuxディストリビューションでは、パスが若干異なる可能性があります。

USBデバイスを挿入し(マウントする必要はありません)、実行します。

 lsusb -tvv

次のようなものが表示されます。

 /: バス 06.ポート 1: Dev 1、クラス=root_hub、ドライバー=xhci_hcd/2p、10000M
ID 1d6b:0003 Linux Foundation 3.0 ルートハブ
/sys/bus/usb/devices/ /dev/bus/usb/006/001
/: バス 05.ポート 1: Dev 1、クラス=root_hub、ドライバー=xhci_hcd/2p、480M
ID 1d6b:0002 Linux Foundation 2.0 ルートハブ
/sys/bus/usb/devices/usb5 /dev/bus/usb/005/001
/: バス 04.ポート 1: Dev 1、クラス=root_hub、ドライバー=ehci-pci/2p、480M
ID 1d6b:0002 Linux Foundation 2.0 ルートハブ
/sys/bus/usb/devices/usb4 /dev/bus/usb/004/001
|__ ポート 1: Dev 2、0 の場合、クラス = ハブ、ドライバー = ハブ/8p、480M
ID 8087:8001 インテル社 統合ハブ
/sys/bus/usb/devices/4-1 /dev/bus/usb/004/002
/: バス 03.ポート 1: Dev 1、クラス = root_hub、ドライバー = xhci_hcd/6p、5000M
ID 1d6b:0003 Linux Foundation 3.0 ルートハブ
/sys/bus/usb/devices/usb3 /dev/bus/usb/003/001
/: バス 02.ポート 1: Dev 1、クラス = root_hub、ドライバー = xhci_hcd/14p、480M
ID 1d6b:0002 Linux Foundation 2.0 ルートハブ
/sys/bus/usb/devices/usb2 /dev/bus/usb/002/001
|__ ポート 12: Dev 6、0 の場合、クラス = マスストレージ、ドライバー = usb-storage、480M
ID abcd:1234 LogiLink UDisk フラッシュドライブ
/sys/bus/usb/devices/2-12 /dev/bus/usb/002/006
/: バス 01.ポート 1: Dev 1、クラス=root_hub、ドライバー=ehci-pci/2p、480M
ID 1d6b:0002 Linux Foundation 2.0 ルートハブ
/sys/bus/usb/devices/usb1 /dev/bus/usb/001/001
|__ ポート 1: Dev 2、0 の場合、クラス = ハブ、ドライバー = ハブ/6p、480M
ID 8087:8009 インテル株式会社 
/sys/bus/usb/devices/1-1 /dev/bus/usb/001/002

これは、複数のUSBハブとポートがあることを示しています。ここで注目するのは「Mass Storage, Driver」です。システムは親切にも、/sys/bus/usb/devices/2-12というパスまで教えてくれます。

驚かれるかもしれませんが、どうやら一部のメーカーは電子機器の規格を実装する際に手抜きをしているようです。あるいは、規格では「シリアル番号」と「一意の識別子」の概念が異なるのかもしれません。最善かつ適切なアプローチは、udevadmを使ってデバイスを照会し、ID_SERIALフィールドを取得し、それに基づいてルールを構築することです。

しかし、多くのデバイスを調べたところ、一般的に次のいずれかのアプローチが採用されていることがわかりました。

  • ID_SERIALフィールドを実装しない
  • 「1234」のような形式で実装する
  • 世界中で一意ではなく、モデル固有の短い値(例:「861F-CC42」)を使用する

一部のベンダーはリムーバブルメディアにシリアル番号を書き込んでいますが、これは明らかに製造上の手間がかかる上に、​​市場は気にしていないようです。シリアル番号に基づいてルールを作成する方法を説明しますが、おそらくそのままでは使えないので、別の方法を使用します。

udevadmとの一体感

下記のようなudevadmコマンドを実行します。パスの最後の部分をシステムに適した情報に置き換えてください。上記のように、バス2/ポート12に接続しているので、/sys/bus/usb/devicesでbashのタブ補完を使って簡単に見つけることができます。

ここでは32GBのGorilla USBメモリを使っています。さあ、金を目指して、使えるWWIDがあるかどうか確認してみましょう。

 # udevadm info -q all /sys/bus/usb/devices/2-12|grep -i seri
E: ID_SERIAL=USB_Flash_Disk

おそらくそうではないでしょう。そこで、別のudevadmコマンドを使ってすべての属性を表示してみましょう。

 # udevadm 情報 -ap /sys/bus/usb/devices/2-12

Udevadm infoはdevpathで指定されたデバイスから始まり、
親デバイスのチェーンを辿ります。すべてのデバイスについて印刷します。
udev ルール キー形式で可能なすべての属性が見つかりました。
一致するルールは、デバイスの属性によって構成できます
単一の親デバイスからの属性。

デバイス '/devices/pci0000:00/0000:00:14.0/usb2/2-12' を参照しています:
カーネル=="2-12"
サブシステム=="usb"
ドライバー=="usb"
ATTR{承認済み}=="1"
ATTR{avoid_reset_quirk}=="0"
ATTR{bConfigurationValue}=="1"
ATTR{bDeviceClass}=="00"
ATTR{bデバイスプロトコル}=="00"
ATTR{bDeviceSubClass}=="00"
ATTR{bMaxPacketSize0}=="64"
ATTR{b最大電力}=="300mA"
ATTR{bNumConfigurations}=="1"
ATTR{bNumInterfaces}==" 1"
ATTR{bcdDevice}=="1100"
ATTR{bmAttributes}=="80"
ATTR{バス番号}=="2"
ATTR{構成}==""
ATTR{devnum}=="16"
ATTR{devpath}=="12"
ATTR{idProduct}=="1000"
ATTR{idVendor}=="090c"
ATTR{ltm_capable}=="いいえ"
ATTR{製造元}=="USB"
ATTR{maxchild}=="0"
ATTR{パワー/アクティブ期間}=="147776"
ATTR{power/async}=="有効"
ATTR{電源/自動サスペンド}=="2"
ATTR{power/autosuspend_delay_ms}=="2000"
ATTR{電源/接続時間}=="147776"
ATTR{電源/コントロール}=="オン"
ATTR{パワー/レベル}=="オン"
ATTR{パワー/持続}=="1"
ATTR{power/runtime_active_kids}=="1"
ATTR{power/runtime_active_time}=="147500"
ATTR{power/runtime_enabled}=="禁止"
ATTR{power/runtime_status}=="アクティブ"
ATTR{power/runtime_suspended_time}=="0"
ATTR{power/runtime_usage}=="1"
ATTR{product}=="フラッシュディスク"
ATTR{癖}=="0x0"
ATTR{removable}=="取り外し可能"
ATTR{rx_lanes}=="1"
ATTR{速度}=="480"
ATTR{tx_lanes}=="1"
ATTR{urbnum}=="573"
ATTR{バージョン}==" 2.10"

これをトリミングしたのは、その後、USB ツリーをたどってコントローラーを報告するなどするためです。必要なのは、最初の空白行で区切られたセクションだけです。

識別を可能な限り一意にするために、これらのフィールドの一部を取得します。もちろん、特定のコンピューターに接続するUSB​​ドライブが1つだけであれば、複数ある場合ほど重要ではありません。

以下は最終的なルールです。これを /etc/udev/rules.d/95-local.rules に追加します (ここではフォーマットのために複数行に分割されていますが、すべて 1 行にする必要があります)。

 SUBSYSTEM=="usb", ACTION=="bind", ATTR{manufacturer}=="USB", ATTR{product}=="フラッシュディスク", 
ATTR{idProduct}=="1000", ATTR{idVendor}=="090c", SYMLINK+="gorilla_drive", 
RUN+="/usr/local/bin/backup-removable.sh gorilla_drive"

はい、説明すべきことがたくさんあります。

  • /etc/udev/rules.d 内のルールはアルファベット順に処理されます。ルールの先頭に大きい数字を付けることで、最後に処理され、上書きされなくなります。ちなみに、/lib/udev/rules.d には、システムで使用されるルールが100以上あります。
  • == と = は使用しないように注意してください。== は等価性の確認、= は代入です。上記の != は「等しくない」のテストとして使用されています。構文は厳密なので、引用符や += などには注意してください。
  • SUBSYSTEM は、udev に私たちが何について話しているかを知らせるだけです。
  • ACTION は「bind」に設定されています。これは「add」よりも後のステップです。「add」を使用するとデバイスは自動的に削除され、何も起こっていない場合は表示されます。/etc/udev/udev.conf で udev_log=debug を設定し、デバイスを接続した後、daemon.log を確認すると、この状態が確認できます。
  • ATTRリンクは製品を一意に識別するための手段です。シリアル番号があれば、ATTR{idSerial}=”whatever_serial” と記述できます。代わりに、「メーカー、製品、idProduct、idVendorが一致する場合、一致とみなす」と記述します。
  • SYMLINK句は/dev/gorilla_driveが作成されることを指定します
  • RUN 句は「run /usr/local/bin/backup-removable.sh」と指定し、gorilla_drive 引数を渡します。(渡されるのはリテラル文字列であるため、backup-removable.sh は「/dev/gorilla_drive」ではなく「gorilla_drive」で呼び出されることに注意してください)。

バックアップスクリプト

ここであなたの出番です。バックアップで何をしたいですか?

簡単な例を以下に示します。

 #!/bin/bash

DEVICE=${1} # 例: "gorilla_drive"

[ ! -f /dev/${DEVICE} ] の場合;
echo "エラー! そのようなデバイスはありません: /dev/${DEVICE}"
# ここで通知を送信する
出口1
フィ

dd if=/dev/${DEVICE} of=/backups/{DEVICE}.$(日付 '+%Y%m%d') bs=1MB

# そして、次のように呼び出します。または、minio、scp、rsync など

rclone 同期 /backups b2:some_backet

echo "$DEVICE のバックアップが完了しました" | mailx -s "$DEVICE のバックアップが完了しました" [email protected]

# あるいは次のようなもの:
# aplay /usr/share/sounds/gnome/default/alerts/sonar.ogg
# または携帯電話のSMSにメールを送信
# またはAPIを呼び出す
# など

試してみる

この例では、backup-removable.sh スクリプトは非常にシンプルです。

 #!/bin/bash

デバイス=$1
echo "`date` が $DEVICE をバックアップしました" >> /tmp/backup_log.txt

95-local.rules を作成した後、次を実行しました。

 systemctl udev を再起動します

必須ではないかもしれませんが、害にはならないと思います。その後、デバイスを挿入しました。

すぐに私は見た:

 # ls -l /dev/gorilla_drive 
lrwxrwxrwx 1 ルート ルート 15 1月 17 12:35 /dev/gorilla_drive -> bus/usb/002/025

# cat /tmp/backup_log.txt
2022年1月17日月曜日 12:35:45 PST gorilla_drive をバックアップしました

復元中

この方法を使用してバックアップし、復元する必要がある場合は、次のように簡単です。

 dd if=/backups/some_image of=/dev/gorilla_drive

または、バックアップから一部のファイルのみを取得する場合:

 mkdir /mnt/thumb
マウント -o ループ gorilla_drive.backup.20220117 /mnt/thumb

暗号化ソリューション(例:TrueCrypt)を使用してマウントする場合は、ドキュメントを確認してください。次のような内容です。

トゥルークリプト ゴリラドライブ.バックアップ.20220117 /mnt/thumb

サムドライブのバックアップは、これでほぼ完璧です。USBメモリを接続して自動バックアップするのが面倒な方は…コインランドリーは避けた方が良いでしょう!

おすすめの記事