Bộ định tuyến đường viền luồng – Kết nối IPv6 hai chiều và phát hiện dịch vụ dựa trên DNS

1. Giới thiệu

699d673d05a55535.png

Thread là gì?

Thread là một giao thức mạng lưới dạng mắt lưới không dây có công suất thấp dựa trên IP, cho phép giao tiếp an toàn giữa các thiết bị và giữa thiết bị với đám mây. Mạng Thread có thể thích ứng với các thay đổi về cấu trúc liên kết để tránh các lỗi tại một điểm duy nhất.

OpenThread là gì?

OpenThread do Google phát hành là một bản triển khai nguồn mở của Thread®.

Bộ định tuyến biên theo giao thức Thread là gì?

Bộ định tuyến biên sử dụng giao thức Thread kết nối mạng Thread với các mạng dựa trên IP khác, chẳng hạn như Wi-Fi hoặc Ethernet. Mạng Thread cần có Bộ định tuyến biên để kết nối với các mạng khác. Bộ định tuyến biên sử dụng giao thức Thread tối thiểu phải hỗ trợ các chức năng sau:

  • Khả năng kết nối IP hai chiều giữa mạng Thread và mạng Wi-Fi/Ethernet.
  • Khám phá dịch vụ hai chiều thông qua mDNS (trên đường liên kết Wi-Fi/Ethernet) và SRP (trên mạng Thread).
  • Thread-over-infrastructure hợp nhất các phân vùng Thread qua các đường liên kết dựa trên IP.
  • Quy trình thiết lập Thread bên ngoài (ví dụ: điện thoại di động) để xác thực và kết nối một thiết bị Thread với mạng Thread.

Bộ định tuyến biên OpenThread (OTBR) do Google phát hành là một cách triển khai nguồn mở của Bộ định tuyến biên sử dụng giao thức Thread.

Sản phẩm bạn sẽ tạo ra

Trong lớp học lập trình này, bạn sẽ thiết lập một Bộ định tuyến biên sử dụng giao thức Thread và kết nối điện thoại di động với một Thiết bị cuối sử dụng giao thức Thread thông qua Bộ định tuyến biên.

Kiến thức bạn sẽ học được

  • Cách thiết lập OTBR
  • Cách tạo mạng Thread bằng OTBR
  • Cách tạo thiết bị OpenThread CLI bằng tính năng SRP
  • Cách đăng ký dịch vụ bằng SRP
  • Cách khám phá và kết nối với một thiết bị cuối Thread

Bạn cần có

  • Một máy trạm Linux để tạo và flash RCP Thread, OpenThread CLI và kiểm thử truyền tin đa hướng IPv6.
  • Một Raspberry Pi cho bộ định tuyến biên sử dụng giao thức Thread.
  • 2 USB Dongle Nordic Semiconductor nRF52840 (một cho RCP và một cho thiết bị cuối Thread).
  • Điện thoại iOS chạy iOS 14 trở lên hoặc điện thoại Android chạy Android 8.1 trở lên.

2. Thiết lập OTBR

Cách nhanh nhất để thiết lập OTBR là làm theo Hướng dẫn thiết lập OTBR.

Sau khi hoàn tất quá trình thiết lập OTBR, hãy sử dụng ot-ctl để xác thực rằng OTBR đang hoạt động như một leader Thread.

$ sudo ot-ctl state
leader
Done

Ngoài ra, hãy xác thực rằng OTBR đã tự động định cấu hình tiền tố off-mesh-routable (OMR) trong Dữ liệu mạng Thread.

$ sudo ot-ctl netdata show
Prefixes:
Prefixes:
fd76:a5d1:fcb0:1707::/64 paos med 4000
Routes:
fd49:7770:7fc5:0::/64 s med 4000
Services:
44970 5d c000 s 4000
44970 01 9a04b000000e10 s 4000
Done
$ sudo ot-ctl ipaddr      
fda8:5ce9:df1e:6620:0:ff:fe00:fc11
fda8:5ce9:df1e:6620:0:0:0:fc38
fda8:5ce9:df1e:6620:0:ff:fe00:fc10
fd76:a5d1:fcb0:1707:f3c7:d88c:efd1:24a9
fda8:5ce9:df1e:6620:0:ff:fe00:fc00
fda8:5ce9:df1e:6620:0:ff:fe00:4000
fda8:5ce9:df1e:6620:3593:acfc:10db:1a8d
fe80:0:0:0:a6:301c:3e9f:2f5b
Done

3. Thiết lập thiết bị đầu cuối ứng dụng SRP

Tạo và flash OT CLI

