亚马逊AWS官方博客
Certification Vending Machine: 智能设备接入AWS IoT平台解决方案
作者:刘洪曦 谢佰臻
背景介绍
AWS IoT平台为了保证终端设备通信的安全性,终端设备与 AWS IoT平台的MQTT通信使用基于证书的TLS 1.2双向认证体系。即IoT平台会验证当前设备使用的证书是否可信,同时,终端设备也会验证IoT平台使用的CA证书是否可信。
这种双向TLS验证模式就会要求设备上所使用的证书需要具备以下条件之一:
- IoT终端设备上所使用的证书为AWS IoT平台所签发的
- IoT终端设备上所使用的证书的CA证书预先导入了AWS IoT平台
所以开发者应该尽量确保每个设备上在出厂前,为每个设备写入独立的证书,并要求该证书为IoT平台所信任的证书。这种方式也是最安全高效的。
何时应当使用 Certificate Vending Machine?
对于部分已经生产出厂的IoT设备,可能在生产过程中没有预装IoT证书,但是又希望这些设备连接至AWS IoT平台。此时,Certificate Vending Machine (简称CVM) 可以作为给终端设备写入IoT证书的可行方案,让设备自行向IoT平台申请CA签发的授信证书,并且通过AWS IoT管理平台控制证书权限,确保物联网通信安全。
通过此项目的设计思想和相关源码,开发者可以快速开发出符合自己项目需求的CVM系统。但是需要注意,由于原设备没有IoT证书进行TLS双向认证,所以进行CVM的过程中需要注意三点:
- IoT设备与CVM系统通信时,原生并没有安全保护手段,所以需要在受信的DNS环境下进行,以防中间人攻击。或者采用其他安全链接的方式,例如使用HTTPS与CVM 服务器交互。
- IoT设备在利用CVM系统申请证书时,由于不具备用于标识设备的证书,所以IoT设备本身应该具备唯一标识符用于设备的身份标识,例如序列号,client ID或者product ID等,通过该身份标识进行证书申请及策略绑定。
- 所有通过CVM系统申请获发的证书的跟证书,均为AWS IoT平台默认使用的CA根证书。如果需要使用自定义的CA跟证书,请参考JITR证书认证方式。
CVM实现原理
整个项目实现可以分为三个模块: IoT设备端、CVM 系统和AWS IoT 平台
A.智能设备端
- 通过Https 请求证书
- 请求时携带设备序列号以及密钥
B. CVM 系统
- 用于向IoT设备提供远程访问接口。
- CVM系统作为代理向IoT平台申请每一个IoT设备的安全证书
- 校验请求合法性:通过校验请求的信息与数据库是否一致再决定是否为当前IoT设备申请证书, CVM使用内部Node.js 语言实现
- 使用了AWS 高性能的NoSQL数据库DynamoDB做为后台用户数据库。该数据库用来保存智能设备出厂时注册的设备ID、密钥和IoT平台证书等信息
- CVM系统通过查询DynamoDB数据中的关联关系,将IoT Thing Name,Certificate Policy以及Certificate ID关联至一起。同时,修改DynamoDB里的证书状态attribute,避免同一台设备遭到攻击后,重复向IoT平台大量申请证书的可能性,从而保证证书与设备的唯一性。
CVM系统的基本工作流程如下:
CVM系统的具体架构如下:
为了使CVM服务端更具稳定与扩展性,可以使用AWS API Gateway 和Lambda 来部署CVM。通过这种方式,不需要长时间维护和管理部署于EC2的CVM,而是通过IoT终端设备的证书申请的需求,灵活的调配AWS上的服务资源。
具体如下:
- IoT终端设备升级时请求接入IoT平台,发送相应API 请求到API Gateway申请IoT 证书
- AWS API Gateway调用申请证书的Lambda向IoT平台发起证书申请
- Lambda接收到请求后, 查询DynamoDB校验请求合法性
- 确认当前请求合法之后,通过API的形式,向IoT平台申请证书
- IoT平台返回当前IoT终端设备对应的证书,以及当前证书的certificate ID
- 通过查找DynamoDB中预先创建的对应关系,根据产品序列号,为当前申请到的证书附加对应的Thing Name(产品属性) 以及Policy(权限)
- Lambda进行证书的策略的绑定及DynamoDB关联关系表的更新
- 最终CVM将证书返回给IoT终端设备
使用EC2 替代API Gateway与Lambda的解决方案,其工作流程与搭建lambda的模式基本一致,仅在IoT终端设备与CVM系统通信时的调用关系上有所区别
- IoT终端设备升级时请求接入IoT平台,向CVM Server申请IoT 证书
- EC2接收到请求后,访问Device DB 校验请求合法性
- CVM Server通过API的形式,向IoT平台发起获取IoT安全证书的请求
- IoT平台返回当前IoT终端设备对应的证书,以及当前证书的certificate ID
- 通过查找DynamoDB中预先创建的对应关系,根据产品序列号,为当前证书附加对应的Thing Name(产品属性) 以及Policy(权限)
- 更新当前设备的所有关联信息到DynamoDB的关联关系表中
- CVM将证书返回给IoT终端设备
安全性说明
为了保证CVM系统的安全性,EC2 或者Lambda 函数需要赋予合适的IAM 角色, 使得CVM系统只能进行其授予的工作权限,以下用lambda举例如何为CVM系统分配正确的IAM角色权限。
首先,需要明确CVM系统需要具备一下IAM权限才能完整证书的申请及颁发过程:
- 访问AWS DynamoDB,用于查询、修改、更新DynamoDB中的设备关联表
- 访问IoT 平台,用于申请IoT终端设备证书
除IAM进行权限划分之外,需要在DynamoDB上创建一张关联关系表,用于设备与证书及策略的绑定关系,具体来说,需要在DynamoDB中创建如下数据库字段:
- productid : 智能设备ID
- accessToken: 智能设备Token
- timestamp : 证书申请时间戳
- applyState : 申请状态(如果申请过证书设置为-1,标记此设备已经注册过证书了)
- certID : 设备关联的证书ID
核心代码说明
以下的CVM server代码使用了 AWS Node.js SDK 提供的IOT接口完成证书申请以及附加对用的thingName和Policy。
CVM系统服务器端源码(EC2):
https://github.com/cncoder/cvm/tree/master/server
CVM系统服务器端源码(Lambda):
https://github.com/cncoder/cvm/tree/serverless/server
智能设备端源码:
https://github.com/cncoder/cvm/tree/serverless/device
参考链接
http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Iot.html
作者介绍:
刘洪曦,AWS解决方案架构师,负责基于AWS的云计算方案架构的咨询和设计,同时致力于帮助海外企业在AWS云服务的应用和推广。在加入AWS之前曾在思科担任网络顾问工程师,负责亚太区域物联网及安全业务的拓展及架构设计,在物联网,数据安全,网络架构有丰富部署实践经验。
谢佰臻,亚马逊AWS解决方案架构师实习生,擅长网站架设与网络应用开发,熟悉使用Node.js、Html5、Mysql数据库,对于Serverless 架构有自己的理解和实践经验。