Thanapon Tapala

Backend Developer

Embedded Developer

Smart Farmer

Maker

Thanapon Tapala

Backend Developer

Embedded Developer

Smart Farmer

Maker

Blog Post

[AWS-IoT] เรียกใช้ AWS Services ผ่าน Device Certificate X.509 โดยใช้ Credential-Provider [1]

January 8, 2023 Arduino, AWS
[AWS-IoT] เรียกใช้ AWS Services ผ่าน Device Certificate X.509 โดยใช้ Credential-Provider [1]

เป็นที่รู้กันอยู่แล้วนะครับว่าถ้าเราจะเชื่อมต่ออุปกรณ์เข้าไปที่ AWS IoT Core service นั้นเราจะใช้ X.509 certificates ผ่าน MQTT with TLS [MQTTs] ไปที่ AWS อีกที

ปกติถ้าเราเชื่อมต่อเข้าไปที่ AWS IoT Core นั้นเราจะต้องมี 3 Component ด้วยกันคือ

  • Root CA ของ AWS
  • Private key
  • Client device certificate

ซึ่งผมก็เกิดคำถามที่ว่า อ่าว!! แล้วถ้าเราจะไปคุยกับ Service อื่นหล่ะต้องทำยังไง? หรือว่าเราสามารถ Generate AWS credentials ที่มี Access token กับ Secret token ออกมาแล้วเอาไปยัดใส่ใน Firmware ได้เลยน้าา ซึ่งมันก็ทำได้เหมือนกันหล่ะ แต่!!!!! ปัญหาต่อไปน่าจะอยู่ที่เรื่อง Security กับ Key-Rotate แล้วหล่ะ เพราะถ้าหากวันหนึ่ง Key นั้นเกิดหลุดออกไป เราต้องไล่เปลี่ยน Key ให้กับอุปกรณ์เราทั้งหมดเลยหรอ ดูเหมือนจะเป็นเรื่องยากเหมือนกันนะ ถึงแม้จะใช้ OTA [over-the-air update] แล้วก็เถอะ

สุดท้ายหลังจากค้นหาก็เจอ Solution หนึ่งที่คิดว่าเป็น Best-practics ที่ดีเลยคือ AWS services นั้นสามารถเรียกได้โดยใช้ AWS Signature Version 4 format ซึ่งเป็นวิธีการ Authorization รูปแบบหนึ่งภายใน AWS services นั้นหล่ะ โดยมันจะใช้ Access token, Secret token ละก็ Session token ในการสร้าง AWS Request ชุดหนึ่งขึ้นมาเอาไว้แปะไปกับ Header ตอนเรียกใช้งาน AWS Service นั้นๆ

โดยที่ Token ทั้ง 3 ตัวนั้นเราสามารถเรียกมาได้ยังไงหรอ??? คำตอบก็คือเราสามารถดึง Token พวกนี้ผ่าน Credential Provider ของ AWS IoT Core ได้เลยโดยที่เราใช้แค่ Device Certificate แบบ X.509 เหมือนเดิมทุกอย่างเลย

การใช้ Credential Provider นั้นเราสามารถกำหนด Role ของ Token ด้วยโดยใช้ Assume role ใน AWS IoT Core กับ IAM ว่าจะให้มี Permission ในการ Access service อะไรได้บ้าง โดยที่ Token ที่เราได้รับมาก็จะมีอายุของมันด้วยนะ


สาธยายมาเยอะและเริ่มเลยละกันครับ

  • เริ่มต้นเราต้องมี Root CA, Private Key และ Device Certificate ก่อนซึ่งจะถูก Generate มาจาก AWS IoT Core ตอนที่เราสร้างแรกๆเลย
  • หลังจากที่ได้ Device certiifcate แล้วเราก็ต้องไปหา Endpoint ของ Credential-provider ของ AWS IoT Core ของเราอีกทีโดยใช้ AWS CLI ในการเรียก Endpoint นั้นๆ
aws iot describe-endpoint --endpoint-type iot:CredentialProvider
  • สร้าง Policy ใน IAM ก่อนเพื่อกำหนดว่า Token นี้เราจะให้ Access service อะไรได้บ้าง

จากตัวอย่างผมจะให้อุปกรณ์ของผมสามารถ Access ไปที่ S3 ได้ดังนั้นต้องไปสร้าง Policy ก่อนแล้วค่อย Attach policy เข้ามาใน Role อีกที

  • สร้าง Role ขึ้นมาใหม่ในหน้า IAM Console เสร็จแล้วก็ Attach policy เข้าไปได้เลย อย่าลืมเพิ่ม Trust policy เข้าไปด้วยนะ
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "credentials.iot.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}
  • เสร็จแล้วเราจะได้ Role ที่มีสิทธิ์ในการ Access S3 มาแล้ว
  • จากนั้นกลับไปที่ AWS IoT Core เพื่อทำการสร้าง Role aliases สำหรับ Authen S3

Credential duration คือ token จะ expire กี่วินาทีหลังจากที่เราสร้างขึ้นมาผ่าน Credential provider

  • ไปที่ Security > Policies เพื่อสร้าง Policy สำหรับเรียกใช้ Role Aliases ที่สร้างมาก่อนหน้านี้ให้กับ Device
  • กลับไปที่ Things ของเราก่อน เลือก Certificate tab แล้วเลือก CertificateID
  • Attact policies ชื่อ AssumeRoleWithCertificate เข้าไปเลย

ทดสอบ Curl ผ่านสักหน่อยว่าสามารถเรียกได้ไหม

curl --cert <CERTIFICATE.crt> --key <PRIVATE-KEY.key> -H "x-amzn-iot-thingname: <THINGS-NAME>" --cacert AmazonRootCA1.pem https://<ENDPOINT>/role-aliases/<ROLE-ALIAS>/credentials

CERTIFICATE.crt: Device Certificate ที่ได้จากการสร้าง Things

PRIVATE-KEY.key: Private Key ที่ได้จากการสร้าง Things

THINGS-NAME: ชื่อ Thing

ENDPOINT: Endpoint ของ Credential provider

ROLE-ALIAS: Role alias ที่สร้างไว้ก่อนหน้านี้

Result:

จากนั้นเราก็สามารถนำ AccessKeyId, SecretAccessKey และ SessionToken ไปใช้ต่อสำหรับสร้าง AWS Signature V4 ซึ่งผมขอยกไปเป็นอีกหนึ่งบทความนะครับ หวังว่าบทความนี้จะมีประโยชน์สำหรับนักพัฒนาบน AWS IoT Core นะครับ ส่วนการใช้งานผ่าน Arduino เดี๋ยวจะพยายามเขียนเพิ่มในบทความหน้าให้นะครับ

สำหรับวันนี้ขอบคุณและสวัสดีปีใหม่ 2566 ครับ 🎆🎆🎆🎆🎇🎇

https://docs.aws.amazon.com/iot/latest/developerguide/authorizing-direct-aws.html

Authorizing direct calls to AWS services using AWS IoT Core credential provider
Taggs: