Amazon IoT Core 中的安全最佳实践 - Amazon IoT Core
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅中国的 Amazon Web Services 服务入门

Amazon IoT Core 中的安全最佳实践

本节包含有关 Amazon IoT Core 的安全最佳实践的信息。有关更多信息,请参阅 IoT 解决方案的十大安全黄金规则

在 Amazon IoT 中保护 MQTT 连接

Amazon IoT Core 是一种托管云服务,可让连接的设备轻松、安全地与云应用程序和其它设备进行交互。Amazon IoT Core 支持 HTTP、WebSocketMQTT,后者是一种专为承受间歇性连接而设计的轻量级通信协议。如果您使用 MQTT 连接到 Amazon IoT,则您的每个连接都必须与一个称为客户端 ID 的标识符关联。MQTT 客户端 ID 唯一地标识 MQTT 连接。如果使用已为另一个连接声明的客户端 ID 建立新连接,则 Amazon IoT 消息代理将删除旧连接以允许新连接。客户端 ID 在每个Amazon Web Services 账户和每个Amazon Web Services 区域中必须是唯一的。这意味着您不需要在Amazon Web Services 账户之外或在您的Amazon Web Services 账户内跨区域强制执行客户端 ID 的全局唯一性。

在设备实例集上删除 MQTT 连接的影响和严重程度取决于许多因素。其中包括:

  • 您的使用案例(例如,您的设备向 Amazon IoT 发送的数据、数据量以及发送数据的频率)。

  • 您的 MQTT 客户端配置(例如,自动重新连接设置、关联的退避计时以及使用 MQTT 持久性会话)。

  • 设备资源限制。

  • 断开连接的根本原因、其主动性和持久性。

要避免客户端 ID 冲突及其潜在的负面影响,请确保每个设备或移动应用程序都有一个 Amazon IoT 或 IAM policy,以限制可以将哪些客户端 ID 用于与 Amazon IoT 消息代理的 MQTT 连接。例如,您可以使用 IAM policy 防止设备无意中通过使用已在使用的客户端 ID 关闭其它设备的连接。有关更多信息,请参阅Authorization

您实例集中的所有设备必须具有相应的凭证,这些凭证仅具有授权执行预期操作的权限,包括(但不限于)Amazon IoT MQTT 操作,例如发布消息或订阅具有特定作用域和上下文的主题。具体的权限策略可能因您的使用案例而异。确定最能满足您的业务和安全要求的权限策略。

要简化权限策略的创建和管理,您可以使用 Amazon IoT Core 策略变量IAM policy 变量。策略变量可以放在策略中,并且在评估策略时,变量将由来自设备请求的值替换。使用策略变量,您可以创建单个策略以授予对多个设备的权限。您可以根据用于连接到 Amazon IoT 消息代理的 Amazon IoT 帐户配置、身份验证机制和网络协议,为您的用例确定相关的策略变量。但是,要编写最佳权限策略,应考虑使用案例和威胁模型的具体情况。

例如,如果您在 Amazon IoT 注册表中注册设备,您可以在 Amazon IoT 策略中使用事物策略变量根据事物名称、事物类型和事物属性值等事物属性来授予或拒绝权限。事物名称从事物连接至 Amazon IoT 时发送的 MQTT Connect 消息中的客户端 ID 获取。当事物通过使用 TLS 双向身份验证的 MQTT 或通过基于 WebSocket 的 MQTT 协议(使用经过身份验证的 Amazon Cognito 身份)连接至 Amazon IoT 时,事物策略变量将被替换。您可以使用 AttachThingPrincipal API 将证书和经过身份验证的 Amazon Cognito 身份附加到事物上。iot:Connection.Thing.ThingName 是一个有用的策略变量,可用来强制执行客户端 ID 限制。以下示例 Amazon IoT 策略要求将已注册事物的名称用作与 Amazon IoT 消息代理的 MQTT 连接的客户端 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 冲突,可以启用和使用适用于 Amazon IoT 的 CloudWatch Logs。对于 Amazon 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 筛选条件(如 {$.reason= "DUPLICATE_CLIENT_ID" })来搜索客户端 ID 冲突的实例,或者设置 CloudWatch 指标筛选条件和相应的 CloudWatch 告警以进行连续监控和报告。

您可以使用 Amazon IoT Device Defender 识别过度宽容的 Amazon IoT 和 IAM policy。Amazon IoTDevice Defender 还提供审核检查,如果实例集中的多个设备使用相同的客户端 ID 连接到 Amazon IoT 消息代理,则会通知您。

您可以使用 Amazon IoT Device Advisor,验证您的设备是否可以可靠地连接到 Amazon IoT Core 并遵守安全最佳实践。

另请参阅

使设备的时钟保持同步

请务必确保您的设备上有准确的时间。X.509 证书具有到期日期和时间。设备上的时钟用于验证服务器证书是否仍有效。如果您要构建商用 IoT 设备,请记住,您的产品在出售前可能会存放较长时间。在此期间,实时时钟可能会出现偏移误差,并且电池可能会放电,因此在工厂设置时间是不够的。

对于大多数系统,这意味着设备的软件必须包含网络时间协议 (NTP) 客户端。设备应等待,直到它与 NTP 服务器同步,然后再尝试连接到 Amazon IoT Core。如果无法做到这一点,系统将为用户提供一种设置设备时间的方法,以便后续连接成功。

设备与 NTP 服务器同步后,便能打开与 Amazon IoT Core 的连接。允许的时钟偏移量取决于您尝试通过此连接执行的操作。

