既定プロファイルを作成する際に必要な応答ファイル(unattend.xml)を調達する

既定プロファイル、デフォルトプロファイルは、システムにユーザーが初めてログオンする際に適用される、各種設定のテンプレートとなるものであり、XP時代は Documents and Settings\Defaults フォルダ内に格納されていました。

このため、当時は当該フォルダを触れば自由にカスタマイズを行うことができましたが、ご存じの通り、Vista以降のOSで既定プロファイルを触ろうとすると、

  1. Administratorアカウントで編集作業を行い
  2. Sysprep コマンドに応答ファイルを食べさせて一般化

というより複雑な手順を踏む必要があります。

が、Sysprepコマンドで一般化(generalize)を行う際に必要な応答ファイル(unattend.xml)を作成するには WAIK を使いましょう、というのが公式見解になっており、その際にインストールディスクが必要になりますが、

  • 余程大規模な導入でなければOEM版のWindowsを選択するケースが多い
  • OEM版だと、リカバリディスクと称して配布されるディスクはネイティブなOSが格納されたインストールディスクではない場合が多い(WIMでHDDイメージを固めただけ、とか)
  • あるいは、HDDの隠し領域にリカバリ領域が設定されており、通常ユーザーがアクセスできるものではないケースも多々ある

という矛盾があり、八方ふさがりになっています。

というわけで、Windows7でDefaultプロファイルの作成 - kenmituoの日記から拝借しつつ Win7 向けに書き換えた、最低限 CopyProfile に必要な応答ファイルはこちら。なお、generalize には認証回数を消費するという罠があるので、 SkipRearm もつけています。

厄介なのが応答ファイル側でアーキテクチャx86/amd64)を明示する必要があることと、Vistaと7/8で同じ機能でもComponent名が変更になっているケースが多々ある*1ことで、ここは特に注意が必要です。

いずれにしても publicKeyToken は変化ないように思うので(それもそれで変な話ですが)、 processorArchitecture だけに注意すればいいかなと思いますが…。

<?xml version="1.0" encoding="utf-8"?>
<unattend xmlns="urn:schemas-microsoft-com:unattend">
  <settings pass="specialize">
    <component name="Microsoft-Windows-Shell-Setup" processorArchitecture="x86" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
      <CopyProfile>true</CopyProfile>
    </component>
  </settings>
  <settings pass="generalize">
    <component name="Microsoft-Windows-Security-SPP" processorArchitecture="x86" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
      <SkipRearm>1</SkipRearm>
    </component>
  </settings>
</unattend>

*1:たとえば、 SkipRearm も Vista では Microsoft-Windows-Security-Licensing-SLC だけど、 7/8 では Microsoft-Windows-Security-SPP とか

GL09PをUnlockしてみた

たまたまGL09Pが手に入ったので、価格.comの口コミ上で報告のあったdc-unlocker を使ったSIM Lock解除を実際に試してみました。費用は 7 credits(=€7、最近のレートで大体1000円くらい)。

結果から言えば、サクッとアンロックできてしまいます。注意点は、作業時に dc-unlocker からの操作で端末をデバッグモードのような状態に持っていく必要がありますが、 Windows 8 ではこの状態のドライバ(Diagnostic Port のドライバ)を読み込むことができないため*1、Win 7(もしくはVista)で作業する必要があります。

一度SIM Lockを解除してしまえば、APN 設定を行って以前の Pocket Wifi シリーズのような形で使用することができます。APNの設定画面上ではEmobileの番号(A番号)とSoftBankの番号(B番号)のそれぞれについて設定を行うことができますが、単一番号しかもたないSIMではB番号側の設定が適用されるようです*2

ただ、この端末は、

