شاهد الفيديو (دقيقتان):
هذه تذكرة دعم يتلقاها كل مدير أنظمة (Sysadmin) عاجلًا أو آجلًا. يُطلق فريق التطوير نظامًا جديدًا، لنسمّه EduHub، وله خمس واجهات:
- واجهة برمجة تطبيقات (API) مبنية بـ Laravel
- لوحة إدارة (admin)
- بوابة للطلاب (student)
- بنك للامتحانات (exam bank)
- بوابة للكادر الأكاديمي (academic staff)
يحتاج كل من على الشبكة إلى الوصول إليها بالاسم، لا بعنوان مثل 10.10.20.15:3002. في هذا المقال سننجز المهمة كاملة: منطقة DNS جديدة، والسجلات، وإعدادات Nginx التي ترسل كل اسم إلى التطبيق الصحيح.
الخطوة 1: خصّص للنظام منطقة مستقلة
الاختصار المغري هو أن تضيف api وadmin وبقية الأسماء مباشرة إلى منطقة نطاق Active Directory لديك (لنفترض أنها college.org). لا تفعل ذلك. خصّص لكل نظام منطقة (Zone) مستقلة، والمنطقة هي الجزء من فضاء أسماء DNS الذي يديره الخادم ويحفظ سجلاته:
| النظام | المنطقة |
|---|---|
| EduHub | eduhub.internal |
| المكتبة | library.internal |
| الموارد البشرية | hr.internal |
لماذا منطقة مستقلة لكل نظام؟
- تبقى منطقة AD نظيفة. فهي تحتوي ما يحتاجه AD فقط (وحدات التحكم بالمجال DCs، وسجلات SRV، والخوادم الأعضاء)، لا عشرات من أسماء التطبيقات.
- يمكن نقل كل نظام أو إيقافه بشكل مستقل. إيقاف EduHub نهائيًا يتم بأمر
Remove-DnsServerZoneواحد، دون البحث عن سجلات متناثرة. - يمكنك تفويض إدارتها. يمكنك منح فريق EduHub صلاحيات على منطقتهم فقط، أو استضافتها لاحقًا على خادم DNS آخر باستخدام مُعيد توجيه شرطي (Conditional Forwarder).
لماذا .internal وليس .local؟
- اللاحقة
.localمحجوزة لنظام DNS متعدد البث (Multicast DNS أو mDNS، وفق RFC 6762). يرسل macOS وiOS وكثير من أنظمة Linux المكتبية استعلامات.localإلى mDNS بدلًا من خادم DNS لديك، فتفشل الأسماء بشكل عشوائي أو تُحلّ ببطء على هذه الأجهزة. - اللاحقة
.internalحجزتها هيئة ICANN عام 2024 للاستخدام الخاص. لن تُفوَّض أبدًا على الإنترنت العام، لذلك لا يمكن أن تتعارض مع نطاق حقيقي.
وهناك خيار جيد آخر، وهو استخدام نطاق فرعي من نطاق تملكه فعلًا، مثل eduhub.int.mouhimen.dev. وهذا الخيار يتيح لك أيضًا الحصول لاحقًا على شهادات TLS عامة.
الخطوة 2: أنشئ المنطقة
على وحدة التحكم بالمجال (Domain Controller)، أو على أي خادم DNS يستخدمه العملاء لديك:
عبر الواجهة الرسومية: DNS Manager ← انقر بزر الفأرة الأيمن على Forward Lookup Zones ← New Zone ← Primary zone ← فعّل الخيار Store the zone in Active Directory ← To all DNS servers in this domain ← اكتب اسم المنطقة eduhub.internal ← Finish.
عبر PowerShell، بسطر واحد:
Add-DnsServerPrimaryZone -Name "eduhub.internal" -ReplicationScope "Domain"
بما أن المنطقة مدمجة مع AD، فإنها تُنسخ إلى كل وحدة تحكم بالمجال تشغّل خدمة DNS، ويستطيع كل جهاز منضم إلى المجال حلّ أسمائها فورًا.
الخطوة 3: أضف سجل A للخادم الرئيسي
Add-DnsServerResourceRecordA -ZoneName "eduhub.internal" -Name "web01" -IPv4Address "10.10.20.15"
web01 هو خادم Ubuntu الذي يشغّل Nginx والتطبيقات الخمسة. وإذا أردت أيضًا أن يفتح الاسم eduhub.internal وحده الموقع، فأضف سجلًا بالمعامل -Name "@" وبعنوان IP نفسه.
الخطوة 4: أضف النطاقات الفرعية كسجلات CNAME
"api","admin","students","exams","staff" | ForEach-Object {
Add-DnsServerResourceRecordCName -ZoneName "eduhub.internal" -Name $_ -HostNameAlias "web01.eduhub.internal"
}
لماذا سجلات CNAME (أي أسماء مستعارة تشير إلى اسم آخر) وليس خمسة سجلات A؟ لأنه إذا تغيّر عنوان IP للخادم، فستعدّل سجلًا واحدًا فقط، وهو سجل A الخاص بـ web01، وستتبعه الأسماء الخمسة كلها.
تحقق من النتيجة:
Get-DnsServerResourceRecord -ZoneName "eduhub.internal" | Format-Table HostName, RecordType, RecordData
الخطوة 5: كتلة خادم Nginx واحدة لكل نطاق فرعي
يرسل DNS الآن الأسماء الخمسة جميعها إلى عنوان IP نفسه. ينظر Nginx إلى ترويسة Host في كل طلب، ويختار كتلة server التي يطابق فيها server_name ذلك الاسم. أنشئ ملفًا واحدًا لكل نطاق فرعي داخل /etc/nginx/sites-available/:
# /etc/nginx/sites-available/api.eduhub.internal
server {
listen 80;
server_name api.eduhub.internal;
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
الملفات الأربعة الأخرى هي الملف نفسه مع تغيير سطرين فقط:
| النطاق الفرعي | proxy_pass | التطبيق |
|---|---|---|
api.eduhub.internal |
http://127.0.0.1:8000 |
واجهة Laravel API |
admin.eduhub.internal |
http://127.0.0.1:3001 |
لوحة الإدارة |
students.eduhub.internal |
http://127.0.0.1:3000 |
بوابة الطلاب |
exams.eduhub.internal |
http://127.0.0.1:3002 |
بنك الامتحانات |
staff.eduhub.internal |
http://127.0.0.1:3003 |
بوابة الكادر الأكاديمي |
تطبيقات Next.js التي تستخدم مقابس الويب (WebSockets)، كما في إعادة التحميل التلقائي أثناء التطوير أو الميزات الحية، تحتاج أيضًا إلى proxy_http_version 1.1; وإلى الترويستين Upgrade وConnection. ستجدها في ملف الأوامر المرفق مع الفيديو.
فعّل المواقع:
sudo ln -s /etc/nginx/sites-available/*.eduhub.internal /etc/nginx/sites-enabled/
الخطوة 6: أضف كتلة لالتقاط كل ما عدا ذلك
بدون هذه الكتلة، فإن خطأً إملائيًا مثل exmas.eduhub.internal (أو وصول أحدهم مباشرة إلى عنوان IP) سينتهي في الكتلة التي يعدّها Nginx افتراضية، وغالبًا ما تكون واجهة API لديك. اجعل الكتلة الافتراضية صريحة، واجعلها تُسقط الاتصال:
server {
listen 80 default_server;
server_name _;
return 444;
}
الرمز 444 رمز خاص في Nginx: يغلق الاتصال دون إرسال أي رد.
اختبر الإعداد
على الخادم web01:
sudo nginx -t
sudo systemctl reload nginx
ومن أي جهاز منضم إلى المجال:
nslookup students.eduhub.internal
curl.exe -I http://students.eduhub.internal
يجب أن يعرض nslookup القيم Name: web01.eduhub.internal وAddress: 10.10.20.15 وAliases: students.eduhub.internal. ويجب أن يُرجع curl.exe الحالة HTTP/1.1 200 OK. استخدم curl.exe وليس curl، لأن curl في Windows PowerShell 5.1 اسم مستعار للأمر Invoke-WebRequest.
قائمة التحقق
- منطقة مستقلة لكل نظام (
eduhub.internal)، مع عدم المساس بمنطقة نطاق AD - استخدام
.internal(أو نطاق فرعي تملكه)، وعدم استخدام.localأبدًا - سجل A للخادم الرئيسي
- النطاقات الفرعية كسجلات CNAME تشير إلى الخادم الرئيسي
- كتلة خادم Nginx واحدة لكل نطاق فرعي، مفعّلة في
sites-enabled - كتلة
default_serverلالتقاط كل ما عدا ذلك تُرجع 444 - تشغيل
nginx -t، ثم إعادة التحميل، ثمnslookupوcurl.exeمن جهاز عميل
الخطوة التالية: HTTPS
لا تستطيع جهات إصدار الشهادات العامة مثل Let’s Encrypt إصدار شهادات لأسماء .internal. لتفعيل HTTPS، استخدم جهة إصدار شهادات داخلية خاصة بك (AD Certificate Services)، وانشر شهادتها الجذرية على أجهزة المجال عبر سياسة المجموعة (Group Policy)، أو أصدر شهادة شاملة (Wildcard) للنطاق *.eduhub.internal. وهذا موضوع يستحق فيديو مستقلًا.
شاهد الفيديو:
المصادر
- Microsoft Learn، الأمر Add-DnsServerPrimaryZone: https://learn.microsoft.com/en-us/powershell/module/dnsserver/add-dnsserverprimaryzone
- Microsoft Learn، الأمر Add-DnsServerResourceRecordCName: https://learn.microsoft.com/en-us/powershell/module/dnsserver/add-dnsserverresourcerecordcname
- Microsoft Learn، الأمر Add-DnsServerResourceRecordA: https://learn.microsoft.com/en-us/powershell/module/dnsserver/add-dnsserverresourcerecorda
- The Register، مقال "ICANN reserves .internal for private use at the DNS level" (أغسطس 2024): https://www.theregister.com/2024/08/08/dot_internal_ratified/
- ويكيبيديا، صفحة .internal: https://en.wikipedia.org/wiki/.internal
- RFC 6762، نظام DNS متعدد البث (فضاء الأسماء .local): https://www.rfc-editor.org/rfc/rfc6762
- توثيق Nginx، كيف يعالج nginx الطلب (server_name وdefault_server و444): https://nginx.org/en/docs/http/request_processing.html
- توثيق Nginx، الوحدة ngx_http_proxy_module (الأمر proxy_pass): https://nginx.org/en/docs/http/ngx_http_proxy_module.html
هذا المقال ترجمة عربية للمقال الأصلي باللغة الإنجليزية للكاتب عبد المهيمن شموط على mouhimen.dev.
