في الجزء الأول رسمنا خزانة البيت: جدار ناري OPNsense مستقل، وSwitch مدار، ونقاط Wi-Fi، وسيرفرات Proxmox، وNAS، وكابلات منظمة. والآن الأجهزة موصولة، ولكنها كلها في شبكة واحدة مسطحة، فالكاميرا ترى ال NAS، وهاتف الضيف يرى لوحة Proxmox، وهذا بالضبط ما بنينا الخزانة لنتخلص منه.
المواضيع في السلسلة:
- الهوم لاب بمواصفات الإنتاج (1): التصميم والعتاد: الأهداف، والقرار حول خدمات العملاء، والتصميم المرجعي، والعتاد والكابلات وال UPS.
- الهوم لاب بمواصفات الإنتاج (2): الشبكة والجدار الناري (الموضوع الحالي): خطة العناوين، وشبكات VLAN، ومصفوفة المناطق، وOPNsense، وال Switch، وWireGuard، وتجربة عملية.
- الهوم لاب بمواصفات الإنتاج (3): الخدمات ونشرها: ما الذي يعمل أين، ونشر خدمات العملاء عبر VPS، والمراقبة والنسخ الاحتياطي.
والمفاهيم نفسها، أي لماذا نقسم الشبكة وما هو ال VLAN ومنفذ Access ومنفذ Trunk، شرحناها في تقسيم الشبكة Network Segmentation، وحساب المجالات في الشبكات الفرعية Subnets وCIDR، لذلك لن نكررها هنا، وسوف نناقش في هذا المقال ما يلي:
- خطة العناوين IP Plan وشبكات VLAN كاملة في جدول واحد.
- من يحمل ماذا: منافذ ال Switch وشبكات Wi-Fi.
- مصفوفة المناطق Zone Matrix: من يكلم من، وعلى أي منفذ.
- إعداد OPNsense خطوة بخطوة من توثيقه الرسمي: الواجهات، وVLAN، وDHCP، وDNS مع Unbound، والقواعد، وكشف التسلل IDS باختصار.
- إعداد ال Switch: الجدول العام، ثم إعداد حقيقي ل MikroTik CRS310.
- WireGuard للمدير من الخارج، ونفق إلى ال VPS، وDNS المنقسم Split Horizon، ولماذا تكون الإدارة عبر VPN فقط.
- تجربة عملية تبني الشبكة كلها من Containers، وتتحقق من المصفوفة بمخرجات حقيقية.
خطة العناوين وشبكات VLAN
الحل البسيط هو أن تترك الشبكة على 192.168.1.0/24 التي جاء بها Router المزود، ثم تضيف شبكات أخرى كلما احتجت، وبعد سنة تجد عندك 192.168.0.0/24 و192.168.88.0/24 و172.16.5.0/24 بلا أي منطق. والمشكلة الأكبر تظهر عندما تتصل بالبيت عبر VPN من فندق أو مقهى شبكته أيضاً 192.168.1.0/24، فيتعارض المجالان ولا يعرف حاسوبك إلى أين يرسل. لذلك نختار من البداية مجالاً خاصاً أقل شيوعاً، ونجعل له قاعدة يتذكرها أي شخص:
- البيت كله في
10.10.0.0/16، وهذا يعني أن مساراً واحداً في إعداد VPN يغطي كل شبكات البيت. - كل VLAN شبكة
/24، ورقم ال VLAN هو الرقم الثالث في العنوان، فشبكة VLAN 40 هي10.10.40.0/24، وعندما ترى عنواناً تعرف شبكته مباشرة. - البوابة Gateway دائماً
.1، والعناوين الثابتة من.2إلى.99، ومجال DHCP من.100إلى.199.
وقد يتساءل البعض: أليست /24 لكل شبكة إسرافاً، وفي شبكة الكاميرات خمسة أجهزة فقط؟ والإجابة أن المجال الخاص 10.0.0.0/8 فيه أكثر من ستة عشر مليون عنوان، والذي تدفعه هنا ليس عناوين، وإنما سهولة القراءة والتوثيق، وهذا ما يهمك في البيت. والجدول التالي هو الخطة كاملة:
| VLAN | الاسم | المجال | البوابة | العناوين | ما فيها |
|---|---|---|---|---|---|
| 10 | MGMT | 10.10.10.0/24 | 10.10.10.1 | ثابتة فقط | واجهات الإدارة: ال Switch ونقاط Wi-Fi ولوحة Proxmox وواجهة إدارة ال NAS وال UPS إن كان له بطاقة شبكة |
| 20 | SERVERS | 10.10.20.0/24 | 10.10.20.1 | ثابتة وحجوزات DHCP | الأجهزة الافتراضية وال Containers التي تقدم الخدمات الداخلية |
| 30 | STORAGE | 10.10.30.0/24 | لا توجد | ثابتة | حركة التخزين بين Proxmox وال NAS فقط، ولا تمر بالجدار الناري |
| 40 | TRUSTED | 10.10.40.0/24 | 10.10.40.1 | DHCP | حواسيب العائلة والفريق وهواتفهم |
| 50 | IOT | 10.10.50.0/24 | 10.10.50.1 | DHCP | التلفاز وأجهزة المنزل الذكي والمكيفات |
| 60 | CAMERAS | 10.10.60.0/24 | 10.10.60.1 | حجوزات DHCP | كاميرات المراقبة، دون إنترنت |
| 70 | GUEST | 10.10.70.0/24 | 10.10.70.1 | DHCP | الضيوف، إنترنت فقط |
| 80 | DMZ | 10.10.80.0/24 | 10.10.80.1 | ثابتة | أي خدمة تقرر نشرها من البيت إلى الإنترنت |
| لا يوجد | VPN | 10.10.90.0/24 | 10.10.90.1 | ثابتة لكل جهاز | أجهزة المدير والفريق عبر WireGuard |
| لا يوجد | S2S | 10.10.99.0/24 | لا توجد | ثابتة | النفق بين البيت وال VPS |
في الجدول أعلاه لاحظ التالي:
- شبكة التخزين بلا بوابة عمداً، فهي شبكة من طبقة الربط Layer 2 فقط بين Proxmox وال NAS، والسبب أن حركة النسخ والأقراص الافتراضية كبيرة، ولا تريدها أن تمر بالجدار الناري فتبطئه، ولا تريد أي جهاز آخر أن يصل إليها.
- لا نستخدم VLAN 1 لأي شيء، لأنه الشبكة الافتراضية في كل Switch، وكل منفذ جديد يدخلها تلقائياً في كثير من الأجهزة.
- شبكتا VPN وS2S ليستا VLAN، فهما واجهات WireGuard في الجدار الناري، ولكننا نعاملهما كمنطقتين لهما قواعدهما.
من يحمل ماذا: منافذ ال Switch وشبكات Wi-Fi
الصورة التالية تبين كيف تصل كل VLAN إلى أجهزتها، من الجدار الناري إلى ال Switch إلى كل منفذ، ومعها شبكات Wi-Fi في نقطة الوصول:

