Milkcocoaで簡単にIoTデバイスのアクセス制御が出来るようになりました

Posted: / Modified: / Tags: MQTT セキュリティ



MQTTの仕様であるClient IDを使って、Milkcocoaで簡単にIoTデバイスのアクセス制御が出来るようになりました。

今までも、セキュリティアップデートの記事に書いてあるように、デバイス上で認証をすることでアクセス制御は出来るのですが、単純に特定のデバイスからのアクセスを制御する目的にしては少々面倒です。

そこで今回は、もう少しシンプルにアクセス制御をする方法について説明します。

※追記(10/09):こちらの方法は、開発時や小規模な事例でのみ使用下さい。また、同レベルのアクセス制御はデータストアに難解な文字列を含ませる方法でも可能です。詳しくは以下をご覧下さい。

アクセス制御の概要

アクセス制御の方法の概要は以下です。とてもシンプルですね。

  1. デバイスのコードに任意の予測しにくい文字列を入れる
  2. セキュリティルールでその文字列を使ってアクセス制御する

具体的な実装方法

それでは、JavaScriptでの具体的な実装方法について説明します。

デバイスのコードに任意の予測しにくい文字列を入れる

app_idからmilkcocoaオブジェクトを作成する際に、オプションでclientIdを設定するだけで良いです。

デバイス側のコード
// YOUR_APP_IDの部分は、Milkcocoaに(無料)登録してアプリを作成した際に生成されるアプリ固有の文字列です。
var milkcocoa = new MilkCocoa('YOUR_APP_ID.mlkcca.com', {clientId : 'hogehoge'});

セキュリティルールでその文字列を使ってアクセス制御する

デバイスのコードが書けたら、clientIdに設定した文字列を使って、セキュリティルールでアクセス制御します。

clientIdは、セキュリティルール上では、client.idで取得します。わかりやすいように実例を見てみましょう。

Milkcocoaのトップページの照度センサーのグラフを例にとると、「データの保存はデバイスからのみ受け付けて、データの取得はブラウザでもできるようにする」というルールを書けば良いかと思います。

APIレベルで言うと、「on(push)stream(セキュリティルール上ではquery)は全員許可」「他のAPIは特定のclientIdの人だけ許可」というルールになります。

※セキュリティルールの基本的な書き方は、Milkcocoaのドキュメントページからご覧下さい。

lightというデータストアを使っていたとすると、以下のようなルールスクリプトになります。

セキュリティルール
light {
  permit: on(push),query;
  rule: true;
}
light {
  permit: all;
  rule: client.id == "hogehoge";
}

たったこれで、アクセス制御ができます。

注意すべきなのは、Client IDは複数のデバイスで同じ値を使うことができない、という点です。同じ値を使うと、頻繁に接続が切れなどの不具合が起きます。

アクセス制御の目的

セキュリティルールは、「接続しているクライアントのうち、どのデータストアでどのAPIを誰が使えるか」を定めるもので、接続自体はどのクライアントでもできます。

「接続も特定のデバイスからしかさせたくない」という場合は、デバイス上で認証を行って、管理画面から設定できるプライベートモードをONにすると可能です。

また、Client IDで制御しているためClient IDが推測されたり、見られてしまえば、アクセス権を与えてしまうことになります。Client IDが見られる可能性としては以下があります。

  • デバイスのコードを見られる
  • 通信を傍受される(TLSを使っていなかった場合)

デバイス側のセキュリティ対策を怠ったり(例:Raspiのルートユーザーpiのパスワードがraspberryのまま)、誰でもアクセスできるWiFiに繋いだりしないように気をつけましょう。

MilkcocoaのセキュリティルールでClientIdを使うことができ、柔軟なアクセス制御を行えるところが、他のサービスにない点です。ClientIdによるアクセス制御は、数台のデバイスでアクセスできるAPIを制御したいような場合に、かなり有効に働くと思います。

多くの人に製品を使っていただくような場合では、セキュリティアップデートの記事のように、トークンを利用した認証をしっかり行った方が良いです。

※ちなみに、Milkcocoa以外にもMQTTのClient IDを使ってアクセス制御しているサービスは存在します。

MQTTクライアントからも使える

冒頭でも言ったように、Client ID自体はMQTTの仕様なので、MQTTクライアントからMilkcocoaを使う場合にもアクセス制御は出来ます。

MQTTクライアントを作成する際に指定するClient IDを同じようにセキュリティルールで指定すればOKです。

不特定多数に利用されるWeb側のコードには注意が必要

Client IDはクライアントごとにユニークである必要がありますが、Web側のコードに書いてしまうと不特定多数のブラウザが同じClient IDになってしまうためWeb側でClient IDを指定することはお勧めしません(そもそもWebにあげた時点で、Client IDが見られてしまう可能性が高いのであまり意味がないです)。

この場合は上のセキュリティルールの例のように、「不特定多数のデバイスはon(push), queryだけができ、特定のClient IDの端末のみpushが行える」といった仕様にすることは可能です。

おわりに

今回は、デバイスのシンプルなアクセス制御の方法を紹介しました。

この機能について開発者の私自身も、このシンプルさが「Milkcocoaっぽい」と感じていて、とてもお気に入りの機能です。

この方法を使うことで、IoT用途の利用がよりしやすくなったのではないかと思いますので、是非試して頂けると幸いです。