Làm theo bước 5 của lớp học lập trình Tạo mạng Thread bằng các bảng nRF52840 và OpenThread để tạo và flash một thiết bị cuối CLI nRF52840.

Nhưng thay vì bật OT_COMMISSIONEROT_JOINER, nút CLI yêu cầu các tính năng OT_SRP_CLIENTOT_ECDSA.

Vì vậy, lệnh gọi bản dựng đầy đủ sẽ có dạng như sau:

$ script/build nrf52840 USB_trans -DOT_SRP_CLIENT=ON -DOT_ECDSA=ON

Tham gia mạng Thread

Để tham gia mạng Thread, chúng ta cần lấy Tập dữ liệu hoạt động đang hoạt động từ thiết bị OTBR. Hãy quay lại ot-ctl và lấy tập dữ liệu đang hoạt động:

$ sudo ot-ctl dataset active -x
0e080000000000010000000300001235060004001fffe002083d3818dc1c8db63f0708fda85ce9df1e662005101d81689e4c0a32f3b4aa112994d29692030f4f70656e5468726561642d35326532010252e204103f23f6b8875d4b05541eeb4f9718d2f40c0302a0ff
Done

Quay lại phiên màn hình nút ứng dụng SRP và đặt tập dữ liệu đang hoạt động:

> dataset set active 0e080000000000010000000300001235060004001fffe002083d3818dc1c8db63f0708fda85ce9df1e662005101d81689e4c0a32f3b4aa112994d29692030f4f70656e5468726561642d35326532010252e204103f23f6b8875d4b05541eeb4f9718d2f40c0302a0ff
Done

Sau đó, hãy khởi động giao diện Thread:

> ifconfig up
Done
> thread start
Done

Đợi vài giây rồi xác minh xem bạn có tham gia được mạng Thread hay không:

> state
child
Done
> netdata show
Prefixes:
fd76:a5d1:fcb0:1707::/64 paos med 4000
Routes:
fd49:7770:7fc5:0::/64 s med 4000
Services:
44970 5d c000 s 4000
44970 01 9a04b000000e10 s 4000
Done
> ipaddr
fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927
fda8:5ce9:df1e:6620:0:ff:fe00:4001
fda8:5ce9:df1e:6620:ed74:123:cc5d:74ba
fe80:0:0:0:d4a9:39a0:abce:b02e
Done

Đảm bảo rằng dữ liệu mạng khớp với dữ liệu được in trên OTBR. Bây giờ, chúng ta có thể ping địa chỉ OMR của OTBR:

> ping fd76:a5d1:fcb0:1707:f3c7:d88c:efd1:24a9
Done
> 16 bytes from fd76:a5d1:fcb0:1707:f3c7:d88c:efd1:24a9: icmp_seq=1 hlim=64 time=49ms

4. Xuất bản Dịch vụ trên Thiết bị đầu cuối

mDNS đã được sử dụng rộng rãi để xuất bản dịch vụ DNS-SD trên đường liên kết cục bộ. Tuy nhiên, các thông báo truyền tin đa hướng tiêu tốn quá nhiều băng thông và sẽ nhanh chóng làm hết pin của các thiết bị có công suất thấp. Thread sử dụng giao thức SRP truyền đơn hướng để đăng ký các dịch vụ của mình với Bộ định tuyến biên và dựa vào Bộ định tuyến biên để quảng cáo các dịch vụ trên đường liên kết Wi-Fi hoặc Ethernet.

Chúng ta có thể đăng ký một dịch vụ bằng lệnh srp client.

Chuyển đến phiên màn hình nút ứng dụng SRP và tự động khởi động ứng dụng SRP:

> srp client autostart enable
Done

Đặt tên máy chủ sẽ được quảng cáo trên đường liên kết Wi-Fi/Ethernet:

> srp client host name ot-host
Done

Để một thiết bị trên đường liên kết Wi-Fi/Ethernet có thể kết nối với một thiết bị cuối Thread, cần phải quảng cáo địa chỉ OMR của thiết bị cuối:

> srp client host address fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927
Done

Cuối cùng, hãy đăng ký một dịch vụ _ipps._tcp giả:

> srp client service add ot-service _ipps._tcp 12345
Done

Đợi vài giây, bạn sẽ thấy dịch vụ đã đăng ký:

> srp client service
instance:"ot-service", name:"_ipps._tcp", state:Registered, port:12345, priority:0, weight:0
Done

Chúng tôi đã hoàn tất mọi công việc thiết lập và dịch vụ _ipps._tcp lẽ ra đã được quảng cáo trên đường liên kết Wi-Fi/Ethernet. Đã đến lúc khám phá và truy cập vào thiết bị cuối!

5. Khám phá Dịch vụ

