ควบคุม ESP8266 โดยไม่ต้องส่งต่อพอร์ต: เส้นทาง MQTT ขาออก
บรอกเกอร์ที่เข้าถึงได้จากอินเทอร์เน็ตช่วยให้ควบคุมอุปกรณ์ในบ้านผ่านการเชื่อมต่อที่ตัวมันเปิดเอง สิ่งนี้เปลี่ยนอะไรสำหรับหน่วยความจำ TLS หัวข้อ และการเล่นซ้ำ
อุปกรณ์อยู่หลังเราเตอร์ในบ้านโดยไม่มีการส่งต่อพอร์ตและไม่มีที่อยู่สาธารณะ แต่ก็ยังต้องได้รับคอนฟิกภายในไม่กี่วินาที กลเม็ดไม่ใช่รูในไฟร์วอลล์ แต่เป็นการเชื่อมต่อที่อุปกรณ์เปิดออกไปหาบรอกเกอร์ที่เข้าถึงได้ แล้วบรอกเกอร์ส่งข้อความกลับมาทางเส้นทางเดิมที่สร้างไว้ ทุกคุณสมบัติที่ผู้คนชอบในการออกแบบนี้ และกับดักทุกอย่างในนั้น ล้วนมาจากการกลับด้านนี้
อะไรที่ผ่าน NAT จริง ๆ
เมื่ออุปกรณ์เปิดการเชื่อมต่อ TCP ไปยังบรอกเกอร์ เราเตอร์ในบ้านสร้างการแมปและคงไว้ตลอดอายุของโฟลว์ คำตอบบนโฟลว์นั้นกลับมาที่อุปกรณ์เพราะการแมปมีอยู่แล้ว บรอกเกอร์ไม่เคยเริ่มอะไรไปยังบ้าน จึงไม่มีแพ็กเก็ตขาเข้าที่ไม่ได้ขอให้เราเตอร์ต้องปฏิเสธ นั่นคือข้อโต้แย้งเรื่องเครือข่ายทั้งหมด และนั่นคือเหตุผลที่วิธีนี้ใช้ได้บนเครือข่ายที่คุณไม่ได้ควบคุม
อุปกรณ์ต้องคงการเชื่อมต่อไว้หรือสร้างใหม่ ซึ่งกลายเป็นคำถามเรื่องความน่าเชื่อถือเมื่อสถาปัตยกรรมถูกกำหนดแล้ว
บรอกเกอร์กำหนดเส้นทางหัวข้อ ไม่ได้เป็นพร็อกซี HTTP
MQTT กำหนดการแลกเปลี่ยนการเผยแพร่และการสมัครรับ: อุปกรณ์สมัครรับตัวกรองหัวข้อที่ได้รับอนุญาตให้อ่าน และคอนโทรลเลอร์ที่ได้รับอนุญาตเผยแพร่ไปยังหัวข้อที่ตรงกัน บรอกเกอร์จับคู่การเผยแพร่กับการสมัครรับและส่งสำเนา มันไม่รู้ว่าคำขอของเบราว์เซอร์คืออะไร และจะไม่ส่งต่อ HTTP GET ไปยังเว็บเซิร์ฟเวอร์ของอุปกรณ์ หากเฟิร์มแวร์ที่มีอยู่พูดได้แค่ HTTP การออกแบบบรอกเกอร์ต้องเปลี่ยนแอปพลิเคชันหรือมีองค์ประกอบแปลที่ตั้งใจไว้
ชื่อหัวข้อก็ไม่ใช่การอนุญาต บรอกเกอร์ส่วนใหญ่รองรับรายการควบคุมการเข้าถึงต่อไคลเอนต์ และอุปกรณ์ควรถูกจำกัดไว้ที่แผนผังการเผยแพร่และการสมัครรับของตัวเอง แทนที่จะใช้เนมสเปซระดับโลกเดียวร่วมกัน
ทรัพยากรของอุปกรณ์กำหนดรูปร่างของ TLS
ESP8266 มี RAM จำกัด และการจับมือ TLS คือสิ่งที่แพงที่สุดที่มันทำ Arduino คอร์จัดส่ง BearSSL มาให้เพราะข้อจำกัดนี้โดยเฉพาะ และการเลือกระหว่างการตรวจสอบ CA กับการปักหมุดลายนิ้วมือเปลี่ยนทั้งรอยหน่วยความจำและสิ่งที่ผู้โจมตีที่มีใบรับรองถูกต้องสำหรับชื่ออื่นทำได้ การตรวจสอบ CA ของบรอกเกอร์เป็นตัวเลือกที่แข็งแกร่งกว่าเมื่อฮีปอนุญาต ขนาดเพย์โหลดก็สำคัญเช่นกัน: ไคลเอนต์ MQTT ถือบัฟเฟอร์ และข้อความที่ใหญ่กว่านั้นจะถูกตัดอย่างเงียบ ๆ เว้นแต่จะเพิ่มบัฟเฟอร์อย่างตั้งใจ
Keepalive และเวลาหมดของซ็อกเก็ตเป็นส่วนหนึ่งของงบเดียวกัน เพราะไคลเอนต์ที่ไม่เคยสังเกตเห็นการเชื่อมต่อที่ตายแล้วจะหยุดรับคำสั่งโดยไม่รายงานข้อผิดพลาด
ความหมายของข้อความที่กัด
ข้อความที่เก็บไว้จะถูกบรอกเกอร์จัดเก็บและส่งไปยังผู้สมัครรับที่ตรงกันในภายหลัง ซึ่งยอดเยี่ยมสำหรับสถานะปัจจุบันและอันตรายสำหรับคำสั่งครั้งเดียว: อุปกรณ์ที่เชื่อมต่อใหม่สามารถได้รับคำสั่งของเมื่อวานราวกับว่าเป็นคำสั่งใหม่ QoS 1 รับประกันการส่งอย่างน้อยหนึ่งครั้ง ดังนั้นการซ้ำจึงเป็นเรื่องปกติและแอปพลิเคชันต้องปลอดภัยต่อการเล่นซ้ำ โดยเฉพาะอย่างยิ่งด้วยตัวระบุหรือการประทับเวลาที่สามารถปฏิเสธได้ พินัยกรรมสุดท้ายให้สัญญาณสถานะเมื่ออุปกรณ์หลุด แต่เฉพาะเมื่อการเชื่อมต่อล้มเหลวจริงแทนที่จะค้าง
พฤติกรรมของเซสชันสะอาดกำหนดว่าบรอกเกอร์เก็บการสมัครรับของคุณไว้ขณะที่คุณไม่อยู่หรือไม่ และการทำผิดตรงนี้คือเหตุผลที่อุปกรณ์บางตัวพลาดข้อความแรกหลังการเชื่อมต่อใหม่ทุกครั้ง
TLS ปกป้องช่วงถึงบรอกเกอร์ ไม่ใช่การเข้ารหัสเพย์โหลดตั้งแต่ต้นจนจบต่อผู้ดำเนินการบรอกเกอร์ ซึ่งสามารถอ่านทุกสิ่งที่คุณเผยแพร่ผ่านมัน
จำกัดวงจรชีวิตและทดสอบด้วยข้อมูลที่ไม่เป็นอันตราย
วางแผนการเชื่อมต่อใหม่ด้วยการถอยหลังแทนลูปพยายามซ้ำที่แน่นหนา สมัครรับใหม่อย่างชัดเจนหากเซสชันไม่ถาวร และบันทึกผลการเชื่อมต่อเพื่อให้อุปกรณ์ออฟไลน์ที่เงียบสงบเหลือหลักฐาน ทดสอบเส้นทางการเชื่อมต่อใหม่ด้วยเพย์โหลดตัวอย่างที่ไม่ทำอะไร เพราะการทดสอบการผลิตครั้งแรกของช่องทางคำสั่งไม่ควรเป็นคำสั่งจริง จากนั้นยืนยันว่าข้อความที่เก็บไว้เก่า ๆ ทำอะไรเมื่อเชื่อมต่อใหม่ และตัดสินว่าพฤติกรรมนั้นยอมรับได้สำหรับแต่ละหัวข้อหรือไม่
เมื่อทำเช่นนี้ การออกแบบจะลบข้อกำหนดเครือข่ายขาเข้าหนึ่งข้อ และปล่อยให้ซอฟต์แวร์ของอุปกรณ์ นโยบายบรอกเกอร์ และความหมายของข้อความเป็นงานที่มองเห็นได้แทนที่จะเป็นสมมติฐานที่ซ่อนอยู่