前回、IAM Roles Anywhereの検証をしてとても良い機能だなと感じました。
そういえば、証明書を使った認証にIoT Coreがあったな🤔と思い出し、同じことができるかやってみました!試したところちょっとした違いがあり、IoT Coreでやるのもアリかもしれません。
手順
IAMロールを作成
IoT Coreの認証情報プロバイダーが引き受けるIAMロールを作成します。 信頼されたエンティティタイプを
カスタム信頼ポリシー
にし、信頼ポリシーに以下のJSONを入力します。{
"Version": "2012-10-17",
"Statement": {
"Effect": "Allow",
"Principal": {
"Service": "credentials.iot.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
}
許可を追加で必要な権限を付与し
次へ
をクリックします。ロールに名前をつけて保存します。(iot-roles-anywhere-role)としました。
IoT ロールエイリアスを作成
IoT Coreの管理画面に移動し、管理メニュー -> セキュリティ -> ロールエイリアスを表示します。
ロールエイリアスを作成
をクリックします。ロールエイリアスに名前をつけ、先程作成したロールを選択して、
作成
をクリックします。
作成したロールエイリアスのARNをメモしておきます。
IoT ポリシーを作成
管理メニュー -> セキュリティ -> ポリシーへ移動します。
ポリシーを作成
をクリックします。ポリシー名を入力します。 ポリシードキュメントは以下を入力して、
作成
をクリックします。- ポリシー効果: 許可
- ポリシーアクション:iot:AssumeRoleWithCertificate
- ポリシーリソース:作成したロールエイリアスのARN
IoT モノのグループを作成
管理メニュー -> すべてのデバイス -> モノのグループへ移動します。
モノのグループを作成
をクリックします。モノの静的グループを作成
を選択して、次へ
をクリックします。モノのグループ名を入力して、
モノのグループを作成
をクリックします。作成したグループを選択して、ポリシータブを選択。
ポリシーを管理
をクリックします。先程作成したIoTポリシーを選択して、
ポリシーの更新
をクリックします。
IoT モノを作成
管理メニュー -> すべてのデバイス -> モノへ移動します。
モノを作成
をクリックします。1 つのモノを作成
を選択し、次へ
をクリックします。モノの名前
を入力して、先ほど作成したモノのグループを選択。次へ
をクリックします。新しい証明書を自動生成 (推奨)
を選択して、次へ
をクリックします。ポリシーはグループに割り当てているので未選択のまま、モノを作成`をクリックします。
デバイス証明書、パブリックキーファイル、プライベートキーファイル、RSA 2048 ビットキー: Amazon ルート CA 1をダウンロードしてから、
続行
をクリックします。
認証情報プロバイダーエンドポイントを取得する
aws iot describe-endpoint --endpoint-type iot:CredentialProvider
{
"endpointAddress": "abcdefghijklm.credentials.iot.ap-northeast-1.amazonaws.com"
}
一時認証情報を取得する
一時認証情報は認証情報プロバイダーエンドポイントにリクエストを送信して取得します。
export ENDPOINT=abcdefghijklm.credentials.iot.ap-northeast-1.amazonaws.com
export ROLE_ALIAS_NAME=alias-for-roles-anywhere
export CERT_PATH=certificate.pem.crt
export PRIVATE_KEY_PATH=private.pem.key
export THING_NAME=client1
export CA_CERT_PATH=AmazonRootCA1.pem
curl \
--cert ${CERT_PATH} \
--key ${PRIVATE_KEY_PATH} \
-H "x-amzn-iot-thingname: ${THING_NAME}" \
--cacert ${CA_CERT_PATH} \
https://${ENDPOINT}/role-aliases/${ROLE_ALIAS_NAME}/credentials
{
"credentials": {
"accessKeyId": "...",
"secretAccessKey": "...",
"sessionToken": "...",
"expiration": "2023-10-21T09:45:03Z"
}
}
credential_process の仕組みに合わせる
もうちょいです。
認証情報プロバイダーエンドポイントの出力をcredential_processのフォーマットに変換します。
{
"Version": 1,
"AccessKeyId": "an AWS access key",
"SecretAccessKey": "your AWS secret access key",
"SessionToken": "the AWS session token for temporary credentials",
"Expiration": "ISO8601 timestamp when the credentials expire"
}
- Versionを追加
- 各キーの先頭を大文字にする
先程の出力をパイプでjq
に繋いで変換します。
export ENDPOINT=abcdefghijklm.credentials.iot.ap-northeast-1.amazonaws.com
export ROLE_ALIAS_NAME=alias-for-roles-anywhere
export CERT_PATH=certificate.pem.crt
export PRIVATE_KEY_PATH=private.pem.key
export THING_NAME=client1
export CA_CERT_PATH=AmazonRootCA1.pem
curl \
--cert ${CERT_PATH} \
--key ${PRIVATE_KEY_PATH} \
-H "x-amzn-iot-thingname: ${THING_NAME}" \
--cacert ${CA_CERT_PATH} \
https://${ENDPOINT}/role-aliases/${ROLE_ALIAS_NAME}/credentials \
| jq '.credentials | {"Version":1, "AccessKeyId":.accessKeyId, "SecretAccessKey":.secretAccessKey, "SessionToken":.sessionToken, "Expiration":.expiration}'
{
"Version": 1,
"AccessKeyId": "...",
"SecretAccessKey": "...",
"SessionToken": "...",
"Expiration": "2023-10-21T09:52:49Z"
}
いい感じです。 うまく行ったのでこいつをシェルスクリプトにして保存します。
#!/bin/sh
ENDPOINT=ce4kc59ulqnzy.credentials.iot.ap-northeast-1.amazonaws.com
ROLE_ALIAS_NAME=alias-for-roles-anywhere
CERT_PATH=certificate.pem.crt
PRIVATE_KEY_PATH=private.pem.key
THING_NAME=client1
CA_CERT_PATH=AmazonRootCA1.pem
curl \
--cert ${CERT_PATH} \
--key ${PRIVATE_KEY_PATH} \
-H "x-amzn-iot-thingname: ${THING_NAME}" \
--cacert ${CA_CERT_PATH} \
https://${ENDPOINT}/role-aliases/${ROLE_ALIAS_NAME}/credentials \
| jq '.credentials | {"Version":1, "AccessKeyId":.accessKeyId, "SecretAccessKey":.secretAccessKey, "SessionToken":.sessionToken, "Expiration":.expiration}'
最後に.aws/config
に登録します。
[profile iotrolesanywhere]
credential_process = sh <<credential-helper.shのフルパス指定>>
AWSコマンドを実行します。
aws sts get-caller-identity --profile iotrolesanywhere
{
"UserId": "...",
"Account": "...",
"Arn": "arn:aws:sts::...:assumed-role/iot-roles-anywhere-role/..."
}
やったぜ
IAM Roles Anywhereとの違い
良いと思った点
- IoT Coreだと証明証が無料でマネージド! IAM Roles AnywhereではAWS Private CA(有料)もしくは自前管理のプライベートCAが必要
- 証明書の失効も簡単!
残念な点
- なんでIoTやねん感
- しっかりルールを明文化して管理しないと後々困りそう
参考
https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-configure-sourcing-external.html
https://docs.aws.amazon.com/ja_jp/iot/latest/developerguide/authorizing-direct-aws.html
おまけ
AWS発行のIoT Coreの証明書に使われているRootCA証明書をIAM Roles Anywhereで使おうとするとエラーになりました😝