形態素解析システムJUMAN++をちょっと試したメモ

京都大学 黒橋・河原研究室より2016-09-23にリリースされた新しい形態素解析システムだそうです.とりあえず手元の環境で動かしてみたのでそのメモです.

環境

Debian stretch amd64 / Ubuntu 16.10 amd64 で確認しました.どちらも以下の手順でOKでした.開発元ではCent OS 6.7で動作確認をしているようです.

build

必要なパッケージを導入してmake.

$ sudo apt install libboost-dev build-essential
$ wget http://lotus.kuee.kyoto-u.ac.jp/nl-resource/jumanpp/jumanpp-1.01.tar.xz
$ sha256sum jumanpp-1.01.tar.xz 0d587416a3eb7123638f9c1e30a649b72dfb483448839168dcb48be572c5919a  jumanpp-1.01.tar.xz
$ tar tvf ./jumanpp-1.01.tar.xz
$ tar xf ./jumanpp-1.01.tar.xz
$ ./configure --prefix=${HOME}/usr/local
$ make
$ make install

動作確認

適当に文章を入れてみたり.

$ ~/usr/local/bin/jumanpp
こんにちはJUMANPP++
こんにち こんにち こんにち 名詞 6 時相名詞 10 * 0 * 0 "代表表記:今日/こんにち カテゴリ:時間"
は は は 助詞 9 副助詞 2 * 0 * 0 NIL
JUMANPP JUMANPP JUMANPP 未定義語 15 その他 1 * 0 * 0 "品詞推定:名詞"
+ + + 未定義語 15 その他 1 * 0 * 0 "品詞推定:名詞"
+ + + 未定義語 15 その他 1 * 0 * 0 "品詞推定:名詞"
EOS

青空文庫の古典を流し込んでみたり.

$ wget -O - http://www.aozora.gr.jp/cards/000160/files/2617_ruby_23916.zip | zcat | iconv -f SJIS -t UTF-8 - | ~/usr/local/bin/jumanpp
三十 三十 三十 名詞 6 数詞 7 * 0 * 0 "カテゴリ:数量"
年 ねん 年 接尾辞 14 名詞性名詞助数辞 3 * 0 * 0 "代表表記:年/ねん 準内容語 カテゴリ:時間"
後 ご 後 接尾辞 14 名詞性名詞接尾辞 2 * 0 * 0 "代表表記:後/ご 内容語"
の の の 助詞 9 接続助詞 3 * 0 * 0 NIL
世界 せかい 世界 名詞 6 普通名詞 1 * 0 * 0 "代表表記:世界/せかい カテゴリ:場所-その他"
      :

古典とかよりTwitterとかのほうがいいかもしれない.

$ curl 'https://twitter.com/search?f=tweets&vertical=default&q=lang%3Aja%20near%3A%22%E6%97%A5%E6%9C%AC%22%20within%3A15mi&src=typd&lang=ja' | grep 'class="TweetTextSize  js-tweet-text tweet-text"' | lynx -stdin -dump -nolist | ~/usr/local/bin/jumanpp

ちなみにちょっと試したいだけであれば導入しなくても以下のページで試せます.ラティス表示も楽しい.

USBGuardの初期デバイスを設定

USBGuardはそのままだとデーモン起動時に接続されていたデバイスは全て許可されるので不正なデバイスが起動時に既に取り付けられていた場合許可されてしまいます. そこで手動で利用可能デバイスをallowで設定に,そしてそれ以外をblockにした.blockでなくrejectの方がセキュリティは上がるけど許可したい場合面倒なのでとりあえずブロックに. これでallow設定されていないデバイスを繋ぐとblock.そのデバイスを利用したい場合は手動でallow-device usbguard-applet-qtでallowにすれば使えます.

※USBGuardは次のページの設定(ユーザ,グループ設定)が済んでいる前提です.

ルールファイルを作成

まずはgenerate-policyで現在の状態をファイルに書き出して編集します. ここでは内蔵カメラもblockにしています.