Khám phá dịch vụ này bằng điện thoại di động

54a136a8940897cc.png

Chúng tôi sử dụng Ứng dụng Service Browser để khám phá các dịch vụ mDNS bằng điện thoại Android. Bạn cũng có thể tìm thấy Ứng dụng tương đương cho thiết bị di động iOS. Mở Ứng dụng và dịch vụ _ipps._tcp sẽ xuất hiện.

Khám phá dịch vụ bằng máy chủ Linux

Nếu muốn khám phá dịch vụ này từ một máy chủ Linux khác, bạn có thể dùng lệnh avahi-browse.

Cài đặt avahi-daemonavahi-utils:

$ sudo apt-get install -y avahi-daemon avahi-utils

Giải quyết vấn đề về dịch vụ:

$ sudo service avahi-daemon start # Ensure the avahi daemon is started.
$ avahi-browse -r _ipps._tcp
+ wlan0 IPv6 ot-service                                    Secure Internet Printer local
= wlan0 IPv6 ot-service                                    Secure Internet Printer local
   hostname = [ot-host.local]
   address = [fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927]
   port = [12345]
   txt = []
...

Khám phá dịch vụ này bằng máy chủ lưu trữ macOS

Bạn có thể dùng dns-sd trên macOS để phân giải dịch vụ:

$ dns-sd -Z _ipps._tcp local.
Browsing for _ipps._tcp.local.
DATE: ---Sun 14 Mar 2021---
21:31:42.125  ...STARTING...

; To direct clients to browse a different domain, substitute that domain in place of '@'
lb._dns-sd._udp                                 PTR     @

; In the list of services below, the SRV records will typically reference dot-local Multicast DNS names.
; When transferring this zone file data to your unicast DNS server, you'll need to replace those dot-local
; names with the correct fully-qualified (unicast) domain name of the target host offering the service.

_ipps._tcp                                      PTR     ot-service._ipps._tcp
ot-service._ipps._tcp                           SRV     0 0 12345 ot-host.local. ; Replace with unicast FQDN of target host
ot-service._ipps._tcp                           TXT     ""
...

6. Ping Thiết bị cuối

Ping từ điện thoại di động

Lấy điện thoại Pixel làm ví dụ, chúng ta có thể tìm ra địa chỉ OMR của dịch vụ "ot-service" đã đăng ký trước đó trong trang chi tiết của phiên bản dịch vụ trong Ứng dụng trình duyệt dịch vụ.

bb992962e68d250b.png 888daa1df1e1a9bf.png

Giờ đây, chúng ta có thể ping địa chỉ OMR bằng một Ứng dụng Network Analyzer khác.

Rất tiếc, phiên bản Android của Ứng dụng Network Analyzer không hỗ trợ các truy vấn mDNS cho tiện ích ping và chúng tôi không thể ping trực tiếp tên máy chủ ot-host.local (chúng tôi có thể ping tên máy chủ bằng phiên bản iOS của Ứng dụng).

Ping từ một máy chủ lưu trữ Linux/macOS

Thread Border Router gửi Thông báo của bộ định tuyến ICMPv6 (RA) để thông báo các tiền tố (thông qua Tuỳ chọn thông tin tiền tố) và các tuyến đường (thông qua Tuỳ chọn thông tin tuyến đường) trên đường liên kết Wi-Fi/Ethernet.

Chuẩn bị máy chủ Linux

Điều quan trọng là bạn phải đảm bảo đã bật RA và RIO trên máy chủ lưu trữ:

  1. net.ipv6.conf.wlan0.accept_ra phải có giá trị ít nhất là 1 nếu tính năng chuyển tiếp IP không được bật và 2 nếu không.
  2. net.ipv6.conf.wlan0.accept_ra_rt_info_max_plen không được nhỏ hơn 64.

accept_ra được đặt mặc định thành 1 cho hầu hết các bản phân phối. Tuy nhiên, có thể có những trình nền mạng khác sẽ ghi đè lựa chọn này (ví dụ: dhcpcd trên Raspberry Pi sẽ ghi đè accept_ra thành 0). Bạn có thể kiểm tra giá trị accept_ra bằng cách:

$ sudo sysctl -n net.ipv6.conf.wlan0.accept_ra
0

Và đặt giá trị thành 1 (hoặc 2 trong trường hợp bạn bật tính năng chuyển tiếp IP) bằng cách:

$ sudo sysctl -w net.ipv6.conf.wlan0.accept_ra=1
Net.ipv6.conf.wlan0.accept_ra = 1

Tuỳ chọn accept_ra_rt_info_max_plen trên hầu hết các bản phân phối Linux được đặt mặc định là 0, hãy đặt tuỳ chọn này thành 64 bằng cách:

