Thanapon Tapala

Backend Developer

Embedded Developer

Smart Farmer

Maker

Thanapon Tapala

Backend Developer

Embedded Developer

Smart Farmer

Maker

Blog Post

[AWS-IoT] Device Provisioning สำหรับสเกลอุปกรณ์หลายๆตัว-1

March 17, 2022 AWS, ESP32, MQTT, PlatformIO
[AWS-IoT] Device Provisioning สำหรับสเกลอุปกรณ์หลายๆตัว-1

สวัสดีครับ เชื่อว่าหลายๆคนต้องมีปัญหาเวลาจะ provision อุปกรณ์หลายร้อยตัวกัน โดยทาง AWS เขาก็ได้แนะนำไว้ 3 วิธีด้วยกันซึ่งก็จะมี

  • Provisioning devices that have device certificates: เป็นวิธีแรกโดยที่เราจะต้องเพิ่ม certificate เข้าไปกับ firmware เลย
  • Provisioning by trusted user: วิธีนี้เราจะทำการเขียน Application มาตัวหนึ่งแล้วให้ตัว Application ซึ่งอาจจะเป็น Web application/Mobile app มา register อุปกรณ์แทน
  • Provisioning by claim: วิธีนี้เราจะต้องสร้าง Claim certificate มา 1 ตัวเพื่อที่จะได้เพิ่มเข้าไปกับ firmware หลังจาก มองง่ายๆเหมือนทำ default certificate ขึ้นมาเพื่อใช้สำหรับลงทะเบียนครั้งแรก

ซึ่งในบทความนี้เราจะมาลองใช้วิธี Provisioning by claim กันนะครับ โดยที่เราจะแยกเป็น 2 ส่วนนะครับ

ส่วนแรกจะเป็น AWS IoT Core ซึ่งจะเป็นการ config IoT service ให้ provision ผ่าน claim certificate

อีกส่วนจะเป็นการ Build firmware สำหรับ Provision ใน ESP32 ซึ่งจะเขียนผ่าน Visual Studio Code ที่ลง extension PlatformIO ในการพัฒนาครับ

มาเริ่มกันเลยครับ

สร้าง Claim certificate สำหรับใช้เป็น default certificate ใน Things

  • เข้าไปที่ AWS IoT management จากนั้นเลือก Secure => Policies => Create policy ตรงแท็ปเมนูด้านข้าง

Policy จะเป็นตัวกำหนดสิทธิในการเข้าถึง service ต่างๆ ของ AWS ผ่าน ARN ID

  • ทำการสร้าง Policy โดยที่ผมจะกำหนดเป็น

Policy name: esp32_claim_policy

Policy document: จะกำหนดตาม Json ด้านล่างนะครับ ซึ่งเราจะต้องเปลี่ยน <aws-region>, <aws-account-id> และก็ <templateName> เองนะครับ อย่าลืม!!

templateName จะขอใช้เป็นชื่อ esp32_fleet_prov_template

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "iot:Connect"
            ],
            "Resource": [
                "*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "iot:Publish",
                "iot:Receive"
            ],
            "Resource": [
                "arn:aws:iot:<aws-region>:<aws-account-id>:topic/$aws/certificates/create/*",
                "arn:aws:iot:<aws-region>:<aws-account-id>:topic/$aws/provisioning-templates/<templateName>/provision/*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": "iot:Subscribe",
            "Resource": [
                "arn:aws:iot:<aws-region>:<aws-account-id>:topicfilter/$aws/certificates/create/*",
                "arn:aws:iot:<aws-region>:<aws-account-id>:topicfilter/$aws/provisioning-templates/<templateName>/provision/*"
            ]
        }
    ]
}
  • เมื่อแก้ไขเสร็จแล้ว กด Create ได้เลยครับ
  • ขั้นต่อไปสร้าง Claim policy สำหรับ embed ลงใน Things ของเรา เลือก Secure => Certificates => Create
  • เมื่อสร้างเสร็จแล้วทำการ Attach policy ที่เราสร้างไปเมื่อกี้เข้าไปได้เลย

