usbrip を使ってLinuxのUSB接続履歴を調査する:物理ポートからの侵入を検出する

Security tutorial - IT technology blog
Security tutorial - IT technology blog

自分がいない間に、誰かLinuxサーバーにUSBを挿したことがないか、と考えたことはあるだろうか。これは以前まで気にもしていなかった問いだ——あるproductionサーバーを監査していて、深夜2時に誰かが不審なUSBデバイスを接続していたことを、誰も知らないまま発見するまでは。

USBフォレンジックはセキュリティチェックリストで見落とされがちだが、非常に危険な攻撃ベクターだ。BadUSB、HIDインジェクション、USB経由のデータ持ち出し——これらはすべて、読み方を知っていればカーネルログに痕跡を残す。この記事では各調査方法を比較してから、専用ツールであるusbripの使い方を詳しく解説する。

LinuxでUSB接続履歴を調査する3つの方法

方法1:システムログを直接読む

LinuxはすべてのUSBイベントをsyslogまたはjournalに記録する。直接grepするには:

# systemd journalの場合
journalctl | grep -i usb

# 従来のsyslogの場合
grep -i usb /var/log/syslog

# USB接続直後にdmesgで確認
dmesg | grep -i usb | tail -50

一般的な出力例は以下のようになる:

Jun 20 02:14:33 server kernel: usb 1-1.2: new high-speed USB device number 5 using xhci_hcd
Jun 20 02:14:33 server kernel: usb 1-1.2: New USB device found, idVendor=0930, idProduct=6545
Jun 20 02:14:33 server kernel: usb 1-1.2: Product: DataTraveler 3.0
Jun 20 02:14:33 server kernel: usb 1-1.2: SerialNumber: 001B12345678

方法2:udevルールとカスタムスクリプトを組み合わせる

USB接続時に自動的にログを記録するudevルールを作成する:

sudo nano /etc/udev/rules.d/99-usb-log.rules
ACTION=="add", SUBSYSTEM=="usb", RUN+="/usr/local/bin/log-usb.sh"
#!/bin/bash
# /usr/local/bin/log-usb.sh
echo "$(date) | VID=$ID_VENDOR_ID | PID=$ID_MODEL_ID | Serial=$ID_SERIAL | Model=$ID_MODEL" \
  >> /var/log/usb-connections.log

方法3:usbrip — 専用ツールを使う

usbripはUSBフォレンジック専用に作られたPythonツールだ。カーネルログをパースして構造化データに整理し、JSON/HTML出力をサポートし、ホワイトリストに基づく違反検出(violation detection)機能も備えている——前の2つの方法にはない機能だ。

# USB履歴を見やすく表示
usbrip events history

# ホワイトリストと照合
usbrip events violations -a auth.json

各方法のメリット・デメリット分析

生のシステムログ:追加インストール不要だが、出力が煩雑で本格的な調査には読みにくい。プレーンテキストのパースに何時間もかかる上、構造化データも自動的な違反検出機能もない。

udev + スクリプト:セットアップ後からのリアルタイム監視には適しているが、セットアップ前の履歴データがない。検出部分を自分でコーディングしなければならず、バグが入りやすくメンテナンスも難しい。

usbrip:セットアップに数分かかるが、その後はずっとシンプルになる。最も重要なのは古いログも読めること——以前に発生したインシデントを調査する際に不可欠だ。レポート用のJSON/HTMLエクスポートも標準装備している。

どの方法を選ぶべきか?

私はよく組み合わせて使う:フォレンジック調査にはusbripリアルタイムアラートにはudevルール

  • すでに発生したインシデントを調査する場合 → usbrip(古いログも読めるため)
  • 不審なUSBが挿された際にすぐアラートが欲しい場合 → udev + スクリプト
  • 一度だけ素早く確認したい場合 → syslogをgrepするだけで十分

10台以上のサーバーをセキュリティ監査してきて、ほとんどに共通する基本的な脆弱性があることに気づいた——その一つがUSBデバイスの追跡ができていないこと。多くのsysadminはネットワークにしか注目せず、物理的なアクセスは完全に放置されている。usbrip はこの問題を大した手間なく解決してくれる。

usbrip のインストールと使い方

インストール

usbrip はPython 3.6以上が必要だ:

# Ubuntu/Debian
sudo apt install python3-pip

# usbrip をインストール
sudo pip3 install usbrip

# バージョン確認
usbrip --version

またはソースからインストールする:

git clone https://github.com/snovvcrash/usbrip.git
cd usbrip
sudo pip3 install -r requirements.txt
sudo python3 setup.py install

