rust製のモダンなlsusb的なcymeというものを見かけたので少し試してみました.
cymeはlsusbとも互換性が有り,Linux/Windows/macOSで動作するようです.
タグ: USB
USB-HDDをスリープさせる(hd-idle)
最近USB接続のUSB HDDの熱が少し気になります.通常時は倉庫的に使っているのでアイドルです.アイドルが一定時間続いたらスリープするように設定できたよなと hdparm -S
を叩いてみましたがコントローラーが非対応のようでエラーとなりました.
$ sudo hdparm -S 60 /dev/sdb /dev/sdb: setting standby to 60 (5 minutes) SG_IO: bad/missing sense data, sb[]: 70 00 05 00 00 00 00 0a 00 00 00 00 20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
hd-idle
を使うとスリープするように出来ました.
Rufusを使ってWindows 10でWindows 10のisoイメージをUSBフラッシュメモリに書き込み
LinuxでWindowsのisoイメージをUSBフラッシュメモリに書き込むのにWoeUSBを利用しました.
WindowsではRufusというツールが使えるようなので試してみました.
ダウンロードして実行して「デバイス」に書き込み先のUSBフラッシュメモリを,「ブートの種類」に書き込むisoファイルを指定して後は既定値で「スタート」を押すと書き込みが始まります.
書き込み完了時に以下のメッセージ.セキュアブートには未対応のようです.
出来上がったUSBフラッシュメモリで起動するとセキュアブート向こうのマシンでは利用できました.
しかしセキュアブートを利用したい場合はRufusは使えないようです.
ということで,WindowsでWindowsのisoファイルの書き込みはWindows標準の「メディア作成ツール」を利用するのが良さそうです.
Windows で以下のページにアクセスして,「ツールを今すぐダウンロード」から入手できます.(Linux等でアクセスするとisoイメージのダウンロードページになります.)
このツールはisoイメージのダウンロード&書き込みをしてくれます.x86, x64の32bit/64bit両方に対応したUSBフラッシュメモリも作成できました.ダウンロード済のisoイメージの指定は出来ないようなのは不便です.
* エディション Windows 10 Pro * バージョン 1903 * OSビルド 18362.449 * システムの種類 64 ビット オペレーティングシステム、x64 ベース プロセッサ
* Windows 10 1903 x64 Win10_1903_V2_Japanese_x64.iso
Windows 10のisoファイルをWoeUSBでUSBフラッシュメモリに書き込み
balenaEtcher でUSBフラッシュメモリにWindows 10のisoイメージを書き込もうとしたのですが,このようなメッセージが表示されました.
Windowsのイメージは特殊なのでそれを処理できるプログラムを紹介しています.Linuxでは WoeUSB
を勧めています.
UbuntuではPPAがあるようなのでこれを導入します.
$ sudo add-apt-repository ppa:nilarimogard/webupd8 $ sudo apt update $ sudo apt install woeusb
起動します.
$ sudo -H woeusb
画面はこんな感じでした.
実際に書き込みをするときはこんな感じ.Soureにisoファイルを指定して,File stysremに「NTFS」を選択,Taeget deviceに対象のUSBフラッシュメモリを指定しました.はじめFATを選択したのですがエラーとなりました.NTFSだとOK.FATの4GB制限に引っかかったのかもしれません.
ここで Install
ボタンを押すことでプログレスが表示されて導入が開始されます.
しばらく待つと書き込み終了.出来上がったUSBフラッシュメモリをPCに接続して起動すると無事Windows 10のインストーラが起動しました.
$ ls -s /media/mk/6647-4A7F/iso/Win10_1903_V2_Japanese_x64.iso 5202048 /media/mk/6647-4A7F/iso/Win10_1903_V2_Japanese_x64.iso $ dpkg-query -W woeusb balena-etcher-electron balena-etcher-electron 1.5.51 woeusb 3.3.0-1~webupd8~eoan0 $ lsb_release -dr Description: Ubuntu 19.10 Release: 19.10 $ uname -a Linux x201i 5.3.0-19-generic #20-Ubuntu SMP Fri Oct 18 09:04:39 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
termux-APIのTermux-usbを少し試す
Androidでdeb系ぽいLinux環境を実現できるTermuxからAndroidを操作するAPIのTermux-APIのupdateがありました.
Add a USB API compatible with libusb – see https://wiki.termux.com/wiki/Termux-usb for more information.
なんだか気になる更新内容です.
早速試してみます.
$ pkg update $ pkg install root-repo $ pkg install termux-api $ pkg install libusb $ pkg install clang
termux-usb
コマンドでデバイスを確認してアクセス許可を与える(ここではUSBメモリ)$ termux-usb -l [ "/dev/bus/usb/001/004" ] $ termux-usb -r /dev/bus/usb/001/004 Access granted.
アクセスの許可はAndroidの画面で操作が必要です.
ちなみに,USB Keyboardは認識できませんでした(Androidでは利用できているのに!)
$ cat << __EOF__ > usbtest.c > $ cat usbtest.c > #include <stdio.h> > #include <assert.h> > #include <libusb-1.0/libusb.h> > > int main(int argc, char **argv) { > libusb_context *context; > libusb_device_handle *handle; > libusb_device *device; > struct libusb_device_descriptor desc; > unsigned char buffer[256]; > int fd; > assert((argc > 1) && (sscanf(argv[1], "%d", &fd) == 1)); > assert(!libusb_init(&context)); > assert(!libusb_wrap_sys_device(context, (intptr_t) fd, &handle)); > device = libusb_get_device(handle); > assert(!libusb_get_device_descriptor(device, &desc)); > printf("Vendor ID: %04x\n", desc.idVendor); > printf("Product ID: %04x\n", desc.idProduct); > assert(libusb_get_string_descriptor_ascii(handle, desc.iManufacturer, buffer, 256) >= 0); > printf("Manufacturer: %s\n", buffer); > assert(libusb_get_string_descriptor_ascii(handle, desc.iProduct, buffer, 256) >= 0); > printf("Product: %s\n", buffer); > assert(libusb_get_string_descriptor_ascii(handle, desc.iSerialNumber, buffer, 256) >= 0); > printf("Serial No: %s\n", buffer); > libusb_exit(context); > } > __EOF__ $ gcc usbtest.c -lusb-1.0 -o usbtest $ termux-usb -e ./usbtest /dev/bus/usb/001/004 Vendor ID: 13fe Product ID: 3600 Manufacturer: Product: USB DISK 2.0 Serial No: 07AC10081C16381A
てことでTermuxからlibusbが使えるようになったようです.
ちなみに,lsusbを実行するとこんな感じです.rootedな端末だと使えるんでしょうけど.
$ lsusb lsusb: /sys/bus/usb/devices: Permission denied $ tsudo lsusb /data/data/com.termux/files/usr/bin/tsu: 146: exec: : Permission denied
$ dpkg-query -W termux-api libusb clang clang 8.0.1-4 libusb 1.0.23-rc1-1 termux-api 0.47 $ adb shell dumpsys package com.termux.api | grep -E 'versionCode|versionName' versionCode=38 minSdk=21 targetSdk=28 versionName=0.38 $ adb shell dumpsys package com.termux | grep -E 'versionCode|versionName' versionCode=75 minSdk=21 targetSdk=28 versionName=0.75 $ getprop ro.bootimage.build.fingerprint essential/mata/mata:10/QP1A.190711.122/420:user/release-keys $ getprop ro.build.version.security_patch 2019-09-05 $ getprop ro.product.cpu.abilist arm64-v8a,armeabi-v7a,armeabi
Raspberry Pi の USB-OTG ethernet の MAC address を model B の ethernet と同じ規則で設定する
Raspberry Pi model A/A+/Zero/ZeroW/ZeroHW/Compute Module/Compute module 3ではUSB-OTGが利用できます.(ZeroHW/Compute Module/Compute module 3は自分は未確認)
USB-OTGでUSBをEthernetにしてHostPCからアクセスするようにするとUSBケーブル1本で電源と併用できて便利です.
このときMACアドレスはモジュール読み込み毎に自動生成されます.
以下の例では,接続先(PC等)から見えるMACが HOST MAC 6a:b3:b1:5e:22:89
で,Raspberry Pi の中でのMACが MAC ae:3a:c7:8e:50:38
になっています.
$ sudo modprobe g_ether $ dmesg | tail -15 [ 88.517568] using random self ethernet address [ 88.517590] using random host ethernet address [ 88.519210] usb0: HOST MAC 6a:b3:b1:5e:22:89 [ 88.520195] usb0: MAC ae:3a:c7:8e:50:38 [ 88.520396] using random self ethernet address [ 88.520412] using random host ethernet address [ 88.520534] g_ether gadget: Ethernet Gadget, version: Memorial Day 2008 [ 88.520546] g_ether gadget: g_ether ready [ 88.520580] dwc2 20980000.usb: bound driver g_ether [ 88.866651] IPv6: ADDRCONF(NETDEV_UP): usb0: link is not ready [ 94.048758] dwc2 20980000.usb: new device is high-speed [ 94.128837] dwc2 20980000.usb: new device is high-speed [ 94.197523] dwc2 20980000.usb: new address 9 [ 96.057234] g_ether gadget: high-speed config #1: CDC Ethernet (ECM) [ 96.095719] IPv6: ADDRCONF(NETDEV_CHANGE): usb0: link becomes ready $ /sbin/ifconfig usb0 usb0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 10.42.0.212 netmask 255.255.255.0 broadcast 10.42.0.255 inet6 fe80::5855:ab0c:6628:557c prefixlen 64 scopeid 0x20<link> ether ae:3a:c7:8e:50:38 txqueuelen 1000 (Ethernet) RX packets 208 bytes 17243 (16.8 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 67 bytes 7696 (7.5 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
これは毎回変わるのでふと気づくとホストPCのネットワークの設定が沢山になっていたり…….
$ nmcli connection show | grep ethernet | wc -l 25
MAC addressを固定するにはモジュール読み込み時に指定してあげればOKです.
$ sudo rmmod g_ether $ sudo modprobe g_ether host_addr=de:ad:fe:ef:00:01 dev_addr=de:ad:fe:ef:00:00 $ dmesg | egrep usb0:.*MAC | tail -2 [ 1067.248443] usb0: HOST MAC de:ad:fe:ef:00:01 [ 1067.248958] usb0: MAC de:ad:fe:ef:00:00
永続化するには,g_etherモジュールを読んでいるところで指定してあげます.
modules-load=dwc2,g_cdc g_ether.host_addr=de:ad:fe:ef:00:01 g_ether.dev_addr=de:ad:fe:ef:00:00
g_ether g_ether.host_addr=de:ad:fe:ef:00:01 g_ether.dev_addr=de:ad:fe:ef:00:00
Note
|
※g_cdcの場合はこんな感じで
|
modprobe g_ether host_addr=de:ad:fe:ef:00:01 dev_addr=de:ad:fe:ef:00:00
このときのMAC addressは g_ether が自動生成したものを使うのが無難だとおもうのですが,ランダムとかでいんだろうか?という不安があります.
ベンダーIDに使われていない領域だったら多分問題ないですが,これから埋まることもありそうです.(IPアドレスのプライベートIPアドレスのような領域があるのかもしれ無いけど未確認)
Raspberry Pi model B シリーズのNICには Raspberry Pi Foundation のベンダーコードが使われています.
$ grep -i raspberry /usr/share/nmap/nmap-mac-prefixes B827EB Raspberry Pi Foundation
Raspberry Pi の smsc95xx の MAC address の生成は,上6桁はベンダーIDの b8:27:eb
を,下6桁はボードのserialの下6桁を割り当てているようです.
MAC address generation
To have a predetermined MAC address, a given SMSC LAN9512 must be attached to an EEPROM that contains the MAC address. But on the Raspberry Pi Model B, this EEPROM is not present; therefore, this driver must assign a MAC address itself. We do this by generating a MAC address from the board’s serial number. This guarantees that a given Raspberry Pi will always have the same MAC address and that two Raspberry Pis are extremely unlikely to be assigned the same MAC address.
手元の Raspberry Pi 2 Model B を確認すると確かにそうなっているようです.
$ ifconfig | grep ether ether b8:27:eb:ff:56:0a txqueuelen 1000 (Ethernet) $ grep Serial /proc/cpuinfo Serial : 0000000094ff560a $ sed -n "s/^Serial.*:.*\(..\)\(..\)\(..\)$/b8:27:eb:::/p" /proc/cpuinfo b8:27:eb:ff:56:0a $ cat /proc/device-tree/model ;echo Raspberry Pi 2 Model B Rev 1.1
Note
|
16進数6桁は 0xFFFFFF → 16777215です,Raspberry Pi は2018年3月時点で190万台出荷しているようなので2周目に入っています.低い確率でしょうが同じMAC addressが割り当てられる可能性が…….
内蔵ネットワークに自分でMAC addressを指定したい場合はこんな感じでいけます. /boot/cmdline.txt に以下を設定
smsc95xx.macaddr=b8:27:eb:00:00:00 /etc/network/interfaces でも設定できるはずだがRaspbianでは未確認
hwaddress ether b8:27:eb:00:00:00 CPU Serialを詐称する手も? |
ということで,Raspberry Pi model A / Zero でもこの MAC address が利用できそうな感じです.外向けの HOST MAC をこのアドレスにしてみます.
$ sed -n "s/^Serial.*:.*\(..\)\(..\)\(..\)$/b8:27:eb:::/p" /proc/cpuinfo | tee ~/macaddress b8:27:eb:d8:63:18 $ sudo vi /boot/cmdline.txt $ sudo reboot : : $ dmesg | grep usb0 [ 4.937660] usb0: HOST MAC b8:27:eb:d8:63:18 [ 4.937845] usb0: MAC 86:d7:fe:57:f2:d5
ホストPCでもちゃんと指定したものになっています.
$ /sbin/ifconfig enxb827ebd86318 | grep ether ether b8:27:eb:d8:63:18 txqueuelen 1000 (Ethernet)
とりあえずこれで使ってみようと思います.
$ lsb_release -d Description: Raspbian GNU/Linux 9.4 (stretch) $ uname -m armv6l $ cat /proc/device-tree/model ;echo Raspberry Pi Model A Rev 2
不正なUSBデバイスからPCを守るUSBGuardを試す
BadUSBなどの不正なUSBデバイスからPCが守れないかなちょっと設定すればできそう?そもそも作っている人がいるんじゃ?ということで探したらUSBGuardというソフトウェアを見つけました.
このソフトウェアを導入しておくと,設定したルールに合致しないUSBデバイスはblockされます. デスクトップ利用の場合はGUIのアプレットを利用してUSB接続時にウィンドウがポップアップして接続するか選べたりもします. 便利.
#USB KILLERは……USB配線を外したりUSBコネクタを塞ぐしかないですよね多分.
導入
Debian/Ubuntuにはパッケージがあるのでそちらから導入します.
$ sudo apt install usbguard usbguard-applet-qt
設定
一般ユーザから利用する場合は設定ファイルを編集してユーザかグループを追加してデーモンの再起動を行います. 設定ファイルは/etc/usbguard/usbguard-daemon.confです.
diff --git a/usbguard/usbguard-daemon.conf b/usbguard/usbguard-daemon.conf
index 4a54ca0..7b3a165 100644
--- a/usbguard/usbguard-daemon.conf
+++ b/usbguard/usbguard-daemon.conf
@@ -65,7 +65,7 @@ PresentControllerPolicy=keep
#
# IPCAllowedUsers=username1 username2 ...
#
-IPCAllowedUsers=root
+IPCAllowedUsers=root user1 user2
#
# Groups allowed to use the IPC interface.
@@ -75,7 +75,7 @@ IPCAllowedUsers=root
#
# IPCAllowedGroups=groupname1 groupname2 ...
#
-IPCAllowedGroups=root
+IPCAllowedGroups=root users
#
# Generate device specific rules including the "via-port"
ユーザの場合はIPCAllowedUsers,グループの場合はIPCAllowedGroupsにスペース区切りで書いていきます.
デーモンの再起動
設定を反映するためにデーモンを再起動します.
$ sudo service usbguard restart
CUIでの利用例
usbguardが起動した後に接続されたデバイスはblockされています.
$ usbguard list-devices| tail -2
9: allow id 8087:0024 serial "" name "" hash "Zx7v0FMQEjScKSAFENAiobEs1OGPPB0YWR+yXDCVE04=" parent-hash "WwvSEwd+7257rAqUGLMQjffF7zyqygmmLeQTYnR9QzQ=" via-port "4-1" with-interface 09:00:00
11: block id 1004:631c serial "03a809c94b4befd4" name "LGE Android Phone" hash "P5dSK5xxK4R5QTRzd7KlD8Agf/+28pztL077j1oWqPI=" parent-hash "Zx7v0FMQEjScKSAFENAiobEs1OGPPB0YWR+yXDCVE04=" via-port "4-1.1" with-interface ff:ff:00
blockされている11番目のデバイスを許可してみます.(これは一時的です)
$ usbguard allow-device 11
$ usbguard list-devices| tail -1
11: allow id 1004:631c serial "03a809c94b4befd4" name "LGE Android Phone" hash "P5dSK5xxK4R5QTRzd7KlD8Agf/+28pztL077j1oWqPI=" parent-hash "Zx7v0FMQEjScKSAFENAiobEs1OGPPB0YWR+yXDCVE04=" via-port "4-1.1" with-interface ff:ff:00
状況の確認
USBデバイスの認識状況を監視します.
$ usbguard watch
[IPC] Connected
[device] Inserted: id=12 hash=vi38heJ4vKEdayxiqrQFylpwa3xkVYYUkZi2zbu3sWs= name=Mass Storage Device product_id=1336 serial=00000000000006 vendor_id=048d interface={ 08:06:50} rule_match=0 rule_id=4294967295
[device] Blocked: id=12 name=Mass Storage Device product_id=1336 vendor_id=048d rule_match=0 rule_id=4294967295
[device] Allowed: id=12 name=Mass Storage Device product_id=1336 vendor_id=048d rule_match=0 rule_id=4294967295
GUI(usbguard-applet-qt)の利用例
CUIだとちょっと面倒ですが,デスクトップ利用の場合はusbguard-applet-qtが便利です.
usbguard-applet-qtが起動した状態でUSBデバイスを接続すると以下のようなダイヤログが表示されます.Allowボタンを押すことで利用できるようになります. このとき,Make the decision permanentにチェックを入れておくと,設定が永続化されます.この設定は/etc/usbguard/rules.confに記録されます.
ダイヤログはタイムアウトすると消えてしまいますが,アプレットのウィンドウから設定画面を呼び出すことができます.ここから設定変更ができます.
とりあえずはこれくらいで良さそうですが,ルールを書くといろいろ応用が効きそうです.
とりあえずはどうもデーモン起動までに接続されていたデバイスは許可されるようなので内臓デバイスを明示的に許可してその他をblockしようと思います.