

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 中的安全最佳實務 AWS IoT Core
<a name="security-best-practices"></a>

本節包含 的安全最佳實務相關資訊 AWS IoT Core。如需產業 IoT 解決方案安全規則的相關資訊，請參閱[產業 IoT 解決方案的十大安全黃金法則](https://aws.amazon.com/blogs/iot/ten-security-golden-rules-for-industrial-iot-solutions/)。

## 在 中保護 MQTT 連線 AWS IoT
<a name="secure-mqtt"></a>

[AWS IoT Core](https://aws.amazon.com/iot-core/) 是一種受管雲端服務，可讓連線裝置輕鬆且安全地與雲端應用程式和其他裝置互動。 AWS IoT Core 支援 HTTP、[WebSocket](https://en.wikipedia.org/wiki/WebSocket) 和 [MQTT](https://en.wikipedia.org/wiki/MQTT)，這是一種輕量型通訊協定，專為容忍間歇性連線而設計。如果您 AWS IoT 使用 MQTT 連線至 ，則每個連線都必須與稱為用戶端 ID 的識別符建立關聯。MQTT 用戶端 ID 是獨一無二的，可識別 MQTT 連線。如果使用已針對另一個連線宣告的用戶端 ID 建立新連線， AWS IoT 訊息中介裝置會捨棄舊連線，以允許新連線。每個 AWS 帳戶 和每個 中的用戶端 IDs都必須是唯一的 AWS 區域。這表示您不需要在 外部 AWS 帳戶 或 內跨區域強制執行用戶端 IDs 的全域唯一性 AWS 帳戶。

在您的裝置機群上捨棄 MQTT 連線的影響和嚴重性，取決於多個因素。其中包含：
+ 您的使用案例 （例如，您的裝置傳送的資料 AWS IoT、多少資料，以及傳送資料的頻率）。
+ 您的 MQTT 用戶端組態 (例如，自動重新連線設定、關聯的退避計時，以及 [MQTT 持久性工作階段](mqtt.md#mqtt-persistent-sessions)的使用)。
+ 裝置資源限制。
+ 連線中斷的根本原因，以及其積極性和持久性。

為了避免用戶端 ID 衝突及其潛在的負面影響，請確定每個裝置或行動應用程式都有 AWS IoT 或 IAM 政策，以限制哪些用戶端 IDs 可用於與 AWS IoT 訊息中介裝置的 MQTT 連線。例如，您可以使用 IAM 政策，藉由使用已在使用中的用戶端 ID 來防止裝置意外關閉其他裝置的連線，如需詳細資訊，請參閱[Authorization](iot-authorization.md)。

機群中的所有裝置都必須具有僅授權預期動作權限的登入資料，其中包括 （但不限於） AWS IoT MQTT 動作，例如發佈訊息或訂閱具有特定範圍和內容的主題。特定的許可政策可能因您的使用案例而異。識別最符合您業務和安全性需求的許可政策。

為了簡化許可政策的建立和管理，您可以使用 [AWS IoT Core 政策變數](iot-policy-variables.md) 和 [IAM 政策變數](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_variables.html)。政策變數可以放置在政策中，當政策接受評估時，該變數可由來自裝置的請求值取代。透過使用政策變數，您可以建立一個單一政策，以授與許可給多個裝置。您可以根據 AWS IoT 帳戶組態、身分驗證機制和用於連線至 AWS IoT 訊息代理程式的網路通訊協定，來識別使用案例的相關政策變數。不過，若要撰寫最佳的許可政策，您需要考慮您使用案例的特定情形和[威脅模型](https://en.wikipedia.org/wiki/Threat_model)。

例如，如果您在 AWS IoT 登錄檔中註冊裝置，您可以在 AWS IoT 政策中使用[物件政策變數](thing-policy-variables.md)，根據物件名稱、物件類型和物件屬性值等物件屬性來授予或拒絕許可。物件名稱是從物件連線時所傳送的 MQTT 連線訊息中的用戶端 ID 取得 AWS IoT。當物件使用 TLS 交互身分驗證 AWS IoT 透過 MQTT 連線至 ，或使用已驗證的 [Amazon Cognito 身分](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-identities.html)透過 WebSocket 通訊協定連線至 MQTT 時，會取代物件政策變數。您可以使用 [AttachThingPrincipal](https://docs.aws.amazon.com/iot/latest/apireference/API_AttachThingPrincipal.html) API，將憑證和驗證的 Amazon Cognito 身分連接到物件。`iot:Connection.Thing.ThingName` 是一種實用的物件政策變數，可強制執行用戶端 ID 限制。下列範例 AWS IoT 政策要求已註冊物件的名稱做為 MQTT 連線至 AWS IoT 訊息代理程式的用戶端 ID：

****  

```
{
	"Version":"2012-10-17",		 	 	 
	"Statement": [
		{
			"Effect": "Allow",
			"Action": "iot:Connect",
			"Resource": [
				"arn:aws:iot:us-east-1:123456789012:client/${iot:Connection.Thing.ThingName}"
			]
		}
	]
}
```

如果您想要識別持續的用戶端 ID 衝突，您可以啟用和使用 [CloudWatch Logs AWS IoT](cloud-watch-logs.md)。對於 AWS IoT 訊息中介裝置因用戶端 ID 衝突而中斷連線的每個 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"
}
```

您可以使用 [CloudWatch Logs 篩選條件](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/MonitoringLogData.html) (例如 `{$.reason= "DUPLICATE_CLIENT_ID" }`) 來搜尋用戶端 ID 衝突的執行個體，或設定 [CloudWatch 指標篩選條件](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/MonitoringPolicyExamples.html)與對應的 CloudWatch 警示，以供持續監控和報告。

您可以使用 [AWS IoT Device Defender](https://aws.amazon.com/iot-device-defender/) 來識別過度寬鬆 AWS IoT 和 IAM 政策。 AWS IoT Device Defender 也提供稽核檢查，如果您機群中的多個裝置使用相同的用戶端 ID 連線到 AWS IoT 訊息中介裝置，則會通知您。

您可以使用 AWS IoT Device Advisor 來驗證您的裝置是否可以可靠地連線至 AWS IoT Core 並遵循安全最佳實務。

### 另請參閱
<a name="mqtt-security-see-also"></a>
+ [AWS IoT Core](https://aws.amazon.com/iot-core/)
+ [AWS IoT的安全性功能](authentication.md)
+ [AWS IoT Core 政策變數](iot-policy-variables.md)
+ [IAM 政策變數](https://docs.aws.amazon.com/service-authorization/latest/reference/reference_policies_variables.html)
+ [Amazon Cognito 身分](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-identities.html)
+ [AWS IoT Device Defender](https://aws.amazon.com/iot-device-defender/)
+ [的 CloudWatch Logs AWS IoT](cloud-watch-logs.md)

## 讓裝置的時鐘保持同步
<a name="device-clock"></a>

在裝置上保持準確的時間是很重要的。X.509 憑證具到期日期和時間。裝置上的時鐘用來驗證伺服器憑證是否仍然有效。如果您正在建置商用 IoT 裝置，請記住您的產品在售出前可能會長期存放。在這段期間，即時時鐘可能會漂移，電池可能會放電，因此在工廠設定時間並不足夠。

對大多數系統而言，這表示裝置的軟體必須包含網路時間通訊協定 (NTP) 用戶端。裝置應該等到與 NTP 伺服器同步時，才會嘗試連線到 AWS IoT Core。如果無法這麼做，系統應該提供方法讓使用者能夠設定裝置的時間，以便讓後續連線成功。

一旦裝置與 NTP 伺服器同步，就可以開啟與 AWS IoT Core的連線。允許的時脈偏移會取決於您嘗試對連線執行的操作而定。

## 驗證伺服器憑證
<a name="validate-server-cert"></a>

裝置與 互動的第一件事 AWS IoT 是開啟安全連線。當您將裝置連線至 時 AWS IoT，請確定您正在與 交談 AWS IoT ，而不是另一個伺服器模擬 AWS IoT。每個 AWS IoT 伺服器都會佈建為網域發行的憑證`iot.amazonaws.com`。此憑證 AWS IoT 是由信任的憑證授權機構核發給 ，該授權機構會驗證我們網域的身分和擁有權。

當裝置連線時，最先 AWS IoT Core 做的一件事就是將伺服器憑證傳送給裝置。裝置可以驗證其預期連線至 `iot.amazonaws.com`，以及該連線端的伺服器是否擁有來自該網域之受信任授權單位的憑證。

TLS 憑證採用 X.509 格式，並包含各種資訊，例如組織的名稱、位置、網域名稱和有效期間。有效期間以稱為 `notBefore` 和 `notAfter` 的一對時間值來指定。這類服務會對其伺服器憑證 AWS IoT Core 使用有限的有效期間 （例如一年），並在舊憑證過期之前開始提供新的憑證。

## 使用每個裝置單一身分
<a name="cert-per-device"></a>

使用每個用戶端單一身分。裝置通常使用 X.509 用戶端憑證。Web 與行動應用程式使用 Amazon Cognito 身分。這可讓您將精細的許可套用至您的裝置。

例如，您有由行動電話裝置組成的應用程式，該裝置從兩個不同的智慧型家用物件 (燈泡和電熱器) 接收狀態更新。燈泡會傳送其電池的電量狀態，恆溫器會傳送報告溫度的訊息。

AWS IoT 會個別驗證裝置，並個別處理每個連線。您可以使用授權政策套用微調的存取控制。您可以定義電熱器的政策，以允許電熱器發佈至主題空間。您可以為燈泡定義個別的政策，以允許燈泡發佈至不同的主題空間。最後，您可以定義行動應用程式的政策，只允許它連線和訂閱電熱器和燈泡的主題，以接收來自這些裝置的訊息。

盡可能套用最低權限的政策，並盡可能降低每個裝置的許可範圍。所有裝置或使用者在 中都應有一個 AWS IoT 政策 AWS IoT ，只允許它與已知的用戶端 ID 連線，並發佈和訂閱已識別和固定的主題集。

## 使用秒 AWS 區域 作為備份
<a name="use-second-region"></a>

請考慮在一秒內將資料的副本 AWS 區域 儲存為備份。請注意，名為 [的災難復原 AWS IoT](https://aws.amazon.com/solutions/implementations/disaster-recovery-for-aws-iot/) AWS 解決方案不再可用。雖然相關聯的 [GitHub 程式庫](https://github.com/awslabs/disaster-recovery-for-aws-iot)仍可存取，但已於 2023 年 7 月 AWS 棄用，不再提供維護或支援。若要實作您自己的解決方案或探索其他支援選項，請造訪[聯絡 AWS](https://aws.amazon.com/contact-us/)。如果有與您的帳戶相關聯的 AWS 技術客戶經理，請聯絡他們尋求協助。

## 使用及時佈建
<a name="use-jitp"></a>

手動建立和佈建每個裝置可能很耗時。 AWS IoT 提供一種方法來定義範本，以在首次連線時佈建裝置 AWS IoT。如需詳細資訊，請參閱[即時佈建](jit-provisioning.md)。

## 執行 AWS IoT Device Advisor 測試的許可
<a name="device-advisor-perms"></a>

下列政策範本顯示執行 AWS IoT Device Advisor 測試案例所需的最低許可和 IAM 實體。您需要將 *your-device-role-arn* 取代為在[先決條件](https://docs.aws.amazon.com/iot/latest/developerguide/device-advisor-workflow.html#device-advisor-workflow-prereqs)下建立的裝置角色 Amazon Resource Name (ARN)。

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": "iam:PassRole",
            "Resource": "arn:aws:iot:us-east-1:123456789012:thinggroup/your-thing-group",
            "Condition": {
                "StringEquals": {
                    "iam:PassedToService": "iotdeviceadvisor.amazonaws.com"
            }
        }
        },
        {
            "Sid": "VisualEditor1",
            "Effect": "Allow",
            "Action": [
                "execute-api:Invoke*",
                "iam:ListRoles",
                "iot:Connect",
                "iot:CreateJob",
                "iot:DeleteJob",
                "iot:DescribeCertificate",
                "iot:DescribeEndpoint",
                "iotjobsdata:DescribeJobExecution",
                "iot:DescribeJob",
                "iot:DescribeThing",
                "iotjobsdata:GetPendingJobExecutions",
                "iot:GetPolicy",
                "iot:ListAttachedPolicies",
                "iot:ListCertificates",
                "iot:ListPrincipalPolicies",
                "iot:ListThingPrincipals",
                "iot:ListThings",
                "iot:Publish",
                "iotjobsdata:StartNextPendingJobExecution",
                "iotjobsdata:UpdateJobExecution",
                "iot:UpdateThingShadow",
                "logs:CreateLogGroup",
                "logs:CreateLogStream",
                "logs:DescribeLogGroups",
                "logs:DescribeLogStreams",
                "logs:PutLogEvents",
                "logs:PutRetentionPolicy"
            ],
            "Resource": "*"
        },
        {
            "Sid": "VisualEditor2",
            "Effect": "Allow",
            "Action": "iotdeviceadvisor:*",
            "Resource": "*"
        }
    ]
}
```

## Device Advisor 跨服務預防混淆代理人
<a name="cross-service-confused-deputy-prevention-DA"></a>

混淆代理人問題屬於安全性議題，其中沒有執行動作許可的實體可以強制具有更多權限的實體執行該動作。在 中 AWS，跨服務模擬可能會導致混淆代理人問題。在某個服務 (*呼叫服務*) 呼叫另一個服務 (*被呼叫服務*) 時，可能會發生跨服務模擬。可以操縱呼叫服務來使用其許可，以其不應有存取許可的方式對其他客戶的資源採取動作。為了防止這種情況， AWS 提供工具，協助您保護所有 服務的資料，其服務主體已獲得您帳戶中資源的存取權。

若要限制 Device Advisor 為資源提供另一項服務的許可，我們推薦在資源政策中使用 [https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-sourcearn](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-sourcearn) 和 [https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-sourceaccount](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-sourceaccount) 全域條件內容索引鍵。如果同時使用全域條件內容金鑰，則在相同政策陳述式中使用 `aws:SourceAccount` 值和 `aws:SourceArn` 值中的帳戶時，必須使用相同的帳戶 ID。

`aws:SourceArn` 值必須是套件定義資源的 ARN。套件定義資源是指使用 Device Advisor 建立的測試套件。

防範混淆代理人問題最有效的方法，是使用 `aws:SourceArn` 全域條件內容金鑰，以及資源的完整 ARN。如果不知道資源的完整 ARN，或者如果您指定了多個資源，請使用 `aws:SourceArn` 全域條件內容金鑰，同時使用萬用字元 (`*`) 表示 ARN 的未知部分。例如 `arn:aws:iotdeviceadvisor:*:account-id:suitedefinition/*` 

下列範例示範如何使用 Device Advisor 中的 `aws:SourceArn` 和 `aws:SourceAccount` 全域條件內容金鑰，來預防混淆代理人問題。

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": {
        "Sid": "ConfusedDeputyPreventionExamplePolicy",
        "Effect": "Allow",
        "Principal": {
            "Service": "iotdeviceadvisor.amazonaws.com"
        },
        "Action": "sts:AssumeRole",
        "Condition": {
            "ArnLike": {
                "aws:SourceArn": "arn:aws:iotdeviceadvisor:us-east-1:123456789012:suitedefinition/ygp6rxa3tzvn"
        },
            "StringEquals": {
                "aws:SourceAccount": "123456789012"
        }
        }
    }
}
```