udev Rules – udev Rules to Allow Only One Vendor and Model USB Drive

12.04udevudisksusb-storage

So, we're working to set up an environment here where we have a secure storage setup on our Linux laptops, such that our Linux laptops can only connect a specific USB drive: a Kingston DataTraveler 2.0. Vendor:Model code is this (from lsusb): Bus 003 Device 003: ID 0951:1665 Kingston Technology

I've been trying to get these rules to work, but on a 12.04 environment the rules aren't working. (Note I've made comments with # prepended lines, but they're not in the udev files):

# If a device is NOT a Kingston drive, ignore it.
SUBSYSTEMS=="usb", DRIVERS=="usb", ATTRS{idVendor}!="0951", OPTIONS+="ignore_device"

# If a device is a Kingston drive, but is NOT the model we have, ignore it.
SUBSYSTEMS=="usb", DRIVERS=="usb", ATTRS{idVendor}=="0951", ATTRS{idProduct}!="1665", OPTIONS+="ignore_device"

# If a device is a Kingston drive and is the model we have, then run a script
SUBSYSTEMS=="usb", DRIVERS=="usb", ATTRS{idVendor}=="0951", ATTRS{idProduct}=="1665", RUN+="/lib/udev/syslog-authorized-device-connected.sh"

The issue I have is that NONE of these rules are working, and I have no idea if this is even the correct approach for this.

Thoughts?

Best Answer

I've faced before same problem with non effective ignore_device. I couldn't figure out why then I always go with other solutions.

  • Well, ignore_device removed with udev release 148. See release note or changelog

    If you noticed, all topics suggesting the use of it are old (~ 2009).

  • A quick alternative is to use: ENV{UDISKS_PRESENTATION_HIDE}="1" (Ubuntu 12.04). For releases (>=12.10) which include udisks2 use: ENV{UDISKS_IGNORE}="1".

    Reference: Archlinux Wiki: Udisks

The other solutions are using SYSFS. Either device/authorized (as solsTiCe mentioned), device/remove or driver/unbind. See Only use Mass Storage devices on a selected USB port - how?

Difficulty comes in how to deny all storage except only one brand/model. So the rule match condition should filter a single device node, no more no less (no child or parent devices). That's why I added KERNELS=="[1-9]*-[0-9]*"

KERNELS=="[1-9]*-[0-9]*", SUBSYSTEMS=="usb", DRIVERS=="usb", ATTRS{idVendor}!="0951", ENV{UDISKS_PRESENTATION_HIDE}="1"
KERNELS=="[1-9]*-[0-9]*", SUBSYSTEMS=="usb", DRIVERS=="usb", ATTRS{idVendor}=="0951", ATTRS{idProduct}!="1665", ENV{UDISKS_PRESENTATION_HIDE}="1"

Well, UDisks hides only mounting hook. These may be better using SYSFS driver unbind.

KERNELS=="[1-9]*-[0-9]*", SUBSYSTEMS=="usb", DRIVERS=="usb", ATTRS{idVendor}!="125f", ENV{IF_STORAGE_REMOVE_ME}="1"
KERNELS=="[1-9]*-[0-9]*", SUBSYSTEMS=="usb", DRIVERS=="usb", ATTRS{idVendor}=="125f", ATTRS{idProduct}!="c96a", ENV{IF_STORAGE_REMOVE_ME}="1"
ENV{IF_STORAGE_REMOVE_ME}=="1", DRIVERS=="usb-storage", DRIVER=="sd", RUN+="/bin/sh -c 'echo -n %k >/sys%p/driver/unbind'"

Reference: udev rule with few parent device attributes

Related Question