AWS IoTの認証処理をSORACOM Beamにオフロードする #soracom

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

ども、大瀧です。
先週金曜日に開催されたソラコムDeveloper Conference #0に私もLTとして参加させていただきました。クラウド寄りのエンジニアとハード寄りのエンジニアが入り交じった白熱したカンファレンスイベントだったと思います。次回の12/11 SORACOM User Group Tokyoも要注目ですね!

さて、その中で公開されたSORACOMアップデートのひとつが、先週ベータリリースされたAWS IoTのSORACOM Beam対応でした。そこで、今回はドキュメントを参考にしつつ実際に連携してみた様子をレポートします。

SORACOM BeamのAWS IoT連携とは

SORACOM BeamSORACOM Air SIMを搭載するマシンからのトラフィックをプロキシするサービスです。HTTP、MQTT、TCPプロトコルに対応し、TLS暗号化、ヘッダの付与、プロトコル変換などが行えます。

AWS IoTはAWSのIoT向けサービスとしてMQTT、HTTPに対応するメッセージブローカーをコアとし、デバイスのメタ情報や状態情報の管理を提供するマネージドサービスです。

両方の連携となるとHTTPとMQTTが共通のプロトコルですが、今回のアップデートは、AWS IoTのMQTTS X509証明書認証にSORACOM Beamが対応したものです。従来のBeamでは、MQTTSのパスワード認証にしか対応していませんでした。

今回の対応により、MQTTSのTLS暗号化処理とX509証明書認証処理をBeamにオフロードできるようになるため、TLS暗号化の負荷軽減と証明書管理がBeamで一括で行えるメリットがあります。

設定手順

現時点ではSORACOMユーザーコンソールでの設定がサポートされていないため、SORACOM CLIで設定を投入していくことになります。

こちらのエントリーにあるように、mosquittoとAWS CLIをインストールし、X509証明書を生成、cert.jsonファイルに保存しておきます。

$ aws iot create-keys-and-certificate --set-as-active > cert.json
$ cat cert.json
{
    "certificateArn": "arn:aws:iot:region:111111111111:cert/(略)",
    "certificatePem": "-----BEGIN CERTIFICATE-----\n(略)-----END CERTIFICATE-----\n",
    "keyPair": {
        "PublicKey": "-----BEGIN PUBLIC KEY-----\n(略)-----END PUBLIC KEY-----\n",
        "PrivateKey": "-----BEGIN RSA PRIVATE KEY-----\n(略)-----END RSA PRIVATE KEY-----\n"
    },
    "certificateId": "ASDF"
}
$

CA証明書はjqでJSONでの文字列形式に変換して保存(今回はca.txtファイル)おきましょう。

$ curl https://www.symantec.com/content/en/us/enterprise/verisign/roots/VeriSign-Class%203-Public-Primary-Certification-Authority-G5.pem | jq -R -s '' > ca.txt
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  1758  100  1758    0     0   4693      0 --:--:-- --:--:-- --:--:--  4688
$ cat ca.txt
"-----BEGIN CERTIFICATE-----\r\nMIIE0zCCA7ugAwIBAgIQGNrRniZ96LtKIVjNzGs7SjANBgkqhkiG9w0BAQUFADCB\r\nyjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL\r\nExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp\r\nU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW\r\nZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0\r\naG9yaXR5IC0gRzUwHhcNMDYxMTA4MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCByjEL\r\nMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW\r\nZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2ln\r\nbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJp\r\nU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9y\r\naXR5IC0gRzUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvJAgIKXo1\r\nnmAMqudLO07cfLw8RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKzj/i5Vbex\r\nt0uz/o9+B1fs70PbZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIz\r\nSdhDY2pSS9KP6HBRTdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQG\r\nBO+QueQA5N06tRn/Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+\r\nrCpSx4/VBEnkjWNHiDxpg8v+R70rfk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/\r\nNIeWiu5T6CUVAgMBAAGjgbIwga8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8E\r\nBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEwHzAH\r\nBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVy\r\naXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFH/TZafC3ey78DAJ80M5+gKv\r\nMzEzMA0GCSqGSIb3DQEBBQUAA4IBAQCTJEowX2LP2BqYLz3q3JktvXf2pXkiOOzE\r\np6B4Eq1iDkVwZMXnl2YtmAl+X6/WzChl8gGqCBpH3vn5fJJaCGkgDdk+bW48DW7Y\r\n5gaRQBi5+MHt39tBquCWIMnNZBU4gcmU7qKEKQsTb47bDN0lAtukixlE0kF6BWlK\r\nWE9gyn6CagsCqiUXObXbf+eEZSqVir2G3l6BFoMtEMze/aiCKm0oHw0LxOXnGiYZ\r\n4fQRbxC1lfznQgUy286dUV4otp6F01vvpX1FQHKOtw5rDgb7MzVIcbidJ4vEZV8N\r\nhnacRHr2lVz2XTIIM6RUthg/aFzyQkqFOFSDX9HoLPKsEdao7WNq\r\n-----END CERTIFICATE-----"
$

