全部產品
Search
文件中心

IoT Platform:MQTT協議雲網關裝置接入樣本(阿里雲FC認證)

更新時間:Jun 30, 2024

裝置通過MQTT協議雲網關接入物聯網平台時,裝置身份可以由自訂認證認證,裝置可以使用認證中CN資訊進行註冊。本文以MQTT協議雲網關三方認證的阿里雲FC認證為例,介紹如何將裝置接入物聯網平台。

使用前必讀

本文操作步驟以普通使用者權限為例。如果您在操作過程中涉及到管理員權限才能執行的操作,可嘗試使用sudo命令執行。

前提條件

已購買尊享型企業版執行個體。本樣本購買華東2(上海)地區的尊享型執行個體。具體操作,請參見購買企業版執行個體

背景資訊

物聯網平台提供MQTT雲網關功能,支援裝置通過Function Compute提供的三方認證、自訂認證、OCSP、自訂通訊Topic等能力認證並接入物聯網平台進行通訊,實現多種物聯網業務情境。

MQTT協議雲網關裝置認證和通訊說明,請參見MQTT協議雲網關概述

準備工作

本文樣本使用開發環境:Ubuntu 22.04版本作業系統。

步驟一:產生自訂認證

  1. 登入Ubuntu作業系統。

  2. 執行以下命令產生裝置端和服務端的根憑證檔案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
  3. 根據根憑證檔案root-ca.crt,自訂服務端認證。

    1. 執行以下命令產生服務端密鑰檔案server.key

      openssl genrsa -out server.key 2048
    2. 執行命令touch openssl.cnf建立檔案openssl.cnf

    3. 執行命令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
    4. 執行以下命令產生服務端請求檔案server.csr

      openssl req -new -key server.key -config openssl.cnf -out server.csr
    5. 執行以下命令產生服務端認證檔案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
    6. 執行以下命令驗證服務端認證。

      openssl verify -CAfile root-ca.crt server.crt
  4. 根據根憑證檔案root-ca.crt,自訂裝置端認證。

    1. 執行以下命令產生裝置端密鑰檔案client.key

      openssl genrsa -out client.key 2048
    2. 執行以下命令產生裝置端認證請求檔案client.csr,設定CNClient_123

      openssl req -new -key client.key -out client.csr -subj "/CN=Client_123"
    3. 執行以下命令產生裝置端認證檔案client.crt

      openssl x509 -req -days 365 -sha256 -in client.csr -CA root-ca.crt -CAkey root-ca.key -CAcreateserial -out client.crt
    4. 執行以下命令驗證裝置端認證。

      openssl verify -CAfile root-ca.crt client.crt

自訂認證檔案如下:

image

步驟二:建立裝置認證的FC函數

  1. 登入Function Compute控制台,在左側導覽列,單擊服務及函數

  2. 在頂部功能表列,選擇華東2(上海)地區,然後在服務列表頁面,單擊建立服務

  3. 建立服務面板,填寫服務名稱,例如:IoT_Service,然後單擊確定。

  4. 函數管理頁面,單擊建立函數

  5. 建立函數頁面,配置以下配置項,然後單擊建立

    image

  6. 函數詳情頁面,將範例程式碼替換為以下代碼,單擊部署代碼

    認證函數將裝置認證的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)

步驟三:建立雲網關產品

  1. 登入物聯網平台控制台,在頁面左上方選擇華東2(上海)地區。

  2. 執行個體概覽頁面,單擊目標尊享型執行個體。

  3. 在左側導覽列,選擇裝置管理 > 雲網關,單擊添加雲網關

  4. 配置如下資訊,單擊確定

    服務端認證server.crt服務端認證私密金鑰server.key裝置根憑證root-ca.crt。參數詳細說明,請參見添加雲網關

    image

  5. 在雲網關列表,複製網關URL儲存。

    image

步驟四:開發裝置端程式

  1. 返回Ubuntu作業系統。

  2. 執行以下命令,安裝依賴庫。

    sudo apt-get install build-essential gcc make cmake cmake-gui cmake-curses-gui
    sudo apt-get install libssl-dev
  3. 執行以下命令,安裝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 ..
  4. 執行命令touch aiot_mqtt_demo.c建立裝置類比程式檔案aiot_mqtt_demo.c

  5. 執行命令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;
    }
  6. 在以上代碼中修改實際裝置相關參數,然後按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個字元。

本樣本相關庫的安裝、認證的製作和裝置程式的開發完成,如下所示:image

步驟五:編譯運行

  1. 執行以下命令編譯運行裝置程式檔案aiot_mqtt_demo.c

    gcc -o aiot_mqtt_demo aiot_mqtt_demo.c -lpaho-mqtt3cs
    ./aiot_mqtt_demo

    運行成功後,通過FC認證函數返回的deviceNameClient_123會作為物聯平台裝置的DeviceName,在物聯網平台控制台執行個體下的裝置管理 > 裝置頁面,自動建立裝置Client_123,裝置狀態顯示為線上image

  2. (可選)在物聯網平台控制台執行個體下的監控營運 > Log Service頁面,查看裝置上報資料。image