Deploy Secure MQTT Server with AWS IoT

Pao Payungsak Klinchampa
PAOCLOUD CO., LTD.
Published in
6 min readJul 13, 2020
Ref: https://aws.amazon.com/blogs/iot/ensure-secure-communication-with-aws-iot-core-using-the-certificate-vending-machine-reference-application/

ในบทความนี้ผมจะพูดถึง บริการตัวนึงบน AWS ที่มีชื่อว่า AWS IoT ครับ โดยเจ้า AWS IoT นี้ รองรับ MQTT Protocol แถมยังมีระบบรักษาความปลอดภัยที่ดีมาก เพราะทั้งมีการเข้ารหัสข้อมูล(MQTT Over TLS) เเละใช้ Certificate ในการทำ Authentication อีกด้วย แต่ถ้าหากไม่เคยรู้จัก MQTT มาก่อน ลองเข้ามาอ่านบทความสั้นๆที่นี่ได้ครับ

https://www.namsaithai.com/blog/knowledge-bulletin-7/post/mqtt-protocol-37

และถ้าพูดถึง MQTT นั้น ใครทำงาน หรืออยู่ในวงการ IoT ย่อมได้ยินชื่อ Protocol ตัวนี้เเน่นอน เพราะมีการนำเอาไปใช้งานอย่างกว้างขวางมากๆ หากต้องการ MQTT Server ที่เสถียร ไม่ล่มง่ายๆ มีระบบรักษาความปลอดภัยที่เเน่นหนา รองรับ Things เยอะๆ AWS IoT คือคำตอบครับ

ส่วนเรื่องของ MQTT นั้น โดยตัวของมันเองเเล้วนั้น มันไม่ได้มีการเข้ารหัสใดๆ ซึ่งหากเราต้องการส่งข้อมูลผ่านทาง Public Network อย่างเช่น Internet ก็ย่อมมีความเสี่ยงที่จะถูกดักข้อมูลเอาได้ จึงมีการเอา TLS มาช่วยเข้ารหัสข้อมูลครับ และการจะใช้ TLS ได้นั้น เราก็ต้องมี Certificate ที่เป็น Key Pair (Public key + Private key ที่ถูกสร้างขึ้นมาด้วยกัน) ซึ่ง AWS เองก็มีการนำเอา TLS นี่ล้ะครับมาช่วยทำให้ Data ของเราปลอดภัยนั่นเอง

ผมได้บรรยายสรรพคุณ และโม้เอาไว้เยอะเเล้ว มาลองสร้าง และทดสอบการ รับ-ส่งค่ากันเลยดีกว่า !!!

ปล. ในบทความนี้จะเเนะนำวิธีการ Set upโดยใช้ Command Line เกือบทั้งหมดนะครับ อาจเหมาะกับคนที่เล่น AWS มาในระดับที่ใช้ Command Line ได้ค่อนข้างคล่องเเล้วมากกว่า แต่ถ้าไม่เคยใช้ AWS เลย หรืออาจเคยใช้มาเเล้วบ้าง ก็ Follow อ่านตามได้ ผมจะเขียนให้เข้าใจง่ายที่สุดครับ หรือใครสงสัยส่วนไหนก็ Inbox เข้ามาถามได้เลย

  1. ขั้นตอนเเรกนั้น เราก็ต้องมี Access Key + Secret Key ซึ่งใช้ในการเชื่อมต่อไปยัง AWS เพื่อที่จะทำให้เราสามารถ run command เพื่อสั่งการให้ AWS ทำตามที่เราต้องการ โดยไปสร้างได้ที่ Service ที่มีชื่อว่า “IAM” ครับ แต่ถ้าใครมี IAM Account และ Acccess Key ที่สามารถเข้าถึง AWS IoT ได้ ก็ข้ามขั้นตอนนี้ไปเลย

จากนั้น เราก็จัดการสร้าง User กันครับ ซึ่งเราสามารถกดที่คำว่า “Users” ได้เลย ตามภาพด้านล่าง สะดวกตรงไหนก็กดได้เลยครับ ซักที่นะ 555+

Add IAM User

แล้วก็กดปุ่ม Add User สีน้ำเงินด้านบน พร้อมทั้งระบุ Username ที่ต้องการ กดกาถูกเฉพาะ Programmatic access นะครับ เเล้วกดปุ่ม next ได้เลย

Add IAM User