في الصورة أعلاه لاحظ التالي:
- ال Trunk إلى الجدار الناري لا يحمل VLAN 30، لأن شبكة التخزين لا تمر به أصلاً.
- منفذ Proxmox Trunk، لأن الأجهزة الافتراضية عليه في شبكات مختلفة، وكل جهاز افتراضي يأخذ رقم VLAN في إعداد واجهته في Proxmox، والمنفذ نفسه يحمل شبكة الإدارة حتى تصل إلى لوحة Proxmox.
- نقطة Wi-Fi تأخذ عنوان إدارتها من VLAN 10 دون وسم Untagged، وتحمل شبكات SSID الثلاث موسومة Tagged، وأي نقطة وصول تدعم عدة شبكات SSID مع VLAN تقوم بذلك من إعداداتها.
- المنفذ غير المستخدم معطل، حتى لا يصبح من يوصل كابلاً فيه داخل أي شبكة.
أما شبكات Wi-Fi فثلاث تكفي: Home للعائلة والفريق على VLAN 40 بباسورد قوي، وHome-IoT على VLAN 50 للأجهزة الذكية، وكثير منها لا يعمل إلا على تردد 2.4 GHz فاجعل هذه الشبكة تدعمه، وGuest على VLAN 70 مع عزل الأجهزة عن بعضها Client Isolation إن كانت النقطة تدعمه، حتى لا يرى هاتف ضيف هاتف ضيف آخر.
مصفوفة المناطق: من يكلم من
الآن نحدد السياسة قبل أن نكتب أي قاعدة، والطريقة هي جدول: كل صف منطقة يبدأ منها الاتصال، وكل عمود منطقة يذهب إليها، وفي كل خلية ما هو مسموح، والقاعدة الافتراضية أن كل ما لم يكتب في الجدول ممنوع، والصورة التالية هي المصفوفة لهذا البيت:

