USB ウェブカメラをソフト的に無効化する

OS は Debian Linux、デスクトップ環境は XFCE で、ウェブカメラを使用している。必要なときだけ USB のプラグを挿しそれ以外のときはプラグを抜くようにしていたのだが、頻繁に抜き挿しするうちに接触不良ぎみになってしまった。

挿しっぱなしにする代わりに物理的なレンズキャップをとも考えたがそれも面倒くさい。USB ポートの論理接続を切り替えることにした。物理的に取り外しのできないノート PC などにも応用できるだろう。

modprobe -r uvcvideo という方法もあるようだが、それではすべての USB カメラデバイスも同時に消えてしまう。特定のカメラだけを無効化したい。

事前情報

lsusb -t で事前にウェブカメラの番号を調べておく。

/:  Bus 003.Port 001: Dev 001, Class=root_hub, Driver=xhci_hcd/4p, 480M
    |__ Port 001: Dev 002, If 0, Class=Hub, Driver=hub/4p, 480M
        |__ Port 002: Dev 004, If 0, Class=Video, Driver=uvcvideo, 480M
        |__ Port 002: Dev 004, If 1, Class=Video, Driver=uvcvideo, 480M
        |__ Port 002: Dev 004, If 2, Class=Audio, Driver=snd-usb-audio, 480M
        |__ Port 002: Dev 004, If 3, Class=Audio, Driver=snd-usb-audio, 480M

のような情報から、

  • Bus 003
  • Port 1 (外付または内部の USB ハブ)
  • Port 2 (カメラ本体)

がわかり、Linuxの sysfs 上の表記でこれは 3-1.2 という ID になる。

それがわかれば、/sys/bus/usb/devices/3-1.2/authorized に 0 を書き込めば無効化、1 を書き込めば有効化できる。

bash のコマンドラインで使うなら、エイリアス

alias cam-off="echo '0' | sudo tee /sys/bus/usb/devices/3-1.2/authorized"
alias cam-on="echo '1' | sudo tee /sys/bus/usb/devices/3-1.2/authorized"

にしておけば楽。

0 を書き込んだ後に lsusb -t で見てみると、Port 2 の項目が消えていることが確認できる。

XFCE パネルへの組み込み

さらに楽にするために、ふだん使用しているデスクトップ環境の XFCE のパネルに切り替えスイッチを設置したい。

制御スクリプトの作成

実行するたびに有効化/無効化を切り替えるメインスクリプトを /usr/local/bin/toggle_camera.sh あたりに作成する。

#!/bin/bash

# 設定: 事前に特定したカメラのパス
DEV_PATH="/sys/bus/usb/devices/3-1.2"

# 現在の状態を取得 (1=ON, 0=OFF)
CURRENT_STATUS=$(cat "$DEV_PATH/authorized")

if [ "$CURRENT_STATUS" -eq "1" ]; then
    # OFFにする
    echo 0 | sudo tee "$DEV_PATH/authorized" > /dev/null
    echo "Camera OFF"
else
    # ONにする
    echo 1 | sudo tee "$DEV_PATH/authorized" > /dev/null
    echo "Camera ON"
fi

実行権限を与えておく。chmod +x /usr/local/bin/toggle_camera.sh

sudo パスワードの回避

パネルからクリックした際に sudo のパスワード入力を求められないようにしておく。

/etc/sudoers の末尾に以下を追記する (username は実際のユーザー名)。

username   ALL=(ALL) NOPASSWD: /usr/local/bin/toggle_camera.sh

パネル表示用スクリプトの作成

XFCE のパネルプラグイン(Generic Monitor)に状態とアイコンを渡すためのスクリプトを ~/bin/cam-status.sh あたりに作成する。

#!/bin/bash

DEV_PATH="/sys/bus/usb/devices/3-1.2"
TOGGLE_SCRIPT="sudo /usr/local/bin/toggle_camera.sh"

# アイコンの設定
if [ -f "$DEV_PATH/authorized" ] && [ "$(cat "$DEV_PATH/authorized")" -eq "1" ]; then
    # ON
    #echo "<img>/usr/share/icons/Adwaita/symbolic/devices/camera-web-symbolic.svg</img>"
    echo "<icon>camera-web</icon>"
    echo "<tool>ウェブカメラは有効(クリックで無効化)</tool>"
else
    # OFF
    #echo "<img>/usr/share/icons/Adwaita/symbolic/status/camera-disabled-symbolic.svg</img>"
    echo "<icon>camera-disabled-symbolic</icon>"
    echo "<tool>ウェブカメラは無効(クリックで有効化)</tool>"
fi

# クリック時の動作
#echo "<click>$TOGGLE_SCRIPT</click>"
echo "<iconclick>$TOGGLE_SCRIPT</iconclick>"

<img> の場合はフルパスで指定、<icon> なら camera-web-symbolic のように名前で指定する。なお <img> のときは <click> にし、<icon> のときは <iconclick> にする。

実行権限を与えておく。 sudo chmod +x ~/bin/cam-status.sh

XFCE パネルへの組み込み

  1. GenMon のインストール: Debian なら sudo apt install xfce4-genmon-plugin
  2. パネルに追加: パネルを右クリック → 新しいアイテムの追加 → ジェネリックモニター
  3. 設定: 追加されたアイコンを右クリック → プロパティ
    • コマンド: cam-status.sh (またはフルパス)
    • ラベル: (チェックを外す)
    • 間隔(秒): 10 (適当に)

以上で、アイコンをクリックするだけで即座に切り替えられる。

起動時の状態

起動時に必ずウェブカメラを無効化の状態にするには、システム起動時に一度だけ authorized を 0 に書き換える設定を追加する。cron@reboot 指定を使う。

root の crontab に

@reboot echo 0 > /sys/bus/usb/devices/3-1.2/authorized

を追加する。

注意

もしポートの場所が変わってしまう可能性がある (USB の挿し口を変えたなど) 場合は、ベンダー ID で自動探索などがいいのかもしれないが、今回は決め打ちとした。

それが変わったときは、2つのスクリプトと root の crontab の計3か所の中のパスを書き換えるのを忘れずに。