$ usbguard generate-policy > rules.conf
$ vi rules.conf
$ sudo cat /etc/usbguard/rules.conf
allow id 1d6b:0002 serial "0000:00:1a.0" name "EHCI Host Controller" hash "MwANH+QnAvclGgMNHjzanbOGkp3bPmwqoyAEZZ6QXTQ=" parent-hash "uvJm0y/N2iYeJgfKJsJqWKTJts/duhYZ7W2zzAYk7Y8=" with-interface 09:00:00
allow id 8087:0024 serial "" name "" hash "kv3v2+rnq9QvYI3/HbJ1EV9vdujZ0aVCQ/CGBYIkEB0=" parent-hash "MwANH+QnAvclGgMNHjzanbOGkp3bPmwqoyAEZZ6QXTQ=" via-port "3-1" with-interface 09:00:00
allow id 0a5c:21e6 serial "2016D8DA016E" name "BCM20702A0" hash "C4Os63DCRvIuWJYU/U+1PXrvWlXa2PmpRUQhp+C5eeE=" parent-hash "kv3v2+rnq9QvYI3/HbJ1EV9vdujZ0aVCQ/CGBYIkEB0=" with-interface { ff:01:01 ff:01:01 ff:01:01 ff:01:01 ff:01:01 ff:01:01 ff:01:01 ff:ff:ff fe:01:01 }
allow id 17ef:100a serial "" name "" hash "dMjTmGpj5dFGqH51kQpO/LVBQxE6JkwibVRJQkFCCuU=" parent-hash "kv3v2+rnq9QvYI3/HbJ1EV9vdujZ0aVCQ/CGBYIkEB0=" via-port "3-1.5" with-interface { 09:00:01 09:00:02 }
block id 04f2:b217 serial "" name "Integrated Camera" hash "BxFRAwzjkHO55cQGR8oMRm6bq+Ps2qQtU88jE1Uk5KE=" parent-hash "kv3v2+rnq9QvYI3/HbJ1EV9vdujZ0aVCQ/CGBYIkEB0=" via-port "3-1.6" with-interface { 0e:01:00 0e:02:00 0e:02:00 0e:02:00 0e:02:00 0e:02:00 0e:02:00 0e:02:00 0e:02:00 }
allow id 1d6b:0002 serial "0000:05:00.0" name "xHCI Host Controller" hash "IV7wk04gfQJink/IY4TiGVdcmTzuc09WcSe6k57kWrs=" parent-hash "3TIXKJ1dp4XFV6VxxWU11xbI0yLS0VmRZIaxdsLZDx4=" with-interface 09:00:00
allow id 1d6b:0003 serial "0000:05:00.0" name "xHCI Host Controller" hash "VlZK5oVuQQAlBH76Ekgc+KaZZDL0BAsF9tEf1ynb154=" parent-hash "3TIXKJ1dp4XFV6VxxWU11xbI0yLS0VmRZIaxdsLZDx4=" with-interface 09:00:00
allow id 1d6b:0002 serial "0000:00:1d.0" name "EHCI Host Controller" hash "WwvSEwd+7257rAqUGLMQjffF7zyqygmmLeQTYnR9QzQ=" parent-hash "FjkaT8Rp/Bh++KC4RQhk++hWack2wTDa1a1G5yXqYys=" with-interface 09:00:00
allow id 8087:0024 serial "" name "" hash "Zx7v0FMQEjScKSAFENAiobEs1OGPPB0YWR+yXDCVE04=" parent-hash "WwvSEwd+7257rAqUGLMQjffF7zyqygmmLeQTYnR9QzQ=" via-port "4-1" with-interface 09:00:00
block

ルールファイルを反映して動作確認

設定ファイルをコピーしてデーモンを再起動して反映.

$ sudo install -m 0600 -o root -g root rules.conf /etc/usbguard/rules.conf
$ sudo systemctl restart usbguard

これでallow設定されていないUSBデバイスを接続した状態で起動してもblockに,新しいUSBデバイスを接続してもblockになるようになります.

新しいデバイスを手動で許可する

設定されていないデバイスを利用したい場合は以下のようにlist-devicesでidを確認してallow-device usbguard-applet-qtでallowにして使えるようにします.

$ usbguard list-devices | grep block
15: block id 04f2:b217 serial "" name "Integrated Camera" hash "BxFRAwzjkHO55cQGR8oMRm6bq+Ps2qQtU88jE1Uk5KE=" parent-hash "kv3v2+rnq9QvYI3/HbJ1EV9vdujZ0aVCQ/CGBYIkEB0=" via-port "3-1.6" with-interface { 0e:01:00 0e:02:00 0e:02:00 0e:02:00 0e:02:00 0e:02:00 0e:02:00 0e:02:00 0e:02:00 }
20: block id 1004:631c serial "03a809c94b4befd4" name "LGE Android Phone" hash "0qSmncueL3SVg+z6yyVNMG2l+KxlAsMZWRfpPvCp0oU=" parent-hash "Zx7v0FMQEjScKSAFENAiobEs1OGPPB0YWR+yXDCVE04=" via-port "4-1.1" with-interface ff:ff:00
$ usbguard allow-device 20

20161010_00:10:37-11962

とりあえずこれで良さそうですが,たまにSSDを差し替えることがあります.そうすると前もって設定し直しておかないとデバイスが認識せず不味いことが起こりそうです.ということで設定ファイルにhostnameを付けてそれを使うようにしてみました.

hostごとの設定ファイルを作る

起動時に設定ファイルは指定できますが,ルールファイルは指定できないようです.両方のファイルをホストごとに用意します.

$ sudo cp -p /etc/usbguard/usbguard-daemon.conf /etc/usbguard/usbguard-daemon-`hostname`.conf
$ sudo vi /etc/usbguard/usbguard-daemon-x220.conf
$ diff /etc/usbguard/usbguard-daemon.conf /etc/usbguard/usbguard-daemon-x220.conf
10c10
< RuleFile=/etc/usbguard/rules.conf
---
> RuleFile=/etc/usbguard/rules-x220.conf
$ sudo cp -p /etc/usbguard/rules.conf /etc/usbguard/rules-`hostname`.conf

systemdの起動ファイルを修正してホスト名付きの設定ファイルを使うようにする

Systemdの設定ファイルを用意して設定ファイルをホスト名付きで呼ぶように修正しました.

$ sudo vi /etc/systemd/system/usbguard.service
$ cat /etc/systemd/system/usbguard.service
[Unit]
Description=USBGuard daemon
Wants=systemd-udevd.service local-fs.target
Documentation=man:usbguard-daemon(8)

