Tự động hóa nhà (III): Làm gì với một rổ nút bấm Wi-Fi?

Tuy là đã làm được cho chiếc đèn trong phòng ngủ bật tắt bằng giọng nói, nhưng hóa ra bệnh lười khó chữa hơn tôi tưởng. Tôi vẫn có hôm đi ngủ quên đèn vì thường ngủ quên trên sofa, khoảng 2h sáng lồm cồm bò dậy vào phòng ngủ. Khi vào phòng ngủ thì không biết để điện thoại ở đâu. Mà gào lên nửa đêm "Siri đi tắt đèn ngủ hộ anh," thì hàng xóm tỉnh dậy. Mà hàng xóm tỉnh dậy thì họ lại phải làm việc. Mà làm việc thì mình lại không ngủ được. Tóm lại là rất nan giải.
Giá mà có nút bấm ngay cạnh giường mà không phải với điện thoại thì hay biết mấy.
Hôm nọ tôi ngó qua ở Fry's có bán nút bấm smart-home của Assmung với giá 15 đô gì đó một cái. Mà muốn cái nút bấm đó hoạt động thì lại phải có hub. Hub thì 80 đô một cái. Tức là nhà 2 nút bấm thôi là đi tong 100 đô, mà phần mềm thì mình phải cài phần mềm riêng. Họ thôi hỗ trợ là mình có mấy cục gạch trong nhà. 
Tôi biết chính Amazon có làm ra một số nút bấm giá rẻ kết nối vào Wi-Fi gọi là Amazon Dash. Họ bán thường 2-3 đô một cái. Cái này bình thường là một cái nút để dụ mọi người order hàng trên Amazon, bấm một lần là Amazon mang đúng nhãn hàng đó đến tận nhà. Lên mạng thì thấy có người rao bán một rổ nút bấm này (chắc họ mua để lấy khuyến mại), 16 chiếc giá 10 đô. Vốn không còn gì để mất, tôi bấm liều mua. Hai ngày sau đúng là một rổ nút đến nhà mình thật:
Xin lỗi không đủ 16 cái trong hộp vì tôi lỡ dùng và gắn mất một số, giờ mới chụp ảnh
Bây giờ làm gì với đống của nợ này? Hack.
Mỗi thiết bị này có đúng một cái nút. Khi bạn bấm cái nút đó, hai việc sẽ xảy ra:
1, Nếu cái nút không kết nối được với Wi-Fi, (hình như) nó sẽ bật Bluetooth BLE lên để ở chế độ pair. Khi đó mình cần dùng app Amazon để cấu hình Wi-Fi.
2, Nếu cái nút kết nối được với Wi-Fi, nó sẽ gửi một câu lệnh tới Amazon bằng một cách nào đó (không rõ). Rồi cái nút bấm nó xem response từ Amazon thế nào. Nếu response "OK" (đại khái như vậy) thì nó sẽ nháy đèn xanh. Nếu không thì nháy đèn đỏ. Rồi nó disconnect Wi-Fi và quay lại standby.
Mình không quan tâm đến bước 1 như thế nào. Bây giờ câu hỏi làm sao để chúng ta intercept được bước 2 để chỉnh hướng request đó về mình. Tất cả các tutorials tôi đọc trên mạng đều detect việc này bằng cách đọc ARP xem có thiết bị nào mới gia nhập Wi-Fi không (vì mỗi khi mình bấm nút cái nút đó cái nút sẽ gia nhập Wi-Fi). Cách này không hay vì:
1, Cái nút vẫn nói chuyện được với Amazon. Chúng ta muốn cắt hoàn toàn mối liên lạc này.
2, Nếu để scan được ARP thì chúng ta phải trên cùng một subnet và phải "nhìn thấy" thiết bị kia. Tôi muốn tất cả các thứ Internet of Things ở trên một subnet biệt lập và không nhìn thấy nhau và không nói chuyện được với nhau. Nếu ai hack được cái nút bấm Amazon của tôi thì cũng không vào được mạng chính nhà tôi.
3, Để scan được ARP thì bạn cần một cái gì có quyền root để scan ARP. Chạy chương trình gì bằng quyền root cũng là hạ sách, nhất là một chương trình ta viết trong một buổi chiều.
Vậy chúng ta cần tìm hiểu khi ta bấm cái nút này thì cái nút thật sự nó nói gì với Amazon ở chỗ nào. Điều này rất dễ thực hiện nếu có router chạy OpenWRT. Chúng ta cấu hình cho dnsmasq ghi lại tất cả các DNS request rồi xem khi ta bấm nút, điều gì sẽ xảy ra:
Phần màu trắng là những gì xảy ra ngay sau khi bấm nút.
Ah-ha! Cái nút này làm hai việc. Một là nó kết nối tới 0.amazon.pool.ntp.org. Hai là nó kết nối tới dash-button-na-aws-opf.amazon.com.
Tại sao cái nút bấm kết nối tới ntp.org? Câu hỏi hay. NTP.org là trang web cung cấp dịch vụ đồng bộ thời gian. Cho nên cái nút nó kết nối tới đó là tại vì nó cần biết thời gian. Bây giờ có hai câu hỏi:
- Tại sao nó không biết thời gian? Tại vì nó không có RTC. Cái nút này cần phải rất rẻ, họ không làm mạch điện đếm thời gian ở đấy, cho nên cái nút bấm lúc bạn gọi nó dậy, nó không biết thời gian. 
- Tại sao nó cần biết thời gian? Khi một cái gì cần biết thời gian là biểu hiện của việc nó sẽ dùng giao thức SSL, vì nó cần kiểm chứng certificate của đầu bên kia.
OK... Bây giờ cách đơn giản nhất là tạo một file hosts rồi redirect các request đáng ra tới dash-button-na-aws-opf.amazon.com tới IP chiếc raspberry pi của ta (tức là chính ta đi poison DNS của ta). 