จากนั้นก็กำหนดว่า User นี้จะทำอะไรได้บ้าง ให้เราก็กำหนดเป็น Attacth existing policies directly เพื่อกำหนด Plolicy ให้กับ User นี้ตรงๆได้เลย เเล้วเลือก Policy เป็น “AWSIoTFullAccess” นะครับ (หากเคยใช้ AWS จะเลือกเป็น Admin ซึ่ง cover permission ต่างๆทั้งหมดก็ได้ อันนี้ส่วนตัวผมใช้บ่อย เลยเลือกเป็น admin เพราะต้องใช้ deploy service ตัวอื่นด้วย แต่ใน blog นี้เพื่อความปลอดภัย ผมจะเเนะนำให้ใช้ในระดับ minimum request โดยจะจัดการได้เฉพาะ AWS IoT เท่านั้น !!) จากนั้นก็กด next ระบบมันจะให้เราตั้งค่า tag ซึ่งอันนี้ไม่ต้องก็ได้ ผ่านไปเลย ก็จะมีหน้าจอสรุป หากทุกอย่างถูกต้อง ก็กดปุ่ม Create user ได้เลย

Add IAM User

และเมื่อ User ถูกสร้างขึ้นเรียบร้อย ระบบจะเเสดง Access Key + Secret Key อันนี้ให้ Copy เก็บไว้ให้ดีๆนะครับ เพราะระบบมันจะเเสดงให้เราเห็นเเค่ครั้งเดียว หากลืมไปเเล้ว เเนะนำให้ revoke หรือลบทิ้งไปเเล้ว เเล้วมาสร้างใหม่

ด้านล่างนี้ผมจะเเสดงตัวอย่าง Access Key + Secret Key ให้ดู หน้าตาจะเป็นแบบนี้ครับ

Access Key : AKIA6GJZJZXOQ7FUBVVO

Secret Key : lNUvqWXOji1znPDxxxxxxxxxxxxx

เรามี Access Key + Secret Key เรียบร้อย ก็ไปลุยกันต่อในขั้นตอนที่สองกันเลย !!

2. เตรียมความพร้อมเพื่อตั้งค่าให้ AWS Command Line ใช้งานได้

ในข้อนี้เราต้องติดตั้ง “aws cli” กันก่อนนะครับ หากมีอยู่เเล้วก็ข้ามไปเลย หากยังไม่มี ก็ศึกษาวิธีการได้จากที่นี่ :

และเมื่อติดตั้งเรียบร้อย เราก็มา set up กะนต่อ โดยเริ่มจาก การ run command ตามนี้ครับ

$ aws configure

ซึ่งเราก็จัดการป้อนค่า Access Key + Secret Key ตามที่เราไปสร้างเอาไว้ในขั้นตอนเเรกได้เลย ส่วน default region ก็ป้อนเป็น ap-southeast-1 ส่วน output format ก็ป้อนเป็น json ครับ

aws configure

มาลอง run คำสั่งอื่นๆดูกันหน่อย (สั่งให้เเสดง AWS S3 Bucket ที่มีอยู่)

Access Denied !!

ผลที่ได้คือ Access Denied ครับ เพราะ Policy ที่ Attacth กับ User นี้นั้นใช้งานได้เฉพาะ AWS IoT Only !!!

นอกเรื่องไปนิด เเต่ผมจะขอย้ำเรื่องความปลอดภัย หาก Access Key ของเรานั้นมี Policy ที่สามารถเข้าถึง Service ต่างๆได้ทั้งหมด ก็ขอเเนะนำให้เก็บรักษาไว้เป็นอย่างดี เพราะผมเคยเจอเคสโดน Hack Account มาเเล้ว จู่ๆก็มี EC2 ขึ้นมาเต็มไปหมด 555+ ภายในไม่ถึงชั่วโมง ก็โดนเก็บตังค์เป็นหมื่นได้เลย ส่วนสาเหตุก็คือ “Access Key นี้ โดย Push ไปเก็บไว้บน GitHub แบบ Public Repo”

ขั้นตอนที่สองก็เรียบร้อยเเล้ว ไปขั้นตอนที่สามกันเลยดีกว่า Go Go >>>

