[108] SORACOM Beam の基本 - soracom/jp-training GitHub Wiki

[108] SORACOM Beam の基本

ここでは、IoT デバイスから IoT バックエンドサービスへのセキュアで簡単なデータ転送方法を解説します。

前提条件

以下を完了し、Raspberry Pi を SORACOM Air を使用して 3G 接続出来ていること

必要なもの

SORACOM Air に接続したRaspberry Pi

SORACOM Beam の特徴

暗号化による安全なデータアップロード・ダウンロード

機密性の高い情報を IoT デバイスから送受信する際には暗号化処理が必要となりますが、IoT デバイスの限られたリソースでは暗号化処理が難しい場合があります。 そのような場合に暗号化処理を SORACOM のリソースを利用して行うことができます。 SORACOM Beam (以下Beam) を用いることで、暗号化処理が難しいデバイスに代わって、お客様のデバイスからお客様のサーバー間の通信を暗号化することが可能になります。

Beam では、IoT デバイスからのデータアップロード時は、3G/LTE 閉域網を通じて Beam のエンドポイントまでデータが送信され、Beam から先のインターネットでは、Beam によって通信が暗号化され、お客様のサーバーに安全にデータを届けることができます。

このように、Beam を利用することによって、CPU や電力制限によって暗号化処理ができない IoT デバイスの通信を暗号化することができ、証明書の管理や脆弱性への対応等の煩雑な処理をクラウドにオフロードすることで、暗号化された通信を簡単に利用することが可能になります。

現在、以下のプロトコル変換に対応しています。

デバイス側のプロトコル サーバーのプロトコル
HTTP HTTPS
MQTT MQTTS
TCP TCPS

プロトコル変換

データを HTTP(S)エンドポイントに送信したいが、お客様のデバイスが HTTP(S) をサポートしていない場合、Beam を用いることで生のTCP/UDP データをJSONとして HTTP(S)で送信することができます。 この機能を利用いただくことで、デバイス側の修正を行うことなく Web API のフレームワークを使いお客様の IoT バックエンドサービスの開発が可能になります。

お客様のデバイスのデータがバイナリ形式の場合、base64エンコードされたデータを、JSON形式で送信します。例えばバイナリデータ 0x0f06020f1201 を送信する場合、JSON形式の"payload"は、{"payload"=>"Bg8PAgES"}になります。

現在、以下のプロトコル変換に対応しています。

デバイス側のプロトコル サーバーのプロトコル
TCP HTTP(S)
UDP HTTP(S)

Beam の利用方法 (HTTP から HTTPS)

Beam を利用するために、グループに SIM を所属させ、グループに対して Beam の設定をします。 ここでは、HTTP から HTTPS へ変換するグループを作成します。

グループの作成

まず、グループを作成します。 画面の上部左にある「Menu」を開きます。 「SIM グループ」を開きます。

「グループ」の画面の 「+ 追加」 をクリックし、新しいグループを作成します。

グループ名を尋ねられますが、お好きな名前を入力し登録します。(どんな名前を付けていただいても構いません。)

グループの設定

グループのリストから、登録したグループ名をクリックし、グループの詳細ページを開きます。 「SORACOM Beam」をクリックし、Beam の設定画面を開きます。 詳細ページには、様々な SORACOM のサービス名が書かれています。

「+」ボタンをクリックし、エントリポイントリストから「HTTP エントリポイント」を選択します。

「SORACOM Beam - HTTP 設定」画面が表示されますので、中を埋めていきます。

  • 設定名 : これはどんな名前でも構いません。ここでは「HTTP to HTTPS」と入力します。
  • エントリポイント - パス : 「/」と明記します。
  • 転送先 - ホスト名 : 「beamtest.soracom.io」と明記します。(これは、Beam用のテストサーバーです)
  • 転送先 - ポート番号 : 空白のまま、もしくは「443」と明記します。(HTTPSのデフォルトのポート、443を利用する場合は、「ポート番号」の記載を省略しても構いません。)
  • 転送先 - パス : 「/」と明記します。