$ sudo sysctl -w net.ipv6.conf.wlan0.accept_ra_rt_info_max_plen=64
net.ipv6.conf.wlan0.accept_ra_rt_info_max_plen = 64

Thay đổi này sẽ bị mất sau khi bạn khởi động lại máy chủ. Ví dụ: hãy thêm các lệnh bên dưới vào /etc/sysctl.conf để bật RIO vĩnh viễn:

$ net.ipv6.conf.wlan0.accept_ra_rt_info_max_plen = 64

Có thể đã quá muộn để thay đổi những cấu hình đó vì OTBR đã gửi các thông báo RA và khoảng thời gian giữa hai thông báo RA không mong muốn có thể lên đến hàng trăm giây. Một cách là ngắt kết nối rồi kết nối lại với AP Wi-Fi để gửi thông báo Yêu cầu bộ định tuyến để OTBR sẽ phản hồi bằng RA được yêu cầu. Một lựa chọn khác là khởi động lại chức năng Định tuyến biên trên Bộ định tuyến biên:

$ sudo ot-ctl br disable
Done
$ sudo ot-ctl br enable
Done

Nếu bạn đang cố gắng kết nối lại Wi-Fi hoặc khởi động lại giao diện Ethernet, hãy đảm bảo rằng bạn không dùng dhcpcd để quản lý mạng IPv6 Wi-Fi/Ethernet. Vì dhcpcd luôn ghi đè tuỳ chọn accept_ra mỗi khi giao diện được khởi động lại và cấu hình accept_ra của bạn sẽ bị mất. Thêm các dòng bên dưới vào tệp cấu hình dhcpcd (ví dụ: /etc/dhcpcd.conf) để tắt IPv6 một cách rõ ràng trong dhcpcd:

noipv6
noipv6rs

Bạn cần khởi động lại để thay đổi có hiệu lực.

Chuẩn bị máy chủ lưu trữ macOS

Cả hai lựa chọn accept_ra* đều được bật theo mặc định, nhưng bạn cần nâng cấp hệ thống lên ít nhất là macOS Big Sur.

Ping tên máy chủ hoặc địa chỉ IPv6

Giờ đây, chúng ta có thể ping tên máy chủ ot-host.local bằng lệnh ping -6 (ping6 cho macOS):

$ ping -6 ot-host.local.
PING ot-host.local.(fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927 (fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927)) 56 data bytes
64 bytes from fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927 (fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927): icmp_seq=1 ttl=63 time=170 ms
64 bytes from fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927 (fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927): icmp_seq=2 ttl=63 time=64.2 ms
64 bytes from fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927 (fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927): icmp_seq=3 ttl=63 time=22.8 ms
64 bytes from fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927 (fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927): icmp_seq=4 ttl=63 time=37.7 ms
64 bytes from fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927 (fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927): icmp_seq=5 ttl=63 time=28.7 ms
...

Lệnh này có thể không hoạt động trên các máy chủ Linux có lỗi "Name or service not known". Nguyên nhân là do lệnh ping không phân giải tên ot-host.local. bằng các truy vấn mDNS. Mở /etc/nsswitch.conf rồi thêm mdns6_minimal vào dòng bắt đầu bằng hosts:

hosts:          files mdns4_minimal mdns6_minimal dns

Tất nhiên, bạn luôn có thể ping trực tiếp địa chỉ IPv6:

$ ping -6 fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927
PING fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927(fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927) 56 data bytes
64 bytes from fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927: icmp_seq=1 ttl=63 time=32.9 ms
64 bytes from fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927: icmp_seq=2 ttl=63 time=27.8 ms
64 bytes from fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927: icmp_seq=3 ttl=63 time=29.9 ms
64 bytes from fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927: icmp_seq=4 ttl=63 time=73.5 ms
64 bytes from fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927: icmp_seq=5 ttl=63 time=26.4 ms
...

7. Kết thúc việc huỷ xuất bản Dịch vụ trên thiết bị

Cách xoá địa chỉ và dịch vụ đã đăng ký khỏi nút máy khách SRP:

> srp client host remove
Done

Bây giờ, bạn không thể phát hiện dịch vụ _ipps._tcp.

8. Xin chúc mừng

Xin chúc mừng, bạn đã thiết lập thành công OTBR làm Bộ định tuyến biên theo giao thức Thread để cung cấp khả năng kết nối IP hai chiều và khám phá dịch vụ cho các thiết bị đầu cuối theo giao thức Thread.

Tiếp theo là gì?

Hãy xem một số lớp học lập trình này...

Tài liệu tham khảo