FDD-LTE
Band 3
TDD-LTE
AXGP(Band 41 で規定された周波数帯のうち、2.5 GHz帯のみ
UMTS
Band 1/5/9/11

という割と中途半端Softbank/Emobile網での使用にほぼ特化した設計になっています。

国内だと、FDD-LTEでBand 3展開をしているのはEmobileと東名阪地域におけるdocomoのみであり、またAXGPに繋ぐにはWCPのMVNOであるSoftbankか東海コミュニケーションズしかなく、それより高周波側にはそもそもサーチに行かない、という状況です。

今更W-CDMAルーター兼モバイルバッテリーとして活躍するしか能がないのは残念な感じですので、もうちょっとまともな使用法を考えてみましょう。

接続帯域固定

この端末は他のモバイルルーター同様、Web UIから設定を行う方式になっています。が、なぜかCSS/スタイルシートで設定項目が多数隠されています(display: noneになっている要素が多数ある)。

ですので、Firebug を使うなどして隠しエレメントを表示させると、3G/4G固定項目があったり、標準設定のAPN接続用ID/パスワードを抜き取ることができたりします。

また、表示画面は JQuery を駆使した使いにくいいい感じに表示されたりする今風のUIですが、実際には設定項目は PC 用の設定ページにログイン後、 HTTP Get で設定することも可能です。

4G固定
http://192.168.128.1/goform/goform_set_cmd_process?isTest=false&goformId=SET_BEARER_PREFERENCE&BearerPreference=Only_LTE
3G固定
http://192.168.128.1/goform/goform_set_cmd_process?isTest=false&goformId=SET_BEARER_PREFERENCE&BearerPreference=Only_WCDMA

という感じ(ホストアドレスは環境に応じて変えてください)。

docomoのSIMで使う

東名阪地域であれば、docomoが必死でLTE 1.8GHz帯/Band3の充実に努めているため、割とよく電波が入ります。壊滅的な Xi 2.1GHz帯/Band1に比べれば混雑度合いは随分マシですし、端末が UE Category 4 対応機でもあるため、条件が良ければ理論値 150MBps に迫ることも可能でしょう(Wifi 側が 2.4GHz 帯オンリーの 11n で Max 150MBps ですのでお察しではありますが)。

ただ、東名阪エリア以外の地域では、使えるバンドが UMTS Band1 のみとなってしまい、FOMAプラスエリア(UMTS Band 6/19)には非対応であるため、郊外エリアでは絶望的な状況になるものと思われます。Emobile機ですので UMTS Band9 にも対応していますが、それも結局東名阪限定じゃん、という話。

なお、本機でISP各社が提供しているXi向けAPNを使用する場合、やはりXiのみ接続可能で、3G Fallbackはできないので注意が必要です。潔くmoperaを使いましょう。

SoftBankのSIMで使う

各所で報告がある通り、 iPhone 5 以降のLTE SIM/APNを使えば AXGP/UltraSpeed 網にも接続可能という話があります。最近であれば iPhone 5s/5c が格安でばらまかれており入手は容易ですし、何より月額料金が比較的安価に済む、というメリットがあります。

EmobileSoftBankに買収されて以降、残念ながらEmobileは草刈り場となってしまった感があり、SoftBankユーザーであればEmobile網に乗り込むことが可能となっているため、正直Emobileを専用で契約するメリットが薄れてしまっています。

残念ながら本機はLTE Band1には非対応なので、SoftBankが本腰を入れている4G LTE網には繋げませんが、それでも jpspir/sirobit なSIMで試すと、4G/3Gともにpanda-world.ne.jpなアドレスで外界に繋ぐことができることを確認できました(蛇足ですが、自己責任で。

KDDI

技適の通り、KDDI/LTEのSIMを刺しても、Wimax2+での接続はおろか、電波すら掴みませんでした*3

本機はエリア圏外(Out of service)とサービス圏外(No service)を区別するのですが、エリア圏外表示であればそもそも全バンドで掴めそうな電波が飛んでいない、ということがわかるものの、サービス圏外表示だと電波を掴んではいるけれど網登録ができていないだけなのか、SIMカードに対応する電波を掴んでいないだけなのかの判別が付かず、WiMAX2+エリア圏内で KDDI/au の SIM を挿入した状態では No Service 表示だったので、もしかしたらいけるかなと思ったけどやっぱり駄目でした。まぁ掴んだら掴んだで、どう考えても技適的にはアウトですしね…。

モデムチップはQualcomm製ですし、BandもAXGPと同じグループ(B41)ですので、例の何かでごにょごにょすればあるいは、という気がしなくもないのですが、明らかにアウトなので止めておきましょう。

端末単体の使い道としてはこんなところでしょうか。

付属SIMの使い道

GL09P に付与されるSIMカードは、Emobileの番号(A番号)とSoftBankの番号(B番号)の両方が入ったDual number SIMになっています。

単一番号でMVNOローミング的な処理をしてくれると有り難いのですが、まぁ契約者数だとかローミング設定だとかという大人の事情があるのでしょう、各社網に乗り入れる際に番号を使い分けるようになっています。

あいにく、単一番号が前提の通常スマートフォンなどではSoftBank側のB番号が優先的に認識されてしまうようで*4Emobile網への接続が絶望的になっています。本来Dual Number SIM自体はそう珍しいものではなく、中国など複数の接続規格が乱立している場合には、各々の番号を持たせたSIMを発行しておいて両規格対応の端末側で切り替える、ということは普通に行われています。ただ、その際にはツールキットも併せて提供されるのが一般的であり、今回のように端末側で触れる部分がない、というのはイレギュラーと言っても過言ではないと思います。

で、SoftBankのB番号ですが、GL09Pから引っこ抜いたAPN情報(axgpdata.softbank.ne.jp)をもとにNexus5でLTE B1に繋ごうとしても、接続できません*5。GL09PはSoftBank網だとAXGPもしくはUltraSpeed(UMTS Band 11)への接続のみ可能になっていることから、網側で何らかの制限を行っているものと考えられます。

ただ、UltraSpeed端末である007zでは接続できた、という話もあるようなので、もしかしたらそこまでシビアな制限、たとえばIMEIによる接続制限などはかかっていないのかもしれません。ですので、例えば301FではAXGP網のみ接続可能、とかいう話もある、かも?

結論

真面目に使いたいなら、値崩れした白ROM買ってきてiPhoneのSIMを刺して使うのが一番良さげ。

正直端末としての出来はそこまで酷評するレベルではないように思いますが、対応バンド設計がキャリア展開と密接すぎて再利用性が悪いことを考えると、正札で契約された方はご愁傷様ですね、という感想を持ってしまうのも確かです。また、エリア展開についても

  • AXGPwillcom基地局をベースに展開されていることは有名な話
  • バックアップとなるべきEmobileもエリア展開は都市部中心、DC-HSDPA の帯域を削ってLTEに振り替え中
  • SoftBank 3G も Band 1(IMTバンド)、8(プラチナバンド)ともに非対応であり、悪名高い Ultra Speed (Band 11)しか選択肢がない

という感じで、地方部ではまず役に立たないものと思われます(その代わり、山手線近辺はアレですが、大都市圏では4G固定でもあまりストレスを感じずに使えました)。

みんな薄々感づいているでしょうが、wifiセット割の親回線として使うのが譲歩できる限界でしょう。ちらほら見かける本体一括ゼロ円で契約できれば、家族でソフトバンク系のスマホ回線を二回線持っていればほぼ実質タダになるわけで、それ以外で買うのは、今回のように玩具として買う、というようなレアケースでもなければ割と博打だと思った方がよいでしょう。

また、光ファイバーなどの有線契約を解約してこれに一本化しよう、とかいうアフィリエイトサイトのようなものもたまに見かけますが、大枚をはたいて愚にもつかないようなことをするのは、止めておいた方が賢明でしょう。

そもそも無線キャリアで富豪的なネットワークの使い方をするのは愚か以外何物でもないわけで、何のためにキャリアが死に物狂いでオフロード戦略練ってると思ってるんだという話なわけです。Emobile/eAccessといえばADSL時代から続く有線キャリアの老舗ですし、現に無線契約者向けの優遇プランも持っているので、速度制限云々という話をする前にこちらを検討されることをオススメしたいですね。

*1:一部のサイトでこの問題を解決するため、野良ドライバを導入するよう勧めるような記述がありますが、出所不明なシステムファイルを読み込ませるのは自殺行為ですので絶対に止めましょう

*2:ただここはちょっとよくわからなくて、B番号設定が4Gモジュール、A番号設定が3Gモジュール向けなのかなという気がする。Xi向けISPを契約しても、3G fallbackができないので無線モジュールが複数入ってるような雰囲気があるのだけど、ただIMEIは1つしか持っていないし、欧州で現地SIM(TIM/O2)にて使ったときは3GでもB番号側の設定で繋がったので、単なる番号設定だけの問題なのかなぁ…

*3:音声契約でfor Data契約済み、APNは kwx2.au-net.ne.jp

*4:もしかしたらGL09Pで最後に接続した網側の番号が生きてるのかも

*5:iPhone 5s の SIM とこの Nexus5 で panda-world.ne.jp に接続可能なことは確認済

広告枠

前々から気にはなっていたのですが、記事と脚注の間にぽっかり空隙があくことがあって、何なんだろうとは思ってたものの突き詰めていなかったのですが、あれ広告枠だったんですね。

プラスユーザーでもないので広告にどうのこうのはないのですが、デザイン的に不格好だったり、記事の末尾に埋め込まれるせいで変な広告がエントリの一部だと誤認されても嫌なので、デザインに一部手を入れ、広告枠だけボーダーで囲って明示するようにしました。

記事内容的にも、「ダウンロードリンク」のような手合いの広告が表示される可能性が十二分にある以上、放置するのもどうかと思いますしね。ただ、広告が読み込まれなかった場合に発生する空隙部分はそのままになってしまうので、その場合は微妙に変な感じになってしまうのですが、まぁ誤認されるよりはマシでしょう。

あと、正方形バナー広告が多いのは何なんでしょうね。デザイン的にも、長方形バナーの方が全体的に統一が取りやすいように思うのですが、あそこまで広告アピールした方がクリック率も高いのでしょうか。

公衆Wifiの認証情報について

PyWispr での認証は、各サービスの認証ページが設置されているドメインをキーに、 secret.xml に記載された情報とマッチさせています。

kddi.com

au Wifi Spot の情報です。au ユーザーであれば、下記ページに接続端末のMACアドレスを投げてアクセスするとID/Passを取得できます( d:id:RobinEgg:20120617:p1 )。

https://auwifi-signup.auone.jp/su2/?{"mac_addrs":["***大文字MACアドレス***"],"manufacturer":"Windows","model":"7","request_type":"0"}

なお、ここで取得できたIDは、そのままでは使えないので、

{"code":"N22","device_num":"01","max_device_num":"02","passwd":"**PASS**","user_id":"**UID**"}

IDの末尾に「@au」を付け、「**UID**@au」のような形にする必要があります。

wi2.ne.jp

Wi2 / UQ Wifi 向け。契約時に割り振られたID/Passを入力します。au wifiローミングが可能ですので、上記で取得したID/Passを同じように設定すれば繋がります。

w-lan.jp

SoftBank Wifi Spot または mobilepoint 向けです。

両サービスの認証APIは同一ドメイン内に設置されているため、両サービスで情報を共用しています。サブドメインは異なるため、サブドメインまで含めた形で分割すると両サービスで別々のIDを使った運用が可能です。

SoftBank Wifi Spot(SWS)

SWS は UserAgent を利用して接続端末を判別している( d:id:RobinEgg:20120829:p1 )ことから、 uastring を記載しています。なお、最近では UAiPhone でも WISPr コードを表示するようになったようです。

認証IDは契約電話番号11桁、パスワードはネットワーク暗証番号4桁になります。なお、SWSの契約がなされていれば、契約上の端末が iPhone であれ Android であれ、電話番号で認証できるようです。

mobilepoint

契約時のID/Passが認証情報になります。

fon.com

FON向け。以前は Softbank と片側乗り入れをやっていたようで AP もよく見かけたのですが、そもそも現時点で WISPr 対応してるのかすら不明…。SoftbankのIDが通るのなら、電話番号と暗証番号で認証ができると思われます。通常の Linus アカウントであれば、メールアドレスとパスワードを設定。

m-zone.jp

docomo Wi-Fi(旧m-zone)向け。いくつか契約方法がありますが、spモード付帯であれば、spモード各種設定から docomo ID でログイン後、docomo Wi-fi 設定で確認可能。

PyWispr 更新

これまで微妙にバグを含んだまま放置していた PyWispr ( d:id:RobinEgg:20121104:p1 )ですが、このたびリファクタリングをして更新しました。Bitbucket のレポジトリを参照ください。なお、以前書いたとおり、使用に際しては自己責任&SSL 証明書の実在確認は仕様上不可、という点を念頭に置いてご使用ください。

機能的な変更点は特に無いのですが、今回のリファクタリングの主な目的は、「Android 上で動くネイティブ Python」こと QPython への対応です。以前は Android 上で Python を動かすには SL4A ベースでごにょごにょしないとなかなか難しかったですが、最近では Google Play からインストールするだけで動くというレベルに達していることもあり、それほど大きくない規模のコードであれば、コードベースをPC/スマートフォンで共用するのは非常に簡単になっているように思います。

また、 WISPr 1.0 の仕様書を配布していたサイトがドメイン失効→別人に取られる、というどうしようもない醜態を晒していることもあり、 Bitbucket の当該プロジェクト上で仕様書の再配布をはじめました(特に規制するような文言はないことを確認していますが、問題ありそうなら止めます)。


しかしアレですね、数年前の自分が書いたコードは理解不能なクソコード、という格言は IT 業界に広く敷衍した真理の一つだと思いますが、なかなかどうして、こんなコードを書いたのは誰だ!あ、俺か、という一人コントはいい加減止めにしたいものです。

余談

コードを書き換えてる最中に気づいたのですが、 d:id:RobinEgg:20120617:p1 で書いた、 KDDIwifi について、

許容台数
4台までに拡張
MACアドレス
登録必須なのは変わらないけど、実際に登録した端末以外からでも、発行済みの認証情報を使って接続可

という仕様に微妙に変更されているようですね。そうすると、いよいよもって何のための MAC アドレス登録なんだ、という話になりそうですが(そもそも登録不要?)。

Graphite のインストールについて

先日、ちょっとしたログを表示するのに Graphite の導入を検討していて、試しに走らせてみたのでそのときの記録をメモしておきます。

Graphite とは

日本語の情報が少ないのでアレですが、高機能版の rrdtool といえば当たらずとも遠からず、という感じ。rrdtool といえば munin や MRTG、あるいは GrowthForecast などでおなじみの Perl 系グラフ表示ミドルウェアですが、ユーザー側でグラフの表示期間やスケールの変更を行ったりすることはちょっと難しいのが難点でした。

また、これは個人的に盲点だったのですが、 rrdtool が扱うデータのタイムスタンプは、原則としてAPIにデータが投入された時刻になってしまうんですね(API への引数として別途時刻を指定できない)。従って、 on-time で投入可能なアクセスログや、逐次投入が可能な HW メトリクスなどの推移を見る用途には向いているものの、過去数時間分のデータを一度に処理したりするような、過去のデータを投入して時系列で表示するという用途には使えません。

この2つの問題を解決するのが Graphite で、元々は非常に大規模なスケール(1分間に数万オーダーのデータ投入があるような環境)での使用を想定しているようなので今回検討した用途には正直オーバースペックかなという感じもしましたが、実際に使ってみるとデータ収集部とグラフ表示部が分離されていること、データ投入が非常にカジュアルにできること、収集データを API を通じて簡単に取得できること、などから、 rrdtool で辟易しているなら一度は試してみた方が良いよという感じです。

準備

Graphite のコアは

Carbon
データ収集
Whisper
回収データの保存管理
Graphite-web
webフロントエンド

の3ユニットから構成されており、いずれも Python 製です。web側のプラットフォームは django で、 WSGI 経由で動くことになります。なお、フロントエンドについてはいくつか Ruby 製の代替があります。

インストールした環境は Ubuntu Server 12.04(Apache 2.2) / 14.04(Apache 2.4) どちらも LTS です。なお、Pythonは両環境とも 2.7 を用いました。

導入

すべて pip でインストールが可能です。標準的な手順だと、インストールディレクトリは

/opt/graphite

になります。まずは関連する依存モジュールから入れていきます。

# apt-get install python-pip python-cairo python-dev libapache2-mod-wsgi build-essential

libapache2-mod-wsgi ですが、 Python 3 の場合は libapache2-mod-wsgi-py3 になります(動くかどうかは未確認。
次いで、 Graphite のコアと django を入れます。

# pip install graphite-web whisper carbon django django-tagging daemonize

正常にインストールされれば、設定ファイルを書き換えていきます。

$ cp /opt/graphite/conf/carbon.conf.example /opt/graphite/conf/carbon.conf
$ cp /opt/graphite/conf/graphite.wsgi.example /opt/graphite/conf/graphite.wsgi
$ cp /opt/graphite/conf/storage-schemas.conf.example /opt/graphite/conf/storage-schemas.conf
$ vi storage-schemas.conf

storage-schemas.conf では、収集したデータをどの程度の粒度・期間で保存しておくか、というルールを決めます。デフォルトでは、1分間隔で24時間しか保存しないようになっているので、必要に応じて変更します。

Whisper のストレージは固定長になっているため、データ収集前に保存期間を決めておく必要があり、また一度データ収集が行われ、データベースが作成されてからこの粒度・期間を変更する場合は別途スクリプト(/usr/local/bin/whisper-resize.py)を走らせる必要があります。

[sensor]
pattern = sensor.*
retentions = 120s:365d

基本的な書式は上記の通りで、この例では2分ごとに取得されるデータを365日間保存します。 pattern 項はデータの名前空間とのマッチングを指定します(正規表現可)。 Graphite が扱う各データはドットで区切られた階層型の名前空間を有しており、たとえば

sensor.cpu.temp
sensor.cpu.fanspeed

などという形になりますので、漏れのないように指定します。設定が終われば、web側の設定を行います。

$ cp /opt/graphite/webapp/graphite/local-settings.py.example /opt/graphite/webapp/graphite/local-settings.py
$ vi /opt/graphite/webapp/graphite/local-settings.py

local-settings.py では、タイムゾーンに Asia/Tokyo を、秘密鍵は必要に応じて指定します。この後、管理用の DB を作成します。

$ sudo python /opt/graphite/webapp/graphite/manage.py syncdb

web 周りのスクリプトの所有者を www-data に変更します。

$ sudo chown www-data:www-data /opt/graphite/storage -R
$ sudo chown www-data:www-data /opt/graphite/webapp -R

ここから Apache の設定です。Virtual Host 用の conf ファイルの見本が用意されているので、apacheの設定フォルダにコピーします。

$ sudo cp /opt/graphite/examples/example-graphite-vhost.conf /etc/apache2/sites-available/graphite.conf
$ sudo ln -s /etc/apache2/sites-available/graphite.conf /etc/apache2/sites-enabled/graphite.conf
$ sudo vi /etc/apache2/sites-enabled/graphite.conf

触るところはほとんどありませんが、

Alias /media/ "/usr/local/lib/python2.7/dist-packages/django/contrib/admin/media/"

django がインストールされているフォルダに書き替えが必要です。また、


節と


節はアクセス許可が必要です。既にリリースから2年近く経過した Apache 2.4 系ではアクセス制限に Allow/Deny ではなく Require を用いるようになっているので、2.4系を使う場合は間違えないように。

  
   Order allow,deny
   Allow from all
  
  = 2.3>
   Require all granted
  

で書いておいてくれれば良いのですけどね。

さて、ここからは一部のスクリプトを改修する必要があります。

/opt/graphite/webapp/graphite
  ./urls.py
  ./events/urls.py
  ./metrics/urls.py
  ./dashboard/urls.py
  ./render/urls.py
  ./version/urls.py
  ./cli/urls.py
  ./graphlot/urls.py
  ./browser/urls.py
  ./composer/urls.py
  ./whitelist/urls.py
  ./account/urls.py

で、

from django.conf.urls.defaults import *

となっているのを

from django.conf.urls import *

に書き換えます。これは、

django.conf.urls.defaults will be removed. The functions include(), patterns() and url() plus handler404, handler500, are now available through django.conf.urls .

https://docs.djangoproject.com/en/1.6/internals/deprecation/#id1

となっているように Django 側のバージョンアップで更新されたものの残り物です。また、

/opt/graphite/lib/carbon/util.py

from twisted.scripts._twistd_unix import daemonize

import daemonize

に書き換えます。これでやっと準備が整いました。

$ cd /opt/graphite
$ sudo service apache2 restart
$ sudo ./bin/carbon-cache.py start

で走らせると、Graphite のトップページにアクセスできるはずです。

ぱすわーどじぇねれーたー

随分前に d:id:RobinEgg:20111217:p1 で書いたパスワードジェネレーターですが、奇を衒いすぎて意味不明なコードになっていたことと、大元の Crypt-JS が更新されていたのでシンプルに書き直し、ついでに使用するハッシュアルゴリズムも SHA3 に変更して最大で64文字まで算出できるようにしました。

今時の web サービスでパスワードに記号使用不可とか64文字未満で文字数制限とかちょっとあり得ないんですが、往々にしてそういうサービスが跋扈している現状、適宜コードを書き換えるとかしてください(需要あんのか凄く疑問だけど。

javascript: (function(){
  var salt = prompt('Salt?') || 'ますたーぱすわーど';
  if ( !document.getElementById('cryptojs-sha-hmac') ){
    var s = document.createElement('script');
      s.id = 'cryptojs-sha-hmac';
      s.src = 'https://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/hmac-sha3.js';
      void(document.body.appendChild(s));
  }

  var genPass = function(binArray){
    var Ascii = ''; for(var i=33; i<127; i++){ Ascii += String.fromCharCode(i); }
    var passPhrase = '';
    for( var i = 0; i < binArray.length; i++){
      passPhrase += Ascii.charAt(parseInt(binArray[i], 10) % Ascii.length);
    }
    return passPhrase;
  };

  setTimeout(function(){
    var hmacBytes = CryptoJS.HmacSHA3(document.domain, salt);
    var u = new Uint8Array(hmacBytes.sigBytes);
    for (var i=0; i<hmacBytes.sigBytes; i++) {
      u[i] = (hmacBytes.words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;
    }
    window.prompt('Pass phrase:', genPass(u));
  }, 1000);

})();

Word 配列から byte 列への変換についてはGoogle グループを参照。

Apple 社の GeoLocation システム周りに関するお話

今年もどうぞよろしく。

GeoLocation サービスのリバースエンジニアリング

些か旧聞に属するのですが、Telecom SudParis (France) の学生が、卒業研究として iOS 端末が位置決定に用いている GeoLocation システムで使われているプロトコルリバースエンジニアリングしたという内容の論文をみつけました*1

周囲の Wifi アクセスポイント (AP) の MAC アドレスから現在位置を割り出す GeoLocation システムはモバイルデバイスの台頭とともに非常に注目される分野になっており、Apple も当初は Skyhook を使っていましたが、いつの頃からか位置情報も自前で管理するようになりました。

以前から gs-loc.apple.com が Apple の位置情報サーバーだろうということと、通信内容は Protocol Buffer でシリアライズされているらしいという話は割と有名だったのですが、シリアライズされている部分の構造や通信内容を明らかにできたという点で新規な内容だと思います。

シリアライズの内容などは原著論文を参照(フランス語なのでちょっと辛いけど)してもらうとして、実証コードも併せて配布されており、それを元にすでに BitBucket に実際に動作するコードが上げられています*2

位置情報と住所の話: 再び

さて、ここで思い出すのは、数年前になされた「Wifi AP のMACアドレスは住所相当ではないか」という指摘です*3

高木氏のサイトでは 2011 年までの時系列に沿って各ベンダーの対応が記されており、メディアからの指摘もあって Microsoft, Google ともに最終的には「位置的に隣接した複数 AP の MAC アドレスが提供されなければ位置情報は返さない」という自主規制を制定し、さらにはオプトアウトの手段も併せて提供しています。

Google の場合

当時、 GoogleAPI*4は正式には一般公開されていない隠し API のようなものでしたが、現在は URI も変更され*5、ドキュメントも整備されて一般公開されており、その中でもこの自主規制については明確に記載されています*6

もう一つ、同様の機能を持つと思われる隠し API のようなものがありますが*7、これも同じく自主規制下で運用されているものと思います。さらに、今回の趣旨からは外れますが 2G/3G の基地局情報から位置決定を行う API もあるようです*8

オプトアウトについては、皆さんご存じの通り SSID に 「_nomap」というサフィックスを付与することで収集対象から外す、という方法をとっています。なお、この手法は Google のおかげでオプトアウト手法のデファクトスタンダードのように誤解されている節もありますが、実際には Google しか見ていない、極めてドメスティックな手法であることは留意すべきでしょう。

ちなみに、 Google の GeoLocation サービスに乗っかっている Firefox の位置情報サービスですが、ソースコードを見ると、別に位置情報サービスに登録する情報を集めているわけでもないのに、わざわざ近傍の SSID 群から「_nomap」サフィックスがあるものを除外してクエリの対象としています*9

Microsoft の場合

MS の Web API は未だに隠し API 扱いのようで、この自主規制に関する明確な記載は見つけられませんでした。が、オプトアウトには専用フォームを提供しており*10、こちらから申請することで利活用されないようにすることができます。

Apple について

さて、唯一言及のなかった Apple ですが、当時の時点では Apple のシステムが解析されていなかったことが最大の理由かと思います。が、上記論文でその詳細がある程度明らかになった結果から、 Apple は現時点においても、両社が実施したクエリに対する自主規制も、オプトアウト手段の提供も行っていない、ということが推測されます

試しにスクリプトを走らせてみるとわかりますが、単一 AP の MAC アドレスを付与するだけで最大 400 カ所の周辺 AP 情報とともに位置情報が返却されてきます。

オプトアウトについてはそもそも Apple から公式な文書が出ていないのでどうしようもないのですが、 Google の手法を踏襲できるのか、という観点からは

  • クエリの際にそもそも SSID のやりとりが発生していない
  • 端末側で Firefox のようにクエリ内容にフィルタリングをかけているわけでもなさそう

ということから、Apple の GeoLocation システムの設計上 SSID を用いたオプトアウトは困難ではないかと考えています*11

SSID 芸と MAC アドレスの話

で、なぜ今更こんな話題かというと、最近よく見る「SSID芸」が割とクリティカルだという話です。

SSID にマルチバイト文字を登録することでコミュニケーションを図る、というアイデアはそう新しいものではないと思いますが、対応機器がここ最近になって増加していることから、twitter などでも随分よく見かけるようになりました。なかでも端緒となったのが

の記事にあるスクリーンショットだと思いますが、ここにばっちり MAC アドレスがそのまま SSID に転用されたと思われるケースが表示されています。

この MAC アドレスを Apple のサーバーに問い合わせ、返ってきた位置情報をさらに Google Maps に投げると、中国地方にあるとある大学の某学部棟という表示が出ます。拡散されたご本人のプロフィールにもそれとおぼしき記載があるのでおそらく当たりだろうと思われますが、これと同様のケースが非常に多いわけです。

なお、比較的よく見かけ、かつ SSIDMAC アドレスの下位 24 bit がよく使われているために MAC アドレスの特定・推定が容易なモバイルルーターテザリング端末の情報は返ってこないことが多いのですが、これは Apple 側で情報の精度を上げるために複数の場所から報告された端末の情報は蓄積しないという対応を取っているせいではないかと考えています*12

結論

国内市場でも Apple 端末はかなりのプレゼンスを有しており、収集した情報量は Google のそれに比肩するものと思われますが、一方は少なくとも対処の姿勢を見せているのに対して、我関せずという姿勢はちょっとどうなのかなと思うところです(「らしい」といえば「らしい」ですが)。このような状況下では、ユーザーサイドでできる対応には身近な端末のMACアドレスが表示されたものを安易にネット上に広げない、程度で限りがあること、さらに Apple が何らかの対応を取るとも到底思えないことから、自己防衛は非常に重要だと思います*13

*1:François-Xavier Aguessy, Côme Demoustier, SSR 2011-2012 : http://fxaguessy.fr/rapport-pfe-interception-ssl-analyse-donnees-localisation-smartphones/

*2:https://bitbucket.org/Kyso/ssid2geo-apple

*3:Wi-FiMACアドレスはもはや住所と考えるしかない, 高木浩光@自宅の日記, 2011 : http://takagi-hiromitsu.jp/diary/20111126.html

*4:http://www.google.com/loc/json

*5:https://www.googleapis.com/geolocation/v1/geolocate

*6:https://developers.google.com/maps/documentation/business/geolocation/#wifi_access_point_object

*7:http://www.google.com/loc/m/api

*8:http://www.google.com/glm/mmap

*9:http://mxr.mozilla.org/mozilla-release/source/dom/system/NetworkGeolocationProvider.js#148

*10:https://www.windowsphone.com/ja-jp/support/location-block-list

*11:なお、念のため開封直後から _nomap を付与した AP でも Apple の位置情報サーバーに登録されていることは確認済

*12:あくまでも推測、半固定位置で使用しているケースがあればもちろん収集対象と思われる

*13:実際、twitter 検索で拾った画像の MAC アドレスからピンポイントで特定できた例が凄く多く、戦慄したのがエントリを上げたきっかけ

Saucy Salamander(13.10) から libapache2-mod-auth-mysql パッケージが削除された件について

追記

どうやらバグとして確認されたようです。

原文

タイトルの通りなのですが、どうやらつい先日正式リリースと相成った Ubuntu 13.10 より、 apache2 系で認証モジュールの一部として広く使われている libapache2-mod-auth-mysql パッケージが削除されたようです。と同時に(というか、こちらが先なのかも)依存関係のある apache2.2-common パッケージも削除となっています。

Launchpadの状況

apache2.2-common
amd64
apache2.2-common : amd64 : Saucy (13.10) : Ubuntu
i386
apache2.2-common : i386 : Saucy (13.10) : Ubuntu

LaunchPad のコメントを見る限り、 trusty-proposed に移動したよと書かれておりかつ個別パッケージのページには Status: published となっているので次期LTSである Trusty Tahr (14.04)では復活しそうな雰囲気なのですが、肝心の apache2.2-common が完全に沈黙しているため、手の施しようがなさそうです。

ちょっと探したのですがこの辺に関するアナウンスが見当たらず、その割に結構影響の大きい変更なのでどうなってるのか正直よくわかっていません。ユーザー管理をMySQLに投げているケースは大手を含めてそれなりに多いと思うのですが、Maria DBへの移行過渡期ということなのでしょうか。また、 apache2.2-common が deleted となっている理由もよくわからず、2.4系に切り替えるという話も出ていなかったと思うので、なぜこのタイミングで?という感じです。

Saucyのサポート期限は2014年6月までなのでまぁ問題は軽微としても、2年ぶりのLTSであるTrustyでも放置というのは流石に考えにくい話でもあります。

LaLaCall を契約してみた

副題: MITM 攻撃による秘匿化された SIP 接続情報の取得について

はじめに

最近サービスインとなった、関西電力傘下の K-opti.com が提供するIP電話サービスである LaLaCall を契約してみました。

この分野は NTT Communications の 050 plus や Fusion Communications の FUSION IP-Phone SMART といったサービスが有名ですが、これらのサービスの基本であるIP電話と LINE のメッセージングサービスのいいとこ取りを図って第3極としての地位を狙う、という感じのようです。

現時点では Android 向けのアプリのみが提供されており、 iOS 端末向けのものは近日公開予定だそうです。

IP電話といえば、古くからSIPが標準プロトコルとしての地位を確立しており、最近スマートフォン向けに提供されている、いわゆる050番号サービスのほとんどが、SIPをベースプロトコルとしていかに3G網のネットワーク制限を突破するか、という点に力を置いてアレンジが加えられたものになっています。

特に、LTE世代に突入し、端末にはプライベートアドレスが割り振られてNATが標準になったこと、また spmode などのISP側でプロトコル制限が掛かるようになり、SIP標準である udp:5060 が通じなくなっていること、が大きな壁となっています。さらに、SIPのみならず音声通信に用いられるRTP側の手当ても必要であり、なおかつ wifi 環境まで視野に入れると盗聴防止という観点からもTLSの選択は必須となります。

ということで、同じくSIPの派生であろうという推測のもと、 LaLaCall の純正アプリを導入しパケットキャプチャを行ってみました。

パケットキャプチャの結果

すると、アプリの初期設定をHTTPSで行っていることが確認できました。

よく知られているように、iOS 端末ではOSで設定したプロクシの設定が全てのアプリに反映されるため、例えば burpproxy のようなソフトウェアを介在させることでHTTP通信を傍受することが可能です。また、偽造証明書を導入すればアプリの実装によってはHTTPS通信をも傍受することが可能です。

一方、Android 端末ではプロクシの設定は通常ブラウザ閲覧にのみ反映され、アプリが行う通信内容を傍受することは比較的困難であり、それこそ透過プロクシなどネットワーク側からの攻撃テクニックを用いる必要がありました。

そこで、rooted な端末に透過プロクシ(SandroProxy)を導入して観察を続けると、SIPパケットについても Port 443 にTLS接続をしていることがわかりました。いわゆる SSL-VPN と同様の回避手段ですね。一般的な NAT/FW ではSSL通信の中身までは確認できないため、ほぼ無条件で通過させてしまうことを逆手に取った方法です。

で、端末に導入した SandroProxy は HTTPS のみ対応だったので、練習がてら本格的な中間者攻撃を仕掛けるべく、今回は有名どころの mitmproxy よりもプロトコル汎用性の高い SSLsplit を導入した環境を構築し、通信内容を解析しました。

SSLsplit によるMITM攻撃の実際

用いた環境は Ubuntu Linux 13.10 です。

これでAPに接続したスマホには、外部アクセスが可能な LAN とは別空間のアドレスが割り当てられます。デフォルトゲートウェイは eth1 のアドレスが指定されているはずですので、通信内容は全て eth1 を経由することになります。その上で、 eth0 と eth1 を iptables でNATします。ここまでが下ごしらえ。

次に、 SSLsplit を導入します。パッケージレポジトリにもあるのかもしれませんが、今回はふつーに make しました。詳細な使い方はこの辺を見て頂くかググってもらうとして、さらに iptables を書き換えて SSLsplit が待ち受けるポートに通信内容をリダイレクトします。

で、この状態でスマホから HTTPS 通信を行うと、本来なら SSLsplit 導入時に OpenSSL で作成したオレオレ証明書スマホ側に提示されるはずなのですが、ブラウザ以外で証明書関連のエラーを吐いたのは twitter 純正クライアントと twicca くらいでした。それ以外は何もエラー出さずに通信内容丸見え。いやはや。

ここまでで準備が終わったので、後は LaLaCall で登録手続きを行います。通信内容を見てもらえばわかりますが、今となっては珍しい SOAP で登録が行われています。API は userLogin → startCallBack → getCallBackResult という3段階を踏んでいて、 startCallBack を叩くと PIN コードが発行され、確認の電話がかかってきます。

どうでもいいんですけど、LaLaCall は携帯番号のみだったと思うので難しいでしょうが、こういう電話確認型の宛先に例えばマージン取得型国際電話番号とかQ2とか指定できるんですかね?Q2ってもう無くなったんでしたっけ?

LaLaCall におけるSIP通信

閑話休題

全ての情報が間違いなく登録されると、サーバー情報などの各種情報が一気に提示されます。メッセージングアプリのプロトコルXMPP なのかーとか。

こうして得られたSIP周りの情報を、今度は microsip を使って登録してみます。SIPの REGISTER 等々各種操作も TCP:443 を通じて行われるので、このまま傍受を続けて情報を収集してみましょう。

SIP パケットを見ていて最初に気づくのは、先の操作で取得した user_id ってダミーじゃね…?ということでしょうか*1。まさか電話番号がユーザーIDだとは…。あとは 407 が発行されているので Proxy Authentication が必須と思われます。さらに電話をかけてみると、 INVITE で RTP オプションとして

m=audio 48888 RTP/SAVP 18 0 101
a=crypto:1 AES_CM_128_HMAC_SHA1_32 inline:******************************
a=rtpmap:18 G729/8000
a=rtpmap:0 PCMU/8000

が指定されていることがわかります。これより、

ということだそうで、microsip はこれら要求条件を全て満たしています。

ということでレジストしてみたのですが、すんなり通ってしまいました。ついでに発着信とも可能でした。 ごめんなさい、発信はOKだけど着信がどうやらダメになっているようです。エラーログを見ていると、

**:**:**.***  pjsua_media.c  ....pjmedia_transport_media_start() failed for call_id 1 media 0: SRTP crypto-suite name not match the offerer tag (PJMEDIA_SRTP_ECRYPTONOTMATCH)

**:**:**.***   pjsua_call.c  ...Unable to create media session: No active media stream after negotiation (PJMEDIA_SDPNEG_ENOMEDIA) [status=220048]

**:**:**.***       endpoint  ....Request msg BYE/cseq=31116 (tdta0520C500) created.

という感じになっていて、クライアント側から提示した暗号化アルゴリズムのシーケンスIDと、それを受けてサーバーから返ってくる指示のシーケンスIDが食い違っている?ようなのが原因ぽい。ソース見たけどちょっと手入れるのは厄介そう…。

両面待ちについて

PCとスマホの両面待ちも可能といえば可能なのですが、不安定なので現実的には同時使用は困難でしょうね。あと、原則的に両面待ちを考慮していない*2根拠として、050番号を端末のデバイスIDと紐付けていることと、所有者確認コールバックが通るとそのたびにパスワードが振り出され、更新されることが挙げられます。パスワードだけを叩き出すAPIが用意されていないのか、スマホのDB上にあるパスワードで接続に失敗する場合、スマホ側ではアプリ初期化のうえ再登録を行うように指示されてしまいます。

なお、スマホ側の DB って sqlite なのですが、格納されている値は BASE64 なものの、デコードしても何か操作された値が出てきて使い物になりませんでしたことをお知らせしておきます。

あとがき

実際には割と試行錯誤してるのですが、文章に起こすと全体的にあっさり通ったかのような印象がありますね…。結局各種情報を取れてもパズルみたいなもので、解けた瞬間に飽きちゃってエントリ起こした後はおとなしく純正アプリで使おうと思います。

SIP 接続情報取得用スクリプト

ご参考まで。
Firefox だと Cross-domain 制限に引っかかるので、実行する場合は UTF-8 でローカルに保存後、 Internet Explorer で見てちょ。

*1:完全にダミーというわけではないのでしょうが…

*2:というか、そもそもSIPの仕様上でも同一IDによる両面待ちって考慮されていなかったはず