上記の設定後の画像はこの様になっています。 画面をスクロールし、「保存」をクリックします。

SIM のグループを変更

画面上部左の「Menu」より「SIM 管理」に遷移し、Raspberry Piに接続しているSIMを選択し、「操作」タブから「所属グループの変更」をクリックします。

最後に、「グループ変更」をクリックします。 どのグループに所属させるかを設定するため、 ▼ をクリックしリストを表示します。先ほど作成したグループを選択します。

Raspberry Pi からテストを実行する

これで、準備はすべて完了しました。Raspberry Piにログインし、下記のコマンドを入力します。

コマンド

curl https://beamtest.soracom.io
curl http://beam.soracom.io:8888

実行結果

pi@raspberrypi:~ $ curl https://beamtest.soracom.io
Hello Unknown Client...

== HTTP Headers ==


pi@raspberrypi:~ $ curl http://beam.soracom.io:8888
Hello Unknown Client...

== HTTP Headers ==

HTTP プロトコルで Beam にアクセスした時に HTTPS リクエストの時と同じ結果が表示されます。もし、デバイスが HTTPS サーバーにアクセスできない場合も、Beam を利用することで、SSL アクセラレーターとしてサーバーに接続することができます。

ノート: HTTPS化によるデバイスの負荷を調べる

HTTPS化によるデバイスの負荷がどの程度なのかを調べてみましょう。 今回は curl コマンドの実行時間を time コマンドで確認してみます。

pi@raspberrypi:~ $ time curl https://beamtest.soracom.io
...
real    0m4.810s
user    0m0.080s
sys     0m0.020s

pi@raspberrypi:~ $ time curl http://beam.soracom.io:8888
...
real    0m1.953s
user    0m0.040s
sys     0m0.010s

程度の差はあれども、総じてHTTPS化(TLS化)することによるハードウェア負荷の増大は明らかです。これによって通信速度の低下や、暗号化によるデータサイズの増加、電力消費の増加といった課題が発生します。このような観点からも、Beamの利用は検討に値すると考えられます。

SIM の認証情報を利用する

SORACOM Air に接続された Raspberry Piはすでに、SORACOM によって認証されています。SORACOM は、ターゲットサーバーと通信をする際に SIM の情報を追加することができます。 「SIM グループ」をクリックし、Rasbperry Piに利用しているSIMのグループを選択します。SORACOM Beam の設定をクリックし、右側の「...」ボタンをクリックします。 下部の「オプション」より、「IMSI ヘッダ」、「IMEI ヘッダ」、「署名ヘッダ付与」をオンにします。

「事前共有鍵」の横にある「+」ボタンをクリックします。

「認証情報ID」と「概要」は、何でも大丈夫です。「事前共有鍵」に 「topsecret」と記入します。

topsecretは、ソラコムが Beam テストサーバーにすでに設定しているパスワードです。

「登録」をクリックし、「HTTP 設定」画面に戻り、「保存」をクリックします。

Raspberry Piに下記のコマンドを実行します。

コマンド

curl http://beam.soracom.io:8888

実行結果

pi@raspberrypi:~ $ curl http://beam.soracom.io:8888
Hello SORACOM Beam Client 44010xxxxxxxxxx !

== HTTP Headers ==
HTTP_X_SORACOM_IMEI = 35636xxxxxxxxxx
HTTP_X_SORACOM_IMSI = 44010xxxxxxxxxx
HTTP_X_SORACOM_SIGNATURE = ccafbf350fffd01f5f4fd0dac0b34da80870864b54c621c97c1125ba30f1e4a7
HTTP_X_SORACOM_SIGNATURE_VERSION = 20151001
HTTP_X_SORACOM_TIMESTAMP = 1494662049112