สร้าง Fleet policy สำหรับใช้งานหลังจากที่ Register Things เสร็จแล้ว

  • ยังอยู่ที่ AWS-IoT อยู่นะครับ เลือก Secure => Policies => Create

Policy name: esp32_fleet_policy

Policy document: กำหนดค่าตาม JSON ด้านล่างนะครับ อย่าลืมเปลี่ยน <aws-region>, <aws-account-id> เหมือนเดิม

ตัวอย่างจะเป็นการ Allow MQTT event ทั้งหมดใน AWS IoT นะครับ

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "iot:Connect",
            "Resource": "arn:aws:iot:<aws-region>:<aws-account-id>:*"
        },
        {
            "Effect": "Allow",
            "Action": "iot:Publish",
            "Resource": "arn:aws:iot:<aws-region>:<aws-account-id>:*"
        },
        {
            "Effect": "Allow",
            "Action": "iot:Subscribe",
            "Resource": "arn:aws:iot:<aws-region>:<aws-account-id>:*"
        },
        {
            "Effect": "Allow",
            "Action": "iot:Receive",
            "Resource": "arn:aws:iot:<aws-region>:<aws-account-id>:*"
        }
    ]
}
  • เสร็จแล้วเราก็จะได้ Policy ทั้งหมด 2 ตัวด้วยกัน

สร้าง Fleet Provisioning Template สำหรับ Register Things

  • เข้าไปที่ Connect => Fleet provisioning templates => Create
  • สร้าง Template กันเลยจากนั้นกด Next

Template name: esp32_fleet_prov_template

Provisioning Role: เลือก Create role ขึ้นมาเลยซึ่งผมจะใช้ชื่อ esp32_fleet_prov_role

Pre Provisioning Hook: ติ้ก “Don’t use pre-provisioning action

Optional settings: ในส่วนนี้ ติ้ก “Use the AWS IoT registry to manage your device fleet option” ด้วย

  • จากนั้นจะไปหน้า “Define AWS IoT policies” เลือก Use an existing AWS IoT policy แล้วเลือก fleet policy name ที่เราสร้างมาก่อนหน้านี้ esp32_fleet_policy
  • ต่อมา Define AWS IoT registry settings ซึ่งจะเป็นส่วนที่กำหนด Things กัน

Thing name prefix: esp32dkc_

Select a group: สร้าง Group name ขึ้นมาใหม่เลย เช่น esp32dkc_group

  • หลังจากกด Create template แล้วเราจะมาที่หน้า Give certificates or users permission to provision devices

ในส่วนนี้ให้เลือก Use a certificate previously generated by AWS IoT ซึ่งในส่วนนี้เราจะเลือก Claim certificate ที่เราสร้างไปก่อนหน้านี้นะครับ [esp32_claim_policy ซึ่งมันจะมี Certificate ID ด้วยต้องเลือกให้ตรงกันนะครับ]

ในส่วนนี้ไม่ต้อง Attach Policy เข้าไปนะครับ จากนั้น Enable Template โลด

ในส่วนการ Config AWS IoT Core ก็เรียบร้อยแล้วครับ ส่วนต่อไปจะเป็น Firmware สำหรับ Provisioning ผ่าน MQTT API ที่ทาง AWS เข้า Provide ไว้ให้กัน


Flow การทำงานคร่าวๆในฝั่ง Firmware จะเหมือนกับ Sequence Diagram ด้านล่างนี้นะครับ

ในส่วนของการเชื่อมต่อ MQTT เข้ากับ AWS IoT นั้นเราจะใช้ Claim certificate ที่ generate จาก step ก่อนหน้านี้นะครับซึ่งในที่นี้จะเป็น certificate ที่เรา attach policy => esp32_claim_policy ที่ขึ้นต้นด้วย eb8…. [มันจะเป็น เลขหรืออักษรที่ Random มานะครับ จะไม่เหมือนกัน]