[Service]
Type=simple
ExecStartPre=/bin/bash -c "/bin/systemctl set-environment hostname=$(/bin/hostname)"
ExecStart=/usr/sbin/usbguard-daemon -k -c /etc/usbguard/usbguard-daemon-${hostname}.conf
Restart=on-failure

[Install]
WantedBy=basic.target

起動し直して確認してみるとホスト名付きのファイルを呼んでいます.

$ sudo systemctl daemon-reload
$ sudo service usbguard restart
$ hostname
x220
$ ps -ef|grep -i usbguard-daemon
root     28545     1  0 00:05 ?        00:00:00 /usr/sbin/usbguard-daemon -k -c /etc/usbguard/usbguard-daemon-x220.conf

ちょっと面倒ですがとりあえずこれで行けそうです.

VirusTotalをコマンドラインから利用する

VirusTotalというオンラインスキャナがあります.不安なファイルなどをここでスキャンするとたくさん(現在は54)のエンジンでスキャンしてその結果を確認できます. 複数のエンジンを利用するのでチェック漏れが少ないので安心感があります.(絶対ではない)

このVirusTotalにはAPIやデスクトップアプリケーション(Win/Mac/Linux)があります.これを利用してコマンドラインからスキャナにファイルを投げたり結果を確認したりしてみます.

※利用するときデータをVirusTotalのサーバにアップロードする必要がありますが,アップロードされたデータはVirusTotalとの契約者が利用できるようになっているので人に見られたら困るものや仕事のファイルなどには利用しないほうがいいでしょう.もしそういうものをたくさんのエンジンでスキャンしたい場合はMetadefender Coreという製品などを検討するといいかもです.

導入

必要パッケージの導入

ビルドに必要なパッケージを導入します.Debian/Ubuntuでは以下のものが必要です.

$ sudo apt install build-essential automake autoconf libtool libjansson-dev libcurl4-openssl-dev git

build

sourceを入手してbuildします.

$ git clone https://github.com/VirusTotal/c-vtapi.git
$ cd c-vtapi
$ ./conigure --prefix=$HOME/usr/local
$ make
$ make install

続いてexampleをbuildします.(この中に簡易的なコマンドがあるのでこれを利用します.)

$ autoreconf -fi
$ ./configure --enable-examples
$ make

API Keyの入手

VirusTotalのコミニュティにサインアップして,API Keyを入手しておきます.

ファイルのアップロード

scanコマンドにapikeyとスキャン対象のファイルを指定してアップロードします.

$ ./examples/c/scan --apikey xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx --filescan ~/Downloads/rootkitXperia_20140719.zip
 apikey: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
progress_callback 0/0
progress_callback 0/0
progress_callback 0/0
progress_callback 0/0
   :
progress_callback 1736497/1736497
progress_callback 1736497/1736497
progress_callback 1736497/1736497
Response:
{
    "md5": "a3j0587afbba733d734b382f4c7fa15ed",
    "scan_id": "115fc4955cbfaa77982b6ced5fc1b5c901a707819c2ed7ed45d7e763c2bda841-1475839569",
    "sha1": "b586a6959843d5dd4004d585faf94d742e34eddc",
    "resource": "115fc4955cbfaa77982b6ced5fc1b5c901a707819c2ed7ed45d7e763c2bda841",
    "verbose_msg": "Scan request successfully queued, come back later for the report",
    "response_code": 1,
    "sha256": "115fc4955cbfaa77982b6ced5fc1b5c901a707819c2ed7ed45d7e763c2bda841",
    "permalink": "https://www.virustotal.com/file/115fc4955cbfaa77982b6ced5fc1b5c901a707819c2ed7ed45d7e763c2bda841/analysis/1475839569/"
}

スキャンの確認

scanコマンドにapikeyとhashを指定するとスキャン結果のレポートが確認できます.