3. สำหรับขั้นตอนนี้ เราจะเริ่มสร้าง Thing , Thing type , Certificate , Policy กันนะครับ โดยเริ่มจากการสร้าง directory ขึ้นมาซักตัว เพื่อเอาไว้เก็บ Certificate กันก่อน ส่วนของผมจะตั้งชื่อว่า aws-iot-paocloud เเล้วก็เข้ามายัง directory นี้ได้เลย

จากนั้น เราก็มา run คำสั่งกันครับ โดยเริ่มจาก

$ aws iot create-thing-type --thing-type-name demo

คำสั่งนี้จะเป็นคำสั่งที่ใช้ในการสร้าง thing type ขึ้นมาครับ จะตั้งชื่อว่าอะไรก็ได้ อย่างเช่น sensor , switch , etc ในที่นี้ผมจะสร้างโดยใช้ชื่อว่า demo ก็เเล้วกัน

Create Thing

หากสร้างได้สำเร็จ AWS ก้จะ return ค่ากลับมาให้เรา ดังตัวอย่างในรูปครับ

หลังจากนั้นก็มาสร้าง Thing กันต่อ ด้วยคำสั่ง

$ aws iot create-thing --thing-name macmini --thing-type-name demo

ที่ thing-name ให้เราระบุชื่อของ thing ที่เราต้องการได้เลย ส่วนใน blog นี้ผมจะตั้งชื่อว่า macmini เเล้วกัน และหากสำเร็จ ระบบก็จะ return ค่า กลับออกมาคล้ายๆกับภาพก่อนหน้าเลยครับ

หลังจากนั้น เราก็สร้าง Policy กัน ส่วนตรง labpol อันนี้เป็นชื่อ ตั้งชื่อได้ตามต้องการเลยครับ ด้วยคำสั่งตามนี้

$ aws iot create-policy --policy-name labpol --policy-document '{"Version": "2012–10–17","Statement": [{"Effect": "Allow","Action": "iot:*","Resource": "*"}]}'
Create Policy

คราวนี้ก็ถึงเวลาของการสร้าง Certificate เพื่อใช้ในการเชื่อมต่อไปหา AWS IoT กันเเล้วครับ โดยให้ใช้คำสั่งนี้

$ curl https://www.amazontrust.com/repository/AmazonRootCA1.pem > rootCA.pem

คำสั่งนี้คือการ Download RootCA ของ AWS เข้ามานะครับ เพราะการเชื่อมต่อจะต้องระบุ RootCA เข้าไปด้วย

แต่ยังไม่จบเเค่นั้น เพราะเราต้องมี Key อีก 1 คู่ครับ โดยใช้คำสั่งตามนี้ได้เลย

$ aws iot create-keys-and-certificate --set-as-active --certificate-pem-outfile cert.crt --private-key-outfile private.key --public-key-outfile public.key --region ap-southeast-1
Create Certificate

หากสร้าง key ได้ ก็จะเจอหน้าแบบนี้ครับ สังเกตตรงค่า CertificateArn ค่านี้เราต้องเอาไปใช้ต่อในขั้นตอนต่อไป จะ copy เก็บไว้ก็ได้นะครับ

หลังจากนั้น เราก็ต้องเอาสิ่งต่างๆที่เราสร้างเอาไว้มา Attacth กันครับ โดยลำดับเเรก จับเอา Policy ที่สร้างไว้ มา Attacth กับ Certificate ด้วยคำสั่ง

$ aws iot attach-principal-policy --policy-name demo --principal <certificateArn>

ตรง <certificateArn> ให้เราป้อนค่า Certificate ARN ที่ระบบมันเเสดงขึ้นมาจากขั้นตอนก่อนหน้าได้เลยครับ โดยรูปแบบจะเป็นเเบบนี้

arn:aws:iot:ap-southeast-1:975614627293:cert/d4a4a13887d3268321xxx

และก็จับเอา Certificate ไป Attacth กับ Thing ด้วยคำสั่ง

$ aws iot attach-thing-principal --thing-name macmini --principal <certificateArn>

ระบุ thing name เป็นค่าเดียวกับที่เคยสร้างเอาไว้ได้เลย ส่วน Certificate Arn ก็เหมือนกับเมื่อซักครู่ครับ

ตอนนี้เราก็มีทุกอย่างสำหรับการเชื่อมต่อไปหา AWS IoT เเล้ว จะทำยังไงต่อ ไปลุยกันในขั้นตอนหน้าได้เลยครับ ลุยยยยย !!!!