Tại sao lại có parker-gateway-na? Tại vì tôi theo dõi các tutorial trên mạng. Họ nói redirect domain này. Họ dùng button hardware v1. Tôi dùng v2, button v2 không kết nối tới parker-gw. Đừng tin những gì chúng ta nghe trên mạng.
Vì button ở trên untrusted subnet (guestzone) và raspberry pi trên trusted subnet (lan), cho nên chúng ta phải cấu hình cho firewall "Traffic Rules" ở trên router cho phép forward traffic từ guestzone tới raspberry pi (để ý rule guestzone-IoT):


Để tiết kiệm thời gian, tôi không sniff traffic để xem cái button nói chuyện với cổng nào ở Amazon nữa vì trên mạng có nói nó kết nối tới cổng 443 (HTTP Secure) rồi. Đúng như dự đoán, cái nút bấm cần biết thời gian vì như lý do này.
Vì chúng ta không phải Amazon, sẽ không ai cấp certificate cho chúng ta để intercept traffic tới Amazon xem cái button nói gì với họ. Ta chỉ có thể viết chương trình để listen được cổng 443 và khi thấy kết nối tới cổng đó thì sẽ xem cái button nào đã bấm.
Chúng ta có thể viết một cái daemon bằng Python cho nhanh. Daemon này sẽ đi xem cái button nào có IP gì kết nối tới mình và chạy lệnh tương ứng, ví dụ như nếu thấy kết nối từ .181 thì nó sẽ chạy lệnh mosquitto_pub tới topic '/bedroom/toggle':
181 và 182 là hai cái nút bấm để bật tắt đèn ngủ. 184 là chuông cửa.
Tại sao chúng ta phải nghe cổng 1443 thay vì 443? Vì 443 là cổng số thấp, chỉ có chương trình root mới được nghe cổng thấp. Chúng ta muốn chạy cái daemon này với một người dùng bình thường. Chúng ta phải nghe cổng số cao, và dùng iptables để redirect tới cổng thấp lúc startup.
Nhớ +x /iptables
Làm cách nào để cho tất cả các nút bấm có địa chỉ IP cố định dựa trên MAC address? OpenWRT có chức năng gọi là static leases cho phép ta cung cấp địa chỉ IP dựa trên MAC.

Và kết quả là...

Có cả chuông cửa - tôi sẽ xóa chữ Camp và chữ "s" đi để còn chữ Bell.

1 tiếng trước hàng xóm nhà tôi vừa bấm chuông:

Tôi vẫn còn 13 cái nút bấm không biết dùng để làm gì. Tôi đang định cài nút bấm vào toilet để ai ở ngoài mà buồn quá thì gọi người trong toilet ra...
43
1284 lượt xem
43
6
6 bình luận