会社の方のブログに、Armadillo-IoT: GPSを使わずに位置情報を取得する | アットマークテクノ ユーザーズサイト というのを書きました。3G接続できるデバイスのおおよその現在地を調べる方法です。精度は全くありませんが、GPS不要で3Gの接続さえ生きていれば使える方法なので、デバイスの盗難対策などには重宝するのではないかと思います。
ただ、つらつらと書いていて思ったのが、「セキュリティの観点からするとイケてない」ということです。
1 は、たくさんあるデバイスで共通のAPIキーを使っていた場合、一つのデバイスがハックされてキーが流出したら、キーを更新するために全てのデバイスのファームを書き換えなくてはならなくなるという問題に繋がります。かといって、デバイスごとに個別のAPIキーを割り振ろうと思うと、キーの管理やデバイスの出荷作業などの手間が掛かって、コストに跳ね返ってきます。
2 は、単純に証明書をインストールすれば、回避できます。(会社ブログでは説明する分量を省くために、あえてスルーしました。)ただ、こちらも実運用を考えると証明書の更新という問題が出てきます。
この二つの問題、SORACOM Beamを使うとキレイに解決できるということに、改めて気づきました。
仕掛け
会社の方のブログでは、Armadillo(デバイス)から直接Google Maps APIを叩いて、結果を取得していました。これを、SORACOM Beam経由で叩くようにします。
Google Maps APIはHTTPSのPOSTメソッドを使い、パラメータはbodyにJSON形式で渡すようになっています。また、APIキーはクエリストリングとして渡します。developers.google.com
SORACOM Beamの設定は、下記のようにしました。
- エントリポイント
- プロトコル: HTTP
- ホスト名: beam.soracom.io
- ポート番号: 8888
- パス: /geo
- ヘッダ操作
- 指定なし
現在位置を調べるスクリプトは下記のようになります*1。URLがbeam.soracom.ioになり、API_KEYがスクリプトから消えています。
#!/bin/sh URL="http://beam.soracom.io:8888/geo" MCC="440" MNC="10" cell=$(/etc/config/3g-celllocation) set -- $cell LAC=$1 CID=$2 BODY=$(cat << EOF { "cellTowers": [ { "cellId": ${CID}, "locationAreaCode": ${LAC}, "mobileCountryCode": ${MCC}, "mobileNetworkCode": ${MNC} } ] } EOF ) curl -H "Content-type: application/json" -d "$BODY" "$URL"
効果
APIキーをデバイス側で持っておく必要が無くなる
これにより、全デバイスが共通のスクリプトで動作できる=運用が楽になるということと、APIキーの流出リスクを減らすことができるという二つのメリットを、同時に享受できます。
元々、APIキーというものは、APIへのアクセスコントロールのために存在するのだと思います。それが、デバイスにAPIキーを持たせた場合には、デバイス認証という意味合いを持ってしまうため、「デバイスごとに個別のAPIキーを発行」などという設計になりがちなのかもしれません。
SORACOM Beamを使うと、指定したグループのSIMからのリクエストしか転送しませんので、それがデバイス認証としての役割を果たします。「デバイスの認証はSIMで、APIのアクセスコントロールはAPIキーで」というように役割をきっちりと分けて考えることができるので、システム全体としての設計もシンプルになります。
証明書の更新が不要になる
デバイスからBeamへのリクエストはHTTPで行いますので、CAの証明書をデバイス側は持つ必要が無くなります。当然ながら、更新も不要ですのでデバイスの管理が楽になります。
それでいながら、デバイスからBeamのエントリポイントまでは、なりすまし不可かつ盗聴不可な経路を通りますので、安全性が損なわれるわけではありません。