ปิดปั้มที่บ้านแบบ IoT Part 1: Setup VPN ภายในบ้าน

สวัสดีครับ บล็อคซีรีส์นี้เป็นความร่วมมือระหว่างผมกับคุณพ่อมานำเสนอเกี่ยวกับการทำ IoT ภายในบ้านเราครับ


เนื่องจากที่บ้านมีปัญหาว่าน้ำในบ้านรั่ว แต่หาจุดที่รั่วไม่เจอ จึงใช้วิธีว่าหากใครออกจากบ้านคนสุดท้ายก็ให้ปิดเบรคเกอร์ปั้มน้ำ

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

จึงคิดว่าใช้ IOT มาช่วยก็น่าจะสะดวกกว่า โดยมีเงื่อนไขดังนี้

  1. หากมีคนอยู่บ้านก็ไม่ต้องปิดปั้ม
  2. หากคนออกจากบ้านหมดแล้วเท่านั้น จึงจะปิดปั้ม
  3. แต่หากคนออกจากบ้านแล้ว แต่เปิดเครื่องซักผ้าไว้จะต้องสามารถหน่วงเวลาปิดปั้มออกไปได้อย่างน้อย 2 ชั่วโมง
  4. ถึงแม้มีคนอยู่ แต่ช่วงเที่ยงคืนถึงตี 4 ให้ทำการปิดปั้ม
  5. กรณีที่ปิดปั้มจะต้องสามารถเข้าไป override เปิดปั้มได้
  6. เมื่อคนออกจากบ้านหมดแล้ว ให้ส่ง notification มาแจ้ง
  7. จะต้องสามารถดูและตั้งค่า สถานะต่างๆได้

ปัจจุบันอุปกรณ์ที่ต่อเข้ากับ wifi ในบ้านนอกจาก Notebook, มือถือแล้วก็มีทีวีพานาโซนิค และ Chromecast อีกด้วย ดังนั้นหากจะควบคุมปั้มน้ำก็ต้องเอาชุดวงจรเข้าไปต่อเข้ากับ wifi


สำหรับฝั่งซอฟต์แวร์ผมเป็นคนจัดการ ซึ่ง setup ที่ใช้ก็จะเบสมาจาก Network ภายในบ้านที่เคย implement ไว้ก่อนหน้านี้ โดยครั้งนี้มีโจทย์ดังนี้

  1. ความปลอดภัยเป็นอันดับหนึ่ง traffic IoT ทั้งหมดภายในบ้านต้อง encrypt จากในบ้านจนถึงมือ
  2. สามารถ Access จากนอกบ้านได้ (ฉะนั้นวาง server ในบ้านไม่ได้เพราะจะติด ISP Large scale NAT)
  3. สามารถ Automate ได้

ทำ VPN เพื่อเข้ารหัส

ถ้าใครติดตามในเฟสจะพอทราบว่าผมทำ VPN ต่อภายในบ้านอีกลักษณะนี้ครับ

โดยวิธีที่ใช้ก็คือ setup IPSec/L2TP บน server ด้วยโปรแกรม Strongswan + xl2tpd จากนั้นให้ Mikrotik ใช้ IPSec กำหนดกุญแจเข้ารหัส และใช้ L2TP เชื่อมต่อเข้าไป ทั้งนี้ Mikrotik สามารถเลือกให้ L2TP ต่อ IPSec เข้าไปได้ด้วย แต่ผมไม่ได้ใช้เนื่องจากมันไม่สามารถกำหนดค่า IPSec เองได้

สำหรับค่า IPSec ที่กำหนดเองหลักๆ ก็มีดังนี้ครับ

ตั้ง IPSec Proposal ให้เป็น cipher ที่ปลอดภัย คือ AES128-SHA256-MODP2048 ซึ่ง AES128 CBC + SHA256 นั้นตัว hEX Gr3 สามารถใช้ hardware เร่งความเร็วได้ ส่วน PFS group นั้นก็เลือกใช้ 2048 bit ขึ้นไปเพื่อป้องกัน Logjam แต่ถ้าเลือกใช้ modp8192 ที่เพิ่งเพิ่มมาในเวอร์ชั่นล่าสุดก็จะช้าเกินไปจน router แทบจะค้าง (ส่วน ec2n155 นั้นไม่ปลอดภัยไม่ควรใช้ครับ)