验证服务器证书

为了与 Amazon IoT 进行交互,设备执行的第一项操作是打开安全连接。在将设备连接到 Amazon IoT 时,请确保正在与 Amazon IoT(而不是模拟 Amazon IoT 的其它服务器)进行通信。为每个 Amazon IoT 服务器提供了针对 iot.amazonaws.com 域颁发的证书。此证书已由受信任的证书颁发机构颁发给 Amazon IoT,该机构验证了我们的身份和域所有权。

在设备连接时,Amazon IoT Core 执行的第一项操作是向设备发送服务器证书。设备可以验证它们是否希望连接到 iot.amazonaws.com,并验证位于该连接一端的服务器是否拥有来自该域的受信任颁发机构的证书。

TLS 证书采用 X.509 格式,并包含各种信息,例如组织的名称、位置、域名和有效期。有效期被指定为一对时间值(分别名为 notBeforenotAfter)。像 Amazon IoT Core 这样的服务对其服务器证书使用有限的有效期(例如,一年),并在旧证书到期之前开始提供新证书。

每个设备使用一个身份

每个客户端使用一个身份。设备通常使用 X.509 客户端证书。Web 和移动应用程序使用 Amazon Cognito Identity。这使您能够对设备应用细化权限。

例如,您有一个由手机设备构成的应用程序,这些设备接收来自两个不同的智能家居对象(灯泡和恒温器)的状态更新。灯泡发送电池电量的状态,恒温器发送报告温度的消息。

Amazon IoT 单独对各个设备进行身份验证,并单独处理每个连接。您可以使用授权策略应用精细访问控制。您可以为恒温器定义一个策略,该策略允许恒温器发布到主题空间的策略。您可以为灯泡定义一个单独策略,该策略允许灯泡发布到不同的主题空间。最后,您可以为移动应用程序定义一个策略,该策略只允许它连接到和订阅恒温器和灯泡的主题以接收来自这些设备的消息。

应用最小权限原则,并尽可能缩小每个设备的权限范围。所有设备或用户都应在 Amazon IoT 中有一个 Amazon IoT 策略,该策略仅允许设备或用户使用已知的客户端 ID 进行连接,并发布和订阅一组已确定的固定主题。

使用次级Amazon Web Services 区域作为备份

考虑在次级Amazon Web Services 区域中存储数据的副本以作为备份。有关更多信息,请参阅 Amazon IoT 的灾难恢复

使用即时预调配

手动创建和预调配每个设备是一项耗时的工作。Amazon IoT 可让您定义模板以便在设备首次连接到 Amazon IoT 时对其进行预调配。有关更多信息,请参阅即时预调配

运行 Amazon IoT Device Advisor 测试的权限

下面的策略模板显示了运行 Amazon IoT Device Advisor 测试用例所需的最低权限和 IAM 实体。您需要将 your-device-role-arn 替换为您根据先决条件创建的设备角色 Amazon Resource Name (ARN)。

{ "Version": "2012-10-17", "Statement": [ { "Sid": "VisualEditor0", "Effect": "Allow", "Action": "iam:PassRole", "Resource": "your-device-role-arn", "Condition": { "StringEquals": { "iam:PassedToService": "iotdeviceadvisor.amazonaws.com" } } }, { "Sid": "VisualEditor1", "Effect": "Allow", "Action": [ "execute-api:Invoke*", "iam:ListRoles", // Required to list device roles in the Device Advisor console "iot:Connect", "iot:CreateJob", "iot:DeleteJob", "iot:DescribeCertificate", "iot:DescribeEndpoint", "iot:DescribeJobExecution", "iot:DescribeJob", "iot:DescribeThing", "iot:GetPendingJobExecutions", "iot:GetPolicy", "iot:ListAttachedPolicies", "iot:ListCertificates", "iot:ListPrincipalPolicies", "iot:ListThingPrincipals", "iot:ListThings", "iot:Publish", "iot:StartNextPendingJobExecution", "iot: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 防范跨服务混淆代理

混淆代理问题是一个安全问题,即没有执行操作权限的实体可能会迫使更具权限的实体执行该操作。在 Amazon 中,跨服务模拟可能会导致混淆代理问题。一个服务(呼叫服务) 调用另一项服务(所谓的服务)时,可能会发生跨服务模拟。可以操纵调用服务,使用其权限以在其他情况下该服务不应有访问权限的方式对另一个客户的资源进行操作。为了防止这种情况,Amazon 提供可帮助您保护所有服务的服务委托人数据的工具,这些服务委托人有权限访问账户中的资源。

我们建议在资源策略中使用 aws:SourceArnaws:SourceAccount 全局条件上下文键,以限制 Device Advisor 为其它服务提供的资源访问权限。如果使用两个全局条件上下文键,在同一策略语句中使用时,aws:SourceAccount 值和 aws:SourceArn 值中的账户必须使用相同的账户 ID。

aws:SourceArn 的值必须是套件定义资源的 ARN。套件定义资源是指您使用 Device Advisor 创建的测试套件。

防范混淆代理问题最有效的方法是使用 aws:SourceArn 全局条件上下文键和资源的完整 ARN。如果不知道资源的完整 ARN,或者正在指定多个资源,请针对 ARN 未知部分使用带有通配符 (*) 的 aws:SourceArn 全局上下文条件键。例如,arn:aws:iotdeviceadvisor:*:account-id:suitedefinition/*

以下示例演示如何使用 Device Advisor 中的 aws:SourceArnaws: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" } } } }