4. มาทดลองเชื่อมต่อกัน เเต่ก่อนจะต่อ ก็ต้องรู้ก่อนว่าต่อไปไหน โดยให้ run คำสั่งเเบบนี้ครับ

$ aws iot describe-endpoint --endpoint-type iot:Data-ATS

ซึ่ง AWS จะ return ค่าที่เป็น host name ซึ่งมีลักษณะเป็น Domain อันเเสนจะยาวตาม style AWS เค้า 555+

Get your Endpoint

เราก็เอาค่านี้ไปใช้ในการเชื่อมต่อได้เลยครับ

จะทำอะไรก่อนดี ???

มาลอง Subscribe กันก่อนก็เเล้วกันนะครับ เเต่ก่อนอื่น ให้ติดตั้ง Mosquitto Client กันก่อนเลย

ติดตั้งเสร็จ ก็มาลอง Subscribe กัน ด้วย Command แบบนี้ครับ

$ mosquitto_sub -h asxxxxxkazfs1-ats.iot.ap-southeast-1.amazonaws.com -t test1 --cafile rootCA.pem --cert cert.crt --key private.key

และลอง Publish กัน ด้วยคำสั่งแบบนี้ครับ

$ mosquitto_pub -h asxxxxxkazfs1-ats.iot.ap-southeast-1.amazonaws.com -t test1 --cafile rootCA.pem --cert cert.crt --key private.key -m "{\"message\": \"Hello PaOCLOUD\"}"
Test Subscribe

ในที่นี้ผมจะตั้งชื่อ topic ว่า test1 ให้ตั้งชื่อให้เหมือนกันนะครับ หากสำเร็จ ตรงหน้า terminal ที่เรา run คำสั่ง Subscribe เราจะเห็น message ที่เรา Publish

เพียงเท่านี้ AWS IoT ก็พร้อมใช้งานเเล้วครับ

มาลองดูหน้า Dashboard ในหน้าเว็บกันหน่อย Log in เข้าไป เเล้วไปที่ IoT Core ได้เลยครับ

AWS IoT Core Dashboard

จะมีพวก Graph เเสดงข้อมูลต่างๆ

ที่เเถบด้านซ้าย ตรง Certificate , Policy ก็จะเเสดง Cetificate , Policy ที่เราได้สร้างเอาไว้ ตามไปดูได้ครับ

แน่นอนว่าไม่ได้มีเเค่นี้ เพราะผมยังมีตัวอย่าง Source Code ง่ายๆในการ Generate Random Data เเล้ว Publish ขึ้นไปยัง AWS IoT โดยใช้ภาษา Type Script ครับ ส่วนภาษาอื่นๆลอง Search คำว่า AWS IoT SDK ดูนะครับ

อันนี้เป็น SDK สำหรับ JS

ตัวอย่าง Source Code

Source Code

พอเรารัน Code นี้ด้วยคำสั่ง npm run start เเล้วลองเปิด Terminal อีกตัวเพื่อลอง Subscribe ก็จะเป็นแบบนี้ครับ

Test Subscribe

อันนี้ตัวอย่าง Code เต็มๆใน GitHub

หากต้องการเชื่อมต่อกับ Thing หรือ Device จริงๆ ก็ต้องรองรับการเชื่อมต่อแบบใช้ Certificate ด้วยนะครับ แต่หากไม่รองรับเเล้วนั้น เราสามารถใช้ท่ายาก โดยใช้ Mosquitto แล้ว config ให้เป็น bridge ครับ เวลาเรา publish ไปที่ Mosquitto เจ้า Mosquitto ก็จะ publish ไปยัง AWS IoT อีกด้วย !!!

รายละเอียดตามไปอ่านได้ที่นี่ครับ

ส่วนเรื่องราคานั้น ถือว่าถูกมากๆครับ หากใช้ในระบบเล็กๆ มันอาจไม่คิดตังค์ไปเลย ราคาไปดูได้ที่นี่ครับ

เป็นอย่างไรกันบ้างครับ หวังว่าคงพอเข้าใจเเละทำตามกันได้ ท่านใดมีคำถามเพิ่มเติม ถามเข้ามาได้เลยครับ สุดท้ายนี้ขอบคุณที่เข้ามาอ่าน เเล้วเจอกันในบทความต่อไป สวัสดีครับ

Payungsak Klinchampa

Network / Cloud Engineer

Facebook : https://www.facebook.com/paov6

--

--