Raspberry Pi Zero WにLEDEをインストールして自分専用の携帯用WiFiアクセスポイントにする
※この記事の投稿時点ではLEDEを選択していますが、2018年にLEDEとOpenWrtはマージされたので、これ以降の選択肢はLEDEではなくOpenWrtとなります。最新のOpenWrtでも基本的な導入手順は同じなので、参考程度のお読みください。
Raspberry PI Zero W が日本国内でも発売となりましたね。とはいえ、スイッチサイエンスやKSYの販売分は品薄が続いているようで、当分は入手が難しい様子。
自分はというと、PIMORONI から Zero W + Adaptors + Pibow Zero W のセットを買ってみました。この通販サイトは在庫はそれなりに潤沢なようです。
Raspberry Pi Zero Wshop.pimoroni.com
手元に届いたのは日本の技適のマークや番号がシルク印刷されているので各種法令上の問題は多分無いと認識しています。
さて、Raspberry Pi Zero W を入手した目的なのですが、「出張時に持ち運びが容易なWiFiアクセス」にしようと考えています。この構成を Raspbian で手作業でいろいろやってもよいのですけど、簡単に設定できる管理画面が欲しいので LEDE でやることにします。
なお LEDE というのは openwrt からフォークしたプロジェクトです。openwrt は Pi 3 や Zero W 向けのインストールイメージが現時点 (2017/08時点) では存在しないのですけど、LEDE は Pi 3 や Pi Zero W 向けのインストールイメージが公開されているので、Raspberry Pi で使う場合は LEDE のほうが便利なのです。
準備物
必要なもの
- Raspberry Pi Zero W
- HDMIアダプタ
- USBキーボード
- microUSB給電ケーブル
- USB-LANアダプタ
USBキーボードとUSB-LANアダプタを除けばこういうセット品が便利ですけど、若干割高な気がしなくもないです。この金額にもうちょい足せばRaspberry Pi 3 が買えてしまいます。品薄感がもうちょっと減ればもうすこしお手頃な価格になるのかなあ、とも思うのですが、当面は厳しいんでしょうねえ。
あったほうがよいもの
- USB-HUB
USB-HUB はあったほうがよいです。USBキーボードとUSB-LANアダプタの両方を同時に使うためには絶対に必須。
これが無い場合はコンソール操作のときにキーボードとLANを同時に使えないのでとても面倒なことになります。
今回の購入先である PIMORONI で販売されているような 3ポートUSBハブ + Ethernet アダプタがあると大変便利なのですが、そうなると全部入りな RasPi3 の方が良いかもしれませんから判断は微妙です。。。
Three Port USB Hub with Ethernet - microB connectorshop.pimoroni.com
作業手順
LEDE は Ethernet + WiFi なRaspberry Pi 3 に導入するのはとてもカンタンなのですが、Pi Zero W は Ethernet を含まないのでセットアップのハードルが少々上がります。そこで、作業の手間を省くために uci コマンドを活用することにします。
LEDEは通常はWebの管理画面で設定を行いますが、USB-HUBが無い場合や手持ちのUSB-LANアダプタが認識されない場合はシェル上で uci コマンドを用いて WiFi ルータの機能を有効化するのが一番カンタンなのですよ。
サマリ
- Raspberry Pi Zero W 向けの LEDE イメージの入手
- 使用するUSB-LANアダプタ用の追加ドライバの入手と導入
- uci コマンドによる設定の投入
- 動作確認
Raspberry Pi Zero W 向けの LEDE イメージの入手
下記のページによると、Pi Zero W 向けの LEDE イメージは snapshot のものがある、ということになっています。
https://lede-project.org/toh/hwdata/raspberrypifoundation/raspberrypifoundation_raspberry_pi_zero_w
しかし実際に探してみると、snapshotの他にも17.01.4 ベースのイメージが下記の場所にありました。(2017年12月時点)
https://downloads.lede-project.org/releases/17.01.4/targets/brcm2708/bcm2708/
このバージョンは KRACKs 対応パッチが当たっているので安心して使えます。
ここから lede-17.01.4-brcm2708-bcm2708-rpi-ext4-sdcard.img.gz というファイルをダウンロードして microSDHC に焼いておきます。
焼く手順は通常どおりに dd ですから、この説明は省略します。
使用するUSB-LANアダプタ用の追加ドライバの入手と導入
LEDE のイメージには、私が持っているLANアダプタのドライバは含まれていませんでした。そこで、USB-LAN アダプタの動作に必要なドライバを予め microSDHC に入れておくことにします。そうすれば、LEDE の起動後にコンソールからの操作でUSB-LAN向けのドライバを導入可能になります。
LEDE 17.01.4 向けの Pi Zero W で利用できるドライバはここからダウンロードできます。
Index of /releases/17.01.4/targets/brcm2708/bcm2708/packages/
USB-LAN アダプタを扱うための必須パッケージはここらへんの6つ。
https://downloads.lede-project.org/releases/17.01.4/targets/brcm2708/bcm2708/packages/kmod-libphy_4.4.92-1_arm_arm1176jzf-s_vfp.ipk https://downloads.lede-project.org/releases/17.01.4/targets/brcm2708/bcm2708/packages/kmod-mii_4.4.92-1_arm_arm1176jzf-s_vfp.ipk https://downloads.lede-project.org/releases/17.01.4/targets/brcm2708/bcm2708/packages/kmod-usb-net_4.4.92-1_arm_arm1176jzf-s_vfp.ipk http://downloads.lede-project.org/releases/17.01.4/packages/arm_arm1176jzf-s_vfp/base/usbutils_007-7_arm_arm1176jzf-s_vfp.ipk http://downloads.lede-project.org/releases/17.01.4/targets/brcm2708/bcm2708/packages/librt_1.1.16-1_arm_arm1176jzf-s_vfp.ipk http://downloads.lede-project.org/releases/17.01.4/packages/arm_arm1176jzf-s_vfp/base/libusb-1.0_1.0.21-1_arm_arm1176jzf-s_vfp.ipk
さらにUSB-LANアダプタ固有のパッケージをインストールします。PIMORONI の3ポートUSBハブ+LANアダプタの場合はRTL8152のドライバを用意します。
https://downloads.lede-project.org/releases/17.01.4/targets/brcm2708/bcm2708/packages/kmod-usb-net-rtl8152_4.4.92-1_arm_arm1176jzf-s_vfp.ipk
また、自分の手元にあったUSB-LANアダプタ2種類のドライバは下記の通りでしたので、自分の場合はこれも入れておきます。
https://downloads.lede-project.org/releases/17.01.4/targets/brcm2708/bcm2708/packages/kmod-usb-net-asix-ax88179_4.4.92-1_arm_arm1176jzf-s_vfp.ipk https://downloads.lede-project.org/releases/17.01.4/targets/brcm2708/bcm2708/packages/kmod-usb-net-pegasus_4.4.92-1_arm_arm1176jzf-s_vfp.ipk
なお、自分が所有しているLANアダプタのドライバがよくわからない、という方は、最低限必要な6種類をインストールの後に lsusb コマンドで認識されているデバイスを表示させてみると良いでしょう。以下は PIMORONI の3ポートUSBに Microsoft のタッチパッド付きワイヤレスキーボードを接続している状態です。
root@LEDE:~# lsusb Bus 001 Device 005: ID 0bda:8152 Realtek Semiconductor Corp. RTL8152 Fast Ethernet Adapter Bus 001 Device 003: ID 045e:0801 Microsoft Corp. Bus 001 Device 002: ID 1a40:0101 Terminus Technology Inc. Hub Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
この出力から、PIMONORI のデバイスは Realtek RTL8152 を使っていることがわかります。この情報で Google 検索するなどして、適切なドライバを探します。
必要なファイルがそろったら LEDE を焼いたあとの microSDHC に転送しておきます。このファイルは LEDE では /boot 上にあります。
なお、microSDHC には、本記事の後半に記載の「uci を使った設定投入用のスクリプト」も入れておいてください。これをこの時点で入れておくと、いろんな意味で手間が省けるはずです。
さて、LEDE を Pi Zero W で起動したら、上記のファイルをインストールします。ファイルは /boot にあるはずです。これを以下のようにインストールします。
cd /boot opkg install *.ipk
インストールすると、こんなメッセージが出るかもしれませんが、これは無視して構いません。他のエラーの場合はパッケージが足りないために出ているはずですから不足するパッケージを追加してインストールしてください。
Collected errors: * pkg_run_script: package "kmod-usb-net" postinst script returned status 255. * opkg_configure: kmod-usb-net.postinst returned 255.
このエラーメッセージが出ないようにするには、下記記事に記載の対処を行います。 pslabo.hatenablog.com
インストールできたら LEDE を reboot します。この reboot は uci コマンド実行の前提となる環境を作るために必須です。
uci コマンドによる設定の投入
LEDE はブラウザからの管理画面で設定できるのですが、Pi Zero W をアクセスポイント化するための設定を行うのは意外にめんどくさいので、ここはサクッとコマンドで設定投入するのがよいだろうと思います。
手元の環境でGUIからの設定を行う前と後で設定内容が変わった箇所を抽出してみると、こんな感じになっておりました。
#!/bin/sh uci set dhcp.lan.ra_management='1' uci delete dropbear.@dropbear[0].RootPasswordAuth='on' uci set network.wan.ifname='eth0' uci set network.wan.proto='dhcp' uci set network.wan=interface uci delete network.lan.ifname='wlan0' uci set network.lan._orig_bridge='true' uci set network.lan._orig_ifname='wlan0 wlan0' uci set network.lan.ipaddr='192.168.4.1' uci set system.@system[0].conloglevel='8' uci set system.@system[0].cronloglevel='8' uci set system.@system[0].log_proto='udp' uci set wireless.default_radio0.encryption='psk2' uci delete wireless.radio0.disabled='1' uci set wireless.radio0.country='JP' uci set wireless.default_radio0.ssid='[設定するSSID名]' uci set wireless.default_radio0.key='[WPA-PSKのパスフレーズ]'
これを microSDHC の /boot にスクリプトとして保存しておき、LEDE のコンソールから実行すれば一通りの設定が完了します。SSID名やパスフレーズは適切に設定しておいてください。
またこの設定では LAN 側 (WiFi側) のIPアドレスが 192.168.4.1 になっています。これも適切に変更しておいてください。
実行した時にエラーメッセージが2つ出る場合があるかもしれませんが、特に問題ありません。(修正の手間に対して得るものがないので放置しています。。。)
設定したら uci commit して reboot してみてください。
動作確認
USB-LANアダプタを接続した状態で、設定したSSIDに接続してインターネット通信できていれば基本的にはOKです。
ただしこの状態は LEDE の管理画面のパスワード設定を行っていない状態ですので、パスワードはかならず設定してください。
また、WAN側には管理画面の口が開かないように dropbear の設定を lan に限定しておきましょう。
その他の設定調整
管理画面を日本語化したい場合は luci-i18n-base-ja を追加した上で System の設定から Language を日本語に変更します。
GoogeDrive で特定のファイルを期間限定公開する方法を考える
GoogleDriveで何かのファイルを共有するときに、期間限定で共有したい場合があると思うんです。
しかしGoogleDriveの標準機能では共有期間を設定する方法が無かったと思います。
そこで、Googel Apps Script で出来ないかと思ってしらべてみました。
そしたら File.setSharing() という関数を見つけました。
Class File | Apps Script | Google Developers
これをこんなふうに使えば、特定のファイルの共有設定を off にできます。
function myFunction() { var GoogleDriveFileID="[ファイルのID]"; var GoogleDriveFile=DriveApp.getFileById(GoogleDriveFileID); GoogleDriveFile.setSharing(DriveApp.Access.PRIVATE, DriveApp.Permission.NONE); }
あとはこれを共有期間終了後に実行してやればよいわけです。
ただし個別のファイル毎にこういう関数を作るのは無駄な作業となりますので、Google Spreadsheet でファイル一覧と共有期限を記入した台帳を作成し、それをトリガーで1日1回チェックして期限が過ぎているものを共有停止にするように実装すればよさげです。
ここらへんの実装は別の機会に。
コマンドプロンプトの新しいカラースキームを作業環境に取り入れてみる
Windows10 Fall Creators Update からは、コマンドプロンプトの配色が変わるようですね。
いままでの配色は青系の色が見づらくてイマイチだと思っていたのですが、もともとの配色はブラウン管向けだったそうです。液晶とブラウン管では色特性が違うので、そのままの配色ではどうしても見やすさが違うわけですが、新しい配色では見やすくなるようです。ただし既存環境からのアップデートでは新しいカラースキームが導入されないそうです。また仮に導入されたとしても結局は来月以降の Fall Creators Update の話です。従って現在利用中の Creators Update には全く関係ありません。
そこで、手元の Creators Update に新しいカラースキームを適用する設定を導入してみることにします。
コンソールのカラースキームは HKEY_CURRENT_USER\Console にありますので、これを上書きしてやればOKです。
ただし手作業でやるのはめんどくさいです。特に複数の環境に同じ設定を適用したい場合には、相当に厳しい。なので reg ファイルをこんなふうに作ってみました。これなら複数の環境にも容易に適用できます。
Windows Registry Editor Version 5.00 [HKEY_CURRENT_USER\Console] "ColorTable00"=dword:000c0c0c "ColorTable01"=dword:00da3700 "ColorTable02"=dword:000ea113 "ColorTable03"=dword:00dd963a "ColorTable04"=dword:001f0fc5 "ColorTable05"=dword:00981788 "ColorTable06"=dword:00009cc1 "ColorTable07"=dword:00cccccc "ColorTable08"=dword:00767676 "ColorTable09"=dword:00ff783b "ColorTable10"=dword:000cc616 "ColorTable11"=dword:00d6d661 "ColorTable12"=dword:005648e7 "ColorTable13"=dword:009e00b4 "ColorTable14"=dword:00a5f1f9 "ColorTable15"=dword:00f2f2f2
あとはこれを newcolorscheme.reg のような名前で保存してインポート(ダブルクリックとか)をすればOKです。
なお、カラースキームのカスタマイズについては2点の注意事項があります。
NextTrain形式の時刻表データを1行1情報に変換してみる
朝の通勤時にできるだけ混雑した電車を避けるために、最寄駅で乗る電車の編成や時刻を把握しておくことはとても大切なことかもしれません。
そして、最寄駅の上流側に車両基地があるようなケースでは時間帯により「途中駅からの始発電車」というラッキーなパターンに乗れる可能性があります。もしも上流側2駅くらいの範囲で始発で出る電車があるならば、その電車は確実に空いているでしょうから、それを積極的に狙いたくなります。しかしそのような分析に使える時刻表はなかなか見当たりません。
駅.Lockyのデータが使えないだろうか?
そんなときにふと思い出したのは駅.lockyという時刻表アプリ。このアプリでは時刻表データが利用者のボランティアベースでメンテナンスされているのですが、Q&Aの中に以下の案内があります。
■ 駅.Lockyで収集された時刻表データを他の時刻表アプリに入れて利用しても良いですか? 個人利用に限り、他のアプリで利用することができます。
というわけで、今回のケースも個人利用なのでOKの範囲と言える、と、多分思います。。。
さて、駅.Lockyの時刻表データは、NextTrain という形式が用いられています。この形式は NextTrain というフリーソフトウェアで用いられていたのですが、フォーマットがシンプルなことから時刻表表示アプリの多くでデファクトスタンダード的に使われています。
そして実際のデータ形式は駅.Lockyの時刻表リストのページで確認できますが、ここではその形式を1行1情報の形式に変換してみることにします。
駅.Lockyのデータの中には、始発電車が明示されているものがありますので、そういうものを使えば、自分の最寄り駅、その上流側の駅のデータを1行1情報で比較できます。すると空いている電車の予測がつけやすくなります。
作ったスクリプト
gawk でこんなのを書いています。macOS の場合は brew などで gawk をインストールした上で、1行目の記述を #!/usr/local/bin/gawk -f
のように書き換える必要があります。
#!/usr/bin/gawk -f # # nexttrain 形式のデータを # 1行1情報に変換するスクリプト # # 例えば 駅.Locky の以下のデータを使うと... # http://eki.locky.jp/site/list?pageid=tbl&code=237978 # # こんな出力が得られる # [MON][TUE][WED][THU][FRI] # 新大阪・博多方面(平日) # 06 06:00 ⑭のぞみ1号博多 # 06 06:16 ⑮のぞみ3号博多 # 06 06:20 ⑰のぞみ293号新大阪◆運転日注意 # 06 06:26 ⑯ひかり501号新大阪 # 06 06:30 ⑱のぞみ5号博多 # 06 06:33 ⑲こだま631号名古屋 # 06 06:43 ⑭のぞみ201号新大阪 # 06 06:50 ⑱のぞみ7号博多 # 06 06:56 ⑰こだま633号新大阪 BEGIN { # フィールドの区切りをデフォルトから変える FS="[:;\t ]*" destination_pattern=0 } # 行き先や種別(各停、急行)から # 置換用のマッピングを作る。 $1 ~ /^[a-zA-Z]/ { destination_char[destination_pattern] = $1 destination_full[destination_pattern] = $2 destination_short[destination_pattern] = $3 destination_color[destination_pattern] = $4 destination_pattern++ next } # 駅名情報や曜日情報はそのまま出す $1 ~ /^[#\[]/ { print next } # 時刻表情報を1行1情報に変換して出力する { hour=$1 # print $0 # 行き先 for ( i = 0 ; i < destination_pattern ; i++ ) { gsub( destination_char[i], destination_full[i], $0 ) } # print $0 for ( i = 2 ; i <= NF ; i++ ) { match($i, /([a-zA-Z]+?)([0-9]+?)/, timedetail) traintype=timedetail[1] min =substr( $i, match($i,/..$/) ) dest=substr( $i, 1, length($i) - length(min)) # printf "%d:%d ", i,NF printf "%02d\t%02d:%02d\t%s\n", hour, hour,min, dest } next }
mitmproxy のプロキシ用ポートを変える
mitmproxy はデフォルトで 8080/TCP を使いますが、このポートはWeb系の様々なツールが標準的に使おうとしたりしますよね。
手元の環境では、Delphi/C++Builderで中間サーバを実装するためのフレームワークである RAD Server (EMS) の開発サーバがデフォルトで 8080/TCP を使っています。
そうするとツールを複数併用したい場合にツールの取り合いになって楽しくないけど、mitmproxy は補助ツールなわけすから、mitmproxy の使用するポートを変えることにします。
さて、手元の環境では Windows 向けの mitmweb を使っているので、この話は mitmweb で検証しました。
パラメータ
プロキシ用のポートは --port
で変更できます。
また mitmweb の Web 用ポートを変更したい場合は --web-port
で変更できます。
たとえば以下のように実行すれば、10080と10081を使うようにできます。
C:\mitmproxy-2.0.2-windows>mitmweb --port 10080 --web-port 10081 Proxy server listening at http://0.0.0.0:10080/ Web server listening at http://127.0.0.1:10081/
mitmdump でもこの通り。
C:\mitmproxy-2.0.2-windows>mitmdump.exe --port 10080 Proxy server listening at http://0.0.0.0:10080
InterBaseデータベースのDB容量、BLOBサイズはデータベース作成時のページサイズで決まるらしい
InterBaseの各種データ量制限を調べていて意外に手間取ったのでメモとして残す。
ネタの出典は InterBase2017 の OpGuide [http://docs.embarcadero.com/products/interbase/IB2017/ OpGuide.pdf]
ページサイズ | データベース上限 | テーブル上限 | BLOB上限 |
---|---|---|---|
1KB | 2TB | 2TB | 64MB |
2KB | 4TB | 4TB | 512MB |
4KB | 8TB | 8TB | 4GB |
8KB | 16TB | 16TB | 32GB |
16KB | 32TB | 32TB | 256GB |
デフォルトのページサイズは4KBだけど、通常はこれで充分だろう。
なお、最初は日本語版の OpGuide を調べたけど記述が微妙に抜けていたりするので、最終的には英語版を見たほうがよさげ。
また docwiki の情報も英語版、日本語版でそれぞれ記述が怪しかったりする場合があるので、そのへんがちょいと困る。
しかしまあ、モバイルデバイス組み込み、デスクトップ、サーバのいずれも同一データファイルで利用できるのは案外便利なのですよ。商用サポートも受けられるわけだし。
FireDACで大量のデータをデータベースに一括登録する
ちょいと調べたのでメモ。
配列DMLを用いるか、またはコマンドバッチを使う方法があるようだ。
配列DMLはクエリのパラメータに配列を使うので、同じ形式のクエリを大量に実行する場合に使える。
http://docwiki.embarcadero.com/RADStudio/Tokyo/ja/配列DMLコマンドのパフォーマンス(FireDAC)
http://docwiki.embarcadero.com/RADStudio/Tokyo/ja/配列_DML(FireDAC)
DBが配列DMLに対応していない場合はFireDACがエミュレーションしてくれるので、接続先のデータベースの仕様によらず使える。ただしエミュレーションの場合は速度は期待できないはず。
コマンドバッチは同じクエリでも異なるクエリでも良さげだけれど、個々のクエリを ; でターミネートすべきかどうかはDBによって異なることが注意点かも。
http://docwiki.embarcadero.com/RADStudio/Tokyo/ja/コマンド_バッチ(FireDAC)