تثبيت Docker
على Raspberry Pi:
ثبِّت Docker:
curl -sSL https://get.docker.com | shإذا كنت تريد استخدام Docker بدون امتيازات الجذر، بدون الحاجة إلى
sudoقبل كل أمر، عدِّل إعدادات المستخدم. سجِّل الخروج لتطبيق التغييرات:sudo usermod -aG docker $USERابدأ Docker إذا لم يكن قيد التشغيل:
sudo dockerd
تفعيل إعادة توجيه عناوين IP
يتم عادةً إيقاف إعادة توجيه عناوين IP تلقائيًا في نظام التشغيل Linux. شغِّل النص البرمجي
setup-host
لتفعيل إعادة توجيه عناوين IP على نظام المضيف.
يتم تلقائيًا ضبط النص البرمجي setup-host على استخدام الواجهة wlan0
ويمكن تنفيذه كما هو موضّح أدناه:
curl -sSL https://raw.githubusercontent.com/openthread/ot-br-posix/refs/heads/main/etc/docker/border-router/setup-host | bash
إذا كنت تستخدم واجهة بنية أساسية مختلفة (على سبيل المثال، eth0)، عليك تحديدها من خلال ضبط متغيّر البيئة INFRA_IF_NAME قبل تشغيل النص البرمجي.
على سبيل المثال:
INFRA_IF_NAME=eth0 curl -sSL https://raw.githubusercontent.com/openthread/ot-br-posix/refs/heads/main/etc/docker/border-router/setup-host | bash
الحصول على صورة OTBR Docker
يمكنك الحصول على صورة OTBR Docker من خلال سحبها مباشرةً من OpenThread Docker Hub، أو من خلال استنساخ مستودع OTBR وإنشاء ملف Dockerfile المضمّن محليًا.
سحب الصورة من Docker Hub
سحب الصورة:
docker pull openthread/border-router:latestمن المفترض أن يظهر الآن في قائمة صور Docker:
docker imagesREPOSITORY TAG IMAGE ID CREATED SIZE openthread/border-router latest 08666d77013d 2 hours ago 132MB
إنشاء الملف الشامل
لإنشاء الصورة بنفسك، استنسِخ مستودع OpenThread Border Router وأنشئ Dockerfile المضمّن.
ثبِّت git:
sudo apt install gitاستنسِخ مستودع OTBR:
git clone --depth=1 https://github.com/openthread/ot-br-posixcd ot-br-posixإنشاء الملف الشامل:
docker build --no-cache -t openthread/border-router -f etc/docker/border-router/Dockerfile .
إنشاء ملف إعداد OTBR
أنشئ ملف otbr-env.list لتخزين إعدادات OTBR Docker.
OT_RCP_DEVICE=spinel+hdlc+uart:///dev/ttyACM0?uart-baudrate=1000000 OT_INFRA_IF=wlan0 OT_THREAD_IF=wpan0 OT_LOG_LEVEL=7
OT_RCP_DEVICE: يحدّد هذا الخيار الاتصال بمعالج Thread Radio Co-Processor (RCP).
OT_INFRA_IF: هي واجهة الشبكة المستخدَمة لشبكة البنية الأساسية المجاورة (عادةً Wi-Fi أو إيثرنت).
OT_THREAD_IF: اسم واجهة الشبكة المستخدَمة لشبكة Thread
OT_LOG_LEVEL: مستوى التفصيل في السجلات التي تم إنشاؤها بواسطة OpenThread.
بدء تشغيل حاوية OTBR Docker
أنشئ حاوية جديدة وشغِّلها من صورة OTBR.
docker run --name=otbr --detach --network=host --cap-add=NET_ADMIN --device=/dev/ttyACM0 --device=/dev/net/tun --volume=/var/lib/otbr:/data --env-file=otbr-env.list --restart=always openthread/border-router
docker run: الأمر الأساسي لتشغيل حاوية Docker.--name=otbr: يحدّد الاسم "otbr" للحاوية قيد التشغيل. يسهّل ذلك الرجوع إلى الحاوية لاحقًا لتنفيذ إجراءات مثل إيقافها أو بدء تشغيلها أو فحصها.
--detach: تشغّل الحاوية في وضع منفصل، ما يعني أنّها تعمل في الخلفية ولا تربط الوحدة الطرفية بتيارات الإدخال أو الإخراج أو الخطأ العادية للحاوية.
--network=host: تجعل الحاوية تستخدم حزمة الشبكة الخاصة بالجهاز المضيف مباشرةً. ويكون ذلك ضروريًا في كثير من الأحيان بالنسبة إلى OTBR، لأنّه يحتاج إلى الوصول المباشر إلى واجهات الشبكة.--cap-add=NET_ADMIN: تمنح الحاوية إذن الوصول إلى إمكانيةNET_ADMIN. هذا الإذن ضروري لكي تنفّذ الحاوية مهام إدارة الشبكة، مثل ضبط واجهات الشبكة والتوجيه.--device=/dev/ttyACM0: يربط جهاز المضيف/dev/ttyACM0بالحاوية. يكون هذا عادةً المنفذ التسلسلي المرتبط بالمعالج المساعد اللاسلكي Thread (RCP). قد يختلف اسم الجهاز المحدّد (ttyACM0) حسب نظامك.--device=/dev/net/tun: يربط جهاز المضيف/dev/net/tunبالحاوية. وهذا ضروري لإنشاء واستخدام واجهات شبكة افتراضية تستخدمها أداة OTBR.
--volume=/var/lib/otbr:/data: يركّب دليل المضيف/var/lib/otbrفي الحاوية في/data. يتيح ذلك للحاوية الاحتفاظ بالبيانات، مثل إعدادات الشبكة، حتى عند إيقاف الحاوية أو إعادة تشغيلها.
--env-file=otbr-env.list: يقرأ متغيرات البيئة من الملف المحدّد ويضبطها داخل الحاوية. من المحتمل أن تكون متغيرات البيئة هذه مَعلمات إعداد لجهاز OTBR.--restart=always: يضبط برنامج Docker الخفي لإعادة تشغيل الحاوية تلقائيًا في حال توقّفها. يضمن ذلك أنّ OTBR يكون دائمًا في وضع التشغيل. openthread/border-router: يحدّد هذا الخيار صورة Docker التي سيتم استخدامها للحاوية. في هذه الحالة، تكون الصورة هي صورة OpenThread Border Router الرسمية.
عرض سجلّات Docker
استخدِم الأمر التالي على المضيف لعرض السجلات:
docker logs otbr
في حال تنفيذ OTBR بنجاح، من المفترض أن تظهر لك نتيجة مشابهة لما يلي:
s6-rc: info: service mdns: starting
s6-rc: info: service s6rc-oneshot-runner: starting
Starting mDNSResponder...
Default: mDNSResponder (Engineering Build) (Mar 26 2025 19:39:09) starting
s6-rc: info: service mdns successfully started
s6-rc: info: service s6rc-oneshot-runner successfully started
s6-rc: info: service fix-attrs: starting
s6-rc: info: service fix-attrs successfully started
s6-rc: info: service legacy-cont-init: starting
s6-rc: info: service legacy-cont-init successfully started
s6-rc: info: service otbr-agent: starting
Configuring OpenThread firewall...
Configuring OpenThread NAT64...
Starting otbr-agent...
[NOTE]-AGENT---: Running 0.3.0-da4b5cf
[NOTE]-AGENT---: Thread version: 1.4.0
[NOTE]-AGENT---: Thread interface: wpan0
[NOTE]-AGENT---: Radio URL: spinel+hdlc+uart:///dev/ttyACM0?uart-baudrate=1000000
[NOTE]-AGENT---: Radio URL: trel://wlan0
[NOTE]-ILS-----: Infra link selected: wlan0
[INFO]-RCP_HOS-: OpenThread log level changed to 5
49d.18:38:43.301 [D] P-SpinelDrive-: Sent spinel frame, flg:0x2, iid:0, tid:0, cmd:RESET
49d.18:38:43.301 [D] P-SpinelDrive-: Waiting response: key=0
49d.18:38:43.311 [D] P-SpinelDrive-: Received spinel frame, flg:0x2, iid:0, tid:0, cmd:PROP_VALUE_IS, key:LAST_STATUS, status:RESET_POWER_ON
49d.18:38:43.311 [I] P-SpinelDrive-: co-processor reset: RESET_POWER_ON
49d.18:38:43.311 [C] P-SpinelDrive-: Software reset co-processor successfully
49d.18:38:43.311 [D] P-SpinelDrive-: Sent spinel frame, flg:0x2, iid:0, tid:1, cmd:PROP_VALUE_GET, key:PROTOCOL_VERSION
49d.18:38:43.311 [D] P-SpinelDrive-: Waiting response: key=1
49d.18:38:43.312 [D] P-SpinelDrive-: Received spinel frame, flg:0x2, iid:0, tid:1, cmd:PROP_VALUE_IS, key:PROTOCOL_VERSION, major:4, minor:3
49d.18:38:43.312 [D] P-SpinelDrive-: Sent spinel frame, flg:0x2, iid:0, tid:1, cmd:PROP_VALUE_GET, key:NCP_VERSION
49d.18:38:43.312 [D] P-SpinelDrive-: Waiting response: key=2
49d.18:38:43.313 [D] P-SpinelDrive-: Received spinel frame, flg:0x2, iid:0, tid:1, cmd:PROP_VALUE_IS, key:NCP_VERSION, version:OPENTHREAD/7a25828-dirty; NRF52840; Mar 25 2025 15:51:02
49d.18:38:43.313 [D] P-SpinelDrive-: Sent spinel frame, flg:0x2, iid:0, tid:1, cmd:PROP_VALUE_GET, key:CAPS
49d.18:38:43.313 [D] P-SpinelDrive-: Waiting response: key=5
49d.18:38:43.314 [D] P-SpinelDrive-: Received spinel frame, flg:0x2, iid:0, tid:1, cmd:PROP_VALUE_IS, key:CAPS, caps:COUNTERS UNSOL_UPDATE_FILTER 802_15_4_2450MHZ_OQPSK CONFIG_RADIO MAC_RAW RCP_API_VERSION RCP_MIN_HOST_API_VERSION OPENTHREAD_LOG_METADATA
49d.18:38:43.376 [D] P-SpinelDrive-: Sent spinel frame, flg:0x2, iid:0, tid:1, cmd:PROP_VALUE_GET, key:HWADDR
49d.18:38:43.376 [D] P-RadioSpinel-: Wait response: tid=1 key=8
49d.18:38:43.376 [D] P-SpinelDrive-: Received spinel frame, flg:0x2, iid:0, tid:1, cmd:PROP_VALUE_IS, key:HWADDR, eui64:f4ce3693ab886040
49d.18:38:43.376 [D] P-SpinelDrive-: Sent spinel frame, flg:0x2, iid:0, tid:2, cmd:PROP_VALUE_GET, key:RCP_API_VERSION
49d.18:38:43.376 [D] P-RadioSpinel-: Wait response: tid=2 key=176
49d.18:38:43.377 [D] P-SpinelDrive-: Received spinel frame, flg:0x2, iid:0, tid:2, cmd:PROP_VALUE_IS, key:RCP_API_VERSION, version:11
49d.18:38:43.377 [D] P-SpinelDrive-: Sent spinel frame, flg:0x2, iid:0, tid:3, cmd:PROP_VALUE_GET, key:RCP_MIN_HOST_API_VERSION
49d.18:38:43.377 [D] P-RadioSpinel-: Wait response: tid=3 key=177
49d.18:38:43.378 [D] P-SpinelDrive-: Received spinel frame, flg:0x2, iid:0, tid:3, cmd:PROP_VALUE_IS, key:RCP_MIN_HOST_API_VERSION, min-host-version:4
49d.18:38:43.378 [D] P-SpinelDrive-: Sent spinel frame, flg:0x2, iid:0, tid:4, cmd:PROP_VALUE_GET, key:RADIO_CAPS
49d.18:38:43.378 [D] P-RadioSpinel-: Wait response: tid=4 key=4619
49d.18:38:43.379 [D] P-SpinelDrive-: Received spinel frame, flg:0x2, iid:0, tid:4, cmd:PROP_VALUE_IS, key:RADIO_CAPS, caps:255
49d.18:38:43.410 [D] P-Trel--------: platformTrelInit(aTrelUrl:"trel://wlan0")
49d.18:38:43.410 [D] P-Trel--------: otSysTrelInit(aInterfaceName:"wlan0")
[DEBG]-TrelDns-: Initialized on netif "wlan0"
[DEBG]-TrelDns-: Netif wlan0 is ready: index = 3
49d.18:38:43.411 [I] P-Netif-------: Sent request#1 to set addr_gen_mode to 1
00:00:00.000 [D] P-SpinelDrive-: Sent spinel frame, flg:0x2, iid:0, tid:5, cmd:PROP_VALUE_GET, key:PHY_CHAN_SUPPORTED
00:00:00.000 [D] P-RadioSpinel-: Wait response: tid=5 key=34
00:00:00.001 [D] P-SpinelDrive-: Received spinel frame, flg:0x2, iid:0, tid:5, cmd:PROP_VALUE_IS, key:PHY_CHAN_SUPPORTED, channelMask:0x07fff800
00:00:00.001 [D] P-SpinelDrive-: Sent spinel frame, flg:0x2, iid:0, tid:6, cmd:PROP_VALUE_SET, key:PHY_ENABLED, enabled:1
00:00:00.001 [D] P-RadioSpinel-: Wait response: tid=6 key=32
00:00:00.003 [D] P-SpinelDrive-: Received spinel frame, flg:0x2, iid:0, tid:6, cmd:PROP_VALUE_IS, key:PHY_ENABLED, enabled:1
00:00:00.003 [D] P-SpinelDrive-: Sent spinel frame, flg:0x2, iid:0, tid:7, cmd:PROP_VALUE_SET, key:MAC_15_4_PANID, panid:0xffff
00:00:00.003 [D] P-RadioSpinel-: Wait response: tid=7 key=54
00:00:00.003 [D] P-SpinelDrive-: Received spinel frame, flg:0x2, iid:0, tid:7, cmd:PROP_VALUE_IS, key:MAC_15_4_PANID, panid:0xffff
00:00:00.003 [D] P-SpinelDrive-: Sent spinel frame, flg:0x2, iid:0, tid:8, cmd:PROP_VALUE_SET, key:MAC_15_4_SADDR, saddr:0x0000
00:00:00.003 [D] P-RadioSpinel-: Wait response: tid=8 key=53
00:00:00.004 [D] P-SpinelDrive-: Received spinel frame, flg:0x2, iid:0, tid:8, cmd:PROP_VALUE_IS, key:MAC_15_4_SADDR, saddr:0x0000
00:00:00.004 [D] P-SpinelDrive-: Sent spinel frame, flg:0x2, iid:0, tid:9, cmd:PROP_VALUE_GET, key:PHY_RX_SENSITIVITY
00:00:00.004 [D] P-RadioSpinel-: Wait response: tid=9 key=39
00:00:00.005 [D] P-SpinelDrive-: Received spinel frame, flg:0x2, iid:0, tid:9, cmd:PROP_VALUE_IS, key:PHY_RX_SENSITIVITY, sensitivity:-100
00:00:00.005 [D] P-SpinelDrive-: Sent spinel frame, flg:0x2, iid:0, tid:10, cmd:PROP_VALUE_SET, key:RCP_MAC_KEY, keyIdMode:8, keyId:1, prevKey:***, currKey:***, nextKey:***
00:00:00.005 [D] P-RadioSpinel-: Wait response: tid=10 key=2048
00:00:00.007 [D] P-SpinelDrive-: Received spinel frame, flg:0x2, iid:0, tid:10, cmd:PROP_VALUE_IS, key:LAST_STATUS, status:OK
00:00:00.007 [D] P-SpinelDrive-: Sent spinel frame, flg:0x2, iid:0, tid:11, cmd:PROP_VALUE_SET, key:MAC_15_4_LADDR, laddr:a2566e135ad5df32
00:00:00.007 [D] P-RadioSpinel-: Wait response: tid=11 key=52
00:00:00.008 [D] P-SpinelDrive-: Received spinel frame, flg:0x2, iid:0, tid:11, cmd:PROP_VALUE_IS, key:MAC_15_4_LADDR, laddr:a2566e135ad5df32
00:00:00.008 [D] P-SpinelDrive-: Sent spinel frame, flg:0x2, iid:0, tid:12, cmd:PROP_VALUE_SET, key:MAC_15_4_SADDR, saddr:0xfffe
00:00:00.008 [D] P-RadioSpinel-: Wait response: tid=12 key=53
00:00:00.009 [D] P-SpinelDrive-: Received spinel frame, flg:0x2, iid:0, tid:12, cmd:PROP_VALUE_IS, key:MAC_15_4_SADDR, saddr:0xfffe
00:00:00.009 [D] P-SpinelDrive-: Sent spinel frame, flg:0x2, iid:0, tid:13, cmd:PROP_VALUE_SET, key:MAC_SRC_MATCH_SHORT_ADDRESSES, saddr:none
00:00:00.009 [D] P-RadioSpinel-: Wait response: tid=13 key=4868
00:00:00.010 [D] P-SpinelDrive-: Received spinel frame, flg:0x2, iid:0, tid:13, cmd:PROP_VALUE_IS, key:LAST_STATUS, status:OK
00:00:00.011 [D] P-SpinelDrive-: Sent spinel frame, flg:0x2, iid:0, tid:14, cmd:PROP_VALUE_SET, key:MAC_SRC_MATCH_EXTENDED_ADDRESSES, extaddr:none
00:00:00.011 [D] P-RadioSpinel-: Wait response: tid=14 key=4869
00:00:00.012 [D] P-SpinelDrive-: Received spinel frame, flg:0x2, iid:0, tid:14, cmd:PROP_VALUE_IS, key:LAST_STATUS, status:OK
00:00:00.012 [I] CslTxScheduler: Set frame request ahead: 6200 usec
00:00:00.012 [I] ChildSupervsn-: Timeout: 0 -> 190
00:00:00.013 [D] P-Trel--------: PrepareSocket()
[DEBG]-TrelDns-: Start browsing _trel._udp services ...
00:00:00.013 [I] TrelInterface-: Enabled interface, local port:52346
00:00:00.013 [I] RoutingManager: Initializing - InfraIfIndex:3
00:00:00.013 [I] InfraIf-------: Init infra netif 3
00:00:00.013 [N] RoutingManager: No valid /48 BR ULA prefix found in settings, generating new one
00:00:00.038 [I] Settings------: Saved BrUlaPrefix fd92:6043:f0e2::/48
00:00:00.038 [N] RoutingManager: BR ULA prefix: fd92:6043:f0e2::/48 (generated)
00:00:00.038 [I] RoutingManager: Generated local OMR prefix: fd92:6043:f0e2:1::/64
00:00:00.038 [I] RoutingManager: Generated local NAT64 prefix: fd92:6043:f0e2:2:0:0::/96
00:00:00.038 [N] RoutingManager: Local on-link prefix: fdde:ad00:beef:cafe::/64
00:00:00.038 [I] InfraIf-------: State changed: NOT RUNNING -> RUNNING
00:00:00.038 [I] RoutingManager: Enabling
00:00:00.038 [I] Nat64---------: IPv4 CIDR for NAT64: 192.168.255.0/24 (actual address pool: 192.168.255.1 - 192.168.255.254, 254 addresses)
[INFO]-UTILS---: Set state callback: OK
00:00:00.039 [I] Nat64---------: NAT64 translator is now NotRunning
[DEBG]-TrelDns-: mDNS Publisher is Ready
[INFO]-TrelDns-: TREL DNS-SD Is Now Ready: Netif=wlan0(3), SubscriberId=1, Register=!
[INFO]-MDNS----: Subscribe service ._trel._udp (total 1)
[INFO]-MDNS----: DNSServiceBrowse _trel._udp
[INFO]-BA------: Start Thread Border Agent
[INFO]-ADPROXY-: Started
[INFO]-DPROXY--: Started
[INFO]-APP-----: Co-processor version: OPENTHREAD/7a25828-dirty; NRF52840; Mar 25 2025 15:51:02
00:00:00.039 [I] Notifier------: StateChanged (0x40038210) [MLAddr NetData PanId NetName ExtPanId Nat64]
00:00:00.041 [I] Platform------: Execute command `ipset flush otbr-ingress-allow-dst-swap` = 0
00:00:00.042 [I] Platform------: Execute command `ipset flush otbr-ingress-deny-src-swap` = 0
00:00:00.044 [I] Platform------: Execute command `ipset add otbr-ingress-deny-src-swap fdde:ad00:beef:0::/64 -exist` = 0
00:00:00.046 [I] Platform------: Execute command `ipset swap otbr-ingress-deny-src-swap otbr-ingress-deny-src` = 0
00:00:00.047 [I] Platform------: Execute command `ipset swap otbr-ingress-allow-dst-swap otbr-ingress-allow-dst` = 0
00:00:00.047 [I] P-Netif-------: NAT64 CIDR updated to 192.168.255.0/24.
00:00:00.047 [I] P-Netif-------: Sent request#2 to delete route 192.168.255.0/24
00:00:00.047 [I] P-Netif-------: Deleting route for NAT64
00:00:00.047 [I] RouterTable---: Route table
00:00:00.047 [I] TrelInterface-: Registering DNS-SD service: port:52346, txt:"xa=a2566e135ad5df32, xp=dead00beef00cafe"
[DEBG]-TrelDns-: Register _trel._udp service: port=52346, TXT=24 bytes
[DEBG]-TrelDns-: Using instance name a2566e135ad5df32
[INFO]-MDNS----: Registering service a2566e135ad5df32._trel._udp
00:00:00.058 [I] Settings------: Saved BorderAgentId {id:27a9a3c44dd733402e8a940a20fc1051}
[INFO]-BA------: Result of decoding MeshCoP TXT data from OT: OK
[INFO]-BA------: Publish meshcop service OpenThread BorderRouter #DF32._meshcop._udp.local.
[INFO]-MDNS----: Registering service OpenThread BorderRouter #DF32._meshcop._udp
00:00:00.059 [I] P-Netif-------: Host netif is down
00:00:00.059 [I] P-Netif-------: Succeeded to process request#1
00:00:00.060 [W] P-Netif-------: Failed to process request#2: No such process
s6-rc: info: service otbr-agent successfully started
...