続いて、AWS IoTのエンドポイントをaws iot describe-endpointで確認しておきます。

$ aws iot describe-endpoint
{
    "endpointAddress": "ランダム文字列.iot.リージョン名.amazonaws.com"
}

そしておもむろに以下のJSONファイルをコピペで作成し、以下4点を転記しましょう。

  • value.destination : mqtts://<エンドポイント名>:8883
  • value.clientCerts.default.cert : cert.jsoncertificatePem
  • value.clientCerts.default.key : cert.jsonkeyPair.PrivateKey
  • value.clientCerts.default.ca : ca.txtの中身から前後の"を除去したもの
[
  {
    "key": "mqtt://beam.soracom.io:1883",
    "value": {
      "name": "MQTTTest",
      "destination": "mqtts://ランダム文字列.iot.リージョン名.amazonaws.com:8883",
      "enabled": true,
      "addSubscriberHeader": false,
      "useClientCert": true,
      "clientCerts": {
        "default": {
          "cert": "-----BEGIN CERTIFICATE-----\n(中略)-----END CERTIFICATE-----\n",
          "key": "-----BEGIN RSA PRIVATE KEY-----\n(中略)-----END RSA PRIVATE KEY-----\n",
          "ca": "-----BEGIN CERTIFICATE-----\r\n(中略)-----END CERTIFICATE-----"
        }
      }
    }
  }
]

このあとSORACOM CLIの引数にコピペで貼り付けるので、改行を除去しておきます。

$ echo `cat beam-config.json` > beam-config.txt

これで準備OKです。
SORACOMのグループを作成していなければ作成し、soracom group listコマンドでグループIDを控えておきます。

$ soracom group list
[
  {
    "operatorId": "OP0067881737",
    "groupId": "35d61131-076c-460e-82ea-e3b805546c2e",
    "createdAt": 1442393707982,
    "lastModifiedAt": 1445181395740,
    "configuration": {
    },
    "tags": {
      "name": "OtakiTest"
    },
    "createdTime": 1442393707982,
    "lastModifiedTime": 1445181395740
  }
]
$

では、soracom group update_configurationコマンドで設定を投入します。先ほどのbeam-config.txtファイルの内容をクリップボードにコピーしておき、--paramsオプションのシングルクォートまで入力したところでペースト、その後シングルクォートを入力し、実行します。

$ soracom group update_configuration --group-id 35d61131-076c-460e-82ea-e3b805546c2e --namespace SoracomBeam --params='<クリップボードの内容をペースト>'
  :(成功すればsoracom group listコマンドと同様のアップデート後の設定が表示される)
$

動作確認

それでは、mosquittoのPub/Subで接続先をBeamのエンドポイント、X509証明書を設定せずに暗号化なしのMQTT のポート1883にアクセスしてみましょう。

Subscriber側

$ mosquitto_sub -h beam.soracom.io -p 1883 -q 0 -d -t topic/test -i clientid1ls
Client clientid1ls sending CONNECT
Client clientid1ls received CONNACK
Client clientid1ls sending SUBSCRIBE (Mid: 1, Topic: topic/test, QoS: 0)

Publisher側

$ mosquitto_pub -h beam.soracom.io  -p 1883 -q 1 -d -t topic/test -i clientid2 -m '{"message":"hello!"}'
Client clientid2 sending CONNECT
Client clientid2 received CONNACK
Client clientid2 sending PUBLISH (d0, q1, r0, m1, 'topic/test', ... (20 bytes))

Publisher側のコマンドを実行すると、Subscriber側の端末に以下が表示され、MQTTメッセージがBeam経由でやり取りできていることがわかりますね。

Client clientid1ls received PUBLISH (d0, q0, r0, m0, 'topic/test', ... (20 bytes))
{"message":"hello!"}

ちなみに、Subscriber側のQoS指定を1にするとメッセージを受信することができず、Publisher側はQoSを1にしてもPUBACKが返ってこないことから、QoS 0のみ対応のようです。

この辺りの細かい仕様は追って精査していく必要がありそうですね。

まとめ

X509証明書をCLIで扱うのはかなり面倒なので、ユーザーコンソールでの設定がサポートされると嬉しいですね。また、Beamで証明書を複数扱えるような形式にも見えるので、今後の機能強化とドキュメントの充実に期待しつつ、バシバシ使っていきましょう!

参考URL