في المصفوفة أعلاه لاحظ التالي:
- لا أحد يصل إلى شبكة الإدارة من داخل البيت، حتى حاسوبك في الشبكة الموثوقة، والطريق الوحيد إليها هو WireGuard، والسبب أن أي جهاز في الشبكة الموثوقة قد يصاب ببرنامج خبيث، ولا تريد أن يكون على بعد خطوة من لوحة Proxmox. وإذا كان هذا مزعجاً لك في البيت، فاجعل لحاسوب الإدارة نفسه عنواناً ثابتاً، واسمح له وحده، ولا تسمح للشبكة كلها.
- الاتصال يبدأ من الأعلى ثقة إلى الأقل ثقة: الحاسوب الموثوق يصل إلى التلفاز ليرسل إليه فيلماً، والتلفاز لا يصل إلى الحاسوب، وHome Assistant على شبكة السيرفرات يتحكم في أجهزة المنزل الذكي، وهي لا تبدأ أي اتصال إلى السيرفرات. والردود تعود لأن الجدار الناري يتتبع الاتصالات Stateful، كما شرحنا في التوجيه بين شبكات VLAN.
- الكاميرات لا تصل إلى الإنترنت أبداً، ومسجل الفيديو على شبكة السيرفرات هو الذي يسحب البث منها على المنفذ 554، وقد شرحنا ذلك مع Frigate.
- ال DMZ لا يصل إلى أي شبكة داخلية، فإذا اخترق أحد الخدمة المنشورة فيه، فلن يجد طريقاً إلى البيت، وهذا ما نتحقق منه في التجربة.
- كل المناطق تستطيع أن تسأل DNS الجدار الناري على المنفذ 53، وهذه قاعدة في سلسلة الدخول Input وليست في المصفوفة.
إعداد OPNsense خطوة بخطوة
الخطوات التالية مأخوذة من توثيق OPNsense الرسمي، وأسماء القوائم كما هي في الواجهة، ونفترض أن المنفذ igc0 للإنترنت WAN والمنفذ igc1 لل Trunk إلى ال Switch، وهذه هي الأسماء التي يعطيها FreeBSD لمنافذ Intel بسرعة 2.5G عبر مشغل igc، وقد تختلف في جهازك.
التثبيت والواجهتان الأوليان
ثبت النظام كما في دليل التثبيت، وعند السؤال عن الواجهات اجعل igc0 هي WAN، وigc1 هي LAN مؤقتاً، وادخل إلى الواجهة من حاسوب موصول بمنفذ LAN. وقبل أن تكمل، تأكد أن جهاز المزود في وضع الجسر، وأن واجهة WAN أخذت العنوان العام.
إنشاء شبكات VLAN وتعيينها
بحسب دليل إعداد VLAN وصفحة الواجهات الأخرى:
- من Interfaces ‣ Devices ‣ VLAN أضف شبكة لكل رقم في الخطة عدا 30: الواجهة الأم Parent هي
igc1، والوسم VLAN tag هو الرقم، والوصف Description هو الاسم مثلMGMT، لأن الوصف هو ما يظهر في قوائم التعيين. - من Interfaces ‣ Assignments عين كل VLAN كواجهة جديدة، ثم افتحها وفعلها Enable، واجعل عنوانها IPv4 ثابتاً Static، مثل
10.10.40.1/24لشبكة TRUSTED. - الدليل يقول إن الواجهة الأم يجب أن تبقى غير معينة في الإعداد المعتاد، ويحذر من خلط الإطارات الموسومة وغير الموسومة على نفس المنفذ، لأن ذلك يسرب إعلانات ال Router وDHCP وغيرها من البث بين الشبكات، لذلك انقل الإدارة إلى VLAN 10 قبل أن تترك LAN المؤقتة.
- وكل واجهة VLAN تحتاج مجالاً فريداً، والدليل يقول إن تعارض المجالات يمنع التوجيه بين الشبكات، وهذا ما تضمنه الخطة أعلاه.
توزيع العناوين DHCP
في الإصدارات الحالية هناك ثلاث خدمات DHCP: ISC DHCP القديمة، وKea، وDnsmasq. وتوثيق Dnsmasq يقول إنه الخادم المناسب للشبكات الصغيرة والمتوسطة بأقل من 1000 جهاز، وإنه يسجل أسماء الأجهزة في DNS، بينما توثيق Kea يصفه بأنه المناسب للشبكات الكبيرة مع التوفر العالي. لذلك في البيت: من Services ‣ Dnsmasq DNS & DHCP ‣ DHCP ranges أضف مجالاً لكل شبكة فيها DHCP، من .100 إلى .199، وأضف حجوزات للأجهزة التي تحتاج عنواناً ثابتاً مثل الكاميرات، ولا تضف مجالاً لشبكتي MGMT وDMZ.
DNS مع Unbound
Unbound هو خادم DNS الافتراضي في OPNsense، ومن صفحته في التوثيق تهمنا ثلاثة أشياء: Services ‣ Unbound DNS ‣ General لاختيار الواجهات التي يستمع عليها، وServices ‣ Unbound DNS ‣ Access Lists ويقول التوثيق إن الواجهات المختارة تأخذ قائمة سماح تلقائياً، وOverrides لإضافة سجلات A وAAAA يدوياً، وهي التي نستخدمها في DNS المنقسم أدناه. وإذا استخدمت Dnsmasq لل DHCP مع Unbound، فالتوثيق يشرح في نفس صفحة Dnsmasq كيف تجعل Unbound يسأله عن أسماء الأجهزة عبر Services ‣ Unbound DNS ‣ Query Forwarding.
الأسماء المستعارة Aliases وقواعد الجدار الناري
قبل القواعد، أنشئ أسماء مستعارة من Firewall ‣ Aliases، مثل RFC1918 لكل المجالات الخاصة، وADMIN_PORTS للمنافذ 22 و8006، حتى تكون القواعد مقروءة. ثم تذكر ثلاث حقائق من صفحة الجدار الناري:
- القواعد افتراضياً تطبق على الحركة الداخلة In إلى الواجهة، أي أن قاعدة TRUSTED إلى SERVERS تكتب على واجهة TRUSTED.
- القواعد افتراضياً Quick، أي أن أول قاعدة تطابق الحزمة هي التي تنفذ First Match، لذلك ترتيبها مهم.
- إذا لم تطابق الحزمة أي قاعدة، فالقاعدة الافتراضية تسقطها Default Deny.
والنمط الذي يحول المصفوفة إلى قواعد على كل واجهة كما يلي، ومثاله واجهة TRUSTED:
- Pass من
TRUSTED netإلىThis Firewallعلى المنفذ 53، للسماح بالسؤال عن الأسماء. - Pass من
TRUSTED netإلىSERVERS netعلى المنفذ 443. - Pass من
TRUSTED netإلىIOT net. - Block من
TRUSTED netإلىRFC1918، أي كل الشبكات الخاصة الأخرى. - Pass من
TRUSTED netإلىany، وهذا هو الإنترنت فقط، لأن القاعدة السابقة منعت كل ما هو داخلي.
وقد يتساءل البعض: لماذا القاعدة الرابعة؟ أليس كل ما لم نسمح به ممنوعاً؟ والإجابة أن القاعدة الخامسة تسمح إلى any، وany تشمل الشبكات الداخلية أيضاً، فلولا القاعدة الرابعة لوصل الحاسوب إلى كل شبكة في البيت، وهذا بالضبط الخطأ الذي نكسر به التجربة العملية أدناه.
كشف التسلل IDS باختصار
بحسب توثيق IDS/IPS فإن OPNsense يستخدم Suricata، ويعمل في وضع الكشف IDS الذي ينبه فقط، أو في وضع المنع IPS الذي يسقط الحزم، ويستخدم في وضع المنع Netmap لتقليل حمل المعالج، ويقول التوثيق إن واجهات IPS يجب أن تكون واجهات حقيقية تدعم Netmap، وإنك مع VLAN تفعله على الواجهة الأم، وإن عليك أن تعطل خصائص التسريع في العتاد Hardware Offloading في وضع المنع. والنصيحة العملية: ابدأ بوضع الكشف IDS على واجهة WAN، وراقب التنبيهات أسبوعين، ثم قرر، لأن قاعدة منع خاطئة في وضع IPS تقطع خدمة دون أن تعرف السبب.
إعداد ال Switch
أياً كان نوع ال Switch، فالإعداد يبدأ من جدول المنافذ الذي رسمناه أعلاه، وهو كما يلي:
| المنفذ | إلى | النوع | VLAN |
|---|---|---|---|
| ether1 | OPNsense igc1 | Trunk | 10,20,40,50,60,70,80 موسومة |
| sfp-sfpplus1 | Proxmox | Trunk | 10,20,30,80 موسومة |
| ether2 | نقطة Wi-Fi | مختلط Hybrid | 10 دون وسم، و40,50,70 موسومة |
| ether3 | Switch PoE للكاميرات | Access | 60 |
| ether4 وether5 | حواسيب المكتب | Access | 40 |
| ether6 | التلفاز | Access | 50 |
| ether7 | غير مستخدم | معطل | لا يوجد |
| ether8 | NAS | Trunk | 20,30 موسومة |
والإعداد التالي هو نفس الجدول على MikroTik CRS310-8G+2S+IN من الجزء الأول، بطريقة Bridge VLAN Filtering التي شرحناها في VLANs على السويتش المدمج في MikroTik، ومبني على Basic VLAN Switching وBridge VLAN Table في توثيق MikroTik، وال Switch هنا لا يوجه بين الشبكات، فله عنوان واحد في شبكة الإدارة فقط:
/interface bridge add name=bridge1 frame-types=admit-only-vlan-tagged vlan-filtering=no
/interface bridge port
add bridge=bridge1 interface=ether1 frame-types=admit-only-vlan-tagged comment="trunk to OPNsense"
add bridge=bridge1 interface=sfp-sfpplus1 frame-types=admit-only-vlan-tagged comment="trunk to Proxmox"
add bridge=bridge1 interface=ether8 frame-types=admit-only-vlan-tagged comment="trunk to NAS"
add bridge=bridge1 interface=ether2 pvid=10 comment="Wi-Fi AP: management untagged, SSIDs tagged"
add bridge=bridge1 interface=ether3 pvid=60 frame-types=admit-only-untagged-and-priority-tagged comment="cameras PoE switch"
add bridge=bridge1 interface=ether4 pvid=40 frame-types=admit-only-untagged-and-priority-tagged comment="office PC"
add bridge=bridge1 interface=ether5 pvid=40 frame-types=admit-only-untagged-and-priority-tagged comment="office PC 2"
add bridge=bridge1 interface=ether6 pvid=50 frame-types=admit-only-untagged-and-priority-tagged comment="TV"
/interface bridge vlan
add bridge=bridge1 vlan-ids=10 tagged=bridge1,ether1,sfp-sfpplus1 untagged=ether2
add bridge=bridge1 vlan-ids=20 tagged=ether1,sfp-sfpplus1,ether8
add bridge=bridge1 vlan-ids=30 tagged=sfp-sfpplus1,ether8
add bridge=bridge1 vlan-ids=40 tagged=ether1,ether2
add bridge=bridge1 vlan-ids=50 tagged=ether1,ether2
add bridge=bridge1 vlan-ids=60 tagged=ether1
add bridge=bridge1 vlan-ids=70 tagged=ether1,ether2
add bridge=bridge1 vlan-ids=80 tagged=ether1,sfp-sfpplus1
/interface ethernet set ether7 disabled=yes
/interface vlan add interface=bridge1 vlan-id=10 name=vlan10-mgmt
/ip address add address=10.10.10.2/24 interface=vlan10-mgmt
/ip route add gateway=10.10.10.1
# the last step, from the serial console or a port outside the bridge:
/interface bridge set bridge1 vlan-filtering=yesفي الإعداد أعلاه لاحظ التالي:
bridge1نفسه موسوم في VLAN 10 فقط، أي أن معالج ال Switch لا يرى إلا شبكة الإدارة، فلا يستطيع جهاز في شبكة الضيوف أن يصل إلى واجهة إدارته حتى لو عرف عنوانها.- منافذ Access أخذت
pvidوadmit-only-untagged-and-priority-tagged، فلا يستطيع جهاز في الغرفة أن يرسل إطاراً موسوماً بشبكة أخرى، وهذا يمنع القفز بين شبكات VLAN بإطارات موسومة. - منفذ نقطة Wi-Fi مختلط:
pvid=10لعنوان الإدارة دون وسم، والشبكات الأخرى موسومة في جدول VLAN. - VLAN 30 لا يوجد على
ether1، فلا تصل حركة التخزين إلى الجدار الناري. - تفعيل
vlan-filteringهو آخر خطوة، ومن الكونسول التسلسلي Serial Console أو منفذ خارج ال Bridge، لأن التفعيل يعيد ضبط ال Bridge فتنقطع الجلسة، وهذه نصيحة التوثيق نفسه، فراجع الإعداد على جهازك قبل التفعيل.
WireGuard: المدير من الخارج والنفق إلى ال VPS
ما هو ال VPN وأنواعه شرحناه في ما هو VPN، وتثبيت WireGuard بواجهة رسومية في شبكة خاصة مع WireGuard وwg-easy، وربط عدة مواقع حول مركز واحد في معمارية Hub and Spoke. وفي بيتنا نحتاج نفقين من نفس الجدار الناري، والصورة التالية تبينهما:

