AWS IoT Coreでのセキュリティのベストプラクティス
このセクションでは、AWS IoT Core のセキュリティのベストプラクティスについて説明します。産業における IoT ソリューションのセキュリティルールについては、「産業における IoT ソリューションにおける 10 のセキュリティゴールデンルール
AWS IoT での MQTT 接続の保護
AWS IoT Core
デバイスフリートでの MQTT 接続の中断の影響と重大度は、多くの要因によって異なります。具体的には次のとおりです。
-
ユースケース (例えば、デバイスが AWS IoT に送信するデータ、データの量、データの送信頻度など)。
-
MQTT クライアント設定 (例えば、自動再接続設定、関連するバックオフタイミング、MQTT 永続セッションの使用など)。
-
デバイスリソースの制約。
-
切断の根本原因、その積極性、永続性。
クライアント ID の競合や潜在的な悪影響を回避するには、各デバイスまたはモバイルアプリケーションに、AWS IoT メッセージブローカーへの MQTT 接続に使用できるクライアント ID を制限する AWS IoT または IAM ポリシーがあることを確認します。例えば、IAM ポリシーを使用すると、既に使用中のクライアント ID を使用することによりデバイスが意図せず別のデバイスの接続を閉じないようにすることができます。詳細については、「認可」を参照してください。
フリート内のすべてのデバイスには、意図したアクションのみを認可する権限を持つ認証情報が必要です。これには、メッセージの発行や特定のスコープとコンテキストを持つトピックへのサブスクライブなどの AWS IoT MQTT アクションが含まれますが、これらに限定されません。特定のアクセス許可ポリシーは、ユースケースによって異なる場合があります。ビジネス要件とセキュリティ要件に最も合うアクセス許可ポリシーを特定します。
アクセス許可ポリシーの作成と管理を簡素化するために、AWS IoT Core ポリシー変数 および IAM ポリシー変数を使用できます。ポリシー変数はポリシーに配置でき、ポリシーが評価されると、変数はデバイスのリクエストから取得された値に置き換えられます。ポリシー変数を使用して、複数のデバイスにアクセス許可を付与する単一のポリシーを作成できます。AWS IoT アカウント設定、認証メカニズム、 AWS IoT メッセージブローカーへの接続に使用されるネットワークプロトコルに基づいて、ユースケースに関連するポリシー変数を特定できます。ただし、最良のアクセス許可ポリシーを記述するには、使用状況と脅威モデル
例えば、デバイスを AWS IoT レジストリに登録した場合、AWS IoT ポリシーでモノのポリシー変数を使用して、モノの名前、モノのタイプ、モノの属性値などのモノのプロパティに基づいてアクセス許可を付与または拒否できます。モノ名は、モノが AWS IoT に接続されるときに送信される MQTT 接続メッセージのクライアント ID から取得されます。モノのポリシー変数は、モノが TLS 相互認証を使用して MQTT を介して AWS IoT に接続するとき、または、認証された Amazon Cognito ID を使用して WebSocket プロトコルを介して MQTT に接続するときに置き換えられます。AttachThingPrincipal API を使用して、証明書と認証された Amazon Cognito ID をモノにアタッチできます。iot:Connection.Thing.ThingName は、クライアント ID の制限を適用するために便利なモノのポリシー変数です。次の AWS IoT ポリシー例では、登録されたモノの名前を、AWS IoT メッセージブローカーへの MQTT 接続のクライアント ID として使用する必要があります。
進行中のクライアント ID の競合を特定する場合は、AWS IoT の CloudWatch Logs を有効にして使用できます。クライアント ID の競合のために AWS IoT メッセージブローカーが切断する MQTT 接続ごとに、次のようなログレコードが生成されます。
{ "timestamp": "2019-04-28 22:05:30.105", "logLevel": "ERROR", "traceId": "02a04a93-0b3a-b608-a27c-1ae8ebdb032a", "accountId": "123456789012", "status": "Failure", "eventType": "Disconnect", "protocol": "MQTT", "clientId": "clientId01", "principalId": "1670fcf6de55adc1930169142405c4a2493d9eb5487127cd0091ca0193a3d3f6", "sourceIp": "203.0.113.1", "sourcePort": 21335, "reason": "DUPLICATE_CLIENT_ID", "details": "A new connection was established with the same client ID" }
{$.reason= "DUPLICATE_CLIENT_ID" } などの CloudWatch Logs フィルターを使用して、クライアント ID が競合するインスタンスを検索したり、CloudWatch メトリクスフィルターおよび対応する CloudWatch アラームを設定して、継続的なモニタリングとレポートを作成したりできます。
AWS IoTDevice Defender
AWS IoT Device Advisor を使用して、デバイスが AWS IoT Core に確実に接続でき、セキュリティのベストプラクティスに従うことができることを検証できます。
以下の資料も参照してください。
デバイスのクロックを同期化させる
デバイスの時刻を正確に保つことが重要です。X.509 証明書には有効期限の日時があります。デバイスのクロックは、サーバー証明書が現在も有効であることを確認するために使用されます。商用 IoT デバイスを構築する場合は、製品が販売される前に長期間保管される可能性があることに注意してください。この間、リアルタイムクロックがドリフトし、電池が放電する可能性があるため、工場での設定時間では不十分です。
ほとんどのシステムでは、デバイスのソフトウェアに Network Time Protocol (NTP) クライアントを含める必要があります。デバイスは、AWS IoT Core への接続を試行する前に、NTP サーバーと同期するまで待機する必要があります。これが不可能な場合は、後続の接続が成功するように、ユーザーがデバイスの時刻を設定する方法を提供する必要があります。
デバイスが NTP サーバーと同期されると、AWS IoT Core との接続を開くことができます。許容されるクロックスキューの量は、接続で何をしようとしているかによって異なります。
サーバー証明書の検証
デバイスが最初に AWS IoT を操作するために行うことは、安全な接続を開くことです。デバイスを AWS IoT に接続するときは、別のサーバーが AWS IoT を偽装しておらず、実際に AWS IoT と通信していることを確認してください。各 AWS IoT サーバーには、iot.amazonaws.com ドメインに対して発行された証明書がプロビジョニングされます。この証明書は、ドメインの ID と所有権を確認した、信頼された認証局から AWS IoT に発行されました。
AWS IoT Core がデバイスを接続するときに最初に行うことの 1 つは、デバイスにサーバー証明書を送信することです。デバイスは、iot.amazonaws.com に接続する予定だったことと、その接続の最後のサーバーが、そのドメインの信頼された機関からの証明書を持っていることを確認できます。
TLS 証明書は X.509 形式で、組織の名前、場所、ドメイン名、有効期間などのさまざまな情報が含まれています。有効期間は、notBefore と notAfter と呼ばれる時間値のペアとして指定されます。AWS IoT Core のようなサービスは、サーバー証明書に限られた有効期間 (例えば 1 年間) を使用し、古い証明書の有効期限が切れる前に新しい証明書を提供し始めます。
デバイスごとの単一の ID を使用する
クライアントごとに 1 つの ID を使用します。通常、デバイスでは X.509 クライアント証明書が使用されます。ウェブおよびモバイルアプリケーションは Amazon Cognito ID を使用します。これにより、デバイスにきめ細かなアクセス許可を適用できます。
例えば、電球とサーモスタットの 2 つの異なるスマートホームオブジェクトからステータス更新を受け取る携帯電話デバイスで構成されるアプリケーションがあるとします。電球は、バッテリーレベルのステータスを送信し、サーモスタットは温度を報告するメッセージを送信します。
AWS IoT はデバイスを個別に認証し、各接続を個別に処理します。承認ポリシーを使用してきめ細かなアクセス制御を適用できます。サーモスタットのポリシーを定義して、トピックスペースに公開することができます。電球に別のポリシーを定義して、別のトピックスペースに公開することができます。最後に、これらのデバイスからのメッセージを受信するために、サーモスタットと電球のトピックへの接続とサブスクライブのみを許可するモバイルアプリのポリシーを定義できます。
最小権限の原則を適用し、デバイスごとのアクセス許可を可能な限り絞り込みます。すべてのデバイスまたはユーザーは、既知のクライアント ID との接続、特定され、固定された一連のトピックの公開とサブスクライブのみを許可する AWS IoT ポリシーを AWS IoT に持つ必要があります。
バックアップとして 2 番目の AWS リージョン を使用する
バックアップとしてデータのコピーを 2 番目のAWS リージョン に格納することを検討してください。[AWS IoT のディザスタリカバリ]
ジャストインタイムプロビジョニングの使用
各デバイスの手動作成とプロビジョニングには、時間がかかる場合があります。AWS IoT は、デバイスが最初に AWS IoT に接続するときにプロビジョニングするテンプレートを定義する方法を提供します。詳細については、「ジャストインタイムプロビジョニング」を参照してください。
AWS IoT Device Advisor のテストを実行するためのアクセス許可
次のポリシーテンプレートは、AWS IoT Device Advisor テストケースを実行するために必要な最小限のアクセス許可と IAM エンティティを示しています。your-device-role-arn を、前提条件の下で作成したデバイスロール Amazon Resource Name (ARN) に置き換える必要があります。
デバイスアドバイザーのクロスサービスでの混乱した代理の防止
混乱した代理問題は、アクションを実行する許可を持たないエンティティが、より特権のあるエンティティにアクションを実行するように強制できるセキュリティの問題です。AWS では、サービス間でのなりすましによって、混乱した代理問題が発生する場合があります。サービス間でのなりすましは、あるサービス (呼び出し元サービス) が、別のサービス (呼び出し対象サービス) を呼び出すときに発生する可能性があります。呼び出し元サービスは、本来ならアクセスすることが許可されるべきではない方法でその許可を使用して、別のお客様のリソースに対する処理を実行するように操作される場合があります。これを防ぐため、AWS では、アカウント内のリソースへのアクセス許可が付与されたサービスプリンシパルですべてのサービスのデータを保護するために役立つツールを提供しています。
リソースポリシー内のグローバル条件コンテキストキー aws:SourceArn と aws:SourceAccount を使用して、リソースについてデバイスアドバイザーが別のサービスに付与する許可を制限することをお勧めします。両方のグローバル条件コンテキストキーを使用しており、それらが同じポリシーステートメントで使用されるときは、aws:SourceAccount 値と、aws:SourceArn 値のアカウントが同じアカウント ID を使用する必要があります。
aws:SourceArn の値は、スイート定義リソースの ARN である必要があります。スイート定義リソースは、デバイスアドバイザーで作成したテストスイートを指します。
混乱した代理問題から保護するための最も効果的な方法は、リソースの完全な ARN を指定して aws:SourceArn グローバル条件コンテキストキーを使用することです。リソースの完全な ARN が不明な場合や、複数のリソースを指定する場合は、aws:SourceArn グローバルコンテキスト条件キーを使用して、ARN の未知部分をワイルドカード (*) で表します。例えば、arn:aws:iotdeviceadvisor:*: です account-id:suitedefinition/*
次の例では、デバイスアドバイザーで aws:SourceArn および aws:SourceAccount グローバル条件コンテキストキーを使用して、混乱した代理問題を回避する方法を示します。