$ ./examples/c/scan --apikey xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx --report 115fc4955cbfaa77982b6ced5fc1b5c901a707819c2ed7ed45d7e763c2bda841
apikey: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
progress_callback 0/0
progress_callback 0/0
progress_callback 0/0
:
progress_callback 366/366
progress_callback 366/366
progress_callback 366/366
Response:
{  
"scans": {
"Bkav": {
"detected": false,
"version": "1.3.0.8383",
"result": null,
"update": "20161007"
},
"Malwarebytes": {
"detected": false,
"version": "2.1.1.1115",
"result": null,
"update": "20161007"
},
"F-Secure": {
"detected": false,
"version": "11.0.19100.45",
"result": null,
"update": "20161007"
},
"MicroWorld-eScan": {
"detected": false,
"version": "12.0.250.0",
"result": null,
"update": "20161007"
},
"Antiy-AVL": {
"detected": false,
"version": "1.0.0.1",
"result": null,
"update": "20161007"
},
"K7AntiVirus": {
"detected": false,
"version": "9.242.21116",
"result": null,
"update": "20161007"
},
"AVware": {
"detected": false,
"version": "1.5.0.42",
"result": null,
"update": "20161007"
},
"Avira": { 
"detected": false,
"version": "8.3.3.4",
"result": null,
"update": "20161007"
},
"nProtect": {
"detected": false,
"version": "2016-10-07.02",
"result": null,
"update": "20161007"
},
"BitDefender": {
"detected": false,
"version": "7.2",
"result": null,
"update": "20161007"
},
"CMC": {
"detected": false,
"version": "1.1.0.977",
"result": null,
"update": "20161003"
},
"ViRobot": {
"detected": false,
"version": "2014.3.20.0",
"result": null,
"update": "20161007"
},
"McAfee": {
"detected": false,
"version": "6.0.6.653",
"result": null,
"update": "20161007"
},
"Kingsoft": {
"detected": false,
"version": "2013.8.14.323",
"result": null,
"update": "20161007"
},
"Baidu": {
"detected": false,
"version": "1.0.0.2",
"result": null,
"update": "20161001"
},
"Symantec": {
"detected": false,
"version": "20151.1.1.4",
"result": null,
"update": "20161007"
},
"CAT-QuickHeal": {
"detected": false,
"version": "14.00",
"result": null,
"update": "20161007"
},
"ALYac": { 
"detected": false,
"version": "1.0.1.9",
"result": null,
"update": "20161007"
},
"TheHacker": {
"detected": false,
"version": "6.8.0.5.1089",
"result": null,
"update": "20161007"
},
"Zillya": {
"detected": true,
"version": "2.0.0.3078",
"result": "Trojan.Towel.Linux.2",
"update": "20161007"
},
"DrWeb": {
"detected": false,
"version": "7.0.23.8290",
"result": null,
"update": "20161007"
},
"Rising": {
"detected": false,
"version": "28.0.0.1",
"result": null,
"update": "20161007"
},
"K7GW": {  
"detected": false,
"version": "9.242.21118",
"result": null,
"update": "20161007"
},
"AegisLab": {
"detected": true,
"version": "4.2",
"result": "Android.Exploit.Gen!c",
"update": "20161007"
},
"ALYac": { 
"detected": false,
"version": "1.0.1.9",
"result": null,
"update": "20161007"
},
"TheHacker": {
"detected": false,
"version": "6.8.0.5.1089",
"result": null,
"update": "20161007"
},
"Zillya": {
"detected": true,
"version": "2.0.0.3078",
"result": "Trojan.Towel.Linux.2",
"update": "20161007"
},
"DrWeb": {
"detected": false,
"version": "7.0.23.8290",
"result": null,
"update": "20161007"
},
"Rising": {
"detected": false,
"version": "28.0.0.1",
"result": null,
"update": "20161007"
},
"K7GW": {  
"detected": false,
"version": "9.242.21118",
"result": null,
"update": "20161007"
},
"AegisLab": {
"detected": true,
"version": "4.2",
"result": "Android.Exploit.Gen!c",
"update": "20161007"
},
"ALYac": { 
"detected": false,
"version": "1.0.1.9",
"result": null,
"update": "20161007"
},
"TheHacker": {
"detected": false,
"version": "6.8.0.5.1089",
"result": null,
"update": "20161007"
},
"Zillya": {
"detected": true,
"version": "2.0.0.3078",
"result": "Trojan.Towel.Linux.2",
"update": "20161007"
},
"DrWeb": {
"detected": false,
"version": "7.0.23.8290",
"result": null,
"update": "20161007"
},
"Rising": {
"detected": false,
"version": "28.0.0.1",
"result": null,
"update": "20161007"
},
"K7GW": {  
"detected": false,
"version": "9.242.21118",
"result": null,
"update": "20161007"
},
"AegisLab": {
"detected": true,
"version": "4.2",
"result": "Android.Exploit.Gen!c",
"update": "20161007"
},
"ALYac": { 
"detected": false,
"version": "1.0.1.9",
"result": null,
"update": "20161007"
},
"TheHacker": {
"detected": false,
"version": "6.8.0.5.1089",
"result": null,
"update": "20161007"
},
"Zillya": {
"detected": true,
"version": "2.0.0.3078",
"result": "Trojan.Towel.Linux.2",
"update": "20161007"
},
"DrWeb": {
"detected": false,
"version": "7.0.23.8290",
"result": null,
"update": "20161007"
},
"Rising": {
"detected": false,
"version": "28.0.0.1",
"result": null,
"update": "20161007"
},
"K7GW": {  
"detected": false,
"version": "9.242.21118",
"result": null,
"update": "20161007"
},
"AegisLab": {
"detected": true,
"version": "4.2",
"result": "Android.Exploit.Gen!c",
"update": "20161007"
},
"ALYac": { 
"detected": false,
"version": "1.0.1.9",
"result": null,
"update": "20161007"
},
"TheHacker": {
"detected": false,
"version": "6.8.0.5.1089",
"result": null,
"update": "20161007"
},
"Zillya": {
"detected": true,
"version": "2.0.0.3078",
"result": "Trojan.Towel.Linux.2",
"update": "20161007"
},
"DrWeb": {
"detected": false,
"version": "7.0.23.8290",
"result": null,
"update": "20161007"
},
"Rising": {
"detected": false,
"version": "28.0.0.1",
"result": null,
"update": "20161007"
},
"K7GW": {  
"detected": false,
"version": "9.242.21118",
"result": null,
"update": "20161007"
},
"AegisLab": {
"detected": true,
"version": "4.2",
"result": "Android.Exploit.Gen!c",
"update": "20161007"
},
"AVG": {
"detected": true,
"version": "16.0.0.4656",
"result": "Android/Exploit.B",
"update": "20161007"
},
"Qihoo-360": {
"detected": false,
"version": "1.0.0.1120",
"result": null,
"update": "20161007"
}
},
"response_code": 1,
"scan_id": "115fc4955cbfaa77982b6ced5fc1b5c901a707819c2ed7ed45d7e763c2bda841-1475839569",
"sha1": "b586a6959843d5dd4004d585faf94d742e34eddc",
"resource": "115fc4955cbfaa77982b6ced5fc1b5c901a707819c2ed7ed45d7e763c2bda841",
"total": 54,
"scan_date": "2016-10-07 11:26:09",
"permalink": "https://www.virustotal.com/file/115fc4955cbfaa77982b6ced5fc1b5c901a707819c2ed7ed45d7e763c2bda841/analysis/1475839569/",
"positives": 10,
"verbose_msg": "Scan finished, information embedded",
"sha256": "115fc4955cbfaa77982b6ced5fc1b5c901a707819c2ed7ed45d7e763c2bda841",
"md5": "a30587afbba733d734b382f4c7fa15ed"
}
Msg: Scan finished, information embedded
response code: 1