ส่วน MQTT connection จะต้องใช้ X.509 certificate โดยที่เราจะต้องมี Amazon Root CA, Device Certificate และก็ Private key ในการ Authenticate นะครับ ซึ่งเดี๋ยวผมจะมาต่อให้ในอีก 1 Blog สำหรับเรื่อง Firmware เลยละกัน

  1. เริ่มต้น Device ทำการ Subscription Topic “$aws/certificates/create/json/accepted” และ “$aws/certificates/create/json/rejected” สำหรับรับ Response body จากการสร้าง Certificate
  2. Publish MQTT message ไปที่ “$aws/certificates/create/json” ซึ่งภายใน message body เราไม่ต้องกำหนดอะไรไปให้เป็นค่าว่างๆไว้
  3. เมื่อ Publish สำเร็จ Response body จะวิ่งเข้ามาที่ Topic “$aws/certificates/create/json/accepted” นี้ซึ่งจะมี format ดังนั้น
// Accept response boy
{
    "certificateId": "string",
    "certificatePem": "string",
    "privateKey": "string",
    "certificateOwnershipToken": "string"
}
// Reject response boy
{
    "statusCode": int,
    "errorCode": "string",
    "errorMessage": "string"
}
  1. หลังจากที่เราได้รับ Response body มาแล้วจะต้องทำการ handle response body โดยที่เราจะต้องเก็บ certificatePem กับ privateKey ไว้ภายใน Device เพื่อใช้ในการ Authenticate จริงๆ ส่วน certificateOwnershipToken จะใช้ในการ Register Things
  2. Subscription Topic “$aws/provisioning-templates/<template_name>/provision/json/accepted กับ “$aws/provisioning-templates/<template_name>/provision/json/rejected” เพื่อรับ Response body ในกรณีที่ Register สำเร็จหรือเกิด Error ขึ้น ส่วน <template_name> จะเป็น ชื่อของ template ที่เราตั้งก่อนหน้านี้ esp32_fleet_prov_template
// Accept response body
{
    "deviceConfiguration": {
        "string": "string",
        ...
    },
    "thingName": "string"
}
// Reject response body
{
    "statusCode": int,
    "errorCode": "string",
    "errorMessage": "string"
}
  1. Publish MQTT message ไปที่ topic “$aws/provisioning-templates/<template_name>/provision/json” อย่าลืมเปลี่ยน <template_name> เป็น esp32_fleet_prov_template โดยที่ message body จะเป็น

ในส่วนนี้จะต้องแนบ certificateOwnershipToken พร้อมกับ Parameter ไปด้วยซึ่งจะเป็น SerialNumber ของอุปกรณ์

{
    "certificateOwnershipToken": "string",
    "parameters": {
        "SerialNumber": "string"
    }
}
  1. เมื่อ Publish message สำเร็จ AWS-IoT จะทำการ Activate Certificate และสร้าง Things ขึ้นมาใหม่ โดยจะใช้ชื่อ esp32dkc_……. และ Things group จะอยู่ใน group esp32dkc_group นี้

เป็นอันว่าจบการ Provision ผ่าน Claim certificate นะครับ ส่วนเนื้อหาถัดไปจะเป็นการ Build firmware ของ ESP32 นะครับ รอติดตามชมได้เลยครับ สำหรับวันนี้ขอบคุณและสวัสดีครับ

อัพเดทภาคต่อครับ https://thanapon.info/aws-iot-device-provisioning-2/


Device provisioning

AWS provides several different ways to provision a device and install unique client certificates on it. This section describes each way and how to select the best one for your IoT solution. These options are described in detail in the white paper titled, Device Manufacturing and Provisioning with X.509 Certificates in AWS IoT Core

Device provisioning MQTT API

Taggs: