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.pngS

Bộ định tuyến đường viền luồng là gì?

Thread là một giao thức mạng lưới không dây không dây 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 các thiết bị. Mạng Thread có thể thích ứng với những thay đổi về cấu trúc liên kết để tránh một điểm lỗi.

Bộ định tuyến đường viền luồng 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 yêu cầu phải có Bộ định tuyến biên để kết nối với các mạng khác. Bộ định tuyến đường viền luồng hỗ trợ tối thiểu các hàm sau:

  • 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 qua mDNS (trên đường liên kết Wi-Fi/Ethernet) và SRP (trên mạng Thread).
  • Cấu trúc Thread trên cơ sở hạ tầng hợp nhất các phân vùng Thread hợp nhất các phân vùng Thread với các liên kết dựa trên IP.
  • Uỷ quyền 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ột mạng Thread.

Trình định tuyến đường viền OpenThread (OTBR) do Google phát hành là một bản triển khai nguồn mở của Bộ định tuyến đường viền luồng.

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 Bộ định tuyến đường viền luồng và kết nối điện thoại di động với Thiết bị cuối luồng 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 xây dựng thiết bị OpenThread CLI bằng tính năng SRP
  • Cách đăng ký một dịch vụ với SRP
  • Cách khám phá và kết nối với thiết bị cuối Thread.

Bạn cần có

  • Một thiết bị Raspberry Pi 3/4 và một thẻ SD có dung lượng ít nhất 8 GB.
  • 2 Bảng phát triển của Bắc Âu nRF52840.
  • Một AP Wi-Fi không bật Trình bảo vệ quảng cáo bộ định tuyến IPv6 trên bộ định tuyến.
  • Điện thoại iOS chạy iOS 14 hoặc điện thoại Android chạy Android 8.1 trở lên.

2. Thiết lập OTBR

Thiết lập Raspberry Pi

Bạn có thể dễ dàng thiết lập thiết bị Raspberry Pi mới bằng công cụ rpi-imager bằng cách làm theo hướng dẫn trên raspberrypi.org (thay vì sử dụng hệ điều hành Raspberry Pi mới nhất trong công cụ này, hãy tự tải 2021-05-07-raspios-buster-armhf-lite xuống). Để hoàn tất các bước dành cho điện thoại di động trong lớp học lập trình này, bạn cần kết nối Raspberry Pi với AP Wi-Fi. Làm theo hướng dẫn này để thiết lập kết nối không dây. Việc đăng nhập vào Raspberry Pi bằng SSH rất thuận tiện. Bạn có thể xem hướng dẫn tại đây.

Nhận mã OTBR

Đăng nhập vào Raspberry Pi và sao chép ot-br-posix từ GitHub:

$ git clone https://github.com/openthread/ot-br-posix.git --depth 1

Tạo và cài đặt OTBR

OTBR có hai tập lệnh tự khởi động và thiết lập Bộ định tuyến đường viền luồng:

$ cd ot-br-posix
$ ./script/bootstrap
$ INFRA_IF_NAME=wlan0 ./script/setup

OTBR hoạt động trên cả giao diện Thread và giao diện mạng của cơ sở hạ tầng (ví dụ: Wi-Fi/Ethernet) được chỉ định bằng INFRA_IF_NAME. Giao diện Thread do chính OTBR tạo ra và được đặt tên là wpan0 theo mặc định, còn giao diện cơ sở hạ tầng có giá trị mặc định là wlan0 nếu INFRA_IF_NAME không được chỉ định rõ ràng. Nếu Raspberry Pi được kết nối bằng cáp Ethernet, hãy chỉ định tên giao diện Ethernet (ví dụ: eth0):

$ INFRA_IF_NAME=eth0 ./script/setup

Kiểm tra xem OTBR đã được cài đặt thành công chưa:

$ sudo service otbr-agent status
● otbr-agent.service - Border Router Agent
   Loaded: loaded (/lib/systemd/system/otbr-agent.service; enabled; vendor preset: enabled)
   Active: activating (auto-restart) (Result: exit-code) since Mon 2021-03-01 05:43:38 GMT; 2s ago
  Process: 2444 ExecStart=/usr/sbin/otbr-agent $OTBR_AGENT_OPTS (code=exited, status=2)
 Main PID: 2444 (code=exited, status=2)

Theo dự kiến, dịch vụ otbr-agent không hoạt động vì dịch vụ này cần có khối RCP để chạy.

Khởi động lại Raspberry Pi để các thay đổi có hiệu lực.

Tạo và cài đặt RCP chương trình cơ sở

OTBR hỗ trợ chip phát thanh 15.4 ở chế độ Đồng bộ xử lý vô tuyến (RCP). Ở chế độ này, ngăn xếp OpenThread đang chạy ở phía máy chủ và truyền/nhận khung qua bộ thu phát IEEE802.15.4.

Làm theo bước 4 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à cài đặt RCP cho thiết bị nRF52840 RCP:

$ script/build nrf52840 USB_trans

Bắt đầu OTBR và xác minh trạng thái

Kết nối bo mạch nRF52840 với Raspberry Pi rồi bắt đầu dịch vụ otbr-agent:

$ sudo service otbr-agent restart

Xác minh dịch vụ otbr-agent đang hoạt động:

$ sudo service otbr-agent status
● otbr-agent.service - Border Router Agent
   Loaded: loaded (/lib/systemd/system/otbr-agent.service; enabled; vendor preset: enabled)
   Active: active (running) since Mon 2021-03-01 05:46:26 GMT; 2s ago
 Main PID: 2997 (otbr-agent)
    Tasks: 1 (limit: 4915)
   CGroup: /system.slice/otbr-agent.service
           └─2997 /usr/sbin/otbr-agent -I wpan0 -B wlan0 spinel+hdlc+uart:///dev/ttyACM0

Mar 01 05:46:26 raspberrypi otbr-agent[2997]: Stop publishing service
Mar 01 05:46:26 raspberrypi otbr-agent[2997]: [adproxy] Stopped
Mar 01 05:46:26 raspberrypi otbr-agent[2997]: PSKc is not initialized
Mar 01 05:46:26 raspberrypi otbr-agent[2997]: Check if PSKc is initialized: OK
Mar 01 05:46:26 raspberrypi otbr-agent[2997]: Initialize OpenThread Border Router Agent: OK
Mar 01 05:46:26 raspberrypi otbr-agent[2997]: Border router agent started.
Mar 01 05:46:26 raspberrypi otbr-agent[2997]: [INFO]-CORE----: Notifier: StateChanged (0x00038200) [NetData PanId NetName ExtPanId]
Mar 01 05:46:26 raspberrypi otbr-agent[2997]: [INFO]-PLAT----: Host netif is down

3. Tạo một mạng Thread

Có một lệnh ot-ctl dùng để kiểm soát dịch vụ otbr-agent. ot-ctl chấp nhận tất cả lệnh OpenThread CLI, hãy xem Hướng dẫn về OpenThread CLI để biết thêm chi tiết.

Tạo một mạng Thread bằng OTBR:

$ sudo ot-ctl dataset init new
Done
$ sudo ot-ctl dataset commit active
Done
$ sudo ot-ctl ifconfig up
Done
$ sudo ot-ctl thread start
Done

Đợi vài giây, chúng ta có thể thấy OTBR đang hoạt động như một Thread leader (Luồng) và có tiền tố off-mesh-routable (OMR) trong Thread Network Data (Dữ liệu mạng Thread):

$ sudo ot-ctl state
leader
Done
$ 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

4. Thiết lập thiết bị cuối máy khách SRP

Tạo và cài đặt ROM 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 bo mạch nRF52840 và OpenThread để tạo và cài đặt ROM thiết bị đầu cuối nRF52840 CLI.

Tuy nhiên, 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 OTBR

Để kết nối với mạng Thread do dịch vụ otbr-agent tạo, 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 dòng lệnh otbr-agent và xem 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 kiểm tra xem bạn có thành công khi tham gia 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

5. Xuất bản Dịch vụ trên thiết bị cuối

mDNS đã được sử dụng rộng rãi để xuất bản dịch vụ DNS-SD trên link-local. Tuy nhiên, tin nhắn phát đa hướng tốn quá nhiều băng thông và sẽ nhanh chóng làm cạn kiệt pin của các thiết bị công suất thấp. Thread sử dụng giao thức SRP unicast để đăng ký dịch vụ của chúng với Border Router và dựa vào Bộ định tuyến biên để quảng cáo các dịch vụ trên 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 bắt đầu ứng dụng SRP:

> srp client autostart enable
Done

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

> srp client host name ot-host
Done

Để thiết bị sử dụng đường liên kết Wi-Fi/Ethernet kết nối với thiết bị đầu cuối Thread, bạn cần 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ả mạo:

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

Đợi một vài giây và chúng ta sẽ có thể thấy dịch vụ đã được đă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 quy trình thiết lập và dịch vụ _ipps._tcp sẽ được quảng cáo trên đường liên kết Wi-Fi/Ethernet. Đã đến lúc khám phá và sử dụng thiết bị cuối ngay bây giờ!

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

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

54a136a8940897cc.pngS

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

Khám phá dịch vụ thông qua máy chủ Linux

Nếu muốn khám phá dịch vụ từ một máy chủ Linux khác, bạn có thể sử 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 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ụ thông qua máy chủ lưu trữ macOS

Bạn có thể sử dụng dns-sd trên macOS để giải quyết dịch vụ này:

$ 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     ""
...

7. Ping thiết bị cuối

Ping trên điện thoại di động

Hãy 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 đó trên 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.pngS

Giờ đây, chúng ta có thể ping địa chỉ OMR bằng một ứng dụng Trình phân tích mạng khác.

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

Ping từ máy chủ Linux/macOS

Bộ định tuyến đường viền luồng gửi Quảng cáo bộ định tuyến ICMPv6 (RA) để quảng cáo tiền tố (thông qua Tuỳ chọn thông tin tiền tố) và tuyến đườ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

Bạn phải đảm bảo đã bật RA và RIO trên máy chủ của mình:

  1. net.ipv6.conf.wlan0.accept_ra phải có giá trị tối thiểu là 1 nếu tính năng chuyển tiếp ip không được bật và phải có giá trị 2 nếu không bật.
  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 là 1 đối với 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 đè tuỳ 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:

$ 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 tính năng chuyển tiếp IP được bật) bằng:

$ 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 mặc định là 0. Hãy đặt thành 64 với:

$ 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 sẽ bị mất sau khi 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 các cấu hình đó vì OTBR đã gửi 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à vài trăm giây. Có một cách là ngắt kết nối rồi kết nối lại với Wi-Fi AP để gửi thông báo Gây quỹ cho bộ định tuyến, qua đó OTBR sẽ phản hồi bằng các RA được yêu cầu. Một cách khác là khởi động lại chức năng Định tuyến đường viề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 sử dụng dhcpcd để quản lý mạng IPv6 Wi-Fi/Ethernet IPv6. 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) để vô hiệu hóa rõ ràng IPv6 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ủ macOS

Cả hai tuỳ 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

Bây giờ, chúng ta có thể ping tên máy chủ ot-host.local bằng lệnh ping -6 (ping6 đối với 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 thực hiện được trên máy chủ Linux kèm theo 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. với các truy vấn mDNS. Mở /etc/nsswitch.conf và 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
...

8. Huỷ xuất bản Dịch vụ trên thiết bị cuối

Cách xoá địa chỉ và dịch vụ đã đăng ký từ nút ứng dụng SRP:

> srp client host remove
Done

Hiện tại, bạn sẽ không thể khám phá dịch vụ _ipps._tcp.

9. 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 dạng luồng để cung cấp khả năng khám phá dịch vụ và kết nối IP hai chiều cho các thiết bị đầu cuối luồng.

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