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の依存が必要で、私のデスクトップ環境にはそれらがないからである。

参考になるサイト