สุดท้ายก็ต้องตั้ง Policy ซึ่งกว่าจะได้ค่านี้มาก็ลองหลายรอบครับ โดยเปิด Tunnel mode และเลือก src address เป็น IP ฝั่งเราใน interface ออกเน็ต (ไม่ใช่ IP จริง) ซึ่งผมก็ใส่เข้าไปทั้งบล็อค Large scale NAT เลย

แยก VLAN สำหรับ IoT

ถัดมาก็คือ config ฝั่ง Wireless ซึ่งก็จะแยก wireless ของ IoT ไปอีกอันนึงเลยเพื่อแยก VLAN ออกจากกัน (ผมเลือกทำเป็น hidden เพราะจะได้ไม่รกหน้าจอ) ตรงนี้ interface ของ OpenWRT บน access point ที่ไม่มี switch แบบรุ่นนี้ทำไม่ได้ ต้องเขียนเอง

หลักๆ ก็คือตั้ง ifname เป็น eth0.101 ก็คือให้ tag VLAN 101 ไว้ แล้วก็ให้ wireless ใหม่ bridge กับ interface นี้แทน ในฝั่ง Mikrotik ก็ add VLAN เข้ามาและเพิ่ม rules ต่างๆ ในการ routing ครับ ซึ่ง rules ที่ใช้อยู่ก็จะมีประมาณนี้

  • LAN connect หา IoT ได้
  • ถ้า connection เปิดอยู่ (state=RELATED,ESTABLISHED) แล้วอนุญาตให้ forward packet ได้
  • IoT สามารถเข้าถึง NTP server (UDP port 123) บน UniFi ได้
  • IoT สามารถเข้าถึง MQTT server (TCP port 1883) บน madoka ได้ โดยใช้ IP ภายใน L2TP เท่านั้น ห้ามใช้ public IP
  • นอกนั้น IoT ไม่มีสิทธิ์ forward packet ทั้งหมด ฉะนั้นจะต่อเน็ตไม่ได้เลย

(Rules ผมรกๆ ขอไม่ถ่ายมาแล้วกันนะครับ)

ทำให้ server เข้าถึงคนในบ้านได้

requirement อันหนึ่งของโครงการนี้คือเราจะต้องรู้ว่ามีคนอยู่บ้านหรือเปล่า ซึ่งเราจะใช้วิธี ping มือถือของทุกคนครับ แต่ server อยู่ด้านนอกบ้าน เลยต้องทำให้มันเข้าถึงของในบ้านได้ด้วยการบอก server ว่า IP วงนี้ให้ส่งมาที่ router ในบ้านเราที่ต่อ VPN อยู่ ซึ่งตอนแรกผมก็ใช้คำสั่ง ip route ธรรมดา แต่ตอนหลังเปลี่ยนใหม่ว่าใช้ BGP จะดีกว่า ซึ่ง BGP จะเป็นโปรโตคอลแลกเปลี่ยน route ที่ใช้กันบนอินเทอร์เน็ตระดับ ISP

สำหรับฝั่ง Mikrotik จะต้อง add BGP Instance ขึ้นมาครับ

(ตรง out filter ไม่ต้องใช้ก็ได้ ผมใช้เพื่อ tag community ให้ DN42 ซึ่งไว้จะเขียนบล็อคต่อไป)

และหน้า peer ใช้ดังนี้ครับ

สุดท้ายตั้งให้ export route ใน LAN ออกมา (สนใจเฉพาะอันที่ highlight พอนะครับ)

สำหรับบน server จะใช้โปรแกรม Bird ซึ่งผมเซตตามวิธีของ DN42 แต่ใช้ peer configuration ดังนี้ครับ

protocol bgp home {
        local as 4200000000;
        neighbor 10.50.50.2 as 4200000001;
        path metric 1;
        import keep filtered;
        import limit 10 action block;
        passive on;
}

เมื่อทำถูกแล้วเราก็เช็คสถานะที่ server ด้วยการสั่ง ip route get 192.168.2.1 ควรจะระบุว่าให้วิ่งผ่าน VPN

สรุป

สำหรับพาร์ทนี้จะเป็นเรื่องของ Network security เป็นหลักครับเกี่ยวกับการทำ VPN ออกไปเพื่อแก้ปัญหาว่า ISP ไม่ให้เรา forward port ไม่ได้แล้ว ซึ่งจะเป็นพื้นฐานของระบบความปลอดภัยอุปกรณ์ IoT ที่เราจะเริ่มเซตกันในพาร์ทหน้า