USB接続履歴を確認する

# 全履歴を表示
usbrip events history

# 特定の日付でフィルタリング
usbrip events history --date 2026-06-20

# 追加分析用にJSONでエクスポート
usbrip events history -q --json /tmp/usb-history.json

出力はカラー表付きで表示され、syslogをgrepするよりもはるかに見やすい:

Connected     | Host     | VID  | PID  | Manufact | Product       | Serial
--------------+----------+------+------+----------+---------------+------------------
2026-06-20    | server01 | 0930 | 6545 | Kingston | DataTraveler  | 001B12345678
02:14:33      |          |      |      |          | 3.0           |

許可デバイスのホワイトリストを作成する

これが違反検出において最も重要なステップだ。どのUSBの接続を許可するかを定義する:

# 現在の履歴から認証リストを自動生成
sudo usbrip events gen_auth /etc/usbrip/auth.json

# または手動で作成
mkdir -p /etc/usbrip
cat > /etc/usbrip/auth.json << 'EOF'
{
  "authorized": [
    {
      "vid": "0930",
      "pid": "6545",
      "prod": "DataTraveler 3.0",
      "manufact": "Kingston",
      "serial": "001B12345678"
    },
    {
      "vid": "046d",
      "pid": "c52b",
      "prod": "USB Receiver",
      "manufact": "Logitech",
      "serial": null
    }
  ]
}
EOF

マウスやキーボードなど通常シリアルナンバーを持たないデバイスにはserial: nullを設定する。

未許可デバイスの検出

# ホワイトリストと照合して違反を確認
usbrip events violations -a /etc/usbrip/auth.json

# 詳細情報を追加表示(verboseモード)
usbrip events violations -a /etc/usbrip/auth.json -v

# 違反内容をJSONファイルにエクスポート
usbrip events violations -a /etc/usbrip/auth.json -q --json /tmp/violations.json

不審なデバイスがある場合、usbrip は赤くハイライトして詳細情報を表示する:接続時刻、VID/PID、デバイス名、シリアルナンバー。

自動化:定期実行とアラート送信

本番環境で真の価値を発揮するには、crontabで自動化するのが理想だ:

#!/bin/bash
# /usr/local/bin/usb-check.sh

AUTH_FILE="/etc/usbrip/auth.json"
REPORT="/tmp/usb-violations-$(date +%Y%m%d).json"
EMAIL="[email protected]"

usbrip events violations -a "$AUTH_FILE" -q --json "$REPORT" 2>/dev/null

# 違反がある場合はメールを送信
if [ -s "$REPORT" ]; then
  echo "警告:$(hostname) で不審なUSBデバイスを検出しました" | \
  mail -s "[SECURITY ALERT] USB Violation" -A "$REPORT" "$EMAIL"
fi
# crontabに追加 — 毎日午前8時に実行
sudo crontab -e

# 以下の行を追加:
0 8 * * * /usr/local/bin/usb-check.sh

システムログから独立した履歴の保存

これは多くの人が見落としているusbrip の便利な機能だ。システムログは7〜30日でローテーションされるが、usbrip のストレージはそうではない:

# 現在のログからストレージを作成
sudo usbrip storage create history

# 新しいイベントでストレージを更新
sudo usbrip storage update history

# ストレージから読み込む(ログのパースより高速)
usbrip storage open history

実際の導入時の注意点

ログローテーションは最大の敵:多くのサーバーではsyslogが7日でローテーションされる。2週間前にインシデントが発生していたら、証跡が失われてしまう。journaldのリテンション期間を延ばして、ログを長期間保持しよう:

sudo nano /etc/systemd/journald.conf
# 追加または修正:
MaxRetentionSec=90day
SystemMaxUse=500M

sudo systemctl restart systemd-journald

usbrip はSIEMではない:USBイベントしか追跡しない。そのUSBがどう使われたか——どこにマウントされ、どのファイルがコピーされたか——を知るにはauditdと組み合わせる必要がある。usbrip はどのデバイスが何時に接続されたかを教えてくれるが、auditdその後何が起きたかを教えてくれる。

一部のコマンドにはroot権限が必要gen_authstorage createはsudoが必要だ。通常の読み取りコマンドは、ログの読み取り権限があれば一般ユーザーでも問題なく実行できる。

USBフォレンジックは毎日必要なものではないが、いざとなれば急を要する。今すぐusbrip をインストールして、ホワイトリストを作り、crontabをセットアップしよう——30分もかからない。本当に調査が必要になったとき、ゼロから始めなくて済む。

Share: