设备通过MQTT协议云网关接入物联网平台时,设备身份可以由自定义证书认证,设备可以使用证书中CN信息进行注册。本文以MQTT协议云网关三方认证的阿里云FC认证为例,介绍如何将设备接入物联网平台。
使用前必读
本文操作步骤以普通用户权限为例。如果您在操作过程中涉及到管理员权限才能执行的操作,可尝试使用sudo
命令执行。
前提条件
已购买尊享型企业版实例。本示例购买华东2(上海)地域的尊享型实例。具体操作,请参见购买企业版实例。
背景信息
物联网平台提供MQTT云网关功能,支持设备通过函数计算提供的三方认证、自定义证书、OCSP、自定义通信Topic等能力认证并接入物联网平台进行通信,实现多种物联网业务场景。
MQTT协议云网关设备认证和通信说明,请参见MQTT协议云网关概述。
准备工作
本文示例使用开发环境:Ubuntu 22.04版本操作系统。
步骤一:生成自定义证书
登录Ubuntu操作系统。
执行以下命令生成设备端和服务端的根证书文件
root-ca.crt
。openssl req \ -new \ -newkey rsa:2048 \ -days 365 \ -nodes \ -x509 \ -subj "/C=CN/O=Aliyun IOT/CN=IoT CA" \ -keyout root-ca.key \ -out root-ca.crt
根据根证书文件
root-ca.crt
,自定义服务端证书。执行以下命令生成服务端密钥文件
server.key
。openssl genrsa -out server.key 2048
执行命令
touch openssl.cnf
新建文件openssl.cnf
。执行命令
vi openssl.cnf
进入文件,填入以下内容后按Esc键,输入:wq
保存。[policy_match] countryName = cn stateOrProvinceName = optional organizationName = optional organizationalUnitName = optional commonName = supplied emailAddress = optional [req] default_bits = 2048 distinguished_name = req_distinguished_name req_extensions = req_ext x509_extensions = v3_req prompt = no [req_distinguished_name] commonName = Server [req_ext] subjectAltName = @alt_names [v3_req] subjectAltName = @alt_names [alt_names] DNS.1 = *.mqtt.iothub.aliyuncs.com DNS.2 = *.igw.iothub.aliyuncs.com
执行以下命令生成服务端请求文件
server.csr
。openssl req -new -key server.key -config openssl.cnf -out server.csr
执行以下命令生成服务端证书文件
server.crt
。openssl x509 -req -days 365 -sha256 -in server.csr -CA root-ca.crt -CAkey root-ca.key -CAcreateserial -out server.crt -extensions v3_req -extfile openssl.cnf
执行以下命令验证服务端证书。
openssl verify -CAfile root-ca.crt server.crt
根据根证书文件
root-ca.crt
,自定义设备端证书。执行以下命令生成设备端密钥文件
client.key
。openssl genrsa -out client.key 2048
执行以下命令生成设备端证书请求文件
client.csr
,设置CN为Client_123
。openssl req -new -key client.key -out client.csr -subj "/CN=Client_123"
执行以下命令生成设备端证书文件
client.crt
。openssl x509 -req -days 365 -sha256 -in client.csr -CA root-ca.crt -CAkey root-ca.key -CAcreateserial -out client.crt
执行以下命令验证设备端证书。
openssl verify -CAfile root-ca.crt client.crt
自定义证书文件如下:
步骤二:创建设备认证的FC函数
在顶部菜单栏,选择华东2(上海)地域,然后在服务列表页面,单击创建服务。
在创建服务面板,填写服务名称,例如:IoT_Service,然后单击确定。
在函数管理页面,单击创建函数。
在创建函数页面,配置以下配置项,然后单击创建。
在函数详情页面,将示例代码替换为以下代码,单击部署代码。
认证函数将设备证书的CN作为deviceName返回。
# -*- coding: utf-8 -*- import logging import json import time import enum import random import string class Request: def __init__(self, json_str): self.clientId = None self.username = None self.password = None self.certificateCommonName = None for key, value in json.loads(json_str).items(): setattr(self, key, value) class Response: def __init__(self): self.deviceName = None self.result = 'true' self.message = 'success' def handler(self, request): # 将设备证书的CN作为deviceName返回 self.deviceName = request.certificateCommonName return json.dumps(self.__dict__) def handler(event, context): request = Request(event) return Response().handler(request)
步骤三:创建云网关产品
在实例概览页面,单击目标尊享型实例。
在左侧导航栏,选择设备管理 > 云网关,单击添加云网关。
配置如下信息,单击确定。
服务端证书为
server.crt
,服务端证书私钥为server.key
,设备根证书为root-ca.crt
。参数详细说明,请参见添加云网关。在云网关列表,复制网关URL保存。
步骤四:开发设备端程序
返回Ubuntu操作系统。
执行以下命令,安装依赖库。
sudo apt-get install build-essential gcc make cmake cmake-gui cmake-curses-gui sudo apt-get install libssl-dev
执行以下命令,安装MQTT开源库Paho。
git clone https://github.com/eclipse/paho.mqtt.c.git mkdir build && cd build cmake ../paho.mqtt.c -DPAHO_WITH_SSL=TRUE -DCMAKE_INSTALL_PREFIX="/usr/lib" make -j sudo make install && cd ..
执行命令
touch aiot_mqtt_demo.c
新建设备模拟程序文件aiot_mqtt_demo.c
。执行命令
vi aiot_mqtt_demo.c
进入文件,填入以下内容。#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include "MQTTClient.h" int msgarrvd(void *context, char *topicName, int topicLen, MQTTClient_message *message) { printf("message recv < topic [%s], payload [%s]\n", topicName, (char *)message->payload); MQTTClient_freeMessage(&message); MQTTClient_free(topicName); return 1; } int main(int argc, char* argv[]) { MQTTClient client; MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer; MQTTClient_SSLOptions ssl_opts = MQTTClient_SSLOptions_initializer; int rc; /* 创建一个mqtt_client, 待替换 */ const char *host = "ssl://iot-0****.igw.iothub.aliyuncs.com:1883"; const char *client_id = "12345"; MQTTClient_create(&client, host, client_id, MQTTCLIENT_PERSISTENCE_NONE, NULL); MQTTClient_setCallbacks(client, NULL, NULL, msgarrvd, NULL); /* 配置建连参数:证书、用户名、密码,待替换*/ ssl_opts.trustStore = "root-ca.crt"; ssl_opts.privateKey = "client.key"; ssl_opts.keyStore = "client.crt"; conn_opts.ssl = &ssl_opts; conn_opts.username = "sdk_test01"; conn_opts.password = "hello123"; /* mqtt完成建连 */ if ((rc = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS) { printf("Failed to connect, return code %d\n", rc); exit(EXIT_FAILURE); } printf("connect success username %s, password %s\n", conn_opts.username, conn_opts.password); /* 订阅消息 */ MQTTClient_subscribe(client, "/user/aiot_mqtt_demo_downraw", 1); /* 生成消息并循环发布消息 */ MQTTClient_message pubmsg = MQTTClient_message_initializer; const char *topic = "/user/aiot_mqtt_demo_upraw"; pubmsg.payload = "Hello Service!"; pubmsg.payloadlen = (int)strlen(pubmsg.payload); pubmsg.qos = 1; for(int i = 0; i < 100; i++) { MQTTClient_publishMessage(client, topic, &pubmsg, NULL); printf("message send > topic [%s], payload [%s]\n", topic, (char *)pubmsg.payload); sleep(10); } /* 断开连接并删除client */ MQTTClient_disconnect(client, 10000); MQTTClient_destroy(&client); return rc; }
在以上代码中修改实际设备相关参数,然后按Esc键,输入
:wq
保存文件aiot_mqtt_demo.c
。参数
说明
host
MQTT云网关设备接入地址,格式为
ssl://${网关接入地址}:${端口号}
。${网关接入地址}
和${端口号}
为本文“步骤三:创建云网关产品”中复制保存的网关URL中的域名和自定义端口号。client_id
(可选)客户端ID,需自定义,长度不可超过64个字符。建议使用设备的MAC地址或SN码,方便您识别区分不同的客户端。
ssl_opts.trustStore
设备端根证书
root-ca.crt
的路径。ssl_opts.privateKey
设备端密钥文件
client.key
的路径。ssl_opts.keyStore
设备端证书文件
client.crt
的路径。conn_opts.username
MQTT的userName。
userName支持英文字母、数字、短划线(-)、下划线(_)、at(@)、英文句号(.)和英文冒号(:),长度限制为4~32个字符。userName在产品维度下不可重复。
conn_opts.password
MQTT的password。
password支持英文字母、数字、短划线(-)、下划线(_)、at(@)、英文句号(.)和英文冒号(:),长度限制为1~32个字符。
本示例相关库的安装、证书的制作和设备程序的开发完成,如下所示: