【macOS】デバイスとAWS IoTとの接続設定を行うスクリプトをかいたった:証明書の設定からThing登録まで行う

AWS IoTには多くの機能が提供されています。その機能を試す際にデバイス側に証明書を配置したり、AWS IoT側でThing登録をしたりしておく必要があったりするのですが、毎回その作業を行うのが億劫になってきたので簡単なスクリプトを書きました。
2018.09.26

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

どうも!大阪オフィスの西村祐二です。

AWS IoTには多くの機能が提供されています。

その機能を試す際にデバイス側に証明書を配置したり、AWS IoT側でThing登録をしたりしておく必要があったりするのですが、毎回その作業を行うのが億劫になってきたので簡単なスクリプトを書きました。コードが汚い点についてはご了承ください…。

個人の検証用で作成したもので、利用する際は検証時のみで利用してください。何か問題が発生しても責任を取る事はできませんのでご注意ください。

環境

  • mac
  • macOS High Sierra
  • 10.13.6

事前準備

  • 下記ドキュメントを参考にaws cliの設定を行っておいてください。

https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-chap-getting-started.html

  • MQTTクライアントをインストールしておいてください。
$ brew install mosquitto

スクリプト

下記のスクリプトを適当に保存して実行してください。私の場合は「connect-aws-iot.sh」というファイル名にしております。

connect-aws-iot.sh

#!/usr/bin/env bash

#----------------------------------------------------------
# 引数があるか確認
#----------------------------------------------------------
if [ "${1}" = "" ]
then
    echo -e "Error:no argument.  \nex) connect-aws-iot.sh <thing name>"
    exit
fi

#----------------------------------------------------------
# 変数設定
#----------------------------------------------------------
cd `dirname ${0}`

readonly BASE_DIR='.'

readonly CERTIFICATE_PEM=${BASE_DIR}/cert-${1}.crt
readonly PRIVATE_KEY=${BASE_DIR}/private-${1}.key
readonly PUBLIC_KEY=${BASE_DIR}/public-${1}.key

readonly ROOT_CA_PEM=${BASE_DIR}/rootCA.pem
readonly ROOT_CA_DL_LINK='https://www.symantec.com/content/en/us/enterprise/verisign/roots/VeriSign-Class%203-Public-Primary-Certification-Authority-G5.pem'


#----------------------------------------------------------
#  root CA 証明書を確認:ないとき取得
#----------------------------------------------------------
if [ ! -e ${ROOT_CA_PEM} ]; then
    wget ${ROOT_CA_DL_LINK} -O ${ROOT_CA_PEM} > /dev/null 2>&1
fi


#----------------------------------------------------------
#  AWS IoTの設定:証明書と鍵がないとき作成
#----------------------------------------------------------
if [ ! -e ${CERTIFICATE_PEM} ] || [ ! -e ${PRIVATE_KEY} ] || [ ! -e ${PUBLIC_KEY} ]; then
    # {thing name}-policy としてのIAM Policyを作成
    aws iot create-policy --policy-name ${1}-policy --policy-document '{"Version": "2012-10-17","Statement": [{"Effect": "Allow","Action": "iot:*","Resource": "*"}]}' > /dev/null 2>&1
    
    # thing 作成
    aws iot create-thing --thing-name ${1} > /dev/null 2>&1
    
    # 証明書と鍵を作成
    ARN_OF_CERTIFICATE=`aws iot create-keys-and-certificate --set-as-active --certificate-pem-outfile ${CERTIFICATE_PEM} --private-key-outfile ${PRIVATE_KEY} --public-key-outfile ${PUBLIC_KEY} --query "certificateArn"`
    echo ${ARN_OF_CERTIFICATE}
    
    # Policyと証明書を紐付け
    eval aws iot attach-principal-policy --policy-name ${1}-policy --principal ${ARN_OF_CERTIFICATE}
    
    # Thingと証明書を紐付け
    eval aws iot attach-thing-principal  --thing-name ${1} --principal ${ARN_OF_CERTIFICATE}
fi


#----------------------------------------------------------
#  AWS IoTのエンドポイント取得
#----------------------------------------------------------
ENDPOINT=`aws iot describe-endpoint --query "endpointAddress"`


#----------------------------------------------------------
#  トピック「topic/test」にPublish
#----------------------------------------------------------
CMD="mosquitto_pub --cafile ${ROOT_CA_PEM} --cert ${CERTIFICATE_PEM} --key ${PRIVATE_KEY} -h ${ENDPOINT} -p 8883 -q 1 -d -t topic/test -i ${1}-id -m '{\"key\": \"hello world from ThingName:${1}\"}'"
eval ${CMD}

スクリプトの挙動を記載します。

  • 引数の有無を確認します。
  • ローカルにrootCA証明書がなければ取得します。
  • ローカルに証明書と鍵がなければ、証明書類の取得、AWS IoTでの設定を行います。
  • AWS IoTのエンドポイントを取得します。
  • トピック「topic/test」にPublishします。

スクリプトを実行するまえに

AWS IoTのマネージメントコンソールのテストから「topic/test」をサブスクライブしておきます。

スクリプトが完了した後に「topic/test」トピックにPublishされます。

これでAWS IoTと接続、通信できているかの確認を行います。

スクリプトを実行してみる

▼下記で実行できます。

$ sh ./connect-aws-iot.sh hoge
  • 引数にThing名を指定してください。
  • 今回の場合は「hoge」というThing名

▼下記のようなログが取得されるかと思います。

arn:aws:iot:ap-northeast-1:00000000000:cert/xxxxxxxxxxxxxxxxxxxxはAWS IoTに登録された証明書のARNになります

$ sh connect-aws-iot.sh hoge
"arn:aws:iot:ap-northeast-1:00000000000:cert/xxxxxxxxxxxxxxxxxxxx"
Client hoge-id sending CONNECT
Client hoge-id received CONNACK
Client hoge-id sending PUBLISH (d0, q1, r0, m1, 'topic/test', ... (42 bytes))
Client hoge-id received PUBACK (Mid: 1)
Client hoge-id sending DISCONNECT

▼マネージメントコンソールでもPublishされたことが確認できます。

{
"key": "hello world from ThingName:hoge"
}

▼ローカルには取得した証明書類が保存されます。

証明書にはprivate-<Thing name>.keyのようにコマンド実行時に付与したThing名が設定されます。

$ ls
private-hoge.key
rootCA.pem
cert-hoge.crt
connect-aws-iot.sh
public-hoge.key

▼AWS IoT上に作成されたリソースは下記になります。

  • 証明書

デバイスと紐づく証明書IDはスクリプト実行時に出力されたarn:aws:iot:ap-northeast-1:00000000000:cert/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxのところが一致した証明書になります。

  • ポリシー

  • モノ(Thing)

さいごに

いかがだったでしょうか。

AWS IoTとの接続を行うための証明書の設定からThing登録まで行うスクリプトを書いてみました。実は削除のスクリプトも作ったのですが誤動作が怖いので掲載は自重しました。

誰かの参考になれば幸いです。