= Signature Verification =
Pre shared key = topsecret

stringToSign:
x-soracom-imei=35636xxxxxxxxxxx-soracom-imsi=44010xxxxxxxxxxx-soracom-timestamp=1494662049112

calculated_signature:
SHA256('topsecret'+stringToSign) = ccafbf350fffd01f5f4fd0dac0b34da80870864b54c621c97c1125ba30f1e4a7

provided_signature:
ccafbf350fffd01f5f4fd0dac0b34da80870864b54c621c97c1125ba30f1e4a7

signature:
Match!

結果は、SIMによって異なる箇所があります。 Beam テストサーバーは、このリクエストがIMSI(44010xxxxxxxxxx)のSIMから送られたものだということを認識しています。サーバーはHTTP_X_SORACOM_IMSIをチェックすることで、IMSIの情報を知ることが可能です。

偽装したアクセスを防ぐため、署名を確認します。サーバーは、「事前共有鍵」、IMSI、IMEI、タイムスタンプから計算します。もし署名が合致したら、このリクエストが設定したSIMからのものであると証明できます。

プロトコル変換(TCPからHTTPS)

設定を追加する

「SIM グループ」をクリックし、設定したいグループ名を選択します。 詳細ページには、様々な SORACOM のサービス名が書かれています。 「SORACOM Beam」をクリックし、Beam の設定画面を開きます。 「+」ボタンをクリックし、エントリポイントリストを表示します。その後、「TCP → HTTP/HTTPSエントリポイント」を選択します。

「SORACOM Beam - TCP → HTTP/HTTPS 設定」画面が表示されますので、中を埋めていきます。

  • 設定名 : これはどんな名前でも構いません。ここでは「TCP to HTTPS」と入力します。

  • 転送先 - ホスト名 : 「beamtest.soracom.io」と明記します。(これは、Beam用のテストサーバーです)

  • 転送先 - ポート番号 : 空白のまま、もしくは「443」と明記します。(HTTPSのデフォルトのポート、443を利用する場合は、「ポート番号」の記載を省略しても構いません。)

  • 転送先 - パス : 「/」と明記します。

  • ヘッダ操作 - IMSI 付与/IMEI 付与/署名ヘッダ付与 : すべてONにします。

  • ヘッダ操作 - 事前共有鍵 : HTTP to HTTPS パートで作成したキーと同じものを選択します。

上記の設定後の画像はこの様になっています。

Raspberry Pi からテストを実行する

nc(netcat)プログラムを利用し、TCPのソケットの生データをBeamのエンドポイントとポートを指定して送ることが出来ます。 署名を確認することで、サーバーはお客様のSIMを認証することができ、base64 にエンコードされたフォーマットでデータを受け取り、お客様が送ったオリジナルのデータと同じコンテンツをデコードします。

コマンド

nc beam.soracom.io 23080
foobar (または任意の文字列)
(Ctrl+C で止める)

実行結果

pi@raspberrypi:~ $ nc beam.soracom.io 23080
foobar
200 Access Authorized: {"payload"=>"Zm9vYmFyCg=="} => foobar

^C

サーバ側では署名をチェックすることで SIM を認証して、base64 フォーマットでエンコードされたデータをデコードしてレスポンスを返しています。デコードされたデータが一致する事を確認してください。

後片付け

Beam 設定自体は費用が発生しないため、無料で設定をそのままにしておくことが出来ます。しかし、設定内容を消したい場合は、エントリポイントの設定の削除やグループ自体の削除をすることができます。 エントリポイントの削除は、Beam設定のページ左下の「-」をクリックし、右端に現れる「削除」ボタンをクリックします。

グループの削除は、画面上部左の「Menu」から「SIMグループ」をクリックし、削除したいグループをクリックします。 右端の「高度な設定」から、「このグループを削除」をクリックします。

赤色の背景の「このグループ」を削除をクリックし、グループを削除します。