たまに使うのでですがブラウザがなくても利用できて便利そうです :)
ちなみにGUIもあるのでGUIで利用したい人はそちらもBUILDすると幸せになれるかもしれません.

不正な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に記録されます.

20161007_02:10:22-9078

ダイヤログはタイムアウトすると消えてしまいますが,アプレットのウィンドウから設定画面を呼び出すことができます.ここから設定変更ができます.

20161007_16:10:49-4107

とりあえずはこれくらいで良さそうですが,ルールを書くといろいろ応用が効きそうです.

とりあえずはどうもデーモン起動までに接続されていたデバイスは許可されるようなので内臓デバイスを明示的に許可してその他をblockしようと思います.

mind mappingアプリのFreeplaneを試す

FreeMindをDebian jessieに導入しようとしたらパッケージが見当たりません. 探してみるとメンテナンスされてないからjessie/sidから消されたようです.

We have Freeplane which is actively maintained and roughly equivalent in features.

でもFreeplaneというメンテされている似たものがあるよということでこれを試してみることにしました.

#ちなみにFreeMindのsiteを見るとstableのリリースが2013年で1.0.1.その後1.1.0-Beta1が2015年1.1.0-Beta2が2016年に出ていて,Debianでは0.9.0だったようです.

FreeplaneはどうもFreeMindのフォークのようです.見た目も使い勝手も似ています.JAVA製でマルチプラットホームなのも同じです.

導入はパッケージがあるのでそれを利用しました.

$ sudo apt install freeplane

起動ロゴ……何だろうこの虫?は.

20161005_01:10:30-30616

初回起動時にはWhats Newが表示されました.

20161005_01:10:09-30241

少し日本語が豆腐になってしまっている場所がありましたがフォントを日本語フォントに変更することで解決しました. 後はチュートリアルとかに目を通しておくと良さそうです.

チュートリアルなどのドキュメントは/usr/share/freeplane/doc/辺りにありました.