- Road Warrior: حاسوب المدير أو هاتفه من أي مكان، والإعداد في OPNsense من VPN ‣ WireGuard ‣ Instances ثم VPN ‣ WireGuard ‣ Peers كما في دليل الإعداد للأجهزة البعيدة، والدليل يوصي بتعيين واجهة للنفق من Interfaces ‣ Assignments حتى تكتب قواعده كأي منطقة. ونجعل النفق منقسماً Split Tunnel، أي أن
AllowedIPsفي جهاز المدير فيها شبكات البيت التي يحتاجها فقط، وليس0.0.0.0/0. - Site-to-Site إلى ال VPS: البيت هو الذي يبدأ الاتصال، لأنه قد يكون خلف CGNAT، و
PersistentKeepalive = 25يبقي الطريق مفتوحاً، وال VPS لا يرى من البيت إلا العنوان الذي فيAllowedIPs. والإعداد في OPNsense في دليل Site-to-Site، وتفاصيل الطرف الآخر وال Reverse Proxy عليه في الجزء الثالث.
اسم واحد وجوابان: DNS المنقسم
لنفرض أن لديك خدمة اسمها cloud.example.com، والعملاء يصلون إليها من الإنترنت عبر ال VPS، وأنت في البيت تستخدمها كل يوم. فإذا سأل حاسوبك DNS العام عن الاسم، فسوف يأخذ عنوان ال VPS، ويخرج طلبه إلى الإنترنت ثم يعود عبر النفق إلى سيرفر على بعد مترين منه، وهذا بطيء ويعتمد على الإنترنت دون سبب. والحل هو DNS المنقسم Split Horizon: نفس الاسم يعطي جواباً داخل البيت وجواباً آخر خارجه، والصورة التالية تبين ذلك:

وفي OPNsense تضيف Host Override في Unbound بالاسم والعنوان الداخلي، وكما سترى في التجربة، فهذا سجل واحد. ولاحظ أن الشهادة TLS يجب أن تكون صالحة للاسم في الطريقين، وهذا ما نرتبه في الجزء الثالث مع ال Reverse Proxy الداخلي، وسجلات DNS نفسها شرحناها في شرح DNS وسجلاته.
الإدارة عبر VPN فقط
القاعدة في هذا البيت بسيطة: لا توجد لوحة إدارة واحدة مكشوفة للإنترنت، لا OPNsense ولا Proxmox ولا ال NAS ولا ال Switch، والطريق الوحيد إليها هو WireGuard ثم شبكة الإدارة. وإذا كان معك في الفريق من يحتاج الوصول إلى سيرفر واحد فقط، فلا تعطه VPN إلى البيت كله، وإنما سيرفر وسيط Bastion كما شرحنا في Bastion Host وJump Server، أو أداة وصول تسجل الجلسات من أدوات الوصول الآمن إلى السيرفرات، مثل Apache Guacamole من المتصفح.
تجربة عملية: الشبكة كلها في Containers
في تجربة تقسيم الشبكة بنينا Switch يفهم VLAN بأدوات Linux داخل Container واحد، وهنا نبني شبكة البيت نفسها بطريقة أخرى: كل منطقة شبكة Docker مستقلة تمثل VLAN، وفي كل منطقة Container يمثل جهازاً، وفي الوسط Container اسمه lab-hlp-fw موصول بكل الشبكات يقوم بدور OPNsense بأدوات Linux نفسها: nftables للقواعد، وUnbound لل DNS، وWireGuard للمدير من الخارج. والصورة التالية تبين ما سنبنيه والنتائج التي سنصل إليها:

