Linuxでロック中に新規挿入されたUSBを使えないようにする
認可するUSBを制限する意義
BadUSBというものがある。多くはUSB HIDキーボードとして動作して、任意のキー入力をしたり、USB Ethernetとして動作して通信経路を曲げて攻撃を行うもので、脆弱性というよりそれがUSBの機能である。
そもそも物理アクセスされている時点で他にいくらでも攻撃手段があるが、Linuxの機能を使うことでUSBデバイスの認可を制限することができる。
- できること
- 出来心でBadUSBを挿入してくる隣人を遠ざけられる。
- できないこと
- DMAの脆弱性を突いたり、別の物理的攻撃をしてくる隣人に対する防護。
- USBポートの物理破壊。
方法
LinuxでUSBデバイスを制限する方法としては、カーネルモジュールのアンロードやカーネルパラメータの設定をするという手もあるが、通常のデスクトップ環境で柔軟に管理するためには、sysfsから制御する方法がいいと思う。
私は次のようなスクリプトを~/.local/bin/に置いてriverでロックするためのショートカットに割り当てている。
#!/bin/sh
set -eu
doas /usr/local/bin/usb-authorize-default.sh lock
waylock -ignore-empty-password &
lock_pid=$!
sleep 1
doas /usr/local/bin/suspend-then-hibernate.sh
# 復帰後、ロック解除されたらusb unlock
wait "$lock_pid"
doas /usr/local/bin/usb-authorize-default.sh unlock
makoctl reload
スクリプトの中で呼びだしているusb-authorize-default.shは以下である。
#!/usr/bin/env bash
set -euo pipefail
mode="${1:-}"
case "$mode" in
lock) val=2 ;; # internal-only
unlock) val=1 ;; # allow-all (default)
*) echo "Usage: $0 {lock|unlock}" <&2; exit 2 ;;
esac
for host in /sys/bus/usb/devices/usb*; do
if [[ -w "$host/authorized_default" ]]; then
printf '%s' "$val" > "$host/authorized_default"
fi
done
Linuxのデバイスをロックする機能を使用して、ロック中には新規に挿入されたUSBを許可しない設定に変えている。
1が通常デフォルトで、全てのUSBデバイスを認可し、2にすると内蔵USBポートのみを認可する。 既に接続されているUSBデバイスは、2にしても認可を解除されることはない。
USBGuardを使えば良くない?
はい。優秀なフロントと優れた権限処理機構を備えたBadUSBに対応するためのLinux向けソフトウェアが存在しているので、普通はそちらを使おう。 私が不出来なスクリプトを使うのはUsbGuardの導入にelogindかsystemd-logindの依存が必要で、私のデスクトップ環境にはそれらがないからである。
参考になるサイト
- Authorizing (or not) your USB devices to connect to the system — The Linux Kernel documentation
- GitHub - USBGuard/usbguard: USBGuard is a software framework for implementing USB device authorization policies (what kind of USB devices are authorized) as well as method of use policies (how a USB device may interact with the system)
- USBGuard - ArchWiki
- The kernel’s command-line parameters — The Linux Kernel documentation