$ ls -1 /usr/share/freeplane/doc/*_ja.mm
/usr/share/freeplane/doc/freeplaneFunctions_ja.mm
/usr/share/freeplane/doc/freeplaneTutorial_ja.mm
/usr/share/freeplane/doc/freeplane_ja.mm

20161005_01:10:53-29876

20161005_01:10:09-28858

20161005_01:10:32-27112

未だそんなに使っていませんが,FreeMindと同じような操作性だし以前書いた.mmも読めるようなのでそのまま移行できそうです.

<追記>

Ubuntu 16.10 amd64(今は未だリリース前)にも入れてみましたが起動しませんでした.とりあえず本家から.zipを貰ってきて動かしています.一応報告はしてみました.

</追記>

ブータブルUSBメモリを作るEtcherを試す

EtcherというブータブルUSBメモリを作るソフトウェアを知ったので試してみました.最近はmkusbを利用していますがこれはLinux用です,Etcherはマルチプラットホームなのも良さそうです.

ダウンロードと念の為ウィルスチェック

$ wget https://resin-production-downloads.s3.amazonaws.com/etcher/1.0.0-beta.15/Etcher-linux-x64.AppImage
$ file Etcher-linux-x64.AppImage
Etcher-linux-x64.AppImage: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.24, BuildID[sha1]=33806643f0ed6abf1f9cbca06043160fe098cd5b, stripped
$ clamscan ./Etcher-linux-x64.AppImage 
./Etcher-linux-x64.AppImage: OK
----------- SCAN SUMMARY -----------
Known viruses: 4867586
Engine version: 0.99.2
Scanned directories: 0
Scanned files: 1
Infected files: 0
Data scanned: 0.00 MB
Data read: 67.12 MB (ratio 0.00:1)
Time: 10.852 sec (0 m 10 s)
$ sha256sum Etcher-linux-x64.AppImage 
ee1eabba9fd0dc6b4d447d328cff54c3fbfff00ef1689abcde02c5654394c6fb  Etcher-linux-x64.AppImage
$ sha512sum Etcher-linux-x64.AppImage 
87632ddd1a4bded54d6da78fd4c5c128ed523b13e00ecc4f9df5ce62a5fec73d95a0765db8d18c7975c5932566315af08acc5488a341513270e4af5b38248b40  Etcher-linux-x64.AppImage

実行権を付けて実行

$ chmod u+x Etcher-linux-x64.AppImage
$ ./Etcher-linux-x64.AppImage

実際に書き込む

起動後,SELECT IMAGEで書き込みたいイメージを選択します.今回はUbuntu16.10b2のイメージを選択肢ました.

20161004_19:10:09-25517

書き込み対象が1つの場合自動的に選択されました.

20161004_19:10:13-28681

SELECT DRIVEChange部分をクリックで書き込み先のドライブの変更が可能です.

20161004_19:10:04-31744

ちなみに右上の歯車マークから設定変更が可能ですが,ここでUnsafe modeを選択するとシステムドライブもドライブの選択肢に出てくるようになります.勿論間違えると上書きされて現在のシステムはなくなるので注意が必要です.

20161004_19:10:21-29726

20161004_20:10:19-30743

20161004_20:10:52-29156

Flashを押して書き込みをはじめると書き込みが始まりプログレスが表示されます.

20161004_19:10:47-726

一旦書き込みが終わると検証が走ります.

20161004_19:10:24-7001

検証後完了です.

20161004_19:10:45-9355

以前はUnetbootinとかを使っていて,最近はmkusbを使っているのですが,これはお手軽でマルチプラットホームなのでこのEtcherは人にも勧めやすいですね. Debian/Ubuntuにはパッケージがないので導入が面倒なのがネックですかね.

mkusb等については以下の辺りを参照してください.

Btrfsでswap fileが作れないことを知らずに嵌まる

ファイルからswapを設定しようとして失敗しました.

$ fallocate -l 500M test
$ /sbin/mkswap test
mkswap: test: insecure permissions 0644, 0600 suggested.
Setting up swapspace version 1, size = 500 MiB (524283904 bytes)
no label, UUID=aaf26c11-4653-40d5-b279-faa7d8c8625d
$ sudo chmod 600 test
$ sudo chown 0.0 test
$ ls -l test
-rw------- 1 root root 524288000 10月  3 07:26 test
$ sudo swapon test
swapon: /home/mk/test: swapon failed: 無効な引数です
$ sudo swapon -v /home/mk/test
swapon: /home/mk/test: found signature [pagesize=4096, signature=swap]
swapon: /home/mk/test: pagesize=4096, swapsize=524288000, devsize=524288000
swapon /home/mk/test
swapon: /home/mk/test: swapon failed: 無効な引数です
$ LANG=C sudo swapon -v /home/mk/test
swapon: /home/mk/test: found signature [pagesize=4096, signature=swap]
swapon: /home/mk/test: pagesize=4096, swapsize=524288000, devsize=524288000
swapon /home/mk/test
swapon: /home/mk/test: swapon failed: Invalid argument

検索するとBtrfsでswap fileがサポートされていないとか.知らなかったorz

性能低下するけどloop deviceを使えばいけるよというワークアラウンドが.

A workaround, albeit with poor performance, is to mount a swap file via a loop device.

試してみます.

$ /sbin/losetup -l
$ sudo /sbin/losetup loop0 ./test
$ /sbin/losetup -l
NAME SIZELIMIT OFFSET AUTOCLEAR RO BACK-FILE DIO
/dev/loop0 0 0 0 0 /home/mk/test 0
$ sudo swapon -v /dev/loop0
swapon: /dev/loop0: found signature [pagesize=4096, signature=swap]
swapon: /dev/loop0: pagesize=4096, swapsize=536870912, devsize=536870912
swapon /dev/loop0
$ /sbin/swapon -s
Filename Type Size Used Priority
/dev/dm-2 partition 16658428 0 -1
/dev/loop0 partition 524284 0 -2

うまく行きました. もとに戻しておきます.

$ sudo swapoff /dev/loop0
$ sudo /sbin/losetup -d /dev/loop0
$ sudo rm ./test

Ubuntu16.10b2でQRCode生成アプリのQreatorを試す

Ubuntu 16.10b2 amd64を最近試しています。 いつも使う感じのアプルケーションをdpkg –set-selectionsで導入したあとUbuntu Softwareを眺めていて良さそうなアプリケーションを導入して試したりしています。

Screenshot from 2016-10-03 01-22-48

そこでQreatorというアプリを見つけました。これは簡単にGUIでQR codeが生成できるアプリケーションです。名刺、位置情報、電話(SMS)、テキスト、URL、Wi-FiのQR codeが生成できるようです。 自分用に似たようなもののweb cgiも作ってあるのですが、便利そうってことで試してみました。

Screenshot from 2016-10-03 00-56-57

$ apt show qreator 
Package: qreator
Version: 13.05.3-2fakesync1
Priority: optional
Section: universe/python
Origin: Ubuntu
Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
Original-Maintainer: Chow Loong Jin <hyperair@debian.org>
Bugs: https://bugs.launchpad.net/ubuntu/+filebug
Installed-Size: 1,303 kB
Depends: python:any (>= 2.6.6-7~), dconf-gsettings-backend | gsettings-backend, python-imaging, python-cairo, python-dbus, python-defer, python-gi, gir1.2-champlain-0.12, gir1.2-clutter-1.0, gir1.2-glib-2.0, gir1.2-gdkpixbuf-2.0, gir1.2-gtk-3.0, gir1.2-gtkchamplain-0.12, gir1.2-gtkclutter-1.0, gir1.2-nmgtk-1.0, gir1.2-networkmanager-1.0, python-qrencode, python-requests, python-vobject, python-xdg
Homepage: https://launchpad.net/qreator
Download-Size: 196 kB
APT-Manual-Installed: yes
APT-Sources: http://jp.archive.ubuntu.com/ubuntu yakkety/universe amd64 Packages
Description: graphical utility for creating QR codes
Qreator enables you to easily create your own QR codes to encode different
types of information in an efficient, compact and cool way.
.
Qreator supports creating the following kinds of QR codes:
- Business card
- Geolocation
- Phone call/SMS
- Text
- URL
- Wi-Fi network

#Debianだとsidにならあるみたい。 * Debian — パッケージ検索結果 — qreator

しかし、起動して情報を入力してもQR codeが表示されません。 バグレポに上がってないかなと探したらありました。

Screenshot from 2016-10-03 00-57-42

python-qrencodeの問題のようです。該当行2行を書き換えてみたところ動くようになりました。

$ diff /tmp/QRCode.py /usr/share/qreator/qreator/QRCode.py
76c76
<         bytearr = array.array('B', self.image.tostring("raw", "BGRA", 0, 1))
-
>         bytearr = array.array('B', self.image.tobytes("raw", "BGRA", 0, 1))
$ diff /tmp/__init__.py /usr/lib/python2.7/dist-packages/qrencode/__init__.py
47c47
<     im = Image.fromstring('L', (size, size), data)
-
>     im = Image.frombytes('L', (size, size), data)

Screenshot from 2016-10-03 01-09-36

とりあえず修正が降りてくるまではPPAを使うと良さそうです。(versionも古いし……)

停電でバックアップが不安なのでlsyncdとNILFS2でバックアップ

先日の台風16号で09/19 23:00頃から09/22 12:45頃まで停電していました……. とりあえずサーバはシャットダウンしてThinkPad X200はバッテリが4本,X220は2本,モバイルバッテリは10000mA x3という感じで停電開始. とりあえず普通に使っていてもX200だけでも3営業日以上は耐えられるはずです.

でも一応NotePCは必須デバイス以外は取り外して輝度を下げてpowertopで省電力モードに.

#powertopについては以下の辺りを参考に.

これで1台ずつ使っていくことに.しかし,不安点がデータのバックアップ. 何時もはワークディレクトリはownCloudで自動バックアップ&デイリーでファイルサーバへのバックアップがされています.しかし停電時はサーバが動いてない&電池の切れたPCから別のPCに作業内容が移行できない.ということでlsyncdを使ってデータをUSBメモリにコピー&ファイルシステムはNILFS2にしてスナップショットも取得できるようにしました.

まずはUSBメモリの用意.普通にNILFS2で作ります.
/dev/sdzのパーティション情報を削除して全領域1パーティションで作成し,NILFS2で初期化して/mntにマウントしてユーザ,グループを自分のものにしています.

$ sudo wipefs -a /dev/sdz
$ sudo fdisk /dev/sdz
Command (m for help): n
Partition type
p   primary (0 primary, 0 extended, 4 free)
e   extended (container for logical partitions)
Select (default p): p
Partition number (1-4, default 1):
First sector (51-7821311, default 51):
Last sector, +sectors or +size{K,M,G,T,P} (51-7821311, default 7821311):
Created a new partition 1 of type 'Linux' and of size 3.7 GiB.
Command (m for help): w
$ sudo mkfs.nilfs2 /dev/sdz1
$ sudo mount /dev/sdz1 /mnt
$ sudo chown `id -u`.`id -g` /mnt
$ sudo chmod 700 /mnt

続いてlsyncdを実行してデータを同期します.lsyncdはinotifyをトリガーに任意のコマンドを実行したり出来ます.一般的にはrsyncでファイルの同期に使います.今回はアドホックにコマンドとして動かしました.同期元同期先はrsyncと同じ書き方だと思うので前もってrsync -avn from toみたいな感じで動作確認しておくと安心です.

$ lsyncd -log all -nodaemon -rsync /home/mk/ownCloud /mnt/ownCloud

これでlsyncdのターゲット以下のファイル,ディレクトリは自動的にUSBメモリにコピーされ,USBメモリの中では自動的にチェックポイントが作成される状態です. 作業の区切りのタイミングで明示的にスナップショットを取るようにしておくと更に安心です.(チェックポイント,スナップショットには何時でもその状態に巻き戻せる.但しチェックポイントは古いものから順に自動的に削除される.スナップショットは自動削除されない)

マシンを切り替えるときにはlsyncdを止めて念の為rsyncをdry runして同期状況を確認しておいて,新しいマシンでUSBメモリからSSDにrsyncしてlsyncdを動かすという感じでした.

関東在住時の計画停電のときは計画的だし時間もずれないしで案外困りませんでした(仕事は大変だったけど).でも念の為NotePCの大容量バッテリは買い増しして持ち歩いていました.(今回のバッテリの一つもそれ)
↓はその頃の発表スライド

ちなみに停電から14,5時間で携帯基地局のバッテリも尽きたようで完全にオフラインになってしまいました.NILFS2は大抵標準では導入されていないし手元ではGit管理もしているのでNILFS2は使わなくても良かったかなと後で思いました.

復旧時の残容量はNotePC が1.5本/モバイルバッテリが50% x2という感じ未だ行けるなという感じでした.でもネットワークが繋がっていたらもっと利用していたでしょう.

しかしこの辺は雷やら強風やらでよく停電になります.大抵は携帯基地局が落ちるまでには復旧するのですが,台風だと今回のように長い停電に.でも復旧状況を停電情報サイトで確認していると深夜にもステータスが変わっていて24時間体制で復旧してるのかと驚きました.九州電力の関係者のみなんさんありがとうございます_o_
(でも昼頃復旧->本日中->本日未明復旧とステータスがずれ込んでいくとはちょっとつらかったです……)

ついでに今回役にたったものを

  • PETZLのワイヤ式ヘッドライト
    手元のは初代かその次くらいの古いもので暗いけど便利でした.

  • モバイルバッテリー
    Cheerox2に秋葉原で買った謎バッテリーの3本を使っていました.基地局が落ちるまではスマホに給電.基地局が落ちてからはiPad/Kobo/Raspberry Piに給電していました.

  • Raspberry Pi B+ とAdafruit3.5インチ液晶
    USB稼働の液晶モニタもあるのですがバッテリ消費量的にこいつのほうが食わない感じなのでちっこいですがこれで作業したりも.でもNotePCのバッテリが切れなかったのでテスト程度.

    Adafruit PiTFT – 320×240 2.8 TFT+Touchscreen for Raspberry Pi ID: 1601 – $34.95 : Adafruit Industries, Unique & fun DIY electronics and kits

  • エネループ
    自己放電の少ない充電式乾電池です.自己放電が少ないので充電しておいておけば何時でも使えるのが良いです.電気をあまり食わないものはこいつで. ちなみに充電器は単三・単四 ニッケル水素充電池対応 放電機能 USB充電ポート搭載 充電器 (16本用)の通信販売【上海問屋】 | 上海問屋を主に使っています.

  • ユニフレームガスバーナー
    一般的なイワタニとかのタイプのカセットコンロガスが使える(非推奨)なガスバーナーです.山向けのガスやアルコールに比べて大分ランニングコストが安く付きます.低地のみならこれで十分.(手持ちのはゴトクの小さい恐らく古いモデルのものもっと安かったし)

ubuntuでpipが見当たらない状態を復旧

鹿児島らぐのオフ会で @seoponさんからpipでjanome入れてみましょうって時に,以前sudo hogehogeしてからpip使えなくなっちゃって方が. 見てみるとpkgは入っているけどpipコマンド自体がいなくなってる感じみたいでした.恐らくオペミスで消したかパスのないところに移動しちゃった? (以下は多分こんなだったというのを再現.)

$ pip
プログラム 'pip' はまだインストールされていません。 次のように入力することでインストールできます:
sudo apt install python-pip
$ sudo apt install python-pip
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています
状態情報を読み取っています... 完了
python-pip はすでに最新バージョン (8.1.1-2ubuntu0.2) です。
アップグレード: 0 個、新規インストール: 0 個、削除: 0 個、保留: 0 個。
$ which pip
$ dpkg -L python-pip | grep \/pip$
/usr/bin/pip
/usr/lib/python2.7/dist-packages/pip
$ ls -l /usr/bin/pip
ls: '/usr/bin/pip' にアクセスできません: そのようなファイルやディレクトリはありません

pkgをreinstallして解決しました.

$ sudo apt install --reinstall python-pip
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています
状態情報を読み取っています... 完了
アップグレード: 0 個、新規インストール: 0 個、再インストール: 1 個、削除: 0 個、保留: 0 個。
144 kB のアーカイブを取得する必要があります。
この操作後に追加で 0 B のディスク容量が消費されます。
取得:1 http://jp.archive.ubuntu.com/ubuntu xenial-updates/universe amd64 python-pip all 8.1.1-2ubuntu0.2 [144 kB]
144 kB を 0秒 で取得しました (571 kB/s)
(データベースを読み込んでいます ... 現在 902816 個のファイルとディレクトリがインストールされています。)
.../python-pip_8.1.1-2ubuntu0.2_all.deb を展開する準備をしています ...
python-pip (8.1.1-2ubuntu0.2) で (8.1.1-2ubuntu0.2 に) 上書き展開しています ...
man-db (2.7.5-1) のトリガを処理しています ...
python-pip (8.1.1-2ubuntu0.2) を設定しています ...
mk@x201s:~$ !ls
ls -l /usr/bin/pip
-rwxr-xr-x 1 root root 292  8月 12 06:59 /usr/bin/pip
$ which pip
/usr/bin/pip
$ pip -V
pip 8.1.2 from /usr/local/lib/python2.7/dist-packages (python 2.7)

とりあえず.