Docker Image فيها الأدوات
شبكات التجربة معزولة عن الإنترنت، فلا يمكن تثبيت الحزم داخل ال Containers بعد تشغيلها، لذلك نبني Docker Image صغيرة فيها كل الأدوات مرة واحدة، وكل الأوامر التالية من Terminal في مجلد فارغ على جهازك:
cat > Dockerfile <<'EOF'
FROM alpine:3.24
RUN apk add --no-cache iproute2 nftables wireguard-tools netcat-openbsd busybox-extras curl bind-tools unbound
EOF
docker build -q -t lab-hlp-tools:1 .
docker run --rm lab-hlp-tools:1 sh -c 'cat /etc/alpine-release; nft --version; wg --version'والمخرج سوف يكون كما يلي:
sha256:00e4f886180fbb4177a697efb4066f08b3b9e7d3a9bd7fc2d4c427c69ea4400b
3.24.2
nftables v1.1.6 (Commodore Bullmoose #7)
wireguard-tools v1.0.20260223 - https://git.zx2c4.com/wireguard-tools/سبع شبكات، كل منها VLAN
نبني شبكة Docker لكل منطقة بنفس المجال الذي في خطة العناوين، ونجعل بوابة Docker نفسها .254 حتى يبقى العنوان .1 للجدار الناري كما في الخطة، ونعطل NAT الخاص ب Docker حتى لا تخرج أي شبكة إلى الإنترنت من غير الجدار الناري. وشبكة wan تمثل الإنترنت:
for z in mgmt:10 srv:20 trusted:40 iot:50 guest:70 dmz:80 wan:200; do
docker network create --subnet 10.10.${z#*:}.0/24 --gateway 10.10.${z#*:}.254 \
-o com.docker.network.bridge.enable_ip_masquerade=false lab-hlp-${z%:*} > /dev/null
done
docker network ls --filter name=lab-hlp --format '{{.Name}}'والمخرج سوف يكون كما يلي:
lab-hlp-dmz
lab-hlp-guest
lab-hlp-iot
lab-hlp-mgmt
lab-hlp-srv
lab-hlp-trusted
lab-hlp-wanالجدار الناري: Container واحد في كل الشبكات
نشغل lab-hlp-fw على شبكة wan بالعنوان 10.10.200.1، ثم نوصله بالشبكات الست الأخرى بالعنوان .1 في كل منها، ثم نغير أسماء الواجهات من eth0 إلى eth6 إلى أسماء المناطق حتى تقرأ القواعد كما تقرأ المصفوفة:
docker run -d --name lab-hlp-fw --hostname fw --cap-add NET_ADMIN \
--sysctl net.ipv4.ip_forward=1 --network lab-hlp-wan --ip 10.10.200.1 \
lab-hlp-tools:1 sleep 14400 > /dev/null
for z in mgmt:10 srv:20 trusted:40 iot:50 guest:70 dmz:80; do
docker network connect --ip 10.10.${z#*:}.1 lab-hlp-${z%:*} lab-hlp-fw
done
docker exec lab-hlp-fw sh -c '
i=0
for name in wan mgmt srv trusted iot guest dmz; do
ip link set eth$i down; ip link set eth$i name $name; ip link set $name up
i=$((i + 1))
done
ip -br -4 addr'والمخرج سوف يكون كما يلي:
lo UNKNOWN 127.0.0.1/8
wan@if3741 UP 10.10.200.1/24
mgmt@if3742 UP 10.10.10.1/24
srv@if3743 UP 10.10.20.1/24
trusted@if3744 UP 10.10.40.1/24
iot@if3745 UP 10.10.50.1/24
guest@if3746 UP 10.10.70.1/24
dmz@if3747 UP 10.10.80.1/24 في الإعداد أعلاه لاحظ التالي:
--cap-add NET_ADMINيعطي ال Container صلاحية تغيير الواجهات والقواعد داخل شبكته هو فقط، ولا يمس شبكة جهازك.--sysctl net.ipv4.ip_forward=1يجعله يمرر الحزم بين واجهاته، أي يعمل Router.- ترتيب الواجهات هو ترتيب توصيل الشبكات، لذلك وصلنا
wanأولاً ثم الشبكات بالترتيب الذي في الحلقة.
جهاز في كل منطقة
الآن نشغل Container لكل جهاز، ونجعل بوابته الافتراضية الجدار الناري، ونشغل على بعضها خدمات صغيرة بأداة httpd من BusyBox تمثل المنافذ الحقيقية: 22 و8006 للوحة Proxmox، و443 و5432 لتطبيق وقاعدة بيانات، و8009 للتلفاز، و443 لخادم ال DMZ، و80 لموقع على الإنترنت:
for h in pve:mgmt:10.10.10.11 app:srv:10.10.20.21 laptop:trusted:10.10.40.50 \
tv:iot:10.10.50.60 phone:guest:10.10.70.70 web:dmz:10.10.80.10 road:wan:10.10.200.50; do
set -- $(echo $h | tr : ' ')
docker run -d --name lab-hlp-$1 --hostname $1 --cap-add NET_ADMIN \
--network lab-hlp-$2 --ip $3 lab-hlp-tools:1 sleep 14400 > /dev/null
[ $2 != wan ] && docker exec lab-hlp-$1 ip route replace default via ${3%.*}.1
done
svc() { docker exec lab-hlp-$1 sh -c "mkdir -p /srv/$2 && echo '$1:$2 ok' > /srv/$2/index.html && httpd -p $2 -h /srv/$2"; }
svc pve 22; svc pve 8006; svc app 443; svc app 5432; svc tv 8009; svc web 443; svc road 80
docker ps --filter name=lab-hlp --format '{{.Names}}' | sort | tr '\n' ' '; echoوالمخرج سوف يكون كما يلي:
lab-hlp-app lab-hlp-fw lab-hlp-laptop lab-hlp-phone lab-hlp-pve lab-hlp-road lab-hlp-tv lab-hlp-web قبل القواعد: كل شيء مفتوح
نكتب دالة صغيرة t تجرب الاتصال من جهاز إلى عنوان ومنفذ، أو ping إذا كتبنا icmp، ونحفظها في ملف t.sh لنستخدمها في كل خطوة:
t() {
if [ "$3" = icmp ]; then docker exec lab-hlp-$1 ping -c 1 -W 2 $2 > /dev/null 2>&1
else docker exec lab-hlp-$1 nc -z -w 2 $2 $3 > /dev/null 2>&1; fi
if [ $? = 0 ]; then r=open; else r=blocked; fi
printf '%-7s -> %-13s %-5s %s\n' $1 $2 $3 $r
}ثم نجرب قبل أن نكتب أي قاعدة:
. ./t.sh
t laptop 10.10.20.21 443
t laptop 10.10.10.11 8006
t tv 10.10.20.21 5432
t phone 10.10.40.50 icmp
t web 10.10.20.21 5432والمخرج سوف يكون كما يلي:
laptop -> 10.10.20.21 443 open
laptop -> 10.10.10.11 8006 open
tv -> 10.10.20.21 5432 open
phone -> 10.10.40.50 icmp open
web -> 10.10.20.21 5432 openهذه هي الشبكة المسطحة حتى مع وجود شبكات منفصلة: التلفاز يصل إلى قاعدة البيانات، وال DMZ يصل إلى قاعدة البيانات، وهاتف الضيف يصل إلى الحاسوب، والسبب أن ال Router يوجه بين الشبكات كل شيء ما دام لا توجد قواعد.
المصفوفة بقواعد nftables
الآن نكتب المصفوفة في ملف zones.nft، وكل سطر في السلسلة forward خلية خضراء من المصفوفة:
flush ruleset
define LAN = { "mgmt", "srv", "trusted", "iot", "guest", "dmz", "wg0" }
table inet fw {
chain input {
type filter hook input priority filter; policy drop;
ct state established,related accept
ct state invalid drop
iifname "lo" accept
iifname "wan" udp dport 51820 accept comment "WireGuard"
iifname $LAN meta l4proto { tcp, udp } th dport 53 accept comment "DNS"
iifname $LAN icmp type echo-request accept
iifname { "mgmt", "wg0" } tcp dport 22 accept comment "admin to the firewall"
counter comment "input dropped"
}
chain forward {
type filter hook forward priority filter; policy drop;
ct state established,related accept
ct state invalid drop
# to the internet
iifname { "mgmt", "srv", "trusted", "iot", "guest", "dmz" } oifname "wan" accept
# trusted devices
iifname "trusted" oifname "srv" tcp dport 443 accept
iifname "trusted" oifname "iot" accept
# administration only through the VPN
iifname "wg0" oifname "mgmt" tcp dport { 22, 8006 } accept
iifname "wg0" oifname "srv" tcp dport 443 accept
# published service: only the DNAT to the web server in the DMZ
iifname "wan" oifname "dmz" ct status dnat ip daddr 10.10.80.10 tcp dport 443 accept
counter comment "forward dropped"
}
}
table ip nat {
chain prerouting {
type nat hook prerouting priority dstnat;
iifname "wan" tcp dport 443 dnat to 10.10.80.10
}
chain postrouting {
type nat hook postrouting priority srcnat;
oifname "wan" masquerade
}
}ثم ننسخه إلى الجدار الناري ونطبقه:
docker cp zones.nft lab-hlp-fw:/etc/zones.nft
docker exec lab-hlp-fw nft -f /etc/zones.nft
docker exec lab-hlp-fw nft list tablesوالمخرج سوف يكون كما يلي:
table inet fw
table ip natفي الإعداد أعلاه لاحظ التالي:
policy dropفي السلسلتين هو القاعدة الافتراضية Default Deny التي في OPNsense، أي أن ما لم نكتبه ممنوع.ct state established,related acceptفي أول السلسلة هو ما يجعل الردود تعود، فنكتب القاعدة في اتجاه بداية الاتصال فقط.- القاعدة إلى الإنترنت تحدد
oifname "wan"، أي أنها تسمح بالخروج إلى الإنترنت فقط، وهذا ما تفعله القاعدتان الرابعة والخامسة في نمط OPNsense أعلاه. - الخدمة المنشورة تمر عبر DNAT في الجدول
nat، وقاعدةforwardتشترطct status dnat، أي أنها تقبل فقط الاتصال الذي ترجمه الجدار الناري، ولا تقبل حزمة أرسلت مباشرة إلى عنوان ال DMZ. - العداد
counterفي آخر كل سلسلة يعد ما سقط، وهذا يساعدك عندما لا يعمل شيء.
التحقق من المصفوفة
الآن نعيد الاختبارات، ونضيف إليها ما يجب أن يبقى مفتوحاً، ثم نطلب الخدمة المنشورة من الإنترنت عبر عنوان الجدار الناري العام، ونقرأ العدادات:
. ./t.sh
t laptop 10.10.20.21 443
t laptop 10.10.20.21 5432
t laptop 10.10.10.11 8006
t laptop 10.10.50.60 8009
t laptop 10.10.200.50 80
t tv 10.10.40.50 icmp
t tv 10.10.200.50 80
t phone 10.10.20.21 443
t phone 10.10.200.50 80
t web 10.10.20.21 5432
t road 10.10.200.1 22
docker exec lab-hlp-road curl -s http://10.10.200.1:443/
docker exec lab-hlp-fw nft list ruleset | grep 'counter packets'والمخرج سوف يكون كما يلي:
laptop -> 10.10.20.21 443 open
laptop -> 10.10.20.21 5432 blocked
laptop -> 10.10.10.11 8006 blocked
laptop -> 10.10.50.60 8009 open
laptop -> 10.10.200.50 80 open
tv -> 10.10.40.50 icmp blocked
tv -> 10.10.200.50 80 open
phone -> 10.10.20.21 443 blocked
phone -> 10.10.200.50 80 open
web -> 10.10.20.21 5432 blocked
road -> 10.10.200.1 22 blocked
web:443 ok
counter packets 2 bytes 120 comment "input dropped"
counter packets 9 bytes 564 comment "forward dropped"في المخرج أعلاه لاحظ التالي:
- الحاسوب الموثوق يصل إلى التطبيق على 443، ولا يصل إلى قاعدة البيانات على 5432، ولا إلى لوحة Proxmox، ويصل إلى التلفاز وإلى الإنترنت، تماماً كما في صف TRUSTED في المصفوفة.
- التلفاز لا يصل إلى الحاسوب، ولكنه يصل إلى الإنترنت، وهاتف الضيف لا يصل إلى أي شيء داخلي.
- خادم ال DMZ لا يصل إلى قاعدة البيانات، وهذا هو الاحتواء Containment الذي نريده لو اخترقت الخدمة المنشورة.
- من الإنترنت لا يصل أحد إلى منفذ 22 في الجدار الناري، ويصل الطلب على 443 إلى خادم ال DMZ عبر DNAT، والجواب
web:443 okجاء منه. - العدادات تبين ما سقط، والرقم أكبر من عدد الاختبارات الممنوعة لأن
ncيعيد إرسال طلب الاتصال قبل أن يستسلم.
نكسر القاعدة: إنترنت للضيوف بالطريقة الخاطئة
لنفرض أنك أضفت شبكة الضيوف بسرعة، وكتبت لها قاعدة تقول «اسمح لكل ما يخرج من الضيوف»، ونسيت أن تحدد أن الوجهة هي الإنترنت فقط، وهذا هو الخطأ الأكثر انتشاراً في القواعد:
. ./t.sh
docker exec lab-hlp-fw nft add rule inet fw forward iifname guest accept
t phone 10.10.200.50 80
t phone 10.10.20.21 5432
t phone 10.10.10.11 8006
docker exec lab-hlp-fw nft -a list chain inet fw forward | grep 'iifname "guest" accept'والمخرج سوف يكون كما يلي:
phone -> 10.10.200.50 80 open
phone -> 10.10.20.21 5432 open
phone -> 10.10.10.11 8006 open
iifname "guest" accept # handle 26الضيف ما زال يصل إلى الإنترنت كما أردت، ولكنه الآن يصل أيضاً إلى قاعدة البيانات وإلى لوحة Proxmox، والسبب أن القاعدة لم تحدد واجهة الخروج، فهي تطابق كل الوجهات، ولن تنتبه لذلك لأن ما أردته يعمل. لذلك نحذف القاعدة برقمها Handle ونتحقق:
. ./t.sh
docker exec lab-hlp-fw nft delete rule inet fw forward handle 26
t phone 10.10.20.21 5432والمخرج سوف يكون كما يلي:
phone -> 10.10.20.21 5432 blockedوهذا هو سبب أن تكون عندك قائمة اختبارات مثل هذه تعيد تشغيلها بعد كل تغيير في القواعد، فهي الطريقة الوحيدة لتعرف أن تغييراً لم يفتح باباً لم تقصده.
المدير من الخارج عبر WireGuard
الآن نعطي الجهاز road الذي على الإنترنت نفقاً إلى الجدار الناري، ونجعل النفق منقسماً لا يحمل إلا شبكتي الإدارة والسيرفرات، ولاحظ أن المفتاح الخاص لا يكتب في ملف الإعداد، وإنما يقرأ من ملفه في PostUp:
docker exec lab-hlp-fw sh -c 'umask 077; wg genkey | tee /etc/wireguard/fw.key | wg pubkey > /etc/wireguard/fw.pub'
docker exec lab-hlp-road sh -c 'umask 077; wg genkey | tee /etc/wireguard/road.key | wg pubkey > /etc/wireguard/road.pub'
FW_PUB=$(docker exec lab-hlp-fw cat /etc/wireguard/fw.pub)
ROAD_PUB=$(docker exec lab-hlp-road cat /etc/wireguard/road.pub)
docker exec -i lab-hlp-fw sh -c 'cat > /etc/wireguard/wg0.conf' <<EOF
[Interface]
Address = 10.10.90.1/24
ListenPort = 51820
PostUp = wg set %i private-key /etc/wireguard/fw.key
[Peer]
# the admin laptop outside the house
PublicKey = $ROAD_PUB
AllowedIPs = 10.10.90.2/32
EOF
docker exec -i lab-hlp-road sh -c 'cat > /etc/wireguard/wg0.conf' <<EOF
[Interface]
Address = 10.10.90.2/32
PostUp = wg set %i private-key /etc/wireguard/road.key
[Peer]
PublicKey = $FW_PUB
Endpoint = 10.10.200.1:51820
AllowedIPs = 10.10.90.0/24, 10.10.10.0/24, 10.10.20.0/24
PersistentKeepalive = 25
EOF
docker exec lab-hlp-fw wg-quick up wg0
docker exec lab-hlp-road wg-quick up wg0والمخرج سوف يكون كما يلي:
[#] ip link add dev wg0 type wireguard
[#] wg addconf wg0 /dev/fd/63
[#] ip -4 address add 10.10.90.1/24 dev wg0
[#] ip link set mtu 1420 up dev wg0
[#] wg set wg0 private-key /etc/wireguard/fw.key
[#] ip link add dev wg0 type wireguard
[#] wg addconf wg0 /dev/fd/63
[#] ip -4 address add 10.10.90.2/32 dev wg0
[#] ip link set mtu 1420 up dev wg0
[#] ip -4 route add 10.10.90.0/24 dev wg0
[#] ip -4 route add 10.10.20.0/24 dev wg0
[#] ip -4 route add 10.10.10.0/24 dev wg0
[#] wg set wg0 private-key /etc/wireguard/road.keyلاحظ أن wg-quick أضاف في جهاز المدير مساراً لكل شبكة في AllowedIPs، وهذا ما يجعل حركة البيت فقط تمر في النفق. ثم نختبر ما يسمح به صف VPN في المصفوفة:
. ./t.sh
t road 10.10.10.11 8006
t road 10.10.10.11 22
t road 10.10.20.21 443
t road 10.10.20.21 5432
docker exec lab-hlp-fw wg show wg0والمخرج سوف يكون كما يلي:
road -> 10.10.10.11 8006 open
road -> 10.10.10.11 22 open
road -> 10.10.20.21 443 open
road -> 10.10.20.21 5432 blocked
interface: wg0
public key: 0wjiJHgJfuUOaXBucTZUlmBvnCIQdY4p1ydcGaGESWo=
private key: (hidden)
listening port: 51820
peer: r1fcUjDscvVKQmk2uqbAQeE2Dnm60jSKDVERgyUjTF0=
endpoint: 10.10.200.50:37156
allowed ips: 10.10.90.2/32
latest handshake: 15 seconds ago
transfer: 1.86 KiB received, 892 B sentفي المخرج أعلاه لاحظ التالي:
- قبل النفق كان
roadلا يصل إلا إلى المنفذ المنشور، والآن يصل إلى لوحة Proxmox على 8006 وSSH على 22 والتطبيق على 443، لأن هذه هي خلايا صف VPN. - قاعدة البيانات على 5432 ما زالت ممنوعة حتى عبر النفق، لأن النفق منطقة لها قواعدها، وليس بطاقة دخول إلى كل شيء.
endpointفي الجدار الناري هو العنوان والمنفذ الذي جاء منه المدير، وهو يتغير كلما تنقل المدير بين الشبكات، وlatest handshakeيبين أن النفق حي.
DNS المنقسم مع Unbound
وأخيراً نشغل Unbound في الجدار الناري بأسماء داخلية في home.arpa، وهو النطاق المخصص للشبكات المنزلية في RFC 8375، وباسم عام يعطي داخل البيت العنوان الداخلي. نكتب الملف unbound.conf:
server:
interface: 0.0.0.0
access-control: 10.10.0.0/16 allow
username: ""
chroot: ""
do-ip6: no
# internal names that never leave the house
local-zone: "home.arpa." static
local-data: "pve.home.arpa. A 10.10.10.11"
local-data: "app.home.arpa. A 10.10.20.21"
# split horizon: inside the house this public name points to the internal server
local-zone: "cloud.example.com." static
local-data: "cloud.example.com. A 10.10.20.21"ثم نشغله ونسأله من عدة أماكن:
docker cp unbound.conf lab-hlp-fw:/etc/unbound/unbound.conf
docker exec lab-hlp-fw unbound-checkconf
docker exec lab-hlp-fw unbound
docker exec lab-hlp-laptop dig +short @10.10.40.1 cloud.example.com
docker exec lab-hlp-laptop dig +short @10.10.40.1 pve.home.arpa
docker exec lab-hlp-phone dig +short @10.10.70.1 cloud.example.com
docker exec lab-hlp-road dig +short @10.10.90.1 pve.home.arpa
docker exec lab-hlp-road dig +time=2 +tries=1 @10.10.200.1 pve.home.arpa | tail -1والمخرج سوف يكون كما يلي:
unbound-checkconf: no errors in /etc/unbound/unbound.conf
10.10.20.21
10.10.10.11
10.10.20.21
10.10.10.11
;; no servers could be reachedفي المخرج أعلاه لاحظ التالي:
- الحاسوب في البيت أخذ لاسم
cloud.example.comالعنوان الداخلي10.10.20.21، وهذا هو ال Host Override في OPNsense. - المدير عبر النفق يسأل الجدار الناري على عنوان النفق
10.10.90.1ويأخذ الأسماء الداخلية، لأن عنوانه فيaccess-control. - من الإنترنت مباشرة لا يجيب ال DNS الداخلي، لأن الجدار الناري لا يقبل المنفذ 53 على واجهة
wan. - هاتف الضيف أخذ العنوان الداخلي أيضاً، ولكنه لا يستطيع الاتصال به كما رأينا، وإذا كنت لا تريد أن يعرف الضيف أسماء شبكتك أصلاً، فاجعل شبكة الضيوف تستخدم DNS عاماً من إعداد DHCP.
التنظيف
نحذف ما أنشأناه فقط، بالاسم:
docker rm -f lab-hlp-fw lab-hlp-pve lab-hlp-app lab-hlp-laptop lab-hlp-tv lab-hlp-phone lab-hlp-web lab-hlp-road > /dev/null
for n in mgmt srv trusted iot guest dmz wan; do docker network rm lab-hlp-$n > /dev/null; done
docker ps -a --filter name=lab-hlp- --format '{{.Names}}'; docker network ls --filter name=lab-hlp- --format '{{.Name}}'ولا يظهر أي مخرج بعد الحذف، لأن الأمرين الأخيرين لا يجدان شيئاً باسم lab-hlp-. ويمكنك أن تحذف ال Docker Image أيضاً بالأمر docker rmi lab-hlp-tools:1 إذا لم تكن ستستخدمها في الجزء الثالث.
أخطاء شائعة
- قاعدة «إلى any» دون منع الشبكات الخاصة قبلها: كما رأيت في التجربة، فهي تفتح كل شيء وأنت تظن أنك فتحت الإنترنت فقط.
- شبكة الإدارة يصل إليها الجميع: فصل الشبكات لا يفيد إذا كانت لوحة Proxmox على بعد قاعدة واحدة من أي حاسوب في البيت.
- خلط الموسوم وغير الموسوم على واجهة الجدار الناري: توثيق OPNsense يحذر منه صراحة لأنه يسرب البث بين الشبكات.
- VLAN 1 مستخدم: كل منفذ جديد يدخله تلقائياً في كثير من الأجهزة، فلا تضع فيه شيئاً.
- نفق VPN إلى
0.0.0.0/0دون حاجة: كل حركة المدير تمر بالبيت، وسرعة الرفع في البيت تصبح سرعة إنترنته. - لا توجد اختبارات بعد التغيير: اكتب قائمة الاختبارات مرة واحدة، وأعد تشغيلها بعد كل تعديل.
قائمة التحقق
- خطة عناوين مكتوبة، ورقم VLAN هو الرقم الثالث في العنوان، ولا يوجد شيء في VLAN 1.
- مصفوفة مناطق مكتوبة قبل القواعد، وكل خلية خضراء قاعدة واحدة.
- الإدارة عبر WireGuard فقط، ولا توجد لوحة إدارة مكشوفة للإنترنت.
- شبكة التخزين بلا بوابة، والكاميرات بلا إنترنت، والضيوف إلى الإنترنت فقط.
- منافذ Access لا تقبل إطارات موسومة، والمنافذ غير المستخدمة معطلة.
- DNS المنقسم للأسماء التي تستخدمها من الداخل والخارج.
- قائمة اختبارات تعيد تشغيلها بعد كل تغيير.
تدريب عملي
- أضف إلى التجربة شبكة الكاميرات
10.10.60.0/24بجهاز اسمهcam، واكتب قاعدة تسمح لشبكة السيرفرات بالوصول إليه على 554 فقط، ثم تأكد أن الكاميرا لا تصل إلى الإنترنت. - عدل قاعدة الضيوف المكسورة بحيث تحدد
oifname "wan"، وأعد تشغيل الاختبارات الثلاثة، وتأكد أن الأول فقط مفتوح.
الخلاصة
وصلنا لنهاية الموضوع، وأهم ما فيه:
- خطة العناوين تكتب مرة واحدة بقاعدة يتذكرها الجميع: البيت في
10.10.0.0/16، وكل VLAN شبكة/24رقمها الثالث هو رقم ال VLAN. - المصفوفة قبل القواعد: من يكلم من، وعلى أي منفذ، وكل ما سواه ممنوع، والاتصال يبدأ من الأعلى ثقة إلى الأقل.
- OPNsense يطبق القواعد على الحركة الداخلة إلى الواجهة، وأول قاعدة مطابقة هي التي تنفذ، وما لا يطابق شيئاً يسقط.
- ال Switch يحمل الشبكات، وال Trunk إلى الجدار الناري لا يحمل شبكة التخزين، ومنافذ Access لا تقبل إطارات موسومة.
- WireGuard هو الطريق الوحيد للإدارة، والنفق إلى ال VPS يبدأ من البيت، وDNS المنقسم يجعل الاسم نفسه يعمل من الداخل والخارج.
- التجربة بينت أن قاعدة واحدة بلا واجهة خروج تفتح الشبكة كلها، لذلك تعاد الاختبارات بعد كل تغيير.
وفي الجزء الثالث نضع الخدمات على هذه الشبكة، وننشر خدمة للعملاء عبر VPS ونفق WireGuard، ونبني المراقبة والنسخ الاحتياطي.
سجل التحديثات
- أكتوبر 2026: كتابة المقال، ومراجعة توثيق OPNsense للواجهات وVLAN وDnsmasq وKea وUnbound والجدار الناري والأسماء المستعارة وIDS وWireGuard، وتوثيق MikroTik لل Bridge VLAN Filtering، وتنفيذ التجربة العملية على Docker Engine 29.8.0 مع alpine:3.24 وnftables 1.1.6 وwireguard-tools 1.0.20260223 وUnbound 1.25.2.