المحتوى عن 'أوبنتو'.



مزيد من الخيارات

  • ابحث بالكلمات المفتاحية

    أضف وسومًا وافصل بينها بفواصل ","
  • ابحث باسم الكاتب

نوع المُحتوى


التصنيفات

  • التخطيط وسير العمل
  • التمويل
  • فريق العمل
  • دراسة حالات
  • نصائح وإرشادات
  • التعامل مع العملاء
  • التعهيد الخارجي
  • التجارة الإلكترونية
  • الإدارة والقيادة
  • السلوك التنظيمي
  • مقالات ريادة أعمال عامة

التصنيفات

  • PHP
    • Laravel
    • ووردبريس
  • جافاسكريبت
    • Node.js
    • jQuery
    • AngularJS
    • Cordova
    • React
  • HTML
    • HTML5
  • CSS
  • SQL
  • لغة C#‎
  • لغة C++‎
  • بايثون
    • Flask
    • Django
  • لغة روبي
    • Sass
    • إطار عمل Bootstrap
    • إطار العمل Ruby on Rails
  • لغة Go
  • لغة جافا
  • لغة Kotlin
  • برمجة أندرويد
  • لغة Swift
  • لغة R
  • لغة TypeScript
  • ASP.NET
    • ASP.NET Core
  • سير العمل
    • Git
  • صناعة الألعاب
    • Unity3D
    • منصة Xamarin
  • سهولة الوصول
  • مقالات برمجة عامة

التصنيفات

  • تجربة المستخدم
  • الرسوميات
    • إنكسكيب
    • أدوبي إليستريتور
    • كوريل درو
  • التصميم الجرافيكي
    • أدوبي فوتوشوب
    • أدوبي إن ديزاين
    • جيمب
  • التصميم ثلاثي الأبعاد
    • 3Ds Max
    • Blender
  • نصائح وإرشادات
  • مقالات تصميم عامة

التصنيفات

  • خواديم
    • الويب HTTP
    • قواعد البيانات
    • البريد الإلكتروني
    • DNS
    • Samba
  • الحوسبة السّحابية
    • Docker
  • إدارة الإعدادات والنّشر
    • Chef
    • Puppet
    • Ansible
  • لينكس
  • FreeBSD
  • حماية
    • الجدران النارية
    • VPN
    • SSH
  • مقالات DevOps عامة

التصنيفات

  • التسويق بالأداء
    • أدوات تحليل الزوار
  • تهيئة محركات البحث SEO
  • الشبكات الاجتماعية
  • التسويق بالبريد الالكتروني
  • التسويق الضمني
  • التسويق بالرسائل النصية القصيرة
  • استسراع النمو
  • المبيعات
  • تجارب ونصائح

التصنيفات

  • إدارة مالية
  • الإنتاجية
  • تجارب
  • مشاريع جانبية
  • التعامل مع العملاء
  • الحفاظ على الصحة
  • التسويق الذاتي
  • مقالات عمل حر عامة

التصنيفات

  • الإنتاجية وسير العمل
    • مايكروسوفت أوفيس
    • ليبر أوفيس
    • جوجل درايف
    • شيربوينت
    • Evernote
    • Trello
  • تطبيقات الويب
    • ووردبريس
    • ماجنتو
  • أندرويد
  • iOS
  • macOS
  • ويندوز

التصنيفات

  • شهادات سيسكو
    • CCNA
  • شهادات مايكروسوفت
  • شهادات Amazon Web Services
  • شهادات ريدهات
    • RHCSA
  • شهادات CompTIA
  • مقالات عامة

أسئلة وأجوبة

  • الأقسام
    • أسئلة ريادة الأعمال
    • أسئلة العمل الحر
    • أسئلة التسويق والمبيعات
    • أسئلة البرمجة
    • أسئلة التصميم
    • أسئلة DevOps
    • أسئلة البرامج والتطبيقات
    • أسئلة الشهادات المتخصصة

التصنيفات

  • ريادة الأعمال
  • العمل الحر
  • التسويق والمبيعات
  • البرمجة
  • التصميم
  • DevOps

تمّ العثور على 117 نتائج

  1. مع انتقال أدوات المطورين إلى السحاب (cloud)، يزداد عدد المتبنين لمنصات بيئة تطوير متكاملة IDE ‏(Integrated Development Environment بيئة التطوير المتكاملة) السحابيّة، فهذه المنصات يمكن الوصول إليها من أي نوع من الأجهزة الحديثة عن طريق المتصفحات، وهي توفّر مميزات مهمة عند التعاون في الوقت الحقيقي، فيوفر العمل في منصة IDE سحابيّة بيئة موحدّة للتطوير والتجربة لك ولفريقك مع تقليل مشاكل عدم توافق المنصات، فيمكنك الوصول إليها من أي نوع من الأجهزة الحديثة عن طريق المتصفحات. فـ Eclipse Theia هي منصة IDE سحابيّة قابلة للتوسع تعمل على خادم عن بعد ويمكن الوصول إليها من متصفح الويب، وشكلها يشبه Microsoft Visual Studio Code وتدعم العديد من لغات البرمجة ولديها تصميم مرن وطرفيّة (Terminal)، وما يفرّق بين Eclipse Theia من بقيّة برامج IDE السحابيّة هي قابليّة تخصيصها وزيادة مميزاتها باستخدام الملحقات المخصّصة، والتي تسمح لك بتعديل IDE السحابي حسب رغباتك. سننشر في هذا الدرس Eclipse Theia إلى خادم أوبنتو 18.04 باستخدام Docker Compose والتي هي أداة لمزامنة الحاوية، والتي ستكشفها في اسم النطاق الخاص بك باستخدام nginx-proxy والذي هو نظام تلقائي لـ Docker يبسط عملية إعداد Nginx ليعمل كوكيل عكسي (reverse proxy) للحاوية، وستأمنها باستخدام شهادة Let’s Encrypt TLS عن طريق الملحق المخصص لها. وفي النهاية ستحصل على Eclipse Theia يعمل على خادم أوبنتو 18.04 متوفّر عن طريق HTTPS يمكن للمستخدم تسجيل دخوله ليبدأ العمل عليه. المتطلبات الأساسية خادم أوبنتو 18.04 مع صلاحيات الجذر بالإضافة إلى حساب آخر عادي ليس جذر، يمكنك اعداد ذلك عن طريق اتباع هذا الدرس بالنسبة لهذا المقال، المستخدم العادي (ليس جذر) هو sammy. تثبيت Docker على خادمك، يمكنك اتباع الخطوة الأولى والثانية من هذا الدرس وللتعرّف على Docker، يمكنك الإطلاع على هذا الدرس. تثبيت Docker Compose على خادمك، يمكنك اتباع الخطوة الأول من درس تثبيت Docker Compose. اسم نطاق مسجّل بالكامل، سنستخدم في هذا درس theia.your_domain والذي يمكنك استبداله بأي اسم ستشتريه من أي موقع يوفر هذه الخدمة. سِجل DNS مع إشارة theia.your_domain إلى عنوان IP الخادم العام، يمكنك الإطلاع على المقدمة إلى DNS الخاص بـ DigitalOcean للمزيد من التفاصيل. الخطوة الأولى - نشر nginx-proxy مع Let’s Encrypt في هذا القسم، ستنشر nginx-proxy مع إضافة Let's Encrypt باستخدام Docker Compose، وسيفعّل هذا عمليّة تفعيل وتجديد شهادة TLS بشكل تلقائي، لذلك عندما تنشر Eclipse Theia، ستتمكن من الوصول إلى نطاقك عن طريق HTTPS. في هذا الدرس، سنسجل جميع الملفات في ‎~/‎eclipse-theia، أنشئ هذا المجلّد عن طريق تشغيل هذا الأمر: mkdir ~/eclipse-theia انتقل إلى هذا المجلّد عن طريق: cd ~/eclipse-theia يجب عليك حفظ إعدادات Docker Compose لـ nginx-proxy في ملف يسمى nginx-proxy-compose.yaml، أنشئه باستخدام محرّر النصوص الخاص بك: nano nginx-proxy-compose.yaml وأضف الأسطر التاليّة إليه (ملف nginx-proxy-compose.yaml): version: '2' services: nginx-proxy: restart: always image: jwilder/nginx-proxy ports: - "80:80" - "443:443" volumes: - "/etc/nginx/htpasswd:/etc/nginx/htpasswd" - "/etc/nginx/vhost.d" - "/usr/share/nginx/html" - "/var/run/docker.sock:/tmp/docker.sock:ro" - "/etc/nginx/certs" letsencrypt-nginx-proxy-companion: restart: always image: jrcs/letsencrypt-nginx-proxy-companion volumes: - "/var/run/docker.sock:/var/run/docker.sock:ro" volumes_from: - "nginx-proxy" ستعرّف هنا خدمتين سيشغلها Docker Compose وهما nginx-proxy و Let’s Encrypt، بالنسبة إلى الوكيل (proxy)، ستحدّد jwilder/nginx-proxy كصورة وستعرّف منافذ HTTP وHTTPS بالإضافة إلى الأماكن (volumes) التي يمكن الوصول إليها وقت التشغيل. الأماكن (Volumes) هي مجلدات في خادمك التي يمكن للخدمات المعرّفة الوصول إليها، والتي ستستخدمها لاحقًا في إعداد مصادقة المستخدم (user authentication)، ولفعل ذلك، ستستخدم المكان الأول من القائمة والذي سيصل مجلد ‎/etc/nginx/htpasswd المحلي إلى نفس المكان في الحاوية، وفي هذا المجلد، سيتوقع nginx-proxy إيجاد نفس الملف مسمى بنفس النطاق المستهدف، ويحتوي على بيانات تسجيل الدخول لمصادقة المستخدم في شكل htpasswd (username:hashed_password). بالنسبة للإضافة، ستضع اسم الصورة وستسمح بالوصول إلى المقبس socket الخاصة بالـ Docker عن طريق تعريف مكان (Volume)، ومن ثم ستحدد أن هذه الإضافة يجب عليها وراثة الوصول إلى الأماكن المعرّفة لـ nginx-proxy، كلا الخدمتين تملكان خيار restart يحتوي على قيمة always، والتي تأمر Docker بإعادة تشغيل الحاويات في حالة التعطل أو إعادة تشغيل النظام. أغلق الملف بعد حفظه وانشر الإعدادات عن طريق تشغيل الأمر التالي: docker-compose -f nginx-proxy-compose.yaml up -d ستمرر في الأمر السابق، اسم ملف nginx-proxy-compose.yaml إلى المعامل ‎-f لأمر docker-compose والذي يحدد الملف الذي سيعمل، وبعد ذلك، ستمرّر فعل up الذي سيشغّل الحاوية. بالنسبة إلى الراية ‎-d فهي تفعّل الوضع المنفصل (detached mode)، والذي يعني أن Docker Compose سيشغّل الحاويات في الخلفية. المخرجات النهائيّة ستشبه لهذه: Creating network "eclipse-theia_default" with the default driver Pulling nginx-proxy (jwilder/nginx-proxy:)... latest: Pulling from jwilder/nginx-proxy 8d691f585fa8: Pull complete 5b07f4e08ad0: Pull complete ... Digest: sha256:dfc0666b9747a6fc851f5fb9b03e65e957b34c95d9635b4b5d1d6b01104bde28 Status: Downloaded newer image for jwilder/nginx-proxy:latest Pulling letsencrypt-nginx-proxy-companion (jrcs/letsencrypt-nginx-proxy-companion:)... latest: Pulling from jrcs/letsencrypt-nginx-proxy-companion 89d9c30c1d48: Pull complete 668840c175f8: Pull complete ... Digest: sha256:a8d369d84079a923fdec8ce2f85827917a15022b0dae9be73e6a0db03be95b5a Status: Downloaded newer image for jrcs/letsencrypt-nginx-proxy-companion:latest Creating eclipse-theia_nginx-proxy_1 ... done Creating eclipse-theia_letsencrypt-nginx-proxy-companion_1 ... done والآن بعد أن نشرنا nginx-proxy ومرافقه Let's Encrypt باستخدام Docker Compose، سننتقل إلى إعداد Eclipse Theia على نطاقك وتأمينه. الخطوة الثانية - نشر Eclipse Thia في Docker سننشئ في هذا القسم ملف يحتوي على بيانات تسجيل الدخول التي سيستخدمها المستخدم، ومن ثم سننشر Eclipse Theia إلى خادمك باستخدام Docker Compose وسنعرضه على نطاقك الآمن باستخدام nginx-proxy. كما شرحنا في الخطوة السابقة، يتوقع nginx-proxy الحصول على بيانات تسجيل الدخول في ملف على النطاق المكشوف على شكل htpasswd ومحفوظة في مجلد ‎/etc/nginx/htpasswd في الحاوية، لا يحتاج المجلد المحلي الذي يشير إلى المجلد الافتراضي أن يكونا نفس الملف، كما حدّدنا في إعدادات nginx-proxy. لإنشاء مجموعات بيانات تسجيل الدخول، ستحتاج أولًا إلى تثبيت htpasswd عن طريق تشغيل الأمر التالي: sudo apt install apache2-utils تحتوي حزمة apache2-utils على أداة htpasswd. أنشئ مجلد ‎/etc/nginx/htpasswd عن طريق الامر التالي: sudo mkdir -p /etc/nginx/htpasswd وأنشئ ملف الذي سيحتوي على بيانات تسجيل الدخول لنطاقك: sudo touch /etc/nginx/htpasswd/theia.your_domain تذكر استبدال theia.your_domain بنطاق Eclipse Theia. لإضافة زوج اسم تسجيل الدخول وكلمة المرور، نفّذ الأمر التالي: sudo htpasswd /etc/nginx/htpasswd/theia.your_domain username استبدل username باسم المستخدم الذي ترغب في إضافته، وسيسألك مرتين عن كلمة المرور، وبعد ذلك سيضيف htpasswd اسم المستخدم وكلمة المرور المشفرة (hashed password) إلى نهاية الملف، يمكنك إعادة هذا الأمر بعدد مرات تسجيلات الدخول التي ترغب في إضافتها. والآن ستنشئ ملف إعدادات لنشر Eclipse Theia، وستخزنها في ملف يسمى eclipse-theia-compose.yaml، أنشئه باستخدام محرر النصوص الخاص بك: nano eclipse-theia-compose.yaml أضف الأسطر التاليّة في ملف ‎~/eclipse-theia/eclipse-theia-compose.yaml: version: '2.2' services: eclipse-theia: restart: always image: theiaide/theia:next init: true environment: - VIRTUAL_HOST=theia.your_domain - LETSENCRYPT_HOST=theia.your_domain عرّفت في هذه الإعدادات خدمة واحدة تسمى eclipse-theia مع خيار restart قيمته always وصورة حاوية theiaide/theia:next ولقد حدّدت init كـ true لإعلام Docker باستخدام init كمدير العمليّة الرئيسي عند تشغيل Eclipse Theia داخل الحاويّة. وبعد ذلك، ستحدّد متغيري بيئة في قسم environment وهما VIRTUAL_HOST و LETSENCRYPT_HOST فالأول سيمرر إلى nginx-proxy وسيخبره على أي نطاق يجب كشف الحاوية، وأما الآخر فسيستخدم من قبل Let's Encrypt لتحديد أي نطاق لطلب شهادات TLS، وفي العادة سيكونان نفسهما إلا لو وضع wildcard كقيمة لـ VIRTUAL_HOST. تذكر استبدال theia.your_domain مع اسم النطاق المطلوب، ومن ثم أغلق الملف بعد حفظه. والآن، انشر Eclipse Theia عن طريق كتابة الأمر: docker-compose -f eclipse-theia-compose.yaml up -d ستكون المخرجات كالتالي: ... Pulling eclipse-theia (theiaide/theia:next)... next: Pulling from theiaide/theia 63bc94deeb28: Pull complete 100db3e2539d: Pull complete ... Digest: sha256:c36dff04e250f1ac52d13f6d6e15ab3e9b8cad9ad68aba0208312e0788ecb109 Status: Downloaded newer image for theiaide/theia:next Creating eclipse-theia_eclipse-theia_1 ... done بعد ذلك في متصفحك، انتقل إلى النطاق الذي تستخدمه لـ Eclipse Theia، سيظهر لك المتصفح واجهة تسجيل الدخول، وبعد توفير البيانات الصحيحة، ستدخل إلى Eclipse Theia وسترى الواجهة الرسوميّة. يدل القفل في شريط العنوان إلى أن الإتصال مؤمن، وإذا لم ترى هذا بشكل فوري، انتظر بضعة دقائق لإصدار شهادات TLS وأعد تحميل الصفحة. والآن، يمكنك الوصول إلى IDE السحابي، ويمكنك البدء باستخدام المحرّر في الخطوة القادمة. الخطوة الثالثة - استخدام واجهة Eclipse Theia ستكتشف في هذا القسم بعض من مميزات واجهة Ecipse Theia. على الجانب الأيسر من IDE، ستجد صف عمودي من أربعة أيقونات لفتح المميزات الشائعة في اللوحة الجانبيّة. يمكنك تخصيص هذا الشريط أي يمكنك تحريك هذه المناظر (Views) لتغيير ترتيبهم أو حذفهم من الشريط. المنظر الأول بشكل افتراضي يفتح لوحة الاكتشاف (Explorer panel) والذي يوفر تصفح شجري لهيكل المشروع، يمكنك إدارة مجلداتك وملفاتك هنا من حيث إنشاء وحذف ونقل وإعادة تسميتهم حسب المطلوب. بعد إنشاء ملف جديد عن طريق قائمة File، سيُفتح ملف فارغ في علامة تبويب جديدة، وبمجرد حفظه، يمكنك رؤية اسم الملف في لوحة الاكتشاف الجانبيّة، ولإنشاء المجلدات، اضغط بالزر الأيمن على شريط Explorer وانقر على New Folder، ويمكنك توسعة المجلد عن طريق الضغط على اسمه وسحب وافلات الملفات والمجلدات إلى الأجزاء العليا من التسلسل الهرمي لتحريكهم إلى المكان الجديد. يوفر المنظر (view) التالي الوصول إلى وظائف البحث والاستبدال، ويوفّر المنظر الثالث لأنظمة التحكم بالمصدر التي قد تستخدمها، مثل Git. أما بالنسبة إلى المنظر الأخير فهو لخيار التنقيح، والذي يوفر الإجراءات الشائعة في اللوحة، ويمكنك حفظ إعدادات التنقيح في ملف launch.json. الجزء الأوسط من الواجهة هو محرّرك، والذي يمكنك فصله بعلامات التبويب لتعديل الشيفرة البرمجيّة، يمكنك تغيير منظر التعديل إلى وضع الشبكة (grid) أو إلى ملفات كل واحدة بجانب الأخرى، ومثل جميع IDE الحديثة، يدعم Eclipse Theia تسليط الضوء على الصياغة لشيفرتك البرمجيّة. يمكنك الوصول إلى الطرفيّة عن طريق ‎CTRL+SHIFT+`‎ أو عن طريق النقر على Terminal في القائمة العلويّة، وتحديد New Terminal، ستفتح الطرفية في لوحة السفليّة وستعمل في المجلد المشروع، والذي سيحتوي على جميع الملفات والمجلدات الموجودة في لوحة Explorer الجانبيّة. والآن لقد تعرّفت على واجهة Eclipse Theia مع أهم المميزات شائعة الاستخدام. الختام الآن، لديك Eclipse Theia مثبت على خادم أوبنتو 18.04 باستخدام Docker Compose وnginx-proxy، ولقد أمنته باستخدام شهادة TLS من Let’s Encrypt مجانيّة وأعددت المثيل لطلب بيانات تسجيل الدخول من المستخدم، يمكنك العمل على شيفرتك المصدريّة والوثائق بشكل فردي أو بالتعاون مع فريقك، ويمكنك تجربة بناء نسختك الخاصة من Eclipse Theia إذا احتجت إلى وظائف إضافيّة، للمزيد من المعلومات حول كيفيّة فعل ذلك، زر توثيق Theia. ترجمة -وبتصرف- للمقال How To Set Up the Eclipse Theia Cloud IDE Platform on Ubuntu 18.04 لصاحبه Savic
  2. Jenkins هو خادم أتمتة مفتوح المصدر يعمل على أتمتة المهام الفنية المتكررة التي ينطوي عليها التكامل المستمر وتقديم البرامج، Jenkins مكتوبة بلغة Java ويمكن تثبيتها من حزم أوبنتو أو عن طريق تنزيل وتشغيل ملف WAR (وهو عبارة عن مجموعة من الملفات التي تشكل تطبيق ويب كاملًا لتشغيله على خادم). في هذا المقال ستقوم بتثبيت Jenkins بإضافة مستودع حزمة ديبيان، واستخدام هذا المستودع لتثبيت الحزمة من خلال الأداة apt-get. المتطلبات الأساسية من أجل متابعة هذا المقال، ستحتاج إلى: خادم اوبنتو 18.04 فيه مستخدم يحمل صلاحيات sudo وغير جذري (non-root) ومثبت عليه جدار حماية وذلك باتباع دليل الاعداد الاولي لخادم اوبنتو18.04 نوصي بالبدء باستخدام 1 غيغابايت على الأقل من الذاكرة RAM، راجع هذه التوصيات للحصول على متطلبات التثبيت اللازمة. بتثبيت Java 8، باتباع هذا المقال. الخطوة الأولى: تثبيت Jenkins الإصدار المتوفر في متجر أوبنتو الحزم على الأغلب هو اصدار أقدم من الإصدار المتوفر في المشروع نفسه، للحصول على اخر التحديثات والميزات سوف نستخدم الحزم المصانة من قبل مشروع Jenkins نفسه. علينا أولًا إضافة مفتاح المستودع repository للنظام من خلال الأمر التالي: $ wget -q -O - https://pkg.jenkins.io/debian/jenkins.io.key | sudo apt-key add - بعد إضافة المفتاح بنجاح سيظهر النظام لك كلمة OK؛ سنضيف بعد ذلك عنوان مستودع لحزمة ديبيان إلى الملف sources.list الموجود في الخادم: $ sudo sh -c 'echo deb http://pkg.jenkins.io/debian-stable binary/ > /etc/apt/sources.list.d/jenkins.list' بعد تنفيذ الأمرين السابقين بنجاح سوف نقوم بتحديث الحزم في المستودع repository باستخدام الأمر التالي: $ sudo apt update اخيرا سنقوم بتثبيت Jenkins وكل ما تعتمد عليه: $ sudo apt install jenkins الآن Jenkins واعتماديته كلها جاهزة لذا سنقوم بتشغيل الخادم. الخطوة الثانية: بدء تشغيل خادم Jenkins سنستخدم systemctl لتشغيل خادم Jenkins: $ sudo systemctl start jenkins و لعدم إظهار الأمر لأي مخرجات سنستخدم الخيار Status لعرض حالة الخدمة للتأكد أنها قد بدأت دون مشاكل: $ sudo systemctl status jenkins إذا كان كل شيئ على ما يرام ستبدأ المخرجات بالظهور لإظهار أن الخدمة تعمل حاليا و ستبدأ تلقائيا عند الاقلاع: ● jenkins.service - LSB: Start Jenkins at boot time Loaded: loaded (/etc/init.d/jenkins; generated) Active: active (exited) since Mon 2018-07-09 17:22:08 UTC; 6min ago Docs: man:systemd-sysv-generator(8) Tasks: 0 (limit: 1153) CGroup: /system.slice/jenkins.service الآن الخدمة شغالة سنبدأ بإعداد قواعد جدار الحماية حتى نصل لها من خلال متصفح الويب لإكمال ضبطه. الخطوة الثالثة: اضبط إعدادات جدار الحماية بشكل تلقائي Jenkins يعمل على منفذ رقم 8080 لذلك سنعمل على فتح هذا المنفذ داخل جدار الحماية ufw: $ sudo ufw allow 8080 من خلال التحقق من حالة الجدار الناري يمكن رؤية القاعدة الجديدة ب ufw: $ sudo ufw status يمكنك الآن رؤية التراسل الشبكي عبر المنفذ 8080 المتاح من كل الشبكات: Status: active To Action From -- ------ ---- OpenSSH ALLOW Anywhere 8080 ALLOW Anywhere OpenSSH (v6) ALLOW Anywhere (v6) 8080 (v6) ALLOW Anywhere (v6) ملاحظة: اذا كان جدار الحماية غير فعال يجب تنفيذ الأوامر التالية للسماح ب OpenSSH وتفعيل جدار الحماية: $ sudo ufw allow OpenSSH $ sudo ufw enable بعد تثبيت Jenkin و ضبط إعدادات جدار الحماية الخاص بنا سنكمل الإعدادات المبدئية له. الخطوة الرابعة: ضبط خدمة Jenkins من أجل ضبط خدمة Jenkins علينا الدخول لصفحة الإعدادات من خلال المنفذ الافتراضي 8080 باستخدام اسم النطاق للخادم أو عنوان http://your_server_ip_or_domain:8080. ستظهر لك شاشة مقفلة من Jenkins تعرض موقع الذي تخزن فيه كلمة المرور المبدئية وتطلب إدخالها. من خلال واجهة سطر الأوامر سوف نستخدم الأمر Cat من أجل اظهار كلمة المرور: $ sudo cat /var/lib/jenkins/secrets/initialAdminPassword تتألف كلمة المرور من 32 حرف سوف نقوم بنسخها من واجهة سطر الأوامر و لصقها داخل الحقل Administrator password ثم الضغط على زر الاستمرار Continue. بعد ذلك ستظهر لك صفحة تعرض لك خيارين تثبيت الإضافات المقترحة أو تحديد إضافات معينة. اختر الخيار Install suggested plugins الذي سيبدأ عملية التنزيل مباشرة. عند الانتهاء من التثبيت، سيُطلب منك أولا إعداد المستخدم الإداري (administrative) ومن الممكن تخطي هذه الخطوة والمتابعة كمسؤول باستخدام كلمة المرور الأولية التي استخدمناها في الأعلى لكننا سنقوم بإنشاء مستخدم جديد. ملاحظة: خادم Jenkins الافتراضي غير مشفر، وبالتالي فإن البيانات المقدمة مع هذا النموذج ليست محمية. عندما تكون جاهزًا لاستخدام هذا التثبيت، اتبع هذا المقال التالي؛ سيؤدي ذلك إلى حماية بيانات المستخدم والمعلومات التي يتم إرسالها عبر واجهة الويب. ادخل اسم و كلمة المرور للمستخدم الخاص بك: ستظهر لك صفحة الضبط Instance Configuration وستطلب منك تأكيد عنوان URL المفضل لنسخة Jenkins. قم بتأكيد اسم النطاق لخادمك أو عنوان IP: بعد تأكيد المعلومات المناسبة، انقر فوق حفظ وإنهاء. سترى صفحة Jenkins is Ready!‎: انقر فوق Start using Jenkins للانتقال للوحة التحكم الرئيسية لـخادم Jenkins: تهانينا ، لقد تم تثبيت Jenkins بنجاح. الخلاصة في هذا المقال قد شرحنا آلية تثبيت Jenkins باستخدام الحزم المقدمة من المشروع، وبدء تشغيل الخادم، وفتح جدار الحماية، وإنشاء مستخدم مسؤول. في هذه المرحلة، يمكنك البدء في استكشاف Jenkins. عند الانتهاء من الاستكشاف، إذا قررت الاستمرار في استخدام Jenkins فاتبع الدليل التالي لحماية كلمات المرور الخاصة بك وأيضًا معلومات النظام أو المنتج الحساسة التي ستكون إرسالها بين جهازك والخادم بنص عادي. ترجمة –وبتصرف– للمقال How To Install Jenkins on Ubuntu 18.04 لصاحبته Melissa Anderson and Kathleen Juell
  3. Postfix هو وكيل نقل البريد مفتوح المصدر (MTA) الذي يمكن استخدامه لتوجيه وتسليم البريد الإلكتروني على نظام Linux، وتشير التقديرات إلى أن حوالي 25 ٪ من خوادم البريد العام على الإنترنت تعمل على تشغيل Postfix. في هذا المقال، سنعلمك كيفية تثبيت Postfix وتشغيله بسرعة على خادم يعمل بنظام تشغيل أوبنتو 18.04. المتطلبات الأساسية من أجل تطبيق هذا المقال، يجب أن يكون لديك حق الوصول كمستخدم غير جذري (non-root) يملك صلاحيات sudo، للتعرف على كيفية إعداد ذلك يمكنك اتباع دليل الإعداد الأولي لخادم اوبنتو18.04 لإنشاء المستخدم. لإعداد Postfix بشكل صحيح، ستحتاج إلى اسم نطاق (Domain Name) مؤهل بالكامل يتم توجيهه إلى خادم اوبنتو 18.04، يمكنك العثور على مساعدة في إعداد اسم النطاق (Domain Name) الخاص بك باستخدام DigitalOcean باتباع هذا المقال، إذا كنت تخطط لقبول البريد، فستحتاج إلى التأكد من أن لديك سجل MX يشير إلى خادم البريد الخاص بك. لأغراض هذا المقال التعليمي، سنفترض أنك تقوم بإعداد الحاسوب المضيف له FQDN الخاص بـ mail.example.com. الخطوة الأولى: تثبيت Postfix يوجد Postfix في متجر أوبنتو الافتراضي، لذلك تثبيته بسيط. ابدأ أولًا تحديث ذاكرة التخزين المؤقت لحزمة apt الخاصة بك ثم قم بتثبيت البرنامج، سنقوم بتمرير DEBIAN_PRIORITY=low كمتغير في أمر التثبيت الخاص بنا للرد على بعض المتطلبات الإضافية: $ sudo apt update $ sudo DEBIAN_PRIORITY=low apt install postfix استخدم المعلومات التالية لملء المطلوب بشكل صحيح للبيئة الخاصة بك: النوع العام من إعدادات البريد (General type of mail configuration): سنختار موقع إنترنت لأن هذا يتناسب مع احتياجات البنية الأساسية لدينا. اسم نظام البريد (System mail name): هذا هو المجال الأساسي للمستخدم من أجل إنشاء عنوان بريد إلكتروني صحيح عند تقديم جزء من عنوان الحساب العنوان الحساب فقط على سبيل المثال، اسم hostname هو mail.example.com لكن ربما نرغب في تعيين اسم بريد النظام إلى example.com يتم إعطاؤه اسم المستخدم user1، سيستخدم Postfix العنوان user1@example.com. مستلما البريد root و postmaster‏ (Root and postmaster mail recipient): هما عبارة عن حسابات Linux يقومان بإعادة ارسال عنوان البريد إلى root@ و postmaster@، استخدم حسابك الأساسي لهذا الغرض في مثالنا هو sammy. مستقبلات أخرى لقبول البريد (Other destinations to accept mail for): وهذا يعرف بمستقبلات البريد التي تقبل Postfix instance، إذا كنت بحاجة لإضافة أي نطاقات أخرى سيكون هذا الخادم مسؤولاً عن تلقيها، فأضف تلك النطاقات هنا وإلا سيطبق الإعداد الافتراضي. فرض تحديثات متزامنة على قائمة انتظار البريد؟ (Force synchronous updates on mail queue?‎): نظرًا لأنك تستخدم على الأرجح ملفات النظام ، فقم برد ب "لا" هنا. الشبكات المحلية (Local networks): هذه قائمة من الشبكات التي تم إعدادها بخادم البريد الخاص بك من أجل ترحيل الرسائل، بمعظم الحالات سيعمل الإعداد الافتراضي، ولكن إذا اخترت تعديله ، فتأكد من أن يكون مقيدًا للغاية فيما يتعلق بنطاق الشبكة. تحديد الحد الأعلى لحجم صندوق البريد الوارد (Mailbox size limit): يستخدم هذا الحد للحد من حجم الرسائل الواردة و يتم تعطيل أي قيود على حجم البريد بضبطه على 0. الحرف المضاف للعنوان المحلي (Local address extension character): هذا الحرف يستخدم للفصل بين الجزء العادي من العنوان و الجزء المضاف (يستخدم لإنشاء أسماء مستعارة ديناميكية). برتوكولات الانترنت الواجب استخدامها (Internet protocols to use): اختر اذا ما كنت تريد تقييد اصدار IP الذي سيدعمه Postfix، سنختار كل IP لاغراضنا هنا. هذه هي الإعدادات التي سنستخدمها في هذا الدليل: General type of mail configuration?: Internet Site System mail name: example.com (not mail.example.com) Root and postmaster mail recipient: sammy Other destinations to accept mail for: $myhostname, example.com, mail.example.com, localhost.example.com, localhost Force synchronous updates on mail queue?: No Local networks: 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 Mailbox size limit: 0 Local address extension character: + Internet protocols to use: all من أجل اعادة ضبط الاعدادات السابقة بأي وقت يمكنك ذلك بتنفيذ الأمر التالي: $ sudo dpkg-reconfigure postfix سيتم ملء الطلبات السابقة بالردود السابقة بشكل تلقائي. عند الانتهاء ، يمكننا الآن إجراء المزيد من التهيئة لإعداد نظامنا بالطريقة التي نرغب بها. الخطوة الثانية: تحسين إعدادات Postfix بعد ذلك، يمكننا ضبط بعض الإعدادات التي لم تطلبها منا الحزمة. بدايةً، يمكننا ضبط صندوق البريد؛سوف نستخدم تنسيق Maildi الذي يفصل الرسائل إلى ملفات فردية يتم نقلها بين المجلدات بناءً على إجراء المستخدم أما الخيار الآخر فهو تنسيق mbox (الذي لن نغطيه هنا) الذي يخزن جميع الرسائل في ملف واحد. سنقوم بتعيين المتغير home_mailbox إلى القيمة Maildir/‎ أي ننشئ مجلدًا داخل المجلد الرئيسي للمستخدم إن استخدام الامر Postconf سيقوم بضبط الإعدادات اكتب الامر التالي لإعداد home/mailbox: $ sudo postconf -e 'home_mailbox= Maildir/' بعد ذلك، يمكنك تعيين موقع الجدول virtual_alias_maps الذي يحتوي حسابات البريد الإلكتروني المرتبطة بحسابات نظام Linux، سننشئ هذا الجدول في etc/postfix/virtual/ سنستخدم الأمر postconf مرة اخرى: $ sudo postconf -e 'virtual_alias_maps= hash:/etc/postfix/virtual' الخطوة الثالثة: خريطة عناوين البريد لحسابات Linux الآن سنقوم باعادة إعداد ملف جدول الخرائط الإفتراضي، افتح الملف في محرر النصوص الخاص بك: $sudo nano /etc/postfix/virtual يستخدم الاسم المستعار في جدول خريطة الافتراضي تنسيقًا بسيطًا على اليسار إذ يمكنك عرض أي عناوين ترغب في قبول بريدها الإلكتروني افصل بينها وبين اسم مستخدم Linux الذي ترغب في تسليم البريد إليه بمسافة بيضاء ثم أدخل مستخدم Linux. على سبيل المثال إذا كنت ترغب بقبول البريد الإلكتروني contact@example.com والبريد admin@example.com وترغب في تسليم رسائل البريد الإلكتروني هذه إلى المستخدم sammy، فيمكنك إعداد الملف ‎/etc/postfix/virtual كما يلي: contact@example.com sammy admin@example.com sammy بعد تعيين جميع العناوين على حسابات الخادم المناسبة، احفظ وأغلق الملف. يمكننا تطبيق وتفعيل السابق بتنفيذ الأمر: $ sudo postmap /etc/postfix/virtual أعد تشغيل عملية Postfix للتأكد من تطبيق جميع التغييرات: $sudo systemctl restart postfix أصبح خادم Postfix الآن مثبت وجاهز؛ سنقوم بإعداد عميل يمكنه التعامل مع البريد الذي يعالجه Postfix. الخطوة الرابعة: ضبط جدار الحماية إذا كنت تقوم بتشغيل جدار حماية UFW باعدادت الأولية التي تم تهيئة الخادم عليها سوف يتعين علينا السماح باستثناء Postfix. يمكنك السماح بالاتصالات بالخدمة بتنفيذ الأمر التالي: $ sudo ufw allow Postfix الآن خادم Postfix مثبت وجاهز سنقوم بإعداد عميل يمكنه التعامل مع البريد الذي يعالجه Postfix. الخطوة الخامسة: إعداد البيئة لربطها مع موقع البريد قبل أن نثبت العميل يجب أن نتأكد من صحة متغير بيئة MAIL الخاص بنا معدة بشكل صحيح، سيقوم العميل بفحص هذا المتغير لمعرفة مكان الذي أبحث فيه عن بريد المستخدم. من أجل تعيين المتغير بغض النظر عن كيفية وصولك إلى حسابك (من خلال ssh ، su ، su - ، sudo ، إلخ) ، نحتاج إلى تعيين المتغير في عدة مواقع مختلفة؛ سنقوم بإضافته إلى داخل ملفetc/bash.bashrc/و ملفetc/profile.d/للتأكد من أن كل مستخدم لديه هذا الإعداد. من أجل إضافة المتغير إلى هذه الملفات نفذ الأمر التالي: $echo 'export MAIL=~/Maildir' | sudo tee -a /etc/bash.bashrc | sudo tee -a /etc/profile.d/mail.sh لقراءة المتغير في جلستك الحالية يمكنك تنفيذ على الملف etc/profile.d/mail.sh/: $ source /etc/profile.d/mail.sh الخطوة السادسة: تثبيت وإعداد بريد العميل للتفاعل مع البريد الذي يتم تسليمه؛ سنقوم بتثبيت حزمةs-nailوهو البديل عن عميل BSD xmailالغني بالميزات ويمكنه التعامل مع تنسيق Maildir بشكل صحيح، وغالبًا ما يكون متوافقًا مع الإصدارات السابقة، يحتوي إصدار GNU للبريد على بعض القيود مثل حفظ بريد القراءة دائمًا بتنسيق mbox بغض النظر عن التنسيق المصدر. لتنزيل حزمة s-nail نستخدم الأمر: $ sudo apt install s-nail من أجل ضبط بعض الإعدادات افتح الملف etc/s-nail.rc/ باستخدام محرر النصوص الخاص بك: $ sudo nano /etc/s-nail.rc أضف الخيارات التالية في أسفل الملف ‎/etc/s-nail.rc: . . . set emptystart set folder=Maildir set record=+sent سيتيح هذا للعميل فتحه حتى مع البريد الوارد الفارغ؛ سيقوم أيضًا بتعيين المجلد Maildir داخل المجلد الداخلي ثم سيستخدم لإنشاء ملف mbox الذي تم ارساله ويخزن البريد المرسل. احفظ وأغلق الملف عند الانتهاء. الخطوة السابعة: تهيئة Maildir واختبار العميل الآن، يمكننا اختبار العميل من الخارج: تهيئة بنية المجلد أسهل طريقة لإنشاء Maildir في مجلدنا الرئيسي هي إرسال بريد إلكتروني إلى أنفسنا يمكننا القيام بذلك باستخدام الأمر s-nail نظرًا لأن الملف المرسل لن يكون متاحًا إلا بعد إنشاء Maildir، سنقوم بتعطيل الكتابة لهذا البريد الإلكتروني الأولي باستخدام الخيار Snorecord-. أرسل رسالة بريد إلكتروني عن طريق تمرير الجملة String إلى الأمر s-nail وحدد مستخدم Linux المستلم للرسالة: $ echo 'init' | s-nail -s 'init' -Snorecord sammy سيكون الرد ربما كتالي: Can't canonicalize "/home/sammy/Maildir" سيظهره هذا الأمر بشكل طبيعي عند ارسال الرسالة أول مرة و يمكننا التحقق من إنشاء المجلد من خلال البحث عن مجلد Maildir/~: $ ls -R ~/Maildir ستشاهد ما يحتوي عليه المجلد وقد تم إنشاء ملف جديد فيه رسالة جديدة في المجلد Maildir/new/~: /home/sammy/Maildir/: cur new tmp /home/sammy/Maildir/cur: /home/sammy/Maildir/new: 1463177269.Vfd01I40e4dM691221.mail.example.com /home/sammy/Maildir/tmp: يبدو أن البريد تم تسليمه. إدارة البريد مع العميل استخدم العميل من أجل التحقق من بريدك: $ s-nail ستجد الرسالة التالية تنتظرك: s-nail version v14.8.6. Type ? for help. "/home/sammy/Maildir": 1 message 1 new >N 1 sammy@example.com Wed Dec 31 19:00 14/369 init اضغط على زر Enter لعرض رسالتك التالية: [-- Message 1 -- 14 lines, 369 bytes --]: From sammy@example.com Wed Dec 31 19:00:00 1969 Date: Fri, 13 May 2016 18:07:49 -0400 To: sammy@example.com Subject: init Message-Id: \<20160513220749.A278F228D9@mail.example.com\> From: sammy@example.com init يمكنك العودة إلى قائمة الرسائل الخاصة بك بكتابة الرمز h ثم Enter: ? h نظرًا لأن هذه الرسالة ليست مفيدة للغاية يمكننا حذفها باستخدام الرمز d ثم Enter : ? d للعودة إلى شاشة الأوامر استخدم الرمز q ثم ENTER: ? q إرسال البريد مع العميل يمكنك اختيار إرسال رسالة عبر كتابة الرسالة بمحرر النصوص : $ nano ~/test_message داخل الملف ‎~/test_message اكتب النص الذي تود ارساله بالبريد: Hello, This is a test. Please confirm receipt! بإمكاننا باستخدام الأمر cat توجيه الرسالة باستخدام s-nail سيؤدي ذلك إلى إرسال الرسالة كمستخدم Linux الافتراضي، يمكنك ضبط الحقل "From" باستخدام الراية r- إذا كنت تريد تعديل هذه القيمة إلى شيء آخر: $ cat ~/test_message | s-nail -s 'Test email subject line' -r from_field_account user@email.com الخيارات بالأمر السابق تعني: s-: موضوع البريد الإلكتروني r-: حقل اختياري لتغيير الحقل "From" في البريد الإلكتروني بشكل افتراضي هو مستخدم Linux الذي قمت بتسجيل الدخول به سيتم استخدامه لملء هذا الحقل، يسمح لك الخيار r- باعادة تعيينه. user@email.com: الحساب المرسل اليه البريد الإلكتروني قم بتغييره ليكون حسابًا صحيحًا لك حق الوصول إليه. يمكنك عرض رسائلك المرسلة داخل عميل s-nail الخاص بك اعد تشغيل العميل التفاعلي مرة أخرى بكتابة الأمر التالي: $ s-nail بإمكانك عرض الرسائل المرسلة عبر الأمر التالي : ? file +sent يمكنك إدارة البريد المرسل باستخدام نفس الأوامر التي تستخدمها للبريد الوارد. الخلاصة يجب أن يكون لديك الآن القدرة على إعداد Postfix على خادم أوبنتو 18.04 إن إدارة خوادم البريد الإلكتروني مهمة صعبة على مسؤولين النظام ولكن مع هذا الإعداد يجب أن يكون لديك وظيفة البريد الإلكتروني MTA الأساسية لتبدأ. ترجمة -وبتصرف- للمقال How To Install and Configure Postfix on Ubuntu 18.04 لصاحبيه Justin Ellingwood و Hanif Jetha
  4. ASP.NET Core هي إطار عمل مفتوح المصدر وعالي الأداء لإنشاء تطبيقات ويب حديثة، ومن المفترض أن يكون النسخة الأفضل من إطار العمل ASP.NET لمايكروسوفت. تمَّ إصداره عام 2016، ويمكن تشغيله على العديد من أنظمة التشغيل مثل لينكس وmacOS، مما يتيح للمطورين استهداف نظام تشغيل معين للتطوير اعتمادًا على متطلبات التصميم. يستطيع المطور باستخدام ASP.NET Core بناء أي نوع من تطبيقات الويب أو الخدمات بغض النظر عن التعقيد والحجم. يمكن للمطورين أيضًا استخدام صفحات Razor لإنشاء تصميم يركز على الصفحة يعمل أعلى النمط التقليدي MVC (اختصارًا للعبارة Model-View-Controller). يوفر ASP.NET Core المرونة للتكامل مع أي إطار عمل للواجهة الأمامية للتعامل مع العمليات المنطقية من طرف العميل أو استخدام خدمة ويب. مثلًا، بإمكانك بناء واجهة برمجية RESTful مع ASP.NET Core واستخدامها ببساطة مع أطر عمل جافاسكربت مثل Angular، React و Vue.js. ستعدّ في هذا الدرس تطبيق ASP.NET Core وتنشره ليكون جاهزًا للإطلاق مع خادم MySQL على أوبنتو 18.04 باستخدام Nginx. ستنشر تطبيق ASP.NET Core تجريبي مماثل للتطبيق من توثيق مايكروسوفت والمُستضاف على GitHub. بمجرد أن يتم النشر، سيسمح لك التطبيق التجريبي بإنشاء قائمة أفلام وتخزينها في قاعدة البيانات. ستكون قادرًا على إنشاء، وقراءة، وتحديث، وحذف سجلات من قاعدة البيانات. يمكنك بدلًا من ذلك استخدام هذا الدرس لتنشر تطبيق ASP.NET Core خاص بك؛ من الممكن أن تحتاج إلى تنفيذ خطواتٍ إضافيةٍ تتضمن إنشاء ملف تهجير (migration) جديد إلى قاعدة البيانات الخاصة بك. المتطلبات الأساسية ستحتاج لما يلي لاتباع هذا الدرس: خادم أوبنتو 18.04 تم ضبطه باستخدام دليل التهيئة الأولية لخادم أوبنتو 18.04، متضمنًا مستخدمًا عاديًا مع وصول sudo وجدار حماية. خادم Nginx مثبَّت باتباع الخطوات كيفية تثبيت Nginx على أوبنتو 18.04. خادم ويب Nginx آمن. بإمكانك اتباع درس كيف تؤمّن خادم Nginx بشهادة Let's Encrypt في أوبنتو للقيام بذلك. ضبط سجلَّي الـ DNS لخادمك. يمكنك اتّباع هذه المقدمة إلى DigitalOcean DNS للتفاصيل حول كيفية إضافتها. سجل A مع إشارة اسم النطاق الخاص بك your-domain إلى عنوان IP العام للخادم. سجل A مع إشارة اسم النطاق الخاص بك مسبوقًا بـ www www.your-domain. إلى عنوان IP العام للخادم. نظام إدارة قواعد البيانات MySQL مثبَّت باتباع خطوات كيف تثبّت الإصدار الأخير من MySQL على أوبنتو 18.0. الخطوة 1: تثبيت مُشِّغل NET Core. الآني مُشِّغل NET Core. الآني (أي NET Core runtime.) مطلوب لتشغيل تطبيق NET Core.، لذا يجب البدء بتثبيته على جهازك. تحتاج أولًا لتسجيل مفتاح مايكروسوفت ومستودع المنتج. بعد ذلك ستثبّت الاعتماديات (dependencies) المطلوبة. أولًا، سجّل الدخول كمستخدم مُنشأ حديثًا، وتأكّد من أنَّك في المجلد الجذر: $ cd ~ ثمّ نفّذ الأمر التالي لتسجيل مفتاح مايكروسوفت ومستودع المنتج: $ wget -q https://packages.microsoft.com/config/ubuntu/18.04/packages-microsoft-prod.deb استخدم dpkg مع الراية i- لتثبيت الملف المحدد: $ sudo dpkg -i packages-microsoft-prod.deb لتسهيل تثبيت الحزم الأخرى الضرورية لتطبيقك، ستثبّت مستودع universe باستخدام الأمر التالي: $ sudo add-apt-repository universe ثمّ ثبّت حزمة apt-transport لتسمح باستخدام المستودعات التي يتم الوصول إليها عبر بروتوكول HTTP الآمن: $ sudo apt install apt-transport-https نفِّذ الأمر التالي لتنزيل قائمة الحزم من المستودعات وتحديثها للحصول على معلومات حول أحدث إصدارات الحزم واعتمادياتها: $ sudo apt update أخيرًا، يمكنك تثبيت SDK لمشغّل NET. الآني عبر الأمر: $ sudo apt install dotnet-sdk-2.2 ستُعرض تفاصيل ما سيجري تنزيله ويُطلب تأكيد ذلك عبر الضغط على Y أي yes للمتابعة. لقد انتهيت الآن من تثبيت SDK لمشغّل NET Core. الآني على الخادم، وأنت جاهز تقريبًا لتنزيل التطبيق التجريبي من Github لضبط إعدادات النشر. لكن أولًا يجب إنشاء قاعدة بيانات التطبيق. الخطوة 2: إنشاء مستخدم MySQL وقاعدة بيانات ستنشئ في هذا الجزء مستخدم على خادم MySQL، وقاعدة بيانات للتطبيق، وتمنح جميع الصلاحيات الضرورية للمستخدم الجديد ليتصل بقاعدة البيانات من تطبيقك. تحتاج لتبدأ إلى الوصول لـMySQL العميل باستخدام حساب MySQL الجذر كما هو موضح هنا: $ mysql -u root -p سيُطلب منك إدخال كلمة سر الحساب الجذر الذي تمّ إعداده ضمن درس المتطلبات الأساسية. ثم أنشئ قاعدة بيانات MySQL للتطبيق باستخدام الأمر: mysql> CREATE DATABASE MovieAppDb; ستشاهد الخرج التالي في سطر الأوامر: Output Query OK, 1 row affected (0.03 sec) لقد أنشأت الآن قاعدة البيانات بنجاح، بعد ذلك ستُنشئ مستخدم MySQL جديد، وتربطه بقاعدة البيانات التي أُنشئت حديثًا، وتمنحه جميع الصلاحيات. نفّذ الأمر التالي لتُنشئ مستخدم MySQL وكلمة مرور. تذكّر أن تغيّر اسم المستخدم وكلمة المرور ليصبحوا أكثر أمانًا: mysql> CREATE USER 'movie-admin'@'localhost' IDENTIFIED BY 'password'; ستشاهد الخرج التالي: Output Query OK, 0 rows affected (0.02 sec) يحتاج مستخدم MySQL إلى الإذن المناسب للوصول إلى قاعدة بيانات أو تنفيذ إجراء محدد عليها، حاليًا لا يملك المستخدم movie-admin الإذن المناسب على قاعدة بيانات التطبيق. سنغيّر ذلك بتنفيذ الأمر التالي لمنح حق الوصول للمستخدم movie-admin إلى قاعدة البيانات MovieAppDb: mysql> GRANT ALL PRIVILEGES ON MovieAppDb.* TO 'movie-admin'@'localhost'; ستشاهد الخرج التالي: Output Query OK, 0 rows affected (0.01 sec) يمكنك الآن إعادة تحميل جداول الصلاحيات بتشغيل الأمر التالي لتطبيق التغييرات التي قمت بها باستخدام عبارة التدفق: mysql> FLUSH PRIVILEGES; ستشاهد الخرج التالي: Output Query OK, 0 rows affected (0.00 sec) لقد أنشأت مستخدم جديد ومنحه الصلاحيات. لتختبر فيما إذا تمّ الأمر بشكلٍ صحيحٍ، أغلق MySQL العميل: mysql> quit; ثمّ سجّل الدخول مجددًا باستخدام بيانات الاعتماد لمستخدم MySQL الذي أنشأته وأدخل كلمة المرور المناسبة عندما تُطلب منك: $ mysql -u movie-admin -p للتأكد من أن المستخدم movie-admin يمكنه الوصول إلى قاعدة البيانات المُنشأة، تحقق باستخدام الأمر: mysql> SHOW DATABASES; الآن ستشاهد جدول MovieAppDb ضمن قائمة الخرج: Output +--------------------+ | Database | +--------------------+ | MovieAppDb | | information_schema | +--------------------+ 2 rows in set (0.01 sec) الآن، أغلق MySQL العميل: mysql> quit; لقد أنشأت قاعدة بيانات، ومستخدم MySQL جديد للتطبيق التجريبي، ومنحت المستخدم الجديد الصلاحيات الصحيحة للوصول إلى قاعدة البيانات. في الجزء التالي، ستبدأ بضبط التطبيق التجريبي. الخطوة 3: ضبط التطبيق التجريبي وبيانات اعتماد قاعدة البيانات كما ذُكر سابقًا، ستنشر تطبيق ASP.NET Core موجود. تم بناء هذا التطبيق لإنشاء قائمة أفلام باستخدام نمط التصميم (Model-View-Controller) لضمان وجود الهيكل المناسب والفصل بين الاهتمامات. لإنشاء أو إضافة فيلم جديد إلى القائمة، سيملأ المستخدم حقول النموذج بالتفاصيل المناسبة ويضغط على زر إنشاء لإرسال التفاصيل إلى المتحكم (controller). عند ذلك يستقبل المتحكم طلب POST HTTP مع التفاصيل المرسلة وتبقى البيانات في قاعدة البيانات من خلال النموذج (model). ستستخدم Git لسحب (pull) الشيفرة المصدرية لهذا التطبيق التجريبي من GitHub وحفظه في مجلد جديد. يمكنك أيضًا تحميل تطبيق بديل إذا كنت ستنشر تطبيقًا مختلفًا. للبدء، أنشئ مجلدًا جديدًا باسم movie-app من الطرفية (terminal) باستخدام الأمر التالي: $ sudo mkdir -p /var/www/movie-app سيكون هذا المجلد بمثابة المجلد الجذر لتطبيقك. بعد ذلك، عدّل مالك ومجموعة المجلد للسماح لحساب المستخدم العادي بالعمل على ملفات المشروع: $ sudo chown sammy:sammy /var/www/movie-app استبدل sammy باسم المستخدم العادي الذي يملك صلاحيات sudo. يمكنك الآن الانتقال إلى المجلد الأب ونسخ (clone) التطبيق من Github: $ cd /var/www $ git clone https://github.com/do-community/movie-app-list.git movie-app ستشاهد الخرج التالي: Output Cloning into 'movie-app'… remote: Enumerating objects: 91, done. remote: Counting objects: 100% (91/91), done. remote: Compressing objects: 100% (73/73), done. remote: Total 91 (delta 13), reused 91 (delta 13), pack-reused 0 Unpacking objects: 100% (91/91), done. لقد نسخت التطبيق التجريبي بنجاح من GitHub، لذا ستكون الخطوة التالية هي إنشاء اتصال ناجح بقاعدة بيانات التطبيق. ستقوم بذلك عن طريق تعديل خاصية ConnectionStrings ضمن ملف appsettings.json وإضافة تفاصيل قاعدة البيانات. غيّر المجلد ضمن التطبيق: $ cd movie-app ثم افتح الملف للتعديل: $ sudo nano appsettings.json أضف بيانات اعتماد قاعدة البيانات في ملف appsettings.json: { "Logging": { "LogLevel": { "Default": "Warning" } }, "AllowedHosts": "*", "ConnectionStrings": { "MovieContext": "Server=localhost;User Id=movie-admin;Password=password;Database=MovieAppDb" } } بوضع هذه البيانات بطريقةٍ صحيحة فقد أنشأت اتصالًا ناجحًا بقاعدة البيانات. الآن اضغط CTRL+X لحفظ تغييرات الملف واضغط Y للتأكيد. ثم اضغط ENTER لإغلاق الصفحة. تستخدم تطبيقات ASP.NET Core مكتبة NET. قياسية تسمّى Entity Framework (EF) Core لإدارة التفاعل مع قاعدة البيانات. Entity Framework Core هي إصدار خفيف عابر للمنصات (cross-platform) من التقنية الشائعة للوصول إلى بيانات Entity Framework. إنّها تقنية ربط الكائنات بالعلاقات (ORM) التي تتيح لمطوري NET. العمل مع قاعدة البيانات باستخدام أي مزود قاعدة بيانات، مثل MySQL. يمكنك الآن تحديث قاعدة بياناتك مع الجداول من التطبيق التجريبي المنسوخ. نفّذ الأمر التالي لهذا الغرض: $ dotnet ef database update سيحدّث هذا الأمر قاعدة البيانات ويُنشئ المخططات المناسبة. الآن، لتبني المشروع وكلّ اعتمادياته، نفّذ الأمر التالي: $ dotnet build ستشاهد خرجًا مشابهًا للتالي: Output Microsoft (R) Build Engine version 16.1.76+g14b0a930a7 for .NET Core Copyright (C) Microsoft Corporation. All rights reserved. Restore completed in 95.09 ms for /var/www/movie-app/MvcMovie.csproj. MvcMovie -> /var/www/movie-app/bin/Debug/netcoreapp2.2/MvcMovie.dll MvcMovie -> /var/www/movie-app/bin/Debug/netcoreapp2.2/MvcMovie.Views.dll Build succeeded. 0 Warning(s) 0 Error(s) Time Elapsed 00:00:01.91 سيؤدي هذا إلى بناء المشروع وتثبيت أيّة اعتماديات خارجية (third-party dependencies) مذكورة في ملف project.assets.json، ولكن لن يكون التطبيق جاهزًا للنشر بعد. نفّذ الأمر التالي ليصبح التطبيق جاهزًا للنشر: $ dotnet publish ستشاهد التالي: Output Microsoft (R) Build Engine version 16.1.76+g14b0a930a7 for .NET Core Copyright (C) Microsoft Corporation. All rights reserved. Restore completed in 89.62 ms for /var/www/movie-app/MvcMovie.csproj. MvcMovie -> /var/www/movie-app/bin/Debug/netcoreapp2.2/MvcMovie.dll MvcMovie -> /var/www/movie-app/bin/Debug/netcoreapp2.2/MvcMovie.Views.dll MvcMovie -> /var/www/movie-app/bin/Debug/netcoreapp2.2/publish/ هذا سيُحزّم التطبيق ويترجمه، ويقرأ اعتمادياته، وينشر مجموعة الملفات الناتجة في مجلد للنشر، ويُنتج ملف dll. عابر للمنصات يستخدم مشغّل NET Core. الآني المثبّت لتشغيل التطبيق. بتثبيت الاعتماديات، وإنشاء اتصال بقاعدة البيانات، وتحديث قاعدة البيانات بالجداول الضرورية، ونشرها للإنتاج، تكون قد أكملت ضبط التطبيق التجريبي. في الخطوة التالية ستضبط إعدادات خادم الويب لجعل التطبيق متاحًا وآمنًا على نطاقك. الخطوة 4: ضبط إعدادات خادم الويب الآن وبعد اتّباع درس كيف تؤمّن خادم Nginx بشهادة Let's Encrypt ستحصل على كتلة الخادم لنطاقك في ‎/etc/nginx/sites-available/your_domain مع توجيه server_name الذي تمّ تعيينه بالفعل بشكلٍ مناسب. في هذه الخطوة ستعدّل كتلة الخادم هذه لتقوم بضبط Nginx كوكيل (proxy) عكسي لتطبيقك. الوكيل العكسي هو خادم يقع أمام خوادم الويب ويعيد توجيه كل طلب من مستعرض الويب إلى خوادم الويب هذه. إنّه يستقبل كل الطلبات من الشبكة ويعيد توجيهها إلى خادم ويب مختلف. في حالة تطبيق ASP.NET Core، يعدّ خادم الويب Kestrel هو الخادم المفضّل المضمّن افتراضيًا، وهذا ممتاز لتقديم المحتوى الديناميكي من تطبيق ASP.NET Core لكونه يوفر أداءً أفضل لمعالجة الطلبات وقد صُمم لجعل ASP.NET أسرع قدر الإمكان. ومع ذلك لا يعد Kestrel خادم ويب كامل المواصفات لأنه لا يمكنه إدارة الأمان وتقديم الملفات الثابتة، ولهذا يُستحسن دائمًا تشغيله خلف خادم ويب. للبدء، تأكد من أنّك داخل المجلد الجذر للخادم: $ cd ~ افتح كتلة الخادم للتعديل بهذا الأمر: $ sudo nano /etc/nginx/sites-available/your_domain كما هو مفصّل في الخطوة 4 من درس كيف تؤمّن خادم Nginx بشهادة Let's Encrypt، إذا اخترت الخيار 2، فإنَّ برنامج Certbot سيضبط تلقائيًا كتلة الخادم هذه لإعادة توجيه حركة مرور HTTP إلى HTTPS مع بعض التعديلات فقط. تابع الإعدادات بضبط أول كتلتين في الملف لتصل إلى ما يلي في ملف ‎/etc/nginx/sites-available/your-domain: server { server_name your-domain www.your-domain; location / { proxy_pass http://localhost:5000; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection keep-alive; proxy_set_header Host $host; proxy_cache_bypass $http_upgrade; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } listen [::]:443 ssl ipv6only=on; # managed by Certbot listen 443 ssl; # managed by Certbot ssl_certificate /etc/letsencrypt/live/your-domain/fullchain.pem; # managed by Certbot ssl_certificate_key /etc/letsencrypt/live/your-domain/privkey.pem; # managed by Certbot include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot } … هذه الإعدادات في كتلة الخادم ستطلب من خادم Nginx التنصّت على المنفذ 443، الذي هو المنفذ القياسي للمواقع التي تستخدم SSL. بالإضافة إلى ذلك سيقبل Nginx حركة المرور العامة على المنفذ 443 ويعيد توجيه كل طلب مطابق إلى خادم Kestrel المدمج http://localhost:5000. أخيرًا، بعد كتلة الخادم التي عدلتها في الملف، تأكّد من أنّ كتلة الخادم الثانية في الملف ‎/etc/nginx/sites-available/your-domain تبدو كالتالي: … server { if ($host = www.your-domain) { return 301 https://$host$request_uri; } # managed by Certbot if ($host = your-domain) { return 301 https://$host$request_uri; } # managed by Certbot listen 80; listen [::]:80; server_name your-domain www.your-domain; return 404; # managed by Certbot } ستعيد كتلة الخادم توجيه كل الطلبات إلى https://your-domain وhttps://www.your-domain لوصول HTTPS آمن. بعد ذلك، دع Nginx يعكس التغييرات التي قمت بها على كتلة الخادم بتنفيذ الأمر: $ sudo nginx -s reload بعد إكمال إعداد خادم Nginx، تمّ ضبط الخادم بالكامل لإعادة توجيه جميع طلبات HTTPS الموجهة إلى https://your-domain على تطبيق ASP.NET Core الذي يعمل على الخادم Kestrel إلى http://localhost:5000. ولكن لم يتم ضبط Nginx ليدير إجراء الخادم Kestrel. ستستخدم وظائف systemd لمعالجة هذا والتأكّد من أنّ عملية Kestrel تعمل في الخلفية. ستسمح لك ملفات Systemd بأن تدير إجراءًا من خلال توفير وظائف البدء، والإيقاف، وإعادة التشغيل، والدخول، حالما تنشئ إجراء عمل يدعى وحدة. انتقل ضمن مجلد systemd: $ cd /etc/systemd/systems أنشئ ملفًا جديدًا للتعديل: $ sudo nano movie.service وأضف المحتوى التالي له: [Unit] Description=Movie app [Service] WorkingDirectory=/var/www/movie-app ExecStart=/usr/bin/dotnet /var/www/movie-app/bin/Debug/netcoreapp2.2/publish/MvcMovie.dll Restart=always RestartSec=10 SyslogIdentifier=movie User=sammy Environment=ASPNETCORE_ENVIRONMENT=Production Environment=DOTNET_PRINT_TELEMETRY_MESSAGE=false [Install] WantedBy=multi-user.target يحدد ملف الإعداد موقع مجلد المشروع مع WorkingDirectory وأمر التنفيذ في بداية العملية في ExecStart. بالإضافة إلى ذلك، لقد اعتدت على استخدام توجيه RestartSec لوصف متى سيتم إعادة تشغيل خدمة systemd إذا تعطلت خدمة مشغّل NET. الآني. الآن، احفظ الملف وفعّل خدمة movie المنشأة حديثًا مع الأمر: $ sudo systemctl enable movie.service بعد ذلك، تابع لتشغيل الخدمة والتحقق من أنّها تعمل عند التشغيل: $ sudo systemctl start movie.service ثمّ تفحّص حالتها: $ sudo systemctl status movie.service ستشاهد الخرج التالي: Output movie.service - Movie app Loaded: loaded (/etc/systemd/system/movie.service; enabled; vendor preset: enabled) Active: active (running) since Sun 2019-06-23 04:51:28 UTC; 11s ago Main PID: 6038 (dotnet) Tasks: 16 (limit: 1152) CGroup: /system.slice/movie.service └─6038 /usr/bin/dotnet /var/www/movie-app/bin/Debug/netcoreapp2.2/publish/MvcMovie.dll يعطيك هذا الخرج نظرةً عامةً عن الحالة الراهنة لخدمة movie.service المنشأة لتحافظ على التطبيق شغّالًا. تشير إلى أنّ الخدمة شغّالة وفعّالة حاليًا. انتقل إلى https://your-domain من متصفحك لتشغيل التطبيق واختباره. ستشاهد الصفحة الرئيسية للتطبيق التجريبي- تطبيق قائمة الأفلام. مع الخادم الوكيل العكسي وKestrel الذي تتم إدارته باستخدام systemd، تم ضبط تطبيق الويب بالكامل ويمكن الوصول إليه من المتصفح. خاتمة نشرت في هذا الدرس تطبيق ASP.NET Core على خادم أوبنتو. وقمت بتثبيت خادم MySQL واستخدمته لاستمرار البيانات وإدارتها، واستخدمت خادم الويب Nginx كوكيل عكسي لخدمة تطبيقك. بعد هذا الدرس، إذا كنت مهتمًا ببناء تطبيق ويب تفاعلي باستخدام #C بدلًا من جافاسكربت، يمكنك تجربة إطار العمل Blazor لواجهة المستخدم للويب من مايكروسوفت. إنّه واجهة المستخدم للويب تعتمد على المكونات ومقادة بالأحداث لتحقيق المنطق من جهة العميل في تطبيق ASP.NET Core. إذا كنت ترغب بنشر تطبيقك، ستحتاج إلى أخذ الإجراءات الأخرى بالحسبان لنشر تطبيقك. الشيفرة المصدرية الكاملة لهذا التطبيق التجريبي تجدها هنا على GitHub. ترجمة -وبتصرف- للمقال How To Deploy an ASP.NET Core Application with MySQL Server Using Nginx on Ubuntu 18.04 لصاحبه Oluyemi Olususi
  5. أصبحت لغة Go -التي هي لغة برمجية عاميّة الغرض- واحدةً من لغات البرمجة الأكثر شعبيةً لتطوير الواجهة الخلفية. بالتركيز على البساطة، فإنَّ مصممي لغة Go ابتكروا لغةً سهلة التعلّم وأسرع من العديد من اللغات الأخرى لتطبيقات الويب، مستفيدين من الميزات الفعّالة مثل قدرتها على التعامل مع عدة طلبات في وقت واحد بسبب تزامنها. لهذا السبب، سيكون نشر تطبيق ويب بلغة Go مفيدًا للعديد من مطوري الواجهة الخلفية. Nginx هو أحد أشهر خوادم الويب في العالم نظرًا لاستخدامه الخفيف للموارد وموثوقيته في حال وجود حمل زائد. تعتمد العديد من المواقع الضخمة والأكثر زيارةً على Nginx لتقدّم محتواها. في النشر، غالبًا ما يُستخدم Nginx موازن حمل(load balancer) أو وكيل عكسي (reverse proxy) لزيادة الأمان وجعل التطبيق أكثر قوة. بالتزامن مع لغة Go لتطوير الواجهة الخلفية في الويب، يمكن لخادم Nginx تقديم تطبيق ويب سريع وقوي. ستتعلم في هذا الدرس كيفية بناء تطبيق ويب Hello World بلغة Go وننشره على خادم أوبنتو 18.04 مستخدمين Nginx كخادم عكسي. المتطلبات الأساسية لمتابعة هذا الدرس، ستحتاج إلى ما يلي: خادم أوبنتو 18.04 تم ضبطه باتباع التهيئة الأولية لخادم أوبنتو 18.04، متضمنًا مستخدمًا عاديًا بصلاحيات sudo وجدار حماية. يجب أن تكون لغة Go مثبّتة على حاسوبك. خادم Nginx مثبّت باتّباع الدرس كيف تثبّت خادم Nginx على أوبنتو 18.04. لا تتبع الخطوة 5 - إعداد كتل الخادم؛ ستنشئ كتلة خادم Nginx لاحقًا في هذا الدرس. اسم نطاق يشير إلى خادمك. سنستخدم your_domain في هذا الدرس. هذا ضروري للحصول على شهادة SSL لموقعك، حتى يمكنك أن تقدّم تطبيقك بأمان مع تشفير TLS. بالإضافة إلى ذلك، لتحقيق نشر بدرجة الإنتاج لتطبيق الويب Go، من المهم أن تحافظ على خادمك آمنًا بتثبيت شهادة TLS/SSL. أرشح لك هذه الخطوة بشدة. لتؤمّن تطبيق الويب Go، اتّبع كيف تؤمّن خادم Nginx بشهادة Let's Encrypt على أوبنتو بعد الخطوة 3 من هذا الدرس لتحصل على شهادة TLS/SSL مجانية. الخطوة 1: بناء تطبيق ويب بلغة البرمجة Go في هذه الخطوة، ستبني نموذج تطبيق ويب بلغة Go يعرض عبارة Hello World على نطاقك your_domain ويقوم بتحيّة المستخدم على الرابط your_domain/greet/. إذا كنت تريد تعلّم المزيد من أساسيات البرمجة في Go، تفحّص مقالتنا كيف تكتب برنامجك الأول بلغة Go. بدايةً، أنشئ مجلد جديد في مجلد GOPATH ليتضمن الملف المصدري. يمكنك تسمية المجلد بأي اسم تريده، ولكن في هذا الدرس سنستخدم اسم go-web: $ mkdir $GOPATH/go-web باتّباع بنية الملف المقترحة في درس فهم، تنصيب وتهيئة بيئة عمل لغة البرمجة Go، سيعطي هذا مجلدك المسار ‎~/go/go-web: بعد ذلك، نفّذ التعليمة التالية لتغيّر المجلد إلى مجلدك الذي أنشأته حديثًا في GOPATH: $ cd $GOPATH/go-web استخدم محرر النصوص nano أو المحرر المفضل لك لإنشاء ملف باسم main.go، والذي سيتضمن الشيفرة المصدرية لتطبيقك الويب: $ nano main.go لإنشاء وظيفة التطبيق Hello World، أضف شيفرة Go التالية إلى ملف main.go المنشأ حديثًا: package main import ( "fmt" "net/http" ) func main() { http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Hello World") }) http.HandleFunc("/greet/", func(w http.ResponseWriter, r *http.Request) { name := r.URL.Path[len("/greet/"):] fmt.Fprintf(w, "Hello %s\n", name) }) http.ListenAndServe(":9990", nil) } لنتعرّف الآن على ما سيفعله جزء الشيفرة السابق، بدءًا من السطر الأول. كتبت أولًا نقطة الدخول إلى تطبيقك: package main … تخبر تعليمة package main مُصرِّف Go أن يصرّف هذا الملف على أنّه برنامجٌ تنفيذي بدلًا من أن يكون مكتبة مشتركة (shared library). ثمّ لديك تعليمات import: … import ( "fmt" "net/http" ) … يستورد هذا الجزء الوحدات الضرورية لعمل هذه الشيفرة، والتي تشمل حزمة fmt القياسية وحزمة net/http لخادم الويب الخاص بك. يُنشئ الجزء التالي مسارك الأول في الدالة main والتي هي نقطة الدخول لأي تطبيق Go: … func main () { http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Hello World") }) … } … أنشئ المسار الأب / ضمن الدالة func main، التي ستعيد النص Hello World عندما تُطلب. كما هو موضح في الجزء التالي فإنّ المسار الثاني يقبل معاملًا في الرابط (URL parameter)، في هذه الحالة اسمًا، لعرضه مصحوبًا بالتحية. … func main () { … http.HandleFunc("/greet/", func(w http.ResponseWriter, r *http.Request) { name := r.URL.Path[len("/greet/"):] fmt.Fprintf(w, "Hello %s\n", name) }) … } … يستخدم هذا URL.Path الخاص بلغة Go لتخزين القيمة مباشرةً بعد /greet/ وتمريرها كاسم من معامل الرابط. أخيرًا، هيّئ الخادم: … func main () { … http.ListenAndServe(":9990", nil) } يشغّل الجزء السابق الخادم ويعرض تطبيقك عبر المنفذ 9990 باستخدام خادم http المدمج بلغة Go. احفظ الملف وأغلق المحرر النصي بمجرد الانتهاء من فحص الشيفرة في main.go. بعد ذلك، ابنِ الملف الثنائي القابل للتنفيذ لتطبيقك باستخدام الأمر: $ go build main.go التعليمة السابقة ستصرِّف الملف main.go لإنتاج ملف قابل للتنفيذ باسم main. لقد أنشأت نموذج تطبيق ويب بلغة Go. بعد ذلك، ستنشئ ملف وحدة systemd ليبقى تطبيقك شغّالًا في الخلفية حتى عندما لا تصل إلى خادمك. الخطوة 2: إنشاء ملف وحدة Systemd في هذه الخطوة، ستنشئ ملف وحدة systemd ليبقى تطبيقك شغّالًا في الخلفية حتى عندما يسجّل المستخدم خروجه من الخادم. سيجعل هذا تطبيقك ثابتًا، مما يجعلك أقرب بخطوة للنشر على مستوى الإنتاج. بدايةً، أنشئ ملفًا جديدًا في مجلد ‎/lib/systemd/system باسم goweb.service باستخدام محرر النصوص nano أو محرر النصوص المفضّل لك: $ sudo nano /lib/systemd/system/goweb.service لضبط معاملات الخدمة، أضف الجزء التالي في الملف. [Unit] Description=goweb [Service] Type=simple Restart=always RestartSec=5s ExecStart=/home/user/go/go-web/main [Install] WantedBy=multi-user.target يحدّد المتغير ExecStart=/home/user/go/go-web/main أنَّ نقطة الدخول لهذه الخدمة عبر الملف main القابل للتنفيذ الموجود في المجلد ‎/home/user/go/go-web، إذ user هو اسم المستخدم لحساب المستخدم العادي الذي يملك صلاحيات sudo على الخادم. Restart=always تضمن أنَّ systemd سيحاول دائمًا أن يعيد تشغيل البرنامج إذا توقف. في السطر التالي، RestartSec=5s يضبط وقت انتظار لخمس ثوانٍ بين محاولات إعادة التشغيل. يحدِّد WantedBy=multi-user.target في أي حالة سيفعّل الخادم الخدمة. احفظ وأغلق الملف. بعد أن كتبت ملف وحدة الخدمة، شغّل خدمة الويب Go باستخدام الأمر: $ sudo service goweb start للتأكّد فيما إذا كانت الخدمة شغّالة، استخدم الأمر التالي: $ sudo service goweb status ستستقبل الخرج التالي: Output ● goweb.service - goweb Loaded: loaded (/lib/systemd/system/goweb.service; disabled; vendor preset: enabled) Active: active (running) since Wed 2019-07-17 23:28:57 UTC; 6s ago Main PID: 1891 (main) Tasks: 4 (limit: 1152) CGroup: /system.slice/goweb.service └─1891 /home/user/go/go-web/main لتتعلم المزيد عن العمل مع ملف وحدة systemd، ألقِ نظرة على فهم وحدات وملفات وحدة Systemd. الآن بعد أن أصبح لديك تطبيقًا شغّالًا، يمكنك ضبط الوكيل العكسي Nginx. الخطوة 3: ضبط وكيل عكسي مع Nginx ستنشئ في هذه الخطوة كتلة خادم Nginx وستضبط الوكيل العكسي Nginx لتعرض تطبيقك على الإنترنت. أولًا، غيّر مجلد العمل الخاص بك إلى مجلد sites-available على الخادم Nginx: $ cd /etc/nginx/sites-available أنشئ ملفًا جديدًا باسم النطاق الذي تريد عرض تطبيقك عليه. سيستخدم هذا الدرس الملف your_domain: $ sudo nano your_domain أضف الأسطر التالية إلى الملف لوضع الإعدادات لـ your_domain: server { server_name your_domain www.your_domain; location / { proxy_pass http://localhost:9990; } } كتلة الخادم Nginx تستخدم proxy_pass لتقديم تطبيق الويب Go على عنوان IP لخادمك المشار إليه على أنّه مضيف محلي localhost لتشغيله على المنفذ 9990 . يشير server_name إلى اسم النطاق المعيّن لعنوان IP الخاص بك، في هذه الحالة your_domain وwww.your_domain. بعد ذلك، أنشئ رابطًا رمزيًا لإعدادات Nginx هذه في مجلد sites-enabled بتشغيل الأمر التالي: $ sudo ln -s /etc/nginx/sites-available/your_domain /etc/nginx/sites-enabled/your_domain الرابط الرمزي هو اختصار لملف في موقع آخر. يشير الاختصار المُنشأ حديثًا إلى الملف الأصلي للتكيّف مع التحديثات عند إجراء التعديلات عليه. يتطلب Nginx نسخة من الإعدادات في كلا المجلدين. بعدها، أعد تحميل إعدادات Nginx بتشغيل تعليمة إعادة التحميل: $ sudo nginx -s reload لتتأكد أن نشرك يعمل، قم بزيارة http://your_domain في متصفحك، إذ ستتم تحيتك بسلسلة نصية Hello World. ملاحظة: كما ذُكر في قسم المتطلبات الأساسية، يُنصح في هذه النقطة أن يتم تفعيل SSL/TLS على خادمك. سيضمن ذلك تشفير جميع الاتصالات بين التطبيق وزوّاره، وهو أمر مهم بشكلٍ خاص إذا طلب التطبيق معلومات حساسة مثل تسجيل الدخول أو كلمة المرور. اتّبع الآن درس كيف تؤمّن خادم Nginx بشهادة Let's Encrypt على أوبنتو لتحصل على شهادة SSL مجانية لخادم Nginx على أوبنتو 18.04. بعد أن تحصل على شهادات SSL/TLS خاصة بك، عُد وأكمل هذا الدرس. ضبطت الآن الوكيل العكسي Nginx لتعرض تطبيقك على اسم النطاق الخاص بك، وقمت بتأمين تطبيق الويب Go مع SSL/TLS. في الخطوة التالية، ستختبر تطبيقك عبر اتصالٍ آمن. الخطوة 4: اختبار التطبيق في هذه الخطوة، ستختبر تطبيقك عبر اتصالٍ آمن لتتأكد من أنَّ كل شيء يعمل. افتح متصفح الويب المفضل لك، وقم بزيارة https://your_domain: ستستقبل رسالة Hello World بسيطة. استقبال هذه الرسالة عند استخدام https://‎ في الرابط يشير إلى أنَّ التطبيق يُعرض عبر اتصالٍ آمن. بعد ذلك، حاول زيارة المسار الثاني https://your_domain/greet/your-name مستبدلًا بالعبارة your-name أيّ اسم آخر تريد أن يلقي عليه تطبيقك التحيّة: سيعيد التطبيق تحيّة بسيطة مع your-name، الذي يعتمد على المعامل الممرّر للرابط. حالما تستقبل هذه النتائج، تكون قد نشرت تطبيق ويب Go بنجاح. خاتمة في هذا الدرس، أنشأت تطبيق ويب بسيط بلغة Go مستخدمًا مكاتبها القياسية، وقمت بضبط وكيل عكسي مستخدمًا Nginx، واستخدمت شهادة SSL على نطاقك لتأمين تطبيقك. لتتعلّم المزيد حول Go، تفحّص توثيقها الرسمي. بإمكانك أيضًا أن تلقي نظرة على قسم لغة GO لتتعلم المزيد حول البرمجة بهذه اللغة الفعالة. ترجمة -وبتصرف- للمقال How To Deploy a Go Web Application Using Nginx on Ubuntu 18.04 لصاحبه Michael Okoh
  6. Nginx خادم ويب قوي ووكيل عكسي (reverse proxy) يُستخدم لتقديم العديد من المواقع الأكثر شهرةً في العالم. سنوضّح في هذا الدليل كيفية ترقية Nginx الموجود القابل للتنفيذ، بدون قطع اتصالات العميل. المتطلبات الأساسية قبل البدء في هذا الدليل، يجب أن يكون لديك مستخدم غير جذر على خادمك، تمَّ إعداده مع صلاحيات sudo. ستحتاج أيضًا أن يكون لديك خادم Nginx مثبَّتًا. إذا كنت تستخدم أبنتو 14.04، يمكنك تعلّم كيفية ضبط مستخدم بصلاحيات sudo هنا. يمكنك تثبيت Nginx باتّباع هذا الدليل. إذا كنت تستخدم CentOS 7، يمكنك الحصول على ضبط المستخدم بصلاحيات sudo عبر هذا الدليل، متّبعًا هذا الدليل لتثبّت Nginx. كيف تعمل الترقية يعمل Nginx على إنشاء إجراء سيّد أو رئيسي (master process) عندما تبدأ الخدمة. ويشغّل الإجراء السيّد بدوره إجراء تابع (worker process) أو أكثر تتعامل مع اتصالات العميل الفعلية. تم تصميم Nginx لأداء إجراءات معينة عندما يتلقّى إشارات محددة من المدير. يمنحك الفرصة باستخدام هذه الإشارات لتقوم بترقيته أو ترقية إعداداته الموجودة بسهولة، بدون قطع اتصالات العميل. هناك سكربتات (scripts) معينة للخدمة مزوّدة من قِبل القائمين على صيانة حزمة التوزيع ستوفر القدرة على الاستخدام مع الترقيات التقليدية. لكن توفر الترقية يدويًا المزيد من المرونة في المنهجية وتسمح لك بمراجعة الترقية للتراجع بسرعة إذا كان هناك مشاكل. هذا أيضًا سيوفر خيارًا للترقية بأمان إذا قمت بتثبيت Nginx من المصدر أو باستخدام طريقة لا توفر هذه الإمكانية. ستُستخدم الإشارات التالية: USR2: تولّد هذه مجموعة جديدة من إجراءات السيد/التابع بدون التأثير على المجموعة القديمة. WINCH: تخبر هذه الإجراء السيد لـNginx أن يوقف أغراض التابع المرتبطة بأمان. HUP: تخبر هذه الإجراء السيد لـNginx أن يعيد قراءة ملفات إعداداته ويستبدل إجراءات التابع بتلك المرتبطة بالإعدادات الجديدة. إذا كان هناك سيد قديم وجديد قيد التشغيل، فإنَّ إرسال هذا إلى السيد القديم سيولّد توابعًا باستخدام إعداداتهم الأصليّة. QUIT: توقف هذه تشغيل السيّد وتوابعه بأمان. TERM: تهيئ هذه إيقاف تشغيل سريع للسيّد وتوابعه. KILL: توقف هذه السيّد وتوابعه بدون أيّ تنظيف. إيجاد معرّفات إجراء Nginx لإرسال إشارات إلى الإجراءات المختلفة، نحتاج إلى معرفة معرّف الإجراء (PID) المستهدف. هناك طريقتان سهلتان لإيجاد هذا. أولًا، يمكنك استخدام الأداة ps وثمّ grep لـNginx بين النتائج. هذا بسيط ويسمح لك برؤية إجراءات السيّد والتابع: $ ps aux | grep nginx output root 10846 0.0 0.3 47564 3280 ? S 13:26 0:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf nginx 10847 0.0 0.1 47936 1908 ? S 13:26 0:00 nginx: worker process user 10961 0.0 0.0 112640 964 pts/0 S+ 13:53 0:00 grep --color=auto nginx يحتوي العمود الثاني على معرّفات الإجراءات المُختارة. المميز هو معرّف الإجراء. يوضّح العمود الأخير أنَّ النتيجة الأولى هي الإجراء السيّد لـNginx. طريقة أخرى لإيجاد معرّف الإجراء السيّد لـNginx وهي طباعة محتويات ملف ‎/run/nginx.pid: $ cat /run/nginx.pid output 10846 إذا كان هناك إجراءين سيّد لـNginx قيد التشغيل، سينتقل الإجراء القديم إلى run/nginx.pid.oldbin/. توليد مجموعة سيّد/توابع جديدة الخطوة الأولى لتحديث ملفنا القابل للتنفيذ بأمان هي في الواقع تحديث ملفك الثنائي.قم بذلك باستخدام أيّ طريقة مناسبة لتثبيت Nginx لديك، سواء من خلال مدير الحزمة أو التثبيت المصدري. بعد وضع الملف الثنائي الجديد في مكانه، يمكنك توليد مجموعة ثانية من إجراءات السيّد/التابع التي تستخدم الملف الجديد القابل للتنفيذ. يمكنك القيام بذلك إمّا بإرسال إشارة USR2 مباشرةً إلى رقم المعرّف الذي استعلمت عنه (تأكّد هنا من استبدال معرّف الإجراء السيّد بمعرّف الإجراء السيّد الخاص بخادمك Nginx): $ sudo kill -s USR2 10846 او يمكنك قراءة واستبدال القيمة المخزّنة في ملف PID مباشرةً باستخدام أمر كهذا: $ sudo kill -s USR2 `cat /run/nginx.pid` إذا تفحّصت إجراءاتك الحاليّة، ستشاهد أنّ لديك الآن مجموعتان من إجراءات السيّد/التوابع لـNginx: $ ps aux | grep nginx output root 10846 0.0 0.3 47564 3280 ? S 13:26 0:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf nginx 10847 0.0 0.1 47936 1908 ? S 13:26 0:00 nginx: worker process root 11003 0.0 0.3 47564 3132 ? S 13:56 0:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf nginx 11004 0.0 0.1 47936 1912 ? S 13:56 0:00 nginx: worker process user 11031 0.0 0.0 112640 960 pts/0 S+ 14:01 0:00 grep --color=auto nginx يمكنك أيضًا أن تشاهد أنَّ ملف run/nginx.pid/ الأصلي قد انتقل إلى run/nginx.pid.oldbin/ ومعرّف الإجراء السيّد الجديد كُتبَ في الملف run/nginx.pid/: $ tail -n +1 /run/nginx.pid* output ==> /run/nginx.pid <== 11003 ==> /run/nginx.pid.oldbin <== 10846 يمكنك الآن إرسال إشارات إلى أيّ من الإجراءين السيّدين مستخدمًا المعرّفات الموجودة في هذه الملفات. عند هذه النقطة، فإن مجموعتي السيّد/التابع شغّالتين وقادرتين على تلبية طلبات العميل. تستخدم المجموعة الأولى الملف الأصلي القابل للتنفيذ والإعدادات الأصلية لـNginx وتستخدم المجموعة الثانية الإصدارات الأحدث. يمكنهم الاستمرار في العمل جنبًا إلى جنب، لكن يجب أن نبدأ في الانتقال إلى المجموعة جديدة من أجل الاتساق. إيقاف تشغيل توابع السيّد الأول للبدء بالانتقال إلى المجموعة الجديدة، فإنَّ أول شيء يمكننا القيام به هو إيقاف الإجراءات توابع السيّد الأصلي. سينهي التوابع الأصليين معالجة كل اتصالاتهم الحالية ثمَّ يخرجون. أوقف توابع المجموعة الأصلية بإصدار إشارة WINCH إلى إجرائهم السيّد: $ sudo kill -s WINCH `cat /run/nginx.pid.oldbin` سيتيح ذلك لتوابع السيّد الجديد أن يتعاملوا مع اتصالات العميل الجديدة بمفردهم. سيظلّ الإجراء السيّد القديم قيد التشغيل، لكن بدون توابع: $ ps aux | grep nginx output root 10846 0.0 0.3 47564 3280 ? S 13:26 0:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf root 11003 0.0 0.3 47564 3132 ? S 13:56 0:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf nginx 11004 0.0 0.1 47936 1912 ? S 13:56 0:00 nginx: worker process user 11089 0.0 0.0 112640 964 pts/0 R+ 14:13 0:00 grep --color=auto nginx يتيح هذا لك مراجعة التوابع الجدد لأنّهم يقبلون الاتصالات بشكلٍ منفصل مع الحفاظ على قابلية العودة إلى الملف القديم القابل للتنفيذ إذا كان هناك خطأٌ ما. تقييم النتيجة واتخاذ الخطوات التالية عند هذه النقطة يجب اختبار النظام ومراجعته للتأكّد من عدم وجود بوادر مشاكل. يمكنك ترك الإعدادات في هذه الحالة طالما ترغب بالتأكّد من أنّ الملف الجديد القابل للتنفيذ لـNginx خالٍ من الأخطاء وقادر على التعامل مع حركة المرور الخاصة بك. ستعتمد خطوتك التالية تمامًا على ما إذا كنت تواجه مشاكل. إذا كانت الترقية ناجحة، أكمل الانتقال إذا لم تواجه أيّ مشاكل مع توابع مجموعتك الجديدة، يمكنك إيقاف تشغيل الإجراء السيّد القديم بأمان. للقيام بذلك، فقط أرسل الإشارة QUIT إلى السيّد القديم: sudo kill -s QUIT `cat /run/nginx.pid.oldbin` سيُغلَق الإجراء السيّد القديم بأمان، تاركًا فقط مجموعتك الجديدة من السيّد/التوابع لـNginx. عند هذه النقطة، تكون قد حدّثت الملف الثنائي الموجود لـNginx بأمان بدون مقاطعة اتصالات العميل. إذا واجهت مشاكل في التوابع الجديدة، عُد إلى الملف الثنائي القديم إذا لاحظت وجود مشاكل في مجموعة التوابع الجديدة، يمكنك العودة إلى الملف الثنائي والإعدادات القديمة. وهذا ممكن خلال الجلسة نفسها. أفضل طريقة للقيام بذلك هي إعادة تشغيل توابع السيّد القديم بإرسال إشارة HUP له. عادةً، عندما ترسل إشارة HUP للسيّد في Nginx، يعيد قراءة ملفات إعداداته ويشغّل توابعًا جديدة. لكن عندما يكون الهدف سيّد أقدم، فقط يولّد توابعًا جديدة باستخدام إعدادات العمل الأصلية: $ sudo kill -s HUP `cat /run/nginx.pid.oldbin` يجب أن تعود الآن ليكون لديك مجموعتين من إجراءات السيّد/التابع: $ ps aux | grep nginx output root 10846 0.0 0.3 47564 3280 ? S 13:26 0:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf root 11003 0.0 0.3 47564 3132 ? S 13:56 0:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf nginx 11004 0.0 0.1 47936 1912 ? S 13:56 0:00 nginx: worker process nginx 19918 0.0 0.1 47936 1900 ? S 14:47 0:00 nginx: worker process user 19920 0.0 0.0 112640 964 pts/0 R+ 14:48 0:00 grep --color=auto nginx ترتبط التوابع الجديدة بالتابع القديم. عند هذه النقطة فإنَّ توابع المجموعتين سيقبلون اتصالات العميل. أوقف الآن الإجراء السيّد الجديد الذي يحوي أخطاء وتوابعه بإرسال إشارة QUIT: $ sudo kill -s QUIT `cat /run/nginx.pid` يجب أن تعود للسيّد والتوابع القديمين: $ ps aux | grep nginx output root 10846 0.0 0.3 47564 3280 ? S 13:26 0:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf nginx 19918 0.0 0.1 47936 1900 ? S 14:47 0:00 nginx: worker process user 19935 0.0 0.0 112640 964 pts/0 R+ 14:50 0:00 grep --color=auto nginx سيستعيد السيّد الأصلي ملف run/nginx.pid/ لمعرّفه. إذا لم يعمل ما سبق لأي سبب من الأسباب، يمكنك أن تحاول فقط إرسال إشارة TERM للسيّد الجديد للخادم، وهذا يجب أن تتهيأ عملية إيقاف التشغيل. ويجب أن يوقف هذا السيّد الجديد وأي تابع من توابعه أثناء البحث التلقائي عن السيّد القديم لبدء إجراءات التابع الخاص به. إذا كان هناك مشاكل خطيرة والتوابع بهم أخطاء ولم يتم إنهاؤهم، يمكنك إرسال إشارة KILL لكلٍّ منهم للتنظيف. يجب أن يكون هذا كحل أخير لأنّه سيؤدي إلى قطع الاتصالات. بعد الانتقال مرة أخرى إلى الملف الثنائي القديم، تذكّر أنّه لا يزال لديك الإصدار الجديد مثبّتًا على نظامك. يجب أن تزيل الإصدار الذي يحوي مشاكل وتعود لإصدارك السابق حتى يعمل Nginx بدون أيّة مشاكل عند إعادة التشغيل. خاتمة يجب أن تكون الآن قادرًا على نقل أجهزتك بسلاسة من ملف ثنائي لـNginx إلى آخر. إنَّ قدرة Nginx على التعامل مع مجموعتي سيّد/توابع مع المحافظة على معلومات علاقاتهم تتيح لنا القدرة على ترقية برنامج الخادم بدون أن يصبح جهاز الخادم في وضع عدم الاتصال. ترجمة -وبتصرف- للمقال How To Upgrade Nginx In-Place Without Dropping Client Connections لصاحبه Justin Ellingwood
  7. عندما تُنشئ خادم أوبونتو 18.04 لأول مرة، فهناك بعض خطوات الإعداد التي ينبغي عليك اتخاذها مبكّرًا كجزء من الإعداد الأساسي. سيزيد ذلك من أمان الخادم وسهولة استخدامه وسيمنحك أساسًا قويًا لاتخاذ إجراءات لاحقة. رغم أنه يمكنك إكمال هذه الخطوات يدويًا، إلا أنه في بعض الأحيان يكون من الأسهل برمجة العمليات عبر سكربت لتوفير الوقت وتفادي الأخطاء البشرية. يشرح هذا الدليل كيفية أتمتة الخطوات الموجودة في دليل إعداد الخادم الأولي في سكربت. ماذا يفعل السكربت؟ يعدّ هذا السكربت بديلًا للتشغيل اليدوي من خلال الطريقة الموضحة في دليل إعداد خادم أوبونتو 18.04 الأولي ودليل إعداد مفاتيح SSH على أوبونتو 18.04. تؤثر المتغيرات التالية على كيفية عمل السكربت: USERNAME: اسم حساب المستخدم العادي الذي ستُنشأ وتمنح له صلاحيات sudo. COPY_AUTHORIZED_KEYS_FROM_ROOT: تحدّد ما إذا كنت تريد نسخ أصول مفتاح SSH من الحساب الجذري root إلى حساب sudo الجديد. OTHER_PUBLIC_KEYS_TO_ADD: مجموعة من السلاسل النصية التي تمثل مفاتيح عامة أخرى تُضاف إلى الحساب sudo. يمكن استخدام هذه بالاختيار بين إضافتها أو جعلها بديلًا لنسخ المفاتيح من الحساب الجذري root. يجب عليك تحديث هذه المتغيرات حسب الحاجة قبل تشغيل السكربت. عند تنفيذ السكربت، تُنفّذ الإجراءات التالية: إنشاء حساب مستخدم عادي مع امتيازات sudo باستخدام الاسم الذي يحدده المتغير USERNAME . إعداد إطار لكلمة المرور الأولية للحساب الجديد: إذا كان الخادم معدًّا لمصادقة الهوية بكلمة المرور، فستُنقل كلمة المرور الإدارية الأصلية التي وُلِّدت لحساب root إلى حساب sudo الجديد. حينها تكون كلمة المرور للحساب الجذري مقفلة. إذا كان الخادم معدًّا لمصادقة الهوية بمفتاح SSH، فستُعيّن كلمة مرور فارغة لحساب sudo. تُعلّم كلمة مرور المستخدم sudo بعلامة "منتهي الصلاحية" مما يوجب تغييرها عند أول تسجيل للدخول. يُنسخ ملف Authorized_keys من الحساب الجذري إلى مستخدم sudo إذا عُيِّن المتغير COPY_AUTHORIZED_KEYS_FROM_ROOT على "صحيح". تُضاف أي مفاتيح معرّفة في OTHER_PUBLIC_KEYS_TO_ADD إلى ملف Authorized_keys للمستخدم sudo. يُعطّل التصديق SSH المستند إلى كلمة المرور في الحساب الجذري root. يُفعّل جدار الحماية UFW مع السماح باتصالات SSH. كيف يُستخدَم السكربت؟ يمكن تنفيذ السكربت بطريقتين: عن طريق إضافته إلى حقل بيانات مستخدم الخادم أثناء الإنشاء أو عن طريق تسجيل الدخول بحساب root وتنفيذه بعد التشغيل. عبر بيانات المستخدم عند إنشاء Droplet على DigitalOcean، يمكنك تحديد بيانات المستخدم، وهو سكربت يُنفّذ أثناء تشغيل الخادم الأولي من أجل إجراء إعدادٍ إضافي. إذا كنت تُنشئ Droplet من لوحة التحكم، فيمكنك تحديد خانة الاختيار "بيانات المستخدم" في قسم تحديد خيارات إضافية. سيظهر لك مربع نصي حيث يمكنك لصق السكربت: إذا كنت تُنشئ Droplet باستخدام واجهة برمجة تطبيقات DigitalOcean، فيمكنك تمرير السكربت باستخدام سمة user_data بدلاً من ذلك. إذا كنت تُنشئ Droplet باستخدام أداة سطر الأوامر doctl، فيمكنك تمرير السكربت باستخدام خيار ‎--user-data-file: $ doctl compute droplet create ... --user-data-file /path/to/script بغض النظر عن الطريقة التي تستخدمها لإضافة بيانات المستخدم، سيُنفّذ السكربت في أول مرة يُشغّل فيها الخادم الجديد. قد تضطر إلى الانتظار لبضع دقائق حتى تكتمل العملية، ولكن بعد ذلك، يمكنك تسجيل الدخول إلى الخادم الخاص بك عبر حساب المستخدم sudo للحصول على أي إعداد إضافي. عند تسجيل الدخول لأول مرة، سيُطلب منك تغيير كلمة المرور الخاصة بك. سينهي الخادم جلسة SSH الحالية بمجرد تقديم بيانات الاعتماد الجديدة الخاصة بك وتأكيدها. بعد ذلك، يمكنك إعادة SSH مرة أخرى مثل العادة. تنفيذ السكربت بعد التشغيل إذا كنت لا ترغب في استخدام بيانات المستخدم، يمكنك أيضًا تشغيل السكربت يدويًا عبر SSH بمجرد تشغيل الخادم. إذا نزّلت السكربت على جهاز الكمبيوتر المحلي الخاص بك، يمكنك تمرير السكربت مباشرةً إلى SSH بكتابة ما يلي: $ ssh root@servers_public_IP "bash -s" -- < /path/to/script/file ينبغي أن تكون الآن قادرًا على تسجيل الدخول باستخدام حساب sudo الخاص بك من أجل أي إعداد إضافي. إذا لم تُنزّل السكربت على جهاز الحاسوب المحلي، فابدأ بتسجيل الدخول إلى الحساب root على الخادم الخاص بك: $ ssh root@servers_public_IP بعد ذلك، نزِّل السكربت الأولي على الخادم: $ curl -L https://raw.githubusercontent.com/do-community/automated-setups/master/Ubuntu-18.04/initial_server_setup.sh -o /tmp/initial_setup.sh افحص السكربت للتأكد من تنزيله بشكل صحيح و حدِّث أي متغيرات ترغب في تغييرها: $ nano /tmp/initial_setup.sh عندما تكون راضيًا عن المعطيات، شغّل السكربت يدويًا باستخدام bash: $ bash /tmp/initial_setup.sh ينبغي أن تكون الآن قادرًا على تسجيل الدخول باستخدام الحساب ذي الصلاحيات sudo لإتمام أي إعدادٍ إضافي. محتويات السكربت يمكنك العثور على السكربت لإعداد الخادم الأولي في مخزن الإعداد التلقائي لمؤسسة DigitalOcean Community GitHub. لنسخ محتويات السكربت أو تنزيلها مباشرةً، انقر فوق الزر (Raw) أعلى النص، أو انقر هنا لعرض المحتويات الأولية مباشرة. لقد أدرجت المحتويات كاملة أيضًا هنا لتسهيل العملية: #!/bin/bash set -euo pipefail ######################## ### SCRIPT VARIABLES ### ######################## # اسم حساب المستخدم العادي الذي ستُنشأ وتمنح له صلاحيات # Name of the user to create and grant sudo privileges USERNAME=sammy # الجديد sudo إلى حساب root من الحساب الجذري SSH تحدّد ما إذا كنت تريد نسخ أصول مفتاح # Whether to copy over the root user's `authorized_keys` file to the new sudo # user. COPY_AUTHORIZED_KEYS_FROM_ROOT=true # sudo مجموعة من السلاسل النصية التي تمثل مفاتيح عامة أخرى تُضاف إلى الحساب # Additional public keys to add to the new sudo user # OTHER_PUBLIC_KEYS_TO_ADD=( # "ssh-rsa AAAAB..." # "ssh-rsa AAAAB..." # ) OTHER_PUBLIC_KEYS_TO_ADD=( ) #################### ### SCRIPT LOGIC ### #################### # ومنحه الصلاحيات sudo إنشاء حساب المستخدم # Add sudo user and grant privileges useradd --create-home --shell "/bin/bash" --groups sudo "${USERNAME}" # تحقق من توفّر الحساب الجذري على كلمة مرور # Check whether the root account has a real password set encrypted_root_pw="$(grep root /etc/shadow | cut --delimiter=: --fields=2)" if [ "${encrypted_root_pw}" != "*" ]; then # تُنقل كلمة المرور الإدارية الأصلية التي وُلِّدت لحساب الجذري إلى الحساب الجديد. حينها تُقفل كلمة المرور للحساب الجذري # Transfer auto-generated root password to user if present # and lock the root account to password-based access echo "${USERNAME}:${encrypted_root_pw}" | chpasswd --encrypted passwd --lock root else # حذف كلمة مرور غير صالحة للمستخدم في حالة استخدام المفاتيح بحيث يمكن تعيين كلمة مرور جديدة دون تقديم قيمة سابقة # Delete invalid password for user if using keys so that a new password # can be set without providing a previous value passwd --delete "${USERNAME}" fi # إنهاء صلاحيات المستخدم العادي لإجباره على تغييرها # Expire the sudo user's password immediately to force a change change --lastday 0 "${USERNAME}" # sudo للمستخدم SSH إنشاء مجلد # Create SSH directory for sudo user home_directory="$(eval echo ~${USERNAME})" mkdir --parents "${home_directory}/.ssh" # نسخ ملف المفاتيح من الحساب الجذري إذا كان ضروريًا # Copy `authorized_keys` file from root if requested if [ "${COPY_AUTHORIZED_KEYS_FROM_ROOT}" = true ]; then cp /root/.ssh/authorized_keys "${home_directory}/.ssh" fi # إضافة المفاتيح الإضافية المتوفرة # Add additional provided public keys for pub_key in "${OTHER_PUBLIC_KEYS_TO_ADD[@]}"; do echo "${pub_key}" >> "${home_directory}/.ssh/authorized_keys" done # SSH ضبط تكوينات ملكية وصلاحيات # Adjust SSH configuration ownership and permissions chmod 0700 "${home_directory}/.ssh" chmod 0600 "${home_directory}/.ssh/authorized_keys" chown --recursive "${USERNAME}":"${USERNAME}" "${home_directory}/.ssh" # إيقاف تسجيل الدخول للحساب الجذري باستعمال كلمة المرور # Disable root SSH login with password sed --in-place 's/^PermitRootLogin.*/PermitRootLogin prohibit-password/g' /etc/ssh/sshd_config if sshd -t -q; then systemctl restart sshd fi # SSH بعد إضافة استثناءات UFW تفعيل جدار الحماية # Add exception for SSH and then enable UFW firewall ufw allow OpenSSH ufw --force enable خاتمة يمكن أن يوفر لك إعداد الخادم الأولي تلقائيًا بعض الوقت ويمنحك أساسًا جيدًا لمزيد من الإعداد. إذا كانت هناك خطوات إضافية ترغب في اتخاذها، فيمكنك إما تسجيل الدخول بعد تشغيل السكربت للمتابعة يدويًا، أو إضافة الخطوات في نهاية السكربت لأتمتة العملية. ترجمة -وبتصرف- للمقال Automating Initial Server Setup with Ubuntu 18.04 لصاحبه Justin Ellingwood
  8. MongoDB عبارة عن قاعدة بيانات NoSQL مستندات مجانية ومفتوحة المصدر تُستخدم غالبا في تطبيقات الويب الحديثة. في هذا المقال سنُثبِّت MongnDB، ونُدير خدماتها، ونحميها، ونُفعل الوصول البعيد لها. المتطلبات تحتاج لتطبيق هذا الدرس إلى خادم أوبونتو مُعَد باتباع مقال الإعداد الأولي، ويحتوي على مستخدم sudo غير مسؤول وجدار حماية. الجزء الأول: تثبيت MongoDB خطوة 1 - تثبيت MongoDB حزمة مخزن أوبونتو الرسمي يحتوي على نسخة مُحدثه من MongoDB، ما يعني أنه بإمكاننا تثبيت حزماتِه المهمة باستخدام apt. بداية حدِّث قائمة الحُزم كي تحصل على أحدث الاصدارات: $ sudo apt update الآن ثبّت حزمة MongoDB: $ sudo apt install -y mongodb يُثبّت هذا الأمر عدة حُزم تحتوي على أحدث إصدار من MongoDB بالاضافة إلى أدوات إدارة مساعدة لخادم MongoDB. يبدأ خادم قاعدة البيانات بالعمل تلقائيا بعد التثبيت. تاليًا، نتحقق ما إن كان الخادم بعمل بصورة صحيحة. خطوة 2 - التحقق من الخدمة وقاعدة البيانات قامت عملية تثبيت MongoDB بتشغيله تلقائيا، لكن لنتأكد من بدء الخدمة ومن صحة عمل قاعدة البيانات. أولا تحقق من حالة الخدمة: $ sudo systemctl status mongodb سترى هذه المخرجات: ● mongodb.service - An object/document-oriented database Loaded: loaded (/lib/systemd/system/mongodb.service; enabled; vendor preset: enabled) Active: active (running) since Sat 2018-05-26 07:48:04 UTC; 2min 17s ago Docs: man:mongod(1) Main PID: 2312 (mongod) Tasks: 23 (limit: 1153) CGroup: /system.slice/mongodb.service └─2312 /usr/bin/mongod --unixSocketPrefix=/run/mongodb --config /etc/mongodb.conf يصرِّح systemd أنَّ خادم MongoDB يعمل. يمكننا التحقق أكثر عن طريق الاتصال بخادم قاعدة البيانات وتنفيذ أمر للفحص .نفّذ الأمر التالي: $ mongo --eval 'db.runCommand({ connectionStatus: 1 })' المخرجات: MongoDB shell version v3.6.3 connecting to: mongodb://127.0.0.1:27017 MongoDB server version: 3.6.3 { "authInfo" : { "authenticatedUsers" : [ ], "authenticatedUserRoles" : [ ] }, "ok" : 1 } القيمة 1 للحقل ok تعني أن الخادم يعمل بطريقة صحيحة. بعد ذلك، سنتطرق إلى كيفية إدارة حالة الخادم. خطوة 3 - إدارة خدمة MongoDB تُثبت MongoDB كخدمة ضمن النظام، ما يعني أنه يُمكنك إدارتها باستخدام أوامر systemd القياسية مثل باقي خدمات النظام على أوبونتو. لتتأكد من حالة الخدمة نفذ الأمر: $ sudo systemctl status mongodb يمكنك إيقاف الخادم في أي وقت من خلال الأمر: $ sudo systemctl stop mongodb لبدء الخادم عندما يكون متوقفًا عن العمل: $ sudo systemctl start mongodb يمكن إعادة تشغيل الخادم باستخدام أمر واحد: $ sudo systemctl restart mongodb MongoDB مُعد لِلبدء تلقائيا مع بدء الخادم، لإيقاف البدء التلقائي: $ sudo systemctl disable mongodb لتفعيل الميزة مجددا: $ sudo systemctl enable mongodb تاليًا، إعداد جدار الحماية لعملية تثبيت MongoDB. خطوة 4 - إعداد جار الحماية (اختياري) بافتراض أنك اتبعت مقال الإعداد الأولي لخادم أوبونتو لِتفعيل جدار الحماية، فإن خادم MongoDB لا يمكن أن يُوصل من خلال الإنترنت. في حال كنت تنوي استخدام خادم MongoDB محليا مع التطبيقات على نفس الخادم فقط فهذا الإعداد هو الأمثل. لكن إن كنت تريد أن تتصل بخادم قاعدة بيانات MongoDB من خلال الانترنت فيجب أن تسمح للاتصالات الخارجية في ufw. للسماح بالوصول من أي مكان إلى MongoDB على المنفذ الافتراضي 27017 يمكنك استخدام sudo ufw allow 27017. لكن تفعيل وصول الإنترنت إلى خادم MongoDB في التثبيت الافتراضي يعطي دخول غير محدود بضوابط لِخادم قاعدة البيانات وبياناته. في معظم الحالات يجب الوصول إلى MongoDB من أماكن موثوقة معينة فقط، مثل خادم آخر يستضيف تطبيقا مًا. للقيام بذلك، يمكنك السماح بالوصول إلى منفذ MongoDB الافتراضي مع تحديد عنوان بروتوكول الإنترنت للخادم الآخر الذي سيتمكن من الوصول إلى خادم MongoDB مباشرة: $ sudo ufw allow from your_other_server_ip/32 to any port 27017 يمكنك التحقق من التغييرات في جدار الحماية باستخدام ufw: $ sudo ufw status يجب أن ترى أن حركة المرور للمنفذ 27017 متاحة في المخرجات "output": Status: active To Action From -- ------ ---- OpenSSH ALLOW Anywhere 27017 ALLOW Anywhere OpenSSH (v6) ALLOW Anywhere (v6) 27017 (v6) ALLOW Anywhere (v6) إن كنت قد قمت بتحديد عنوان بروتوكول إنترنت معين للاتصال بخادم MongoDB، فستراه بدلا من كلمة Anywhere في المخرجات. للمزيد من إعدادات جدار الحماية المتقدمة لحد الوصول إلى خدمات UFW الأساسية: قواعد وأوامر جدار الحماية الشائعة. على الرغم من أنَّ المنفذ مفتوح، إلا أن MongoDB يسمع فقط للعنوان المحلي 127.0.0.1. للسماح بالوصول من بعد، أضف عنوان بروتوكول الخادم العام و القابل للتوجيه إلى ملف mongod.conf. افتح ملف ضبط MongoDB: $ sudo nano /etc/mongodb.conf أضف عنوان بروتوكول الانترنت الخاص بالخادم إلى قيمة bindIP: ... logappend=true bind_ip = 127.0.0.1,your_server_ip #port = 27017 ... لا تنسَ وضع فاصلة بين عناوين بروتوكول الإنترنت الموجودة والعنوان الذي أضفته الآن. احفظ الملف واغلقه، ثم أعد تشغيل MongoDB: $ sudo systemctl restart mongodb الجزء الثاني: تأمين MongoDB كانت الاصدارات السابقة ل MongoDB مُعرَّضة للاختراق لأنَّها لا تتطلب أي مصادقة للتفاعل مع قاعدة البيانات. يمكن لأي مستخدم إنشاء وحذف قواعد بيانات وقراءة محتواها والكتابة فيها تلقائيا. أعدَّت أيضا هذه الاصدارات برنامج MongoDB خفي يسمع لجميع الواجهات تلقائيًا، مما يعني أن السكربتات التلقائية يمكن أن تكتشف حالات MongoDB الغير محمية بجدار حماية، وإن لم تكُن المصادقة مفعلة، يمكن لهذه السكربتات الحصول على وصول كامل إلى MongoDB. خُفِّفَت الحالة في الاصدار ‎3.x وبعض الاصدارات السابقة المُقدَّمة من بعض مديري الحُزم لأن البرنامج الخفي أصبح الآن مرتبط ب 127.0.0.1، لذلك سيقبل الاتصالات على حزمة يونكس فقط. أي أنه أصبح غير مفتوحًا للإنترنت. لأن المصادقة ما زالت مُعَطَّلة افتراضيا، فإن لدى أي مستخدم على النظام المحلي وصول كامل لقاعدة البيانات. سنُنشِئ مستخدمًا مسؤولًا لتأمين ذلك، ونُفَعِّل المصادقة ونتحقق من ذلك. خطوة 1 - إضافة مستخدم مسؤول سنتَّصِل بسطر أوامر Mongo لإضافة مستخدم: $ mongo تُحذِّر المُخرجات عندما نستخدم سطر أوامر Mongo من أن التحكم بالوصول معطل لقاعدة البيانات وأن وصول القراءة والكتابة للبيانات والإعدادت غير مقيدة. مخرجات تنفيذ الأمرالسابق هي: MongoDB shell version v3.4.2 connecting to: mongodb://127.0.0.1:27017 MongoDB server version: 3.4.2 Welcome to the MongoDB shell. For interactive help, type "help". For more comprehensive documentation, see http://docs.mongodb.org/ Questions? Try the support group http://groups.google.com/group/mongodb-user Server has startup warnings: 2017-02-21T19:10:42.446+0000 I STORAGE [initandlisten] 2017-02-21T19:10:42.446+0000 I STORAGE [initandlisten] ** WARNING: Using the XFS filesystem is strongly recommended with the WiredTiger storage engine 2017-02-21T19:10:42.446+0000 I STORAGE [initandlisten] ** See http://dochub.mongodb.org/core/prodnotes-filesystem 2017-02-21T19:10:42.534+0000 I CONTROL [initandlisten] 2017-02-21T19:10:42.534+0000 I CONTROL [initandlisten] ** WARNING: Access control is not enabled for the database. 2017-02-21T19:10:42.534+0000 I CONTROL [initandlisten] ** Read and write access to data and configuration is unrestricted. 2017-02-21T19:10:42.534+0000 I CONTROL [initandlisten] > يمكنك اختيار الاسم الذي تريده للمستخدم المسؤول لأنَّ الصلاحيات تأتي من إعطاء الدور userAdminAnyDatabase. تُحدد قاعدة البيانات admin أين تُخَزَّن بيانات الاعتماد. يمكنك الاطلاع أكثر عن المصادقة في جزء مصادقة أمنية MongoDB. حدد اسم مستخدم وتأكد من اختيار كلمة مرور آمنة واستبدِلهما في الأمر التالي: > use admin > db.createUser( > { > user: "AdminSammy", > pwd: "AdminSammy'sSecurePassword", > roles: [ { role: "userAdminAnyDatabase", db: "admin" } ] > } > ) عند بدء أمر db.createUser، فإن سطر الأوامر سيضع ثلاث نقاط قبل كل سطر حتى انتهاء الأمر. بعد ذلك، يظهر رد بأن المستخدم قد أُنشِئ كالتالي: المخرجات: > use admin switched to db admin > db.createUser( ... { ... user: "AdminSammy", ... pwd: "AdminSammy'sSecurePassword", ... roles: [ { role: "userAdminAnyDatabase", db: "admin" } ] ... } ... ) Successfully added user: { "user" : "AdminSammy", "roles" : [ { "role" : "userAdminAnyDatabase", "db" : "admin" } ] } اكتب "exit" ثم اضغط على ENTER أو اضغط على CTRL+C للخروج. سَيُتاح الآن للمستخدم إدخال بيانات الاعتماد، لكن لن يُطلَب هذا من المستخدام حتى تفعيل المصادقة وإعادة تشغيل برنامج MongoDB الخفي. خطوة 2 - تفعيل المصادقة المصادقة مفعلة في ملف mongod.conf. عند تفعيلها وإعادة تشغيل mongod، سيظل المستخدمون قادرون على الاتصال ب Mongo بدون مصادقة، لكن سيُطلَب منهم اسم مستخدم وكلمة مرور قبل أي تفاعل. لنفتح ملف الإعداد: $ sudo nano /etc/mongod.conf في الجزء ‎#security، ستُزيل التعليق من أمام security لتفعيل المقطع. ثم سنُضيف إعداد المصادقة. يجب أن تبدو الأسطر كما في الأسفل بعد إلغاء تعليقها: الملف mongodb.conf: . . . security: authorization: "enabled" . . . لاحظ أنَّ سطر "Security" لا يحوي مسافة في بدايته، بينما سطر "authorization" يجب أن يبدأ بِمسافتين. نُعيد تشغيل البرنامج الخفي بعد حفظ الملف وإغلاقه: $ sudo systemctl restart mongod إن أخطأنا في ملف الإعداد فلن يبدأ البرنامج الخفي بالعمل. ولأن systemctl لا تعرض أي مخرجات فَسنستخدم خيار status للتحقق من ذلك: $ sudo systemctl status mongod إن ظهر Active: active (running)‎ في المخرجات وانتهى بشيء كما يلي، فإن أمر restart قد نُفِّذ بنجاح: المخرجات: Jan 23 19:15:42 MongoHost systemd[1]: Started High-performance, schema-free document-oriented database. بعد التأكد من أن البرنامج الخفي يعمل، لنُجَرِّب المصادقة. خطوة 3 - التحقق من منع المستخدمين غير المخولين أولا، نحاول الاتصال بدون معلومات اعتماد للتحقق من أن الدخول ممنوع: $ mongo تم حل جميع التحذيرات بعد تفعيل المصادقة. المخرجات: MongoDB shell version v3.4.2 connecting to: mongodb://127.0.0.1:27017 MongoDB server version: 3.4.2 اتصلنا بقاعدة بيانات test. سَنتأكد من أن الوصول ممنوع باستخدام الأمر show dbs: > show dbs المخرجات: 2017-02-21T19:20:42.919+0000 E QUERY [thread1] Error: listDatabases failed:{ "ok" : 0, "errmsg" : "not authorized on admin to execute command { listDatabases: 1.0 }", "code" : 13, "codeName" : "Unauthorized" . . . لن نتمكن من إنشاء مستخدمين أو تنفيذ أوامر بصلاحيات مشابهة بدون مصادقة. نُغلِق سطر الأوامر للمتابعة: > exit ثانيًا، نتحقق من أن المستخدم المسؤول الذي أنشأناه يمكنه الوصول. خطوة 4 - التحقق من إمكانية وصول المستخدم المسؤول سَنَتَّصِل باستخدام المستخدم المسؤول الذي أنشأناه باستخدام الخيار ‎-u لتزويد اسم المستخدم والخيار ‎-p ليطلب كلمة مرور. سنحتاج أيضا إلى تزويد اسم قاعدة البيانات التي خُزِّنَت فيها بيانات اعتماد المستخدم باستخدام الخيار ‎--authenticationDatabase. $ mongo -u AdminSammy -p --authenticationDatabase admin سيُطلب منَّا كلمة المرور، لذلك ندخلها. سننتقل إلى سطر الأوامر عند ادخال كلمة المرور الصحيحة حيث يمكننا تنفيذ الأمر show dbs: المخرجات MongoDB shell version v3.4.2 Enter password: connecting to: mongodb://127.0.0.1:27017 MongoDB server version: 3.4.2 > يجب أن نرى قاعدة البيانات بدلًا من رفض الوصول: > show dbs المخرجات: admin 0.000GB local 0.000GB للخروج، أدخل exit أو اضغط CTRL+C. خاتمة ثبَّتنا الآن MongoDB وإجرينا عمليات التهيئة والحماية المطلوبة وتحققنا من عملها. يمكنك الآن بدء استعمالها وأنت مطمئن القلب ومرتاح البال. يمكنك العثور على المزيد من الدروس المتعمقة في كيفية إعداد واستخدام MongoDB في هذه المقالات من أكاديمية حسوب. يُعد التوثيق الرسمي ل MongoDB أيضا مصدر ممتاز للخيارات التي يقدمها MongoDB. كما يمكنك الاطلاع على توثيق MongoDB لتتعلم أكثر عن المصادقة، والتحكم بالوصول وفقا للدور، والمستخدمون والأدوار. ترجمة -وبتصرف- للمقال How to Install MongoDB on Ubuntu 18.04 لصاحبه الكاتب Mateusz Papiernik.
  9. Nginx هو أحد أشهر خوادم الويب عالميا وهو المسؤول عن استضافة بعض أكبر المواقع وأكثرها ازدحاما على الإنترنت. يُعد Nginx غالبا أفضل من Apache من ناحية ملاءمته للموارد، ويمكن استخدامه كخادم ويب أو وكيل عكسي (reverse proxy). في هذا المقال سنشرح كيفية تثبيت Nginx على خادم أوبونتو 18.04. المتطلبات قبل البدء، تحتاج لمستخدم عادي - غير مسؤول - بصلاحيات "sudo" معد على الخادم. يمكنك معرفة كيفية إعداد خادم عادي في مقال الإعداد الأولي لِخادم أوبونتو 18.04. إن كان لديك حساب متاح، سجل الدخول إلى المستخدم غير المسؤول للبدء. خطوة 1 - تثبيت Nginx يمكنك تثبيت Nginx باستخدام مدير الحزم "apt" وذلك لأنه متاح في مخزن أوبونتو الافتراضي. ولأنها أول مرة نَستخدم فيها نظام تحزيم "apt"، سنُحدِث الحزمة المحلية الرئيسية كي نحصل على قائمة بأحدث الحزم. ثم ننفذ أمر تثبيت nginx: $ sudo apt update $ sudo apt install nginx بعد الموافقة على الإجراءات سيُثبِّت apt Nginx وأي متعلقات يتطلبها الخادم. خطوة 2 - إعداد جدار الحماية قبل اختبار Nginx، يجب إعداد جدار الحماية كي يتيح الوصول للخدمة. يُسجل Nginx نفسه كخدمة في ufw أثناء التثبيت مما يجعل السماح بالدخول إلى Nginx أسهل. أدرج إعدادت التطبيق التي تعلم ufw كيف تتعامل معها باستخدام الأمر: $ sudo ufw app list يجب أن تحصل على قائمة بملفات تعريف التطبيق: المخرجات: Available applications: Nginx Full Nginx HTTP Nginx HTTPS OpenSSH يوجد ثلاثة ملفات تعريف ل Nginx متاحة كما ترى: Nginx Full: يفتح هذا الملف كِلا المنافذ 80 (حركة مرور الويب العادية وغير المشفرة)، والمنفذ 443 (حركة المرور المشفرة TLS/SSL) Nginx HTTP: يفتح هذا الملف المنفذ 80 فقط (حركة مرور الويب العادية وغير المشفرة) Nginx HTTPS: يفتح هذا الملف المنفذ 443 فقط (حركة المرور المشفرة TLS/SSL) يستحسن تفعيل الملف الأكثر صرامة والذي لا يزال يسمح بحركة المرور التي تم إعدادها. لأننا لم نقم بإعداد SSL للخادم بعد، نحتاج لتفعيل المنفذ 80 فقط. يمكنك تفعيله باستخدام الأمر: $ sudo ufw allow 'Nginx HTTP' للتحقق من التغييرات: $ sudo ufw status يجب أن ترى أن حركة المرور باستخدام HTTP مفعلة كما في المخرجات: المخرجات: Status: active To Action From -- ------ ---- OpenSSH ALLOW Anywhere Nginx HTTP ALLOW Anywhere OpenSSH (v6) ALLOW Anywhere (v6) Nginx HTTP (v6) ALLOW Anywhere (v6) خطوة 3 - فحص خادم الويب بعد انتهاء عملية التثبيت، سيُشغل أوبونتو Nginx. يجب أن يكون خادم الويب يعمل. يمكننا التحقق من ذلك باستخدام نظام التهيئة systemd عن طريق الأمر: $ systemctl status nginx المخرجات: ● nginx.service - A high performance web server and a reverse proxy server Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled) Active: active (running) since Fri 2018-04-20 16:08:19 UTC; 3 days ago Docs: man:nginx(8) Main PID: 2369 (nginx) Tasks: 2 (limit: 1153) CGroup: /system.slice/nginx.service ├─2369 nginx: master process /usr/sbin/nginx -g daemon on; master_process on; └─2380 nginx: worker process كما ترى في الأعلى، يظهر أن الخدمة بدأت بنجاح. لكن الطريقة المثلى لاختبار ذلك هو جلب صفحة من Nginx فعليا. يمكنك الوصول إلى صفحة Nginx الرئيسية لتتأكد من أن التطبيق يعمل بطريقة صحيحة عن طريق الدخول إلى عنوان بروتوكول الإنترنت (IP) الخاص بالخادم. يمكنك الحصول عليه بعدة طرق. جرب تنفيذ هذا الأمر على شاشة أوامر الخادم: $ ip addr show eth0 | grep inet | awk '{ print $2; }' | sed 's/\/.*$//' ستحصل على بعض الأسطر التي يمكنك تجريبها سطرًا تلو الآخر على متصفح الإنترنت لتتأكد إن كانت تعمل. الطريقة الأخرى هي عبر تنفيذ الأمر التالي، والذي سيعطيك عنوان بروتوكول الإنترنت العام للخادم كما يُرى على المواقع الآخرى على الإنترنت: $ curl -4 icanhazip.com عند حصولك على عنوان بروتوكول الإنترنت الخاص بالخادم، أدخله إلى شريط المتصفح: http://your_server_ip يجب أن ترى الصفحة الرئيسية ل Nginx: تُضمَّن هذه الصفحة مع Nginx لتأكيد أن Nginx يعمل بطريقة صحيحة. خطوة 4 - إدارة عملية Nginx الآن وبما أن خادم الويب أصبح يعمل بطريقة صحيحة، لنراجع بعض أوامر التحكم الأساسية. لإيقاف خادم الويب نفذ الأمر: $ sudo systemctl stop nginx لِتشغيل خادم الويب عندما يكون موقفا، نفذ الأمر: $ sudo systemctl start nginx لِإيقاف وإعادة تشغيل الخدمة استخدم الأمر: $ sudo systemctl restart nginx إن كنت تقوم بتعديل في إعدادت Nginx، فإنه يٌعيد التحميل بدون قطع اتصالاته. للقيام بذلك نفذ الأمر: $ sudo systemctl reload nginx Nginx مٌعد ليبدأ تلقائيا مع بدء تشغيل الخادم. إن كنت لا تريد ذلك؛ يمكنك إلغاء تفعيل هذه الميزة باستخدام الأمر: $ sudo systemctl disable nginx لإعادة تفعيل هذه الميزة: $ sudo systemctl enable nginx خطوة 5 - إعداد أجزاء الخادم (Server Blocks) (إعداد مستحسن) عند استخدام خادم Nginx، أجزاء الخادم (شبيهة بالمضيف الوهمي [virtual host] في Apache) تُستخدم لتغليف تفاصيل الإعدادات وتمكين استضافة أكثر من نطاق من خادم واحد. سنقوم بإعداد نطاق ونُسمية example.com، يمكنك استبدال هذا الاسم باسم النطاق الذي تريده. لدى Nginx جزء خادم مُفعَّل تلقائيا على أوبونتو ومُعَد لتشغيل الملفات في مجلد "‎/var/www/html". رغما من أن هذا يعمل بشكل جيد لموقع واحد؛ إلا أنه ليس عمليا إن كنت تستضيف عدة مواقع. عوضا عن التعديل على ‎/var/www/html؛ لنقم بإنشاء بينة هيكلية في ‎/var/www لموقع example.com ونترك ‎/var/www/html في مكانه كَمجلد رئيسي ليعمل في حال طلب أحد العملاء صفحة لا توافق بقية المواقع. أنشئ مجلدا ل example.com كما يلي مستخدما -p لإنشاء أي مجلدات ضرورية أخرى: $ sudo mkdir -p /var/www/example.com/html ثم قم بمنح ملكية الجلد باستخدام متغير البيئة ‎$USER: $ sudo chown -R $USER:$USER /var/www/example.com/html يجب أن تكون صلاحيات جذور الويب صحيحة إن كنت لم تقم بتعديل قيمة umask يمكنك التأكد من ذلك باستخدام الأمر: $ sudo chmod -R 755 /var/www/example.com قم بإنشاء صفحة كعينة index.html باستخدام الأمر nano على مُحررك المفضل: $ nano /var/www/example.com/html/index.html بداخل هذه الصفحة، ضع عينة HTML التالية: /var/www/example.com/html/index.html <html> <head> <title>Welcome to Example.com!</title> </head> <body> <h1>Success! The example.com server block is working!</h1> </body> </html> بعد الانتهاء احفظ وأغلق الملف. كي يقوم Nginx بمعالجة هذا المحتوى، فمن الضروري إنشاء جزء خادم (server block) بالموجهات الصحيحة. بدلا من القيام بذلك عبر تعديل ملفالإعداد الافتراضي مباشرة، لنُنشئ ملفًا جديدًا في ‎/etc/nginx/sites-available/example.com: $ sudo nano /etc/nginx/sites-available/example.com قم بنسخ جزء الإعداد التالي الشبيه بالافتراضي لكنه محدث للمجلد واسم المجلد الجديد: /etc/nginx/sites-available/example.com server { listen 80; listen [::]:80; root /var/www/example.com/html; index index.html index.htm index.nginx-debian.html; server_name example.com www.example.com; location / { try_files $uri $uri/ =404; } } لاحظ أننا قمنا بتحديث إعداد root للمجلد الجديد و server_name لاسم النطاق الجديد. ثم نقوم بتفعيل الملف من خلال إنشاء رابط منه إلى مجلد sites-enabled والذي يقوم Nginx بالقراءة منه أثناء التشغيل: $ sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/ الآن أصبح لدينا جزئي خادم مفعلين ومُعدين للاستجابة للطلبات وفقا لموجهي listen و server_name (يمكنك قراءة المزيد حول كيفية معالجة Nginx لهذه الموجهات في هذا المقال example.com: سيستجيب للطلب على example.com و www.example.com. default: سيستجيب لأي طلبات على المنفذ 80 والتي لا تطابق جزء آخر. لتجنب مشكلة "hash bucket memory" التي قد تطرأ من إضافة أسماء خوادم إضافية، من الضروري تعديل قيمة واحدة في ملف ‎/etc/nginx/nginx.conf. افتح هذا الملف: $ sudo nano /etc/nginx/nginx.conf ابحث عن الموجّه server_names_hash_bucket_size واحذف رمز # لإلغاء تعليق هذا السطر: /etc/nginx/nginx.conf ... http { ... server_names_hash_bucket_size 64; ... } ... ثم نتحقق من عدم وجود من أي أخطاء في جمل ملفات Nginx: $ sudo nginx -t احفظ وأغلق الملف بعد انتهائك. إن لم يكن هناك أي أخطاء أعد تشغيل Nginx لتفعيل التغييرات: $ sudo systemctl restart nginx يجب أن يقوم Nginx الآن بالاستجابة للطلبات على النطاق الجديد. للتحقق من ذلك، ادخل على http://example.com. هنا يجب أن ترى شيئا كالتالي: خطوة 6 - التعرف على مجلدات وملفات Nginx المهمة الآن، وبعد أن أصبحت تعرف كيف تُدير خدمة Nginx. يجب أن تأخذ لمحة سريعة حول بعض المجلدات والملفات المهمة. المحتوى ‎/var/www/html: محتوى الويب الفعلي ل Nginx والذي يحتوي فقط على صفحة Nginx الافتراضية التي رأيناها سابقا. تُعرض هذه الصفحة من مجلد ‎/var/www/html. يمكن تغيير هذا الإعداد عن طريق ملف إعداد Nginx. إعداد الخادم ‎/etc/nginx: مجلد إعداد Nginx والذي يحوي جميع ملفات التكوين. ‎/etc/nginx/nginx.conf: ملف تكوين Nginx الرئيسي. يمكن تعديل هذا الملف لتغيير الإعدادات العامة ل Nginx. ‎/etc/nginx/sites-available/‎: المجلد الذي يتم تخزين أجزاء الخادم فيه. لن يقوم Nginx باستخدام ملفات التكوين الموجودة في هذا المجلد إلا إذا تم ربطها لمجلد sites-enabled. بشكل عام، يتم تخزين ملفات إعداد أجزاء الخادم في هذا المجلد ثم تُفعّل بربطها بالمجلد الآخر. /etc/nginx/sites-enabled/: المجلد الذي يتم تخزين أجزاء الخادم لكل موقع (per-site server blocks) فيه. تُنشئ هذه المجلدات بربط ملفات التكوين الموجودة في مجلد sites-available. ‎/etc/nginx/snippets: يحتوي هذا المجلد على أجزاء التكوين التي يمكن تضمينها في أي مكان آخر في تكوين Nginx. أجزاء الإعداد المُكررة عن قصد تُعد بدائل جيدة لإعادة بناء أجزاء الأكواد البرمجية. سجلات الخادم ‎/var/log/nginx/access.log: يتم تخزين كل طلب يصل إلى خادم الويب في ملف السجل هذا إلا إن كان Nginx مُعد لعدم القيام بذلك. ‎/var/log/nginx/error.log: يتم تسجيل أي خطأ في Nginx في هذا السجل. الآن وبما أن خادم الويب أصبح مُعدًا لديك، فلديك عدة خيارات للمحتوى الذي يمكن أن يعالجه الخادم والتقنيات التي يمكن أن تستخدمها لتجربة أفضل. الخلاصة إن كنت تريد بناء حزمة تطبيق متكاملة، اطلع على هذا المقال عن كيفية إعداد حزمة LEMP على أوبونتو 18.04. ترجمة -وبتصرف- للمقال How To Install Nginx on Ubuntu 18.04 لصاحبيه Justin Ellingwood و Kathleen Juell.
  10. MySQL هو نظام مفتوح المصدر لإدارة قواعد البيانات، ويُثبت غالبا كجزء من الحزمة الشهيرة LAMP (Linux, Apache, MySQL, PHP/Python/Perl). يستخدم MySQL قواعد بيانات علائقية و SQL (لغة استعلام مهيكلة) لإدارة بياناته. الطريقة المختصرة لتثبيت MySQL سهلة جدا: حدث الحزمة الرئيسية، ثم ثبت حزمة mysql-server ثم شغِّل سكريبت الحماية المضمن. $ sudo apt update $ sudo apt install mysql-server $ sudo mysql_secure_installation متطلبات أولية لإكمال هذا الإعداد، ستحتاج إلى: خادم أوبونتو 18.04 مُعد كما في مقال الإعداد الأولي لِخادم أوبونتو. متضمنا مستخدم غير مسؤول (non-root user) بصلاحيات sudo وجدار حماية. خطوة 1 - تثبيت MySQL تتضمن تلقائيا حزمة مخزن APT في أوبونتو 18.04 أحدث إصدار فقط من MySQL. في الوقت الراهن، أحدث اصدار هو MySQL 5.7. للتثبيت، حدّث الحزمة الرئيسية على الخادم باستخدام الأمر apt: $ sudo apt update ثم ثبت الحزمة الافتراضية: $ sudo apt install mysql-server سيُثبت هذا الأمر MySQL لكنه لن يتيح لك إعداد كلمة مرور أو القيام بأي تعديل على الإعدادات. مما يجعل تثبيت MySQL غير آمن وسيتم شرح ذلك لاحقا. خطوة 2 - إعداد MySQL ستحتاج لِتشغيل سكريبت الحماية المضمن للحصول على تثبيت صحيح. الأمر الذي سيغير بعض الخيارات الأقل أمنا مثل دخول المستخدمين المسؤولين عن بعد أو عينات المستخدمين. كنا نقوم بإعداد هذه البيانات يدويا في إصدارات سابقة، لكن في هذا الإصدار يتم إعدادها تلقائيا. قم بتشغيل السكربت: $ sudo mysql_secure_installation ستنتقل عبر بعض الخيارات حيث يمكنك القيام ببعض التغييرات على إعدادات حماية MySQL المٌعدة أثناء التثبيت. الخيار الأول سيسألك إن كنت تريد إعداد إضافة التحقق بكلمة المرور والمستخدمة لقياس قوة كلمة مرور MySQL. بغض النظر عن خيارك، الخيار التالي سيكون لإعداد كلمة مرور للمستخدم المسؤول ل MySQL. أدخل وأكِد كلمة مرور آمنة. بعد ذلك يمكنك الضغط على Y ثم ENTER لقبول الإعداد الافتراضي لبقية الأسئلة التالية. سيقوم ذلك بحذف بعض المستخدمين المجهولين وقاعدة البيانات التجريبية، وإلغاء تفعيل دخول المستخدمين المسؤولين عن بعد، وسيُحمل الإعدادات الجديدة التي قمت بعملها على MySQL. لإعداد دليل بيانات MySQL يمكنك استخدام mysql_install_db للإصدارات قبل 5.7.6 و mysqld --initialize لتهيئة الإصدار 5.7.6 والإصدارات الأحدث. لكن إن كنت قد ثبتت MySQL من موزع Debian كما في الخطوة 1، فإن دليل البيانات قد تم إعداده تلقائيا ولن تحتاج للقيام بأي شيء. وبحال أو بآخر إن قمت بتنفيذ الأمر، فسترى الخطأ التالي: المخرجات: mysqld: Can't create directory '/var/lib/mysql/' (Errcode: 17 - File exists) . . . 2018-04-23T13:48:00.572066Z 0 [ERROR] Aborting لاحظ أنه حتى إن قمت بإعداد كلمة مرور لمستخدم MySQL المسؤول، فإن هذا المستخدم ليس معدًا للتحقق عبر كلمة المرور عند الاتصال بشاشة اوامر MySQL. إن أردت تغيير هذا الإعداد اتبع الخطوة 3. خطوة 3 - (اختيارية) إعداد مصادقة وصلاحيات المستخدم المستخدم المسؤول في أنظمة أوبونتو التي تستخدم MySQL 5.7 مُعد للمصادقة تلقائيا باستخدام اضافة auth_socket بدلا من كلمة المرور. توفر هذه الإضافة أمانًا أكبر وسهولةً في الاستخدام في حالات متعددة، لكنها تضيف بعض التعقيد عند حاجتك للسماح لبرنامج خارجي بالوصول للمستخدم (مثل phpMyAdmin). حتى تتمكن من الدخول إلى MySQL كمستخدم رئيسي باستخدام كلمة مرور، تحتاج لتبديل طريقة المصادقة من auth_socket إلى mysql_native_password. للقيام بذلك افتح شاشة اوامر MySQL: $ sudo mysql ثم تأكد من طريقة المصادقة لكل حساب مستخدم MySQL باستخدام الأمر التالي: mysql> SELECT user,authentication_string,plugin,host FROM mysql.user; المخرجات: +------------------+-------------------------------------------+-----------------------+-----------+ | user | authentication_string | plugin | host | +------------------+-------------------------------------------+-----------------------+-----------+ | root | | auth_socket | localhost | | mysql.session | *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE | mysql_native_password | localhost | | mysql.sys | *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE | mysql_native_password | localhost | | debian-sys-maint | *CC744277A401A7D25BE1CA89AFF17BF607F876FF | mysql_native_password | localhost | +------------------+-------------------------------------------+-----------------------+-----------+ 4 rows in set (0.00 sec) يمكنك ملاحظة أن المستخدم المسؤول في هذا المثال يستخدم المصادقة بواسطة إضافة auth_socket. لإعداد حساب المستخدم المسؤول ليستخدم المصادقة بكلمة المرور استخدم أمر ALTER USER التالي. تأكد من تغيير password إلى كلمة مرور قوية من اختيارك وتذكر أن هذا الأمر سيغير كلمة المرور التي وضعتها في خطوة 2: mysql> ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password'; ثم نفذ الأمر FLUSH PRIVILEGES الذي يوجه الخادم بإعادة تحميل جداول الصلاحيات كي تعمل التغييرات التي قمت بها: mysql> FLUSH PRIVILEGES; تحقق من طريقة المصادقة لكل حساب مستخدم مجددا للتأكد من أن المستخدم المسؤول لم يعد يستخدم المصادقة باستخدام إضافة auth_socket: mysql> SELECT user,authentication_string,plugin,host FROM mysql.user; المخرجات: +------------------+-------------------------------------------+-----------------------+-----------+ | user | authentication_string | plugin| host | +------------------+-------------------------------------------+-----------------------+-----------+ | root | *3636DACC8616D997782ADD0839F92C1571D6D78F | mysql_native_password | localhost | | mysql.session| *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE | mysql_native_password | localhost | | mysql.sys| *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE | mysql_native_password | localhost | | debian-sys-maint | *CC744277A401A7D25BE1CA89AFF17BF607F876FF | mysql_native_password | localhost | +------------------+-------------------------------------------+-----------------------+-----------+ 4 rows in set (0.00 sec) يمكنك رؤية أن المستخدم المسؤول أصبح يستخدم المصادقة بكلمة المرور في هذا المثال. بعد أن تتأكد من ذلك يمكنك الخروج من شاشة اوامر MySQL: mysql> exit بدلا من ذلك؛ قد يفضل البعض استخدام مستخدم خصص للاتصال ب MySQL. لِإنشاء مستخدم مخصص افتح شاشة اوامر MySQL مجددا: $ sudo mysql ملاحظة: إن كنت تستخدم المصادقة بكلمة المرور للمستخدم المسؤول كما تم الشرح سابقا؛ فستحتاج لاستخدام أمر آخر للدخول إلى شاشة اوامر MySQL. سيقوم الأمر التالي بتشغيل عميل MySQL مع صلاحيات مستخدم عادي. وستحصل على صلاحيات المسؤول فقط عن طريق المصادقة: $ mysql -u root -p بعد ذلك قم بإنشاء مستخدم بكلمة مرور قوية: mysql> CREATE USER 'sammy'@'localhost' IDENTIFIED BY 'password'; ثم امنح الصلاحيات المناسبة للمستخدم الجديد. كمثال، يمكنك منح المستخدم صلاحيات لجميع جداول قاعدة البيانات، بالإضافة إلى إمكانية إضافة وتعديل وحذف صلاحيات المستخدمين باستخدام الأمر التالي: mysql> GRANT ALL PRIVILEGES ON *.* TO 'sammy'@'localhost' WITH GRANT OPTION; لاحظ أنك لا تحتاج في هذه النقطة لاستخدام أمر FLUSH PRIVILEGES مرة أخرى. تحتاج لاستخدام هذا الأمر فقط عند تعديل جداول منح الصلاحيات باستخدام أحد الأوامر INSERT، أو UPDATE، أو DELETE. ولأنك قمت بإنشاء مستخدم هنا عوضا عن تعديل مستخدم موجود فإن الأمر FLUSH PRIVILEGES غير مهم هنا. أغلق شاشة اوامر MySQL: mysql> exit وأخيرا نختبر صحة تثبيت MySQL. خطوة 4 - اختبار MySQL يجب أن يبدأ MySQL بالعمل تلقائيا بغض النظر عن الطريقة التي قمت بتثبيته بها. للتحقق من ذلك، نقوم بفحص حالته. $ systemctl status mysql.service سترى مخرجات شبيهة بالمخرجات التالية: ● mysql.service - MySQL Community Server Loaded: loaded (/lib/systemd/system/mysql.service; enabled; vendor preset: en Active: active (running) since Wed 2018-04-23 21:21:25 UTC; 30min ago Main PID: 3754 (mysqld) Tasks: 28 Memory: 142.3M CPU: 1.994s CGroup: /system.slice/mysql.service └─3754 /usr/sbin/mysqld إن كان MySQL لا يعمل فيمكنك تشغيله باستخدام الأمر sudo systemctl start mysql. للمزيد من الفحص يمكنك محاولة الاتصال بقاعدة البيانات باستخدام أداة mysqladmin والتي تعتبر أداة عميل تتيح لك تنفيذ أوامر ذات صلاحيات مسؤول. كمثال، الأمر التالي يتصل ب MySQL كمستخدم مسؤول ("‎-u root") ويطلب كلمة مرور ("‎-p") ويعرض الإصدار. $ sudo mysqladmin -p -u root version يجب أن ترى مخرجات كالتالي: mysqladmin Ver 8.42 Distrib 5.7.21, for Linux on x86_64 Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Server version 5.7.21-1ubuntu1 Protocol version 10 Connection Localhost via UNIX socket UNIX socket /var/run/mysqld/mysqld.sock Uptime: 30 min 54 sec Threads: 1 Questions: 12 Slow queries: 0 Opens: 115 Flush tables: 1 Open tables: 34 Queries per second avg: 0.006 هذا يعني أن MySQL يعمل. الخلاصة الآن أصبح لديك الإعداد الأولي ل MySQL على الخادم الخاص بك. هنا بعض الأمثلة على بعض الخطوات اللاحقة: إعداد بعض الميزات الأمنية الاضافية نقل مجلد البيانات ترجمة -وبتصرف- للمقال How To Install MySQL on Ubuntu 18.04 لصاحبه الكاتب Mark Drake.
  11. Redis عبارة عن مخزن يعتمد على مفتاح وقيمته ويُعرف بمرونته، وأدائه، ودعمه العديد من اللغات. يوضح هذا المقال كيفية تثبيت وإعداد وتأمين Redis على خادم أوبونتو 18.04. المتطلبات ستحتاج إلى الدخول إلى خادم أوبونتو 18.04 والذي لا يملك صلاحيات مستخدم مسؤول ويملك صلاحيات sudo. بالإضافة إلى جدار حماية معد. يمكنك إعداد ذلك من خلال مقال التهيئة الأولية لِخادم أوبونتو. للبدء سجل دخولك إلى خادم أوبونتو 18.04 باستخدام مستخدم sudo وليس مستخدم مسؤول. خطوة 1 - تثبيت وإعداد Redis للحصول على أحدث إصدار من Redis، سنستخدم الأمر apt لتثبيته من متجر أوبونتو الرسمي. حدِّث ذاكرة التخزين المؤقتة لحزمة apt وثبت Redis باستخدام الأمرين التاليين: $ sudo apt update $ sudo apt install redis-server تنفيذ هذان الأمران سيؤدي إلى تنزيلRedis وتثبيته بالإضافة إلى تثبيت كل الأشياء المتعلقة به. بعد ذلك، يوجد إعداد مهم يجب تغييره في ملف إعداد Redis والذي وُلد تلقائيا أثناء التثبيت. افتح هذا الملف بأي محرر تفضله: $ sudo nano /etc/redis/redis.conf ابحث عن supervised في الملف. تتيح لك هذه التعليمة تعريف init في النظام لإضافة Redis كخدمة، مما يتيح لك تحكمًا أفضل بعملياته. تعليمة supervised تكون معطلة no بشكل افتراضي. غيِّر قيمة no إلى systemd؛ ذلك لأنك تستخدم أوبونتو المعتمد على نظام "systemd init". الملف ‎/etc/redis/redis.conf: . . . # If you run Redis from upstart or systemd, Redis can interact with your # supervision tree. Options: # supervised no - no supervision interaction # supervised upstart - signal upstart by putting Redis into SIGSTOP mode # supervised systemd - signal systemd by writing READY=1 to $NOTIFY_SOCKET # supervised auto - detect upstart or systemd method based on # UPSTART_JOB or NOTIFY_SOCKET environment variables # Note: these supervision methods only signal "process is ready." # They do not enable continuous liveness pings back to your supervisor. supervised systemd . . . حتى الآن هذا هو التعديل الوحيد الذي نحتاج القيام به في ملف إعداد Redis. احفظ الملف واغلقه بعد تعديله. ثم أعد تشغيل خدمة Redis لتصبح التغييرات التي أجريتها على الملف سارية المفعول. $ sudo systemctl restart redis.service وبهذا تكون قد أعددت Redis، لكن قبل استخدامة يجب التأكد من أنه يعمل بالطريقة الصحيحة. خطوة 2 - اختبار Redis يفضل التأكد من صحة عمل أي برنامج جديد قبل تغيير أي من إعداداته. في هذه الخطوة سنتعرف على بعض الطرق للتأكد من ذلك. نبدأ بالتأكد من أن خدمة Redis تعمل: $ sudo systemctl status redis ستظهر مخرجات مشابهة لما يلي في حال كان Redis يعمل بدون أي أخطاء: المخرجات: ● redis-server.service - Advanced key-value store Loaded: loaded (/lib/systemd/system/redis-server.service; enabled; vendor preset: enabled) Active: active (running) since Wed 2018-06-27 18:48:52 UTC; 12s ago Docs: http://redis.io/documentation, man:redis-server(1) Process: 2421 ExecStop=/bin/kill -s TERM $MAINPID (code=exited, status=0/SUCCESS) Process: 2424 ExecStart=/usr/bin/redis-server /etc/redis/redis.conf (code=exited, status=0/SUCCESS) Main PID: 2445 (redis-server) Tasks: 4 (limit: 4704) CGroup: /system.slice/redis-server.service └─2445 /usr/bin/redis-server 127.0.0.1:6379 . . . يمكنك رؤية أن Redis مُفعَّل وقيد التشغيل، ما يعني أنه معد كي يبدأ التشغيل مع بدء تشغيل الخادم. ملاحظة: هذا الإعداد مستحسن في أغلب حالات استخدام Redis. إن كنت تفضل تشغيل Redis يدويا في كل مرة تحتاج إليه. يمكنك القيام بذلك باستخدام الأمر: $ sudo systemctl disable redis لاختبار صحة أداء Redis، اتصل بالخادم باستخدام سطر أوامر العميل: $ redis-cli في الشاشة التالية، اختبر الاتصال باستخدام أمر ping: 127.0.0.1:6379> ping المخرجات: PONG تأكد هذه المخرجات أن اتصال الخادم مفعل. بعد ذلك، تأكد من إمكانية إعداد المفاتيح باستخدام الأمر: 127.0.0.1:6379> set test "It's working!" المخرجات: OK استرجِع القيمة باستخدام الأمر: 127.0.0.1:6379> get test ستتمكن من استرجاع القيمة التي أدخلتها في حال كان كل شيء يعمل بشكل صحيح: المخرجات: "It's working!" بعد تأكدك من إمكانية استرجاع القيمة، أغلق شاشة تنفيذ أوامر Redis: 127.0.0.1:6379> exit كاختبار أخير لفحص ما إن كان Redis قادرا على الاستمرار حتى بعد إبقافة أو إعادة تشغيله. لتطبيق هذا الاختبار نبدأ بإعادة تشغيل Redis: $ sudo systemctl restart redis اتصل بشاشة أوامر عميل Redis مرة أخرى وتأكد من بقاء القيمة التي خزنتها: $ redis-cli 127.0.0.1:6379> get test يجب أن تظل القيمة المخزنة متاحة: المخرجات: "It's working!" أخرج مجددَا بعد انتهائك: 127.0.0.1:6379> exit وبذلك، يكون Redis مثبتَا ويعمل بشكل صحيح وجاهز للاستخدام. بالرغم من ذلك، ما تزال بعض إعداداته الافتراضية غير آمنة وتوفر بعض الفرص للأشخاص المخترقون للهجوم على الخادم وبياناته. تشرح باقي الخطوات في هذا المقال بعض الطرق لتقليل هذه الثغرات الأمنية كما ذكر في موقع Redis الرسمي. هذه الخطوات اختيارية وسيستمر Redis بالعمل حتى لو لم تنفذها، لكن يفضل أن تكمل هذه الخطوات لتقوية أمن نظامك. خطوة 3 - الربط مع المضيف المحلي (localhost) Redis متاح تلقائيا عبر المضيف المحلي، لكن إن كنت قد ثبتت Redis بطريقة أخرى فربما تكون قد حدَّثت ملف الإعداد الخاص ب Redis الأمر الذي يتيح اتصالات Redis من أي مكان. هذا الأمر غير آمن كالربط بالمضيف المحلي. لتصحيح الأمر، افتح ملف تكوين Redis لتعديله: sudo nano /etc/redis/redis.conf إذهب إلى السطر التالي وتأكد من إلغاء تعليقه (احذِف # إن وجدت): الملف /etc/redis/redis.conf: bind 127.0.0.1 ::1 احفظ الملف واغلقه عند الانتهاء (اضغط على CTRL + X, Y, ثم ENTER). أعد تشغيل الخدمة للتأكد من قراءة النظام للتغييرات: $ sudo systemctl restart redis للتأكد من تأثير هذه التغييرات، نفِّذ أمر netstat التالي: $ sudo netstat -lnp | grep redis المخرجات: tcp 0 0 127.0.0.1:6379 0.0.0.0:* LISTEN 14222/redis-server tcp 0 0 ::1:6379 :::* LISTEN 14222/redis-server توضح هذه المخرجات أن برنامج خادم Redis مرتبط بالمضيف المحلي (127.0.0.1). مما يدل على انعكاس التغيير الذي أجريته على ملف التكوين. إن رأيت عنوان بروتوكول إنترنت آخر (مثل 0.0.0.0) فتأكد من إلغاء تعليق السطر المطلوب وأعد تشغيل خدمة Redis مجددَا. الآن وبعد أن أصبح Redis مربوطا بالمضيف المحلي فقط سيصبح من الصعب على جهات الاختراق تقديم الطلبات أو الوصول إلى الخادم. مع ذلك لا يزال Redis غير معد لِطلب المصادقة من المستخدمين قبل القيام بأي تغيير على إعداداته أو البيانات التي يحتفظ بها. لمعالجة هذا، يتيح لك Redis طلب تأكيد هوية من المستخدمين باستخدام كلمة مرور قبل إحداث ي تغيير وذلك باستخدام الأمر (redis-cli). خطوة 4 - إعداد كلمة مرور Redis يتيح لك إعداد كلمة مرور Redis تفعيل إحدى ميزات الحماية المدمجة فيه — الأمر auth يطلب من المستخدمين إثبات الهوية للوصول إلى قاعدة البيانات. يتم تكوين كلمة المرور مباشرة في ملف تكوين Redis "/etc/redis/redis.conf", لذلك؛ افتح الملف مجددا باستخدام محرِّرك المفضل: $ sudo nano /etc/redis/redis.conf انتقل إلى جزء "SECURITY" وابحث عن السطر التالي: الملف ‎/etc/redis/redis.conf: # requirepass foobared ألغِ تعليق هذا السطر بِإزالة "#" وغير "foobared" إلى كلمة مرور أكثر أمانًا. ملاحظة: يوجد تحذير معلق فوق الموجه "requirepass" في ملف "redis.conf": # Warning: since Redis is pretty fast an outside user can try up to # 150k passwords per second against a good box. This means that you should # use a very strong password otherwise it will be very easy to break. # لذلك، من المهم تحديد كلمة مرور طويلة. يمكنك استخدام الأمر "openssl" ِلتوليد كلمة مرور تلقائيا بدلا من القيام بذلك يدويا كما في المثال التالي. وذلك بتمرير مخرجات الأمر الأول إلى أمر "openssl" الثاني. سيزيل الأمر أي أسطر فارغة تم توليدها من الأمر الأول: $ openssl rand 60 | openssl base64 -A ستكون المخرجات مشابهة لما يلي: RBOJ9cCNoGCKhlEBwQLHri1g+atWgn4Xn4HwNUbtzoVxAYxkiYBi7aufl4MILv1nxBqR4L6NNzI0X6cE بعد نسخ ولصق المخرجات لتكون هي القيمة الجديدة ل "requirepass": /etc/redis/redis.conf requirepass RBOJ9cCNoGCKhlEBwQLHri1g+atWgn4Xn4HwNUbtzoVxAYxkiYBi7aufl4MILv1nxBqR4L6NNzI0X6cE بعد إضافة كلمة المرور، احفظ وأغلق الملف ثم أعد تشغيل Redis: $ sudo systemctl restart redis.service لِاختبار من عمل كلمة المرور، أدخل إلى سطر أوامر Redis: $ redis-cli الأوامر التالية تستخدم لاختبار ما إن كانت كلمة المرور تعمل أم لا. يحاول الأمر الأول إضافة مفتاح إلى قيمة قبل المصادقة: 127.0.0.1:6379> set key1 10 لن يتنفذ الأمر لعدم المصادقة وسيرجع Redis خطأ: المخرجات: (error) NOAUTH Authentication required. يقوم الأمر التالي بالمصادقة باستخدام كلمة المرور المحددة في ملف التكوين: 127.0.0.1:6379> auth your_redis_password يُأكد Redis المصادقة: المخرجات: ok بعد ذلك، سينجح الأمر السابق: 127.0.0.1:6379> set key1 10 المخرجات: ok الأمر "get key1" يطلب من Redis قيمة المفتاح الجديدة. 127.0.0.1:6379> get key1 المخرجات: ok يمكنك إغلاق "redis-cli" بعد تأكدك من أنه يمكنك تنفيذ أوامر عميل Redis: 127.0.0.1:6379> quit لاحقا، ستتعلم كيفية إعادة تسمية أوامر Redis والتي إن تم إدخالها بالخطأ أو من خلال جهة غير مُخَوًّلًة سيسبب الكثير من الأضرار لجهازك. خطوة 5 - إعادة تسمية الأوامر المهمة تتضمن ميزة الحماية الأخرى المدمجة في Redis إعادة تسمية بعض الأوامر التي تعتبر خطرة أو إلغاء تفعيلها. يمكن أن تستخدم بعض هذه الأوامر بواسطة مستخدمون غير مخولين بالدخول لإعادة إعداد، أو تدمير أو حذف بياناتك. سيتم إعادة تسمية الأوامر بنفس الجزء الذي تم تعديل كلمة المرور منه "SECURITY" من ملف "/etc/redis/redis.conf" بعض الأوامر المهمة والتي قد تكون ذات خطورة هي: FLUSHDB FLUSHALL KEYS PEXPIRE DEL CONFIG SHUTDOWN BGREWRITEAOF BGSAVE SAVE SPOP SREM RENAME DEBUG هذه القائمة ليست شاملة، لكن إعادة تسمية أو تعطيل هذه القائمة يعتبر بداية جيدة لتعزيز أمان خادم Redis. يعتمد إعادة تسمية أو تعطيل الأوامر على احتياجك لها لموقعك. إن كنت تعلم أنك لن تستخدم أمرًا ما؛ فيمكنك تعطيله. أو إعادة تسميته إن ان ذات أهمية لك. افتح ملف تكوين Redis لتفعيل أو تعطيل أي أمر: $ sudo nano /etc/redis/redis.conf تحذير: توضح الخطوات التالية كيفية تعطيل أو إعادة تسمية كأمثلة. يجب أن تختار تعطيل أو إعادة تسمية الأوامر التي تريدها فقط. يمكنك مراجعة قائمة الأوامر كاملة ومعرفة كيف يمكن أن تستخدم بطريقة ضارة على redis.io/commands. لِتعطيل أمر ما، أعد تسميته إلى نص فارغ (يشار إلى النص الفارغ بِعلامتي تنصيص "") كما في الأسفل: الملف ‎/etc/redis/redis.conf: . . . # It is also possible to completely kill a command by renaming it into # an empty string: # rename-command FLUSHDB "" rename-command FLUSHALL "" rename-command DEBUG "" . . . لإعادة تسمية أمر ما، اعطه اسما آخر كما في المثال بالأسفل. يجب أن تكون الأسماء صعبة التخمين للآخرين ولكن سهلة بالنسبة لك كي تتذكرها لاحقًا: الملف ‎/etc/redis/redis.conf: . . . # rename-command CONFIG "" rename-command SHUTDOWN SHUTDOWN_MENOT rename-command CONFIG ASC12_CONFIG . . . احفظ التغييرات وأغلق الملف. أعد تشغيل Redis بعد إعادة تسمية الأمر لتطبيق التغييرات: $ sudo systemctl restart redis.service أدخل إلى سطر أوامر Redis لاختبار الأمر الجديد: $ redis-cli قم بالمصادقة: 127.0.0.1:6379> auth your_redis_password المخرجات: OK لنفترض أنك أعدت تسمية الأمر "CONFIG" إلى "ASC12_CONFIG" كما في المثال السابق. أولا حاول استخدام الأمر الأصلي "CONFIG". يجب أن يفشل تنفيذ الأمر لأنك أعدت تسميته: 127.0.0.1:6379> config get requirepass المخرجات: (error) ERR unknown command 'config' سينجح الأمر عند استخدام الاسم الجديد. لا يهم حالة الأحرف. 127.0.0.1:6379> asc12_config get requirepass المخرجات: 1) "requirepass" 2) "your_redis_password" وأخيرا يمكنك الخروج من "redis-cli". 127.0.0.1:6379> exit ملاحظة: عندما تُعيد تشغيل سطر أوامر Redis، سيطلب منك إعادة المصادقة أو سيظهر لك الخطأ التالي عند محاولتك لتنفيذ أمر ما: المخرجات: NOAUTH Authentication required. ملاحظة: بالنسبة لإعادة تسمية الأوامر؛ يوجد جملة تحذيرية في نهاية جزء SECURITY في الملف "‎/etc/redis/redis.conf" والتي تنص على: Please note that changing the name of commands that are logged into the AOF file or transmitted to slaves may cause problems. يعني هذا التحذير أن إعادة تسمية الأوامر المحفوظة في ملف AOF أو المنقولة في ملف فرعي قد يتسبب ببعض المشاكل. ملاحظة: يستخدم Redis المصطلحات “master” و “slave” بينما يفضل DigitalOcean استخدام البدائل “primary” و “secondary”. ولتجنب الخلط بين المصطلحات فإننا نستخدم المصطلحات التي يستخدمها Redis في ملفات التوثيق الخاصة به. يعني ذلك أنه إن كانت الأوامر التي تمت إعادة تسميتها ليست في ملف AOF أو إن كانت فيه لكن لم يتم نقلها إلى مجلد فرعي فلن يكون هناك أية مشاكل. لذلك يجب أن تتذكر هذا عند قيامك بإعادة تسمية أمر ما. أفضل وقت لإعادة تسمية الأوامر هو عند عدم استخدامك ل AOF أو بعد التثبيت مباشرة قبل استخدام Redis. عند استخدامك ل AOF وتعاملك مع التثبيت بنوع master-slave، خذ بعين الاعتبار هذه الإجابة من صفحة المشروع على GitHub: الإجابة: تُسجَّل الأوامر في AOF ثم تُكرر إلى المجلدات الفرعية بنفس الطريقة التي تم إرسالها، لذلك إن شغَّلت AOF على نسخة لا تحتوي الأوامر التي تمت إعادة اسميتها ستواجه بعض التعارضات ولن تنفذ بعض الأوامر. لذلك فإن أفضل طريقة لإعادة تسمية لأوامر في مثل هذه الحالة هي عبر التأكد من أن الأوامر التي تمت إعادة تسميتها مطبقة على جميع النسخ في طريقة التثبيت باستخدام master-slave. الخلاصة ختاما، في هذا المقال، لقد ثبتته وإعداد Redis، وتأكدت من صحة عمل Redis، واستخدمت ميزات الحماية المدمجة فيه والتي تقلل عدد الثغرات الممكنة للهجوم من قبل المخترقين. تذكر أنه بمجرد تسجيل أحدهم الدخول إلى الخادم، فمن السهل عليه التحايل على إعدادت حماية Redis التي قمنا بها. لذلك فإن أهم ميزة أمان على الخادم هي جدار الحماية (الذي أعددته إن كنت تابعت المقال السابق حول التهيئة الأولية لخادم أوبونتو 18.04) الذي يجعل الاختراق صعبًا جدًا. ترجمة -وبتصرف- للمقال How To Install and Secure Redis on Ubuntu 18.04 لصاحبه الكاتب Mark Drake.
  12. عند إنشاءك خادم أوبونتو 18.04 للمرة الأولى، يجب عليك اتخاذ بعض الخطوات كجزء من الإعدادات الأولية. سيزيد ذلك من أمان وسهولة استخدام الخادم، ويمنحك أساسًا قويًا لإجراءات لاحقة. ملاحظة: يشرح المقال أدناه الخطوات التي نوصي بها لإكمال تهيئة خادم أوبنتو 18.04 يدويا. اتباع هذه الاعدادات اليدوية سيساعدك في تعلم بعض المهارات الأساسية لإدارة الخادم وكتمرين لفهم الإجراءات التي تحدث في الخادم بصورة عامة. إن كنت تريد تهيئة الخادم وبدء استخدامة بسرعة، يمكنك استخدام نصنا البرمجي لتهيئة الخادم الأولي والذي ينفذ خطوات التهيئة تلقائيا. خطوة 1 - تسجيل الدخول كمستخدم مسؤول (root) تحتاج لمعرفة عنوان بروتوكول الإنترنت العام (public IP) للخادم الخاص بك لتسجيل الدخول. تحتاج أيضا إلى كلمة المرور، أو المفتاح السري لمستخدم مسؤول (ما يسمى ب root users) إن كنت قد ثبتت مفتاح SSH للمصادقة. إن لم تكن قد سجلت الدخول إلى الخادم الخاص بك، فيمكنك اتباع المقال حول كيفية الاتصال ب Droplet باستخدام SSH. قم بتسجيل الدخول إلى الخادم كمستخدم مسؤول root إن كنت غير متصلا حتى الآن باستخدام الأمر التالي. استبدل النص المظلل بعنوان بروتوكول الإنترنت العام للخادم الخاص بك. $ ssh root@your_server_ip في حال ظهور تحذير عن موثوقية المضيف قم بقبوله. إن كنت تقوم بالدخول باستخدام إثبات الهوية؛ قم بتقديم كلمة المرور. أما إن كنت تستخدم مفتاح SSH المحمي بعبارة مرور (passphrase)، سيُطلب منك إدخال عبارة المرور في بداية كل جلسة. قد يُطلب منك أيضا تغيير كلمة المرور للمستخدم المسؤول root في أول مرة تقوم بالتسجيل بها. عن المستخدم root المستخدم المسؤول root في بيئة لينكس هو المتحكم والذي يمتلك صلاحيات عديدة. ونظرا لهذه الصلاحيات فلا ينصح باستخدامه دائمًا وذلك لتجنب القيام بتغييرات عن طريق الخطأ. الخطوة التالية هي إعداد مستخدم بديل بصلاحيات أقل للعمل اليومي. كما سنشرح كيفية إضافة صلاحيات في أي وقت تحتاج إليها. خطوة 2 - إنشاء مستخدم جديد بعد تسجيل دخولك كمستخدم مسؤول root، فأنت جاهز لإضافة حساب مستخدم جديد لاستخدامه من الآن فصاعدا. الأمر التالي يقوم بإنشاء مستخدم بالاسم sammy، يمكنك تسمية المستخدم بأي اسم تريده. # adduser sammy ستُعرض عليك بعض الاسئلة بدأَ بكلمة مرور للحساب الجديد. يجب أن تقوم بإدخال كلمة مرور قوية. ومن ثم تعبئة باقي المعلومات والتي تعتبر اختيارية ويمكنك تجاوزها بالضغط على زر ENTER. خطوة 3 - منح صلاحيات إدارية يمتلك الحساب الذي قمنا بإنشائه صلاحيات اعتيادية. لكن قد نحتاج في بعض الأحيان إلى صلاحيات إدارية. لتجنب الخروج من هذا المستخدم والدخول إلى المستخدم المسؤول root بكثرة؛ يمكننا إعداد ما يسمى بصلاحيات المستخدم الأعلى أو صلاحيات مسؤول root لحساب المستخدم العادي، مما يتيح للمستخدم العادي تنفيذ الأوامر التي تحتاج إلى صلاحيات إدارية عن طريق استخدام الكلمة "sudo" قبل كل أمر. لإضافة هذه الصلاحيات للمستخدم الجديد، نحتاج لإضافة هذا المستخدم إلى مجموعة sudo. يمكن للمستخدمين ضمن مجموعة sudo في اوبنتو 18.14 استخدام الأمر sudo. نفِّذ الأمر التالي لإضافة المستخدم الجديد إلى مجموعة sudo، يجب أن تكون متصلا بالخادم باستخدام حساب مسؤول root (استخدم اسم المستخدم الذي أنشأته مسبقا). # usermod -aG sudo sammy الآن يمكنك الدخول باستخدام الحساب الجديد وتنفيذ الأوامر ذات الصلاحيات العليا عن طريق كتابة "sudo" قبل هذه الأوامر. خطوة 4 - إعداد جدار حماية رئيسي يمكن لخادم أوبونتو 18.04 استخدام جدار الحماية Uncomplicated Firewall) UFW) -جدار الحماية في نظام لينكس- للتأكد من عدم الاتصال سوى بخدمات معينة. يمكن إعداد جدار حماية رئيسي بسهولة باستخدام تطبيق UFW. ملاحظة: إن كان الخادم الخاص بك يعمل على DigitalOcean؛ فيمكنك استخدام DigitalOcean Cloud Firewalls بدلا من تطبيق UFW وذلك يعد اختياريا. يستحسن استخدام جدار حماية واحد فقط لتجنب أي تعارضات والتي قد تكون صعبة التصحيح. يمكن لمختلف التطبيقات تسجيل ملفات التعريف الخاصة بها مع UFW أثناء تثبيتها. تسمح هذه الملفات لتطبيق UFW بإدارة هذه التطبيقات وفقا لاسم التطبيق. لدى خدمة OpenSSH (Open Secure Shell) -أداة الاتصال الأولى لتسجيل الدخول عن بُعد باستخدام بروتوكول SSH- التي تتيح لنا الاتصال بالخادم ملف تعريف مسجل لدى UFW. لرؤية ذلك نستخدم الأمر: # ufw app list المخرجات: Available applications: OpenSSH يجب التأكد من أن جدار الحماية يسمح لاتصالات SSH حتى نتمكن من تسجيل الدخول مرة أخرى. يمكن القيام بذلك باستخدام الأمر: # ufw allow OpenSSH ثم يمكننا تفعيل جدار الحماية: # ufw enable قم بإدخال الحرف "y" وقم بالضغط على "ENTER" للمتابعة، للتأكد من أن اتصالات SSH ما زالت تعمل نفذ الأمر: # ufw status المخرجات Status: active To Action From -- ------ ---- OpenSSH ALLOW Anywhere OpenSSH (v6) ALLOW Anywhere (v6) في حال قمت بإعداد خدمات إضافية، قم بتعديل إعدادات جدار الحماية للسماح باتصالات هذه الخدمات؛ كون جدار الحماية يقوم بمنع الاتصالات عدا اتصالات SSH. يمكنك اتباع هذا المقال لتعلم بعض عمليات UFW الشهيرة. خطوة 5 - السماح بالوصول الخارجي للمستخدم الجديد بما أنه أصبح لدينا مستخدم جديد للاستخدام اليومي، سنحتاج للتأكد من أنه يمكننا الدخول إلى هذا المستخدم عبر SSH. ملاحظة: للتأكد من ذلك، يمكنك الدخول إلى المستخدم الجديد باستخدام كلمة المرور واستخدام sudo. يستحسن البقاء متصلا باسم المستخدم المسؤول root. بهذه الطريقة يمكنك تصحيح أي مشاكل وإضافة أي تعديلات تحتاجها. إن تستخدم واجهتك أي مشكلة في الاتصال بالمستخدم المسؤول root باستخدام SSH وكنت تستخدم DigitalOcean Droplet فيمكنك الدخول إلى Droplet باستخدام شاشة أوامر DigitalOcean. عملية إعداد وصول SSH لمستخدم الجديد تعتمد على ما إن كان حساب المستخدم المسؤول root يستخدم كلمة مرور أو مفتاح SSH للمصادقة. في حال كان المستخدم root يستخدم المصادقة بكلمة المرور إن كنت مسجلا دخولك إلى حساب المستخدم المسؤول root باستخدام كلمة مرور، فإن عملية المصادقة باستخدام كلمة المرور مفعلة ل SSH. مما يمكنك من إضافة SSH لحساب المستخدم الجديد عن طريق تنفيذ الأمر التالي مستخدما اسم المستخدم الذي انشأته سابقا: $ ssh sammy@your_server_ip بعد إدخال كلمة المرور الخاصة بالمستخدم الجديد؛ ستكون مسجلًا إلى النظام بالحساب الجديد ويمكنك تنفيذ الأوامر الإدارية من خلاله عن طريق إضافةsudoقبل الأمر: $ sudo command_to_run سيطلب منك النظام إدخال كلمة المرور الخاصة بالمستخدم الحالي لأول مرة من كل جلسة ومن ثم في بعض الأوقات فقط. لتعزيز أمان الخادم الخاص بك، يستحسن أن تقوم بإعداد مفاتيح SSH بدلا من استخدام كلمة المرور للمصادقة. يمكنك اتباع هذا المقال عن كيفية إعداد مفاتيح SSH على أوبنتو 18.04 لتتعرف على طريقة إعداد المصادقة المعتمده على المفاتيح السرية. في حال كان المستخدم المسؤول root يستخدم المصادقة بمفتاح SSH في حال كنت مسجلا الى حساب المسؤول root باستخدام مفاتيح SSH، فإن المصادقة باستخدام كلمة المرور ل SSH معطلة. للدخول إلى حساب المستخدم الجديد بنجاح، تحتاج لإضافة نسخة من المفتاح العام المحلي إلى الملف "‎~/.ssh/authorized_keys". يمكنك أيضا نسخ الملف "‎~/.ssh/authorized_keys" - والذي يحتوي على المفتاح العام الخاص بك- من حساب المسؤول root إلى الحساب الجديد باستخدام الجلسة الحالية. لنسخ الملف بطريقة سهلة وبالملكية والصلاحيات الصحيحة؛ نستخدم الأمر "rsync". سيقوم هذا الأمر بنسخ مجلد "‎.ssh" للمستخدم المسؤول root ،يحافظ على الصلاحيات ويقوم بتعديل ملكية الملفات في مرة واحدة. تأكد من وضع اسم المستخدم الجديد الذي أنشأته مسبقا. ملاحظة يتعامل الأمر "rsync" مع المجلدات التي تنتهي بشرطة مائلة "/" بطريقة مختلفة عن المجلدات التي لا تنتهي بشرطة مائلة. تأكد من أن أسماء المجلدات (‎~/.ssh) لا تنتهي بشرطة مائلة عند استخدام هذا الأمر"‎~/.ssh/‎". في حال أضفت شرطة مائلة في نهاية اسم المجلد عن طريق الخطأ في هذا الأمر، فسيقوم بنسخ محتويات المجلد من حساب المستخدم المسؤول root إلى المجلد الرئيسي لمستخدم "sudo" بدلا من نسخ الهيكل كاملا للمجلد "‎~/.ssh". وهكذا تكون الملفات في المكان الخاطئ ولن يتمكن SSH من العثور عليها واستخدامها. # rsync --archive --chown=sammy:sammy ~/.ssh /home/sammy الآن يمكنك استخدام SSH مع المستخدم الجديد عن طريق الأمر التالي في شاشة الأوامر: $ ssh sammy@your_server_ip يجب أن تقوم بالدخول إلى المستخدم الجديد بدون استخدام كلمة مرور. تذكر، لتنفيذ أمر باستخدام صلاحيات إدارية استخدم "sudo" قبل الأمر: $ sudo command_to_run ماذا بعد؟ الآن أصبح لديك إعدادات قوية للخادم الخاص بك. يمكنك تثبيت اي برنامج تحتاجه. اطلع على قسم لينكس في الأكاديمية لقراءة دليل آخر أو تعلم تثبيت برامج أخرى. ترجمة -وبتصرف- للمقال Initial Server Setup with Ubuntu 18.04 لصاحبه الكاتب Justin Ellingwood.
  13. حاوية لينكس (Linux container) هي تجميع لمجموعة من عمليات تكون منفصلة عن باقي النظام عبر استعمال الخصائص الأمنية لنواة لينكس مثل مجالات الأسماء (Namespaces) ومجموعات المراقبة (Control groups). وهي بنية مُشابهة للأجهزة الوهميّة (Virtual Machines)، إلا أنها أكثر خفّة، بحيث أنك لن تحتاج إلى تشغيل نواة إضافية أو محاكاة العتاد، ما يعني أنه بالإمكان إنشاء حاويات متعددة على نفس الخادوم. ويُمكنك باستعمال حاويات لينكس تشغيل وحدات متعددة لأنظمة تشغيل بأكملها، كلّها محجوزة بنفس الخادوم. أو تحزيم تطبيقاتك الخاصة والملفات التابعة لها في حاوية خاصة دون التأثير على باقي مكونات النظام. على سبيل المثال تخيّل أنك تملك خادوما وتريد تجهيز عدد من الخدمات، بما فيها المواقع اﻹلكترونية لعملائك. في النظام التقليدي، كل موقع إلكتروني سيكون عبارة عن مضيف وهمي (virtual host) من نفس خادوم Nginx أو Apache، لكن مع حاويات لينكس، كل موقع إلكتروني يتم إعداده في حاويته الخاصة مع خادوم ويب خاصّ به. ﻹنشاء وتسيير هذه الحاويات يمكن استعمال LXD الذي يوفر خدمة مراقبة الأجهزة الافتراضية hypervisor لتسيير دورة حياة الحاويات بأكملها. سنقوم في هذا الدرس بتنصيب موقعين إلكترونيين مبنيين على Nginx في نفس الخادوم. كل منهما محجوز في حاويته الخاصة، ثم سنقوم بتنصيب HAProxy ليعمل على شكل وسيط عكسي (reverse proxy) على حاوية ثالثة، ثم سنقوم بتوجيه الزوار إلى حاوية HAProxy لجعل كلا الموقعين قابلين للولوج من خلال شبكة الإنترنت. المتطلّبات لإتمام المطلوب نحتاج إلى ما يلي: خادوم Ubuntu 16.04 معد بإتباع الخطوات المتواجدة في هذا الدّرس ومستخدم إداري بامتيازات sudo غير المستخدم الجذر وجدار ناري. اسما نطاق مؤهلان بالكامل (FQDNs)، مع كل سجل DNS A موجه نحو عنوان IP الخاصّ بالخادوم، لتحقيق ذلك يمكن إتباع هذا الدرس. اختياريا، قم بإضافة 20 GB من تخزين الكتل (Block storage) عن طريق إتباع هذا الدرس الذي يُمكن استعماله لتخزين جميع البيانات المتعلقة بالحاويات. الخطوة الأولى - إضافة المستخدم إلى مجموعة LXD نسجل الدخول إلى الخادوم عن طريق حساب المستخدم غير الجذر الذي سيُستعمل لتأدية جميع مهام تسيير الحاوية، وليُنجِز ذلك يجب إضافة هذا الحساب إلى مجموعة lxd عن طريق الأمر التّالي: sudo usermod --append --groups lxd sammy أبدل sammy باسم المستخدم الخاصّ بك. نقوم بتسجيل الخروج من الخادوم ثم تسجيل الدخول إليه لتحديث جلسة SHH بعضوية المجموعة الجديدة، بعد ذلك، يمكن البدء بإعداد LXD. الخطوة الثانية - إعداد LXD يحتاج LXD إلى إعدادات معينة ليعمل بالشكل المطلوب قبل استعماله، نوع التخزين على مستوى الواجهة الخلفية هو أهم إعداد يجب علينا تحديده، لتخزين الحاويات، التخزين المقترح لـLXD هو استعمال ملف من نوع ZFS مُخزّن إما داخل ملف مخصص مسبقا أو عن طريق استعمال تخزين الكتل. لدعم ملفات ZFS في LXD، سنقوم بتنصيب حزمة zfsutils-linux: sudo apt-get update sudo apt-get install zfsutils-linux بعد ذلك سنكون مستعدين لتهيئة LXD، أثناء التهيئة سيُطلَبُ منك تخصيص تفاصيل تخزين ZFS على مستوى النظام الخلفي. هناك طريقتان لذلك اعتمادا على إذا ما كنا سنستعمل ملفا معدا مسبقا أو تخزين الكتل، بعد تحديد آلية التخزين سنقوم بإعداد اختيارات تواصل الحاويات الخاصة بنا. لكن قبل ذلك، سنتعرّف على خياري تهيئة التّخزين. الخيار الأول - استعمال ملف مخصص مسبقا اتبع الخطوات التالية لإعداد LXD لاستعمال ملف مخصص مسبقا لتخزين الحاويات. أولا نفّذ اﻷمر التالي لبدأ عملية تهيئة LXD: sudo lxd init سيُطلب منا اﻹدلاء بمجموعة من المعلومات كما يظهر في النتائج التالية، سنقوم باختيار الاختيارات الافتراضية بما في ذلك حجم الملف المقترح والمسمى جهاز الحلقة (loop device). المُخرجات: Name of the storage backend to use (dir or zfs) [default=zfs]: zfs Create a new ZFS pool (yes/no) [default=yes]? yes Name of the new ZFS pool [default=lxd]: lxd Would you like to use an existing block device (yes/no) [default=no]? no Size in GB of the new loop device (1GB minimum) [default=15]: 15 Would you like LXD to be available over the network (yes/no) [default=no]? no Do you want to configure the LXD bridge (yes/no) [default=yes]? yes Warning: Stopping lxd.service, but it can still be activated by: lxd.socket LXD has been successfully configured. يتم حساب الحجم المقترح تلقائيا بناء على المساحة المتاحة في الخادوم. بعد إعداد الجهاز، سنقوم بضبط إعدادات التشبيك، لكن قبل ذلك، لنتعرّف على الخيار الثاني. الخيار الثاني - استعمال تخزين الكتل إذا كنت تريد استعمال تخزين الكتل، ستحتاج إلى البحث عن الجهاز الذي يُشير نحو حجم تخزين الكتل (block storage volume) الذي تمّ إنشاؤه لتخصيصه في إعدادات LXD، سنذهب إلى تبويبة Volumes في لوحة التحكم الخاصّة بـDigitalOcean. ثم نقوم بتحديد مكان للمساحة ثم النقر على النافذة المنبثقة More، ثم انقر على Config instructions. نقوم بتحديد مكان الجهاز عن طريق النّظر إلى مُخرج أمر تشكيل الحجم، ابحث بشكل خاص عن المسار المخصّص في أمر sudo mkfs.ext4 -F. تمثل الوثيقة التالية مثالا على هذا الحجم: الذي يهمنا هو الجزء المسطر بالأحمر. في هذه الحالة اسم الحجم هو: /dev/disk/by-id/scsi-0D0_Volume_volume-fra1-01 يمكن لهذا الاسم أن يختلف في حالتك. بعد تعريف الحجم سنعود إلى الطرفية وسننفّذ الأمر التالي لبدء عملية تهيئة LXD: sudo lxd init سوف تُطرَح علينا مجموعة من اﻷسئلة، أجب عليها بالأجوبة المُوضّحة أسفله: Name of the storage backend to use (dir or zfs) [default=zfs]: zfs Create a new ZFS pool (yes/no) [default=yes]? yes Name of the new ZFS pool [default=lxd]: lxd إذا طُلب منك استخدام جهاز كتل جاهز آنفا فاختَر نعم (yes)، مع اﻹدلاء بمساره. Would you like to use an existing block device (yes/no) [default=no]? yes Path to the existing block device: /dev/disk/by-id/scsi-0DO_Volume_volume-fra1-01 ثم اختر القيم الافتراضية لباقي اﻷسئلة. Would you like LXD to be available over the network (yes/no) [default=no]? no Do you want to configure the LXD bridge (yes/no) [default=yes]? yes Warning: Stopping lxd.service, but it can still be activated by: lxd.socket LXD has been successfully configured. بعد انتهاء العملية، سنقوم بإعداد الشبكة. إعداد التشبيك (Networking) ستُظهِر لنا عمليّة التّهيئة مجموعة من شاشات التّعليمات كما هو موضّح في الصورة أسفله، ستمكّننا هذه التّعليمات من إعداد جسر التشبيك للحاويات حتى تتمكن من الحصول على عناوين IP خاصّة بها، وتتمكن من التواصل بينها والاتصال بشبكة الأنترنت. قم باستعمال جميع القيم الافتراضية باستثناء تشبيك IPv6، قم باختيار الخيار No في هذه الحالة. إذ لن نستعمله في هذا الدرس. بعد الانتهاء من إعداد التّشبيك، ستكون جاهزا لإنشاء الحاويات. الخطوة الثّالثة - إنشاء الحاويات قمنا بإعداد LXD بنجاح، إذ قمنا بتخصيص موقع للتخزين على مستوى الواجهة الخلفية وقمنا بإعداد التشبيك الافتراضي ﻷي حاويات منشأة حديثا. ما يعني بأنّنا جاهزون ﻹنشاء وتسيير بعض الحاويات، وذلك باستعمال الأمر lxc. أول أمر سنُجرّبه هو الأمر lxc list، والذي يُعطينا لائحة الحاويات المُنصّبة المتوفرة: lxc list المُخرجات: Generating a client certificate. This may take a minute... If this is your first time using LXD, you should also run: sudo lxd init To start your first container, try: lxc launch ubuntu:16.04 +------+-------+------+------+------+-----------+ | NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS | +------+-------+------+------+------+-----------+ ولأنها المرة اﻷولى التي يتواصل فيها أمر lxc مع مراقب الأجهزة الافتراضية (Hypervisor) الخاص بـLXD،فإن المخرج يخبرنا بأن اﻷمر قام بإنشاء شهادة عميل تلقائيا وذلك للتواصل اﻵمن مع LXD. بعد ذلك، يخبرنا بمعلومات حول كيفيّة إطلاق الحاويات، ثمّ يعرِض لائحة فارغة من الحاويات ﻷننا لم ننشئ أيا منها بعد. لنَقُم بإنشاء ثلاثة حاويات، واحدة لكل خادوم ويب والثالثة للوسيط العكسي، دور هذا اﻷخير هو توجيه الاتصالات الواردة من اﻷنترنت نحو الخادوم المناسب داخل الحاوية. نقوم باستعمال أمر lxc launch لإنشاء وتشغيل حاوية (ubuntu:x) Ubuntu 16.04 باسم web1. الحرف x في ubuntu:x هو اختصار لكلمة Xenial الاسم الرمزي لـUbuntu 16.04، أمّا ubuntu: فهو مُعرّف المجلد المضبوط مسبقا الخاص بصور LXD. ملاحظة: يمكنك الوصول إلى اللائحة الكاملة لصور Ubuntu المتاحة عن طريق الأمر lxc image list ubuntu:، ولتوزيعات أخرى استعمل اﻷمر lxc image list images:. نفّذ الأوامر التالية لإنشاء الحاويات: lxc launch ubuntu:x web1 lxc launch ubuntu:x web2 lxc launch ubuntu:x haproxy وبما أنها المرة اﻷولى التي ننشئُ فيها الحاويات، فسيقوم اﻷمر اﻷول بتنزيل صور الحاويات من اﻷنترنت وسيخزنها محليا، ستُنشَئُ الحاويّتان المتبقيّتان بشكل أسرع. لاحظ بيانات المخرج جرّاء إنشاء الحاوية web1: Creating web1 Retrieving image: 100% Starting web1 بعد أن قمنا بإنشاء ثلاثة حاويات فارغة سنقوم باستعمال الأمر lxc list ﻹظهار المعلومات حولها: lxc list يُظهِر المخرج جدولا باسم الحاوية وحالتها الحالية، عنوان IP الخاص بها، نوعها وما إذا تم أخد أية لقطات (snapshots) لها: +---------+---------+-----------------------+------+------------+-----------+ | NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS | +---------+---------+-----------------------+------+------------+-----------+ | haproxy | RUNNING | 10.10.10.10 (eth0) | | PERSISTENT | 0 | +---------+---------+-----------------------+------+------------+-----------+ | web1 | RUNNING | 10.10.10.100 (eth0) | | PERSISTENT | 0 | +---------+---------+-----------------------+------+------------+-----------+ | web2 | RUNNING | 10.10.10.200 (eth0) | | PERSISTENT | 0 | +---------+---------+-----------------------+------+------------+-----------+ سَجِّل أسماء الحاويات وعناوين IPv4 الخاصة بها لأننا سنحتاجها لإعداد الخدمات. الخطوة الرابعة - إعداد حاويات Nginx لنقم بالاتصال مع الحاوية web1 وإعداد الخادوم اﻷول، وللقيام بذلك نستعمل الأمر lxc exec الذي يأخذ اسم الحاوية والأوامر التي تريد تنفيذها. استعمل اﻷمر التالي للاتصال بالحاوية: lxc exec web1 -- sudo --login --user ubuntu يَدُلّ المقطع -- على أنّ العوامل التي ستُمرَّرُ للأمر lxc ستنتهي وسيتم تمرير باقي السطر على شكل أوامر للتنفيذ داخل الحاوية، اﻷمر الذي سيُمرَّرُ في هذه الحالة هو sudo --login --user ubuntu والذي يوفر صدفة ولوج (login shell) للحساب ubuntu المعد مسبقا داخل الحاويّة. ملاحظة: إذا كنت تريد الاتصال بالحاوية بصلاحيات حساب الجذر، فقم باستعمال اﻷمر lxc exec web1 -- /bin/bash عوضا عمّا سبق. فور الدخول إلى الحاويّة، سيظهر لنا محثّ الصدفة على الشكل التالي: ubuntu@web1:~$ المُستخدم ubuntu هذا معد مسبقا بصلاحيات sudo داخل الحاوية ويستطيع إصدار أوامر sudo دون الحاجة إلى اﻹدلاء بكلمة المرور. هذه الصدفة محدودة داخل حدود الحاوية. أي أنّ أيّ أمر نُشغله داخل هذه الصدفة يبقى داخل الحاوية ولا يخرج إلى الخادوم المُضيف. لِنحدّث لائحة حزم Ubuntu داخل الحاوية ولنُنصِّب Nginx: sudo apt-get update sudo apt-get install nginx لنعدل صفحة الويب الافتراضية لهذا الموقع ولنُضِف نصّا يوضح أن هذا الموقع مستضاف على الحاوية web1. افتح الملف /var/www/html/index.nginx-debian.html: sudo nano /var/www/html/index.nginx-debian.html قم بالتعديلات التالية للملف: <!DOCTYPE html> <html> <head> <title>Welcome to nginx on LXD container web1!</title> <style> body { width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; } </style> </head> <body> <h1>Welcome to nginx on LXD container web1!</h1> <p>If you see this page, the nginx web server is successfully installed and working. Further configuration is required.</p> ... قمنا بتعديل الملف في مكانين العنوان <title> والوسم <h1> وذلك بإضافة المقطع on LXD container web1. أغلق المحرر بعد الحفظ. واﻵن، سجّل الخروج من الحاوية لنَعودَ إلى الخادوم المُضيف: logout سنُكرر نفس اﻷمر بالنسبة لحاويّة web2، نسجل الدخول نُنصّب Nginx ثمّ نعدّل الملفّ /var/www/html/index.nginx-debian.html لذِكرِ web2، ثم نخرج من الحاويّة web2. لنستعمل curl للتأكد من أن الخواديم داخل الحاويات تعمل بشكل جيد. نحتاج إلى عناوين IP الخاصّة بالحاويات، والتي حصلنا عليها سابقا. curl http://10.10.10.100/ يجب على المُخرج أن يكون كما يلي: <!DOCTYPE html> <html> <head> <title>Welcome to nginx on LXD container web1!</title> <style> body { width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; } </style> </head> <body> <h1>Welcome to nginx on LXD container web1!</h1> <p>If you see this page, the nginx web server is successfully installed and working. Further configuration is required.</p> ... تفقّد الحاوية الثانية كذلك باستعمال الأمر curl وعنوان IP الخاصّ بها للتّأكد من أنّها قد ضُبطت بالشكل الصحيح، يمكن المرور إلى ضبط HAProxy بعد ذلك. الخطوة الخامسة - إعداد حاوية HAProxy سنقوم بإعداد حاوية HAProxy لتعمل كوسيط أمام هاتين الحاويتين. ولمزيد من المعلومات حول طريقة عمل HAProxy يمكنك الرجوع إلى هذا الدرس. سنقوم بتوجيه حركة المرور نحو كل حاوية بناءا على اسم النطاق الذي نستعمله، سوف نستعمل اسم النطاق example.com في مثال الإعدادات الموالي، وهو نطاق خاص للتوثيقات التعليمية مثل هذا الدرس، سنقوم بإنشاء أول موقع إلكتروني متاح على اسمي النطاق example.com و www.example.com. الموقع اﻹلكتروني الثاني سيكون على اسم النّطاق www2.example.com. أبدِل أسماء النطاقات الخاصة بك مكان هذه اﻷسماء. سجل الدخول إلى حاوية haproxy: lxc exec haproxy -- sudo --login --user ubuntu حدّث لائحة الحزم ونصِّب HAProxy: sudo apt-get update sudo apt-get install haproxy بعد انتهاء التنصيب سننتقل إلى إعداد HAProxy. ملف إعدادات HAProxy مُتواجد في المسار ‎/etc/haproxy/haproxy.cfg. افتح هذا الملف بواسطة محرر النصوص المُفضّل لديك: sudo nano /etc/haproxy/haproxy.cfg أولا سنقوم ببعض التعديلات في قسم defaults. سنقوم بإضافة خيار forwardfor لكي نحتفظ بعنوان IP المصدري لعميل الويب، وسنضيف الخيار http-server-close، والذي سيقوم بتمكين إعادة استخدام الجلسة (session reuse) وتخفيض زمن الوصول (Latency). global ... defaults log global mode http option httplog option dontlognull option forwardfor option http-server-close timeout connect 5000 timeout client 50000 timeout server 50000 ... سنقوم بعد ذلك بإعداد الواجهة اﻷمامية للإشارة نحو حاويتي الواجهة الخلفية الخاصة بنا. أضف قسم frontend تحت اسم www_frontend كما يلي: frontend www_frontend bind *:80 # Bind to port 80 (www) on the container # It matches if the HTTP Host: field mentions any of the hostnames (after the '-i'). acl host_web1 hdr(host) -i example.com www.example.com acl host_web2 hdr(host) -i web2.example.com # Redirect the connection to the proper server cluster, depending on the match. use_backend web1_cluster if host_web1 use_backend web2_cluster if host_web2 توافق أوامر acl أسماء مُضيفات خواديم الويب ثم تقوم بإعادة توجيه الطلب إلى قسم backend المناسب. ثم نعرف قسمي backend جديدين واحد لكل خادوم ويب، ثم نقوم بتسميتهما web1_cluster وweb2_cluster تباعا. أضف الشفرة التالية للملف لتعريف الواجهات الخلفية: backend web1_cluster balance leastconn # We set the X-Client-IP HTTP header. This is useful if we want the web server to know the real client IP. http-request set-header X-Client-IP %[src] # This backend, named here "web1", directs to container "web1.lxd" (hostname). server web1 web1.lxd:80 check backend web2_cluster balance leastconn http-request set-header X-Client-IP %[src] server web2 web2.lxd:80 check يحدّد خيار balance استراتيجية موازنة الحمل (load-balancing). في هذه الحالة، نُفضّل اقل عدد من الاتصالات. خيار http-request يضبط ترويسة HTTP (HTTP header) مع عنوان IP الخاصّ بعميل الويب الحقيقي، إذا لم نحدد هذه الترويسة فإن خادوم الويب سيسجل عنوان HAProxy IP على انه العنوان المصدري لجميع الاتصالات مما سيصعب تحليل أماكن و أصول حركة المرور. يُخصّص خيار server اسما كيفيا (arbitrary name) للخادوم web1 متبوعا باسم المُضيف ومنفذ الخادوم. يُزوّد LXD الحاويات بخادوم DNS، وذلك لكي يُشير web1.lxd إلى عنوان IP التّابع للحاوية web1. الحاويات اﻷخرى لها أسماء مُضيفات خاصة بها مثل web2.lxd وhaproxy.lxd. يدفع المُعامل check HAProxy إلى أداء فحوصات السلامة (Health checks) على الخادوم للتأكد من توفره. لاختبار صحة اﻹعدادات، نفّذ اﻷمر التالي: /usr/sbin/haproxy -f /etc/haproxy/haproxy.cfg -c ينبغي على المخرج أن يكون كما يلي: Configuration file is valid لِنُعد تحميل Haproxy لكي يقرأ اﻹعدادات الجديدة: sudo systemctl reload haproxy والآن سجل الخروج من الحاوية للعودة إلى المُضيف: logout قمنا بتجهيز Haproxy ليتصرف على شكل وسيط عكسي يوجّه أي اتصال يتلقاه عبر المنفذ رقم 80 نحو الخادوم الملائِم داخل كلا الحاويتين. لنتحقق من أن haproxy يستطيع فعلا تحويل الطلبات نحو الحاوية الصحيحة. ولذلك نستعمل اﻷمر التّالي: curl --verbose --header 'Host: web2.example.com' http://10.10.10.10 يُرسل الأمر أعلاه طلبا لـHAProxy ويضبط ترويسة HTTP باسم host والتي سيستعملها HAProxy لتوجيه الاتصال نحو الخادوم الملائم. يجب على المخرج أن يكون كالتالي: ... > GET / HTTP/1.1 > Host: web2.example.com > User-Agent: curl/7.47.0 > Accept: */* > ... < <!DOCTYPE html> <html> <head> <title>Welcome to nginx on LXD container web2!</title> <style> ... تمكن Hproxy من فهم الطلب وتوجيهه نحو الحاوية web2 بنجاح. ومنه فإن الخادوم قدم لنا الصّفحة الرّئيسيّة الافتراضيّة التي قمنا بتعديلها سابقا وأظهر النص on LXD container web2. لنقم الآن بتوجيه الطلبات الخارجية إلى HAProxy حتى يتمكن بقية العالم من الولوج إلى مواقعنا الإلكترونية. الخطوة السادسة - توجيه الاتصالات الواردة نحو حاوية HAProxy القطعة اﻷخيرة من اﻷحجية هي توصيل الوسيط العكسي مع شبكة اﻷنترنت. نحتاج إلي ضبط الخادوم لتوجيه أي اتصال وارد إليه من اﻷنترنت عبر المنفذ 80 نحو حاوية HAProxy. نُصِّبَ HAProxy في حاوية خاصّة به، وبالتالي، فإنه غير قابل للولوج من اﻷنترنت افتراضيا ولحل هذه المشكلة، سنقوم بإنشاء قاعدة iptables لتوجيه الاتصالات. يحتاج اﻷمر iptables إلى عنواني IP، عنوان الخادوم العمومي (your_server_ip) وعنوان IP الخاصّ بالحاويّة haproxy (أي your_haproxy_ip أسفله)، والذي نحصل عليه من خلال اﻷمر lxc list. نفّذ هذا اﻷمر ﻹنشاء القاعدة: sudo iptables -t nat -I PREROUTING -i eth0 -p TCP -d your_server_ip/32 --dport 80 -j DNAT --to-destination your_haproxy_ip:80 وهذا شرح لتفاصيل هذا اﻷمر: المقطع -t nat يعني بأننا نستعمل الجدول nat. المقطع -I PREROUTING يعني أننا نضيف القاعدة إلى سلسلة التوجيه المسبَق (PREROUTING). المقطع -i eth0 يعني أن الواجهة eth0 هي التي ستُستَعمَل، وهي الواجهة العمومية الافتراضية على الخواديم. المقطع -p TCP يعني أننا نستعمل بروتوكول TCP. المقطع -d your_server_ip/32 يحدد عنوان IP الهدف للقاعدة. المقطع --dport 80 يُحدّد رقم المنفذ الهدف. المقطع -j DNAT يعني أننا نريد أن نؤدي قفزة نحو الهدف NAT (DNAT). المقطع --to-destination your_haproxy_ip:80 يدلّ على أننا نريد من الطلب الذهاب إلى عنوان IP الخاصّ بالحاوية من طريق HAProxy. للمزيد من المعلومات حول IPTables، تفقّد الدّرس ما هو الجدار الناري وكيف يعمل؟ والدّرس أساسيات IPTables - قواعد وأوامر شائعة للجدار الناري . أخيرا لحفظ أمر iptables لكي يُعاد تطبيقُه بعد إعادة التشغيل نقوم بتنصيب حزمة iptables-persistent: sudo apt-get install iptables-persistent أثناء تنصيب الحزم سيطلب منك حفظ قواعد iptables الحاليّة. وافق واحفظ جميع قواعد iptables الحاليّة. إذا قمت بإعداد اسمي نطاق FQDN، فسيمكنك أن تتصل بكل من الموقعين باستعمال متصفحك. لذا جرب ذلك. للتحقق من أن الخادومين يمكن الولوج لهما عن طريق اﻷنترنت، ادخل إلى كل منهما باستعمال حاسوبك المحلي عن طريق أمر curl بالشكل التالي: curl --verbose --header 'Host: example.com' 'http://your_server_ip' curl --verbose --header 'Host: web2.example.com' 'http://your_server_ip' هذه اﻷوامر تقوم باتصالات HTTP مع عنوان IP العمومي الخاصّ بالخادوم وتضيف حقل ترويسة HTTP مع خيار --header والذي سيستعمله HAProxy لتنفيذ الطلب كما فعلنا في الخطوة الخامسة. هذا هو المخرج بالنسبة لأمر curl الأول: * Trying your_server_ip... * Connected to your_server_ip (your_server_ip) port 80 (#0) > GET / HTTP/1.1 > Host: example.com > User-Agent: curl/7.47.0 > Accept: */* > < HTTP/1.1 200 OK < Server: nginx/1.10.0 (Ubuntu) ... <!DOCTYPE html> <html> <head> <title>Welcome to nginx on LXD container web1!</title> <style> body { ... وهذا هو مٌخرج الأمر الثّاني: * Trying your_server_ip... * Connected to your_server_ip (your_server_ip) port 80 (#0) > GET / HTTP/1.1 > Host: web2.example.com > User-Agent: curl/7.47.0 > Accept: */* > < HTTP/1.1 200 OK < Server: nginx/1.10.0 (Ubuntu) ... <!DOCTYPE html> <html> <head> <title>Welcome to nginx on LXD container web2!</title> <style> body { ... تم إظهار الموقع الصحيح في كلتا الحالتين. خاتمة قمت الآن بضبط موقعي ويب كل منهما داخل حاويته الخاصة مع HAProxy كموجه للمرور، يمكنك تكرار نفس العملية ﻹعداد مواقع ويب أخرى كل داخل حاويته الخاصة، يمكن كذلك إضافة MySQL في حاوية جديدة وتنصيب نظام إدارة محتوى مثل Wordpress لتسيير كل موقع ويب على حدة. يمكنك كذلك استعمال هذه العملية لدعم نُسخِِ أقدم من برمجية معينة، على سبيل المثال، إن كان نظام إدارة محتوى يتطلب برمجية قديمة مثل PHP5 فبإمكانك تنصيب Ubuntu 14.04 على حاوية (lxc launch ubuntu:t) عوضا عن محاولة تخفيض إصدارات مدير الحزم المتوفرة على Ubuntu 16.04. يوفر LXD القدرة على أخذ لقطات للحالة الكاملة للحاويات، ما يجعل إنشاء النسخ الاحتياطية وإرجاع الحاويات إلى الوراء في وقت لاحق أمرا سهلا. إضافة إلى ما سبق فتنصيب LXD على خادومين مختلفين يمكّن من الربط بينهما وتهجير الحاويات بين الخواديم عبر الإنترنت. ترجمة -بتصرّف- للمقال How to Host Multiple Web Sites with Nginx and HAProxy Using LXD on Ubuntu 16.04 لصاحبه Simos Xenitellis.
  14. ProxySQL هو عبارة عن خادم وكيل (proxy server) مفتوح المصدر لخادم قاعدة البيانات MySQL، أي أنه يعمل كوسيط بين خادم قاعدة البيانات MySQL والتطبيقات التي تتعامل مع قاعدة البيانات هذه. حيث يقوم الخادم الوكيل بتحسين الأداء، وذلك عن طريق توزيع النقل بين خوادم قاعدة البيانات مشتركة. كما يحسّن من عملية توفّر قاعدة البيانات، وذلك من خلال الانتقال الآلي إلى خادم أخر متاح عند فشل أحد خوادم قاعدة البيانات. سيتم في هذه المقالة شرح طريقة تنصيب الخادم الوكيل ProxySQL كموازن تحميل (load balancer، توزيع الحمل) لعدة خوادم بيانات MySQL مع تمكين الانتقال الآلي إلى الخوادم المتاحة عند فشل أحدها. حيث سيتم استخدام مجموعة التناسخ المتماثل Group Replication ذات العُقد الرئيسية المتعددة multi-primary مكونة من ثلاث خوادم MySQL، غير أنه يمكن تطبيق الشرح الوارد في هذه المقالة على أي عدد من الخوادم. المتطلبات قبل البدء يجب أن يتوفر ما يلي: خادم أوبنتو 16.04 يتضمن على حساب مستخدم عادي (غير جزر) بصلاحيات sudo وجدار حماية. ثلاث خوادم بيانات MySQL مهيّأة للعمل كمجموعة تناسخ متماثل، والتي يمكن إعدادها اعتمادًا على هذه المقالة، الفقرة multi-primary. الخطوة الأولى- تنصيب ProxySQL قام مطورو ProxySQL بتوفير حزم أوبنتو رسمية لكل إصدارات ProxySQL، وذلك على صفحتهم في موقع GitHub، لذا سنقوم بتحميل أخر إصدار ProxySQL من هذه الصفحة، حيث تتضمن هذه الصفحة على لائحة بجميع إصدارات ProxySQL، وكل إصدار تَمّت تسميته وفق الصيغة proxysql_version-distribution.deb، إذ version هي عبارة عن رقم إصدار حزمة ProxySQL مثل 1.4.4، و distribution هي عبارة عن توزيعة لينكس المخصصة لها هذه الحزمة مثل ubuntu16_amd64. سنقوم الآن بتحميل أخر إصدار من حزمة ProxySQL (1.4.4 هو آخر إصدار لحظة كتابة هذه المقالة) إلى المسار ‎/tmp، وذلك بتنفيذ الأوامر التالية في موجه أوامر لينكس: $ cd /tmp $ curl -OL https://github.com/sysown/proxysql/releases/download/v1.4.4/ proxysql_1.4.4-ubuntu16_amd64.deb ثم نقوم بعد انتهاء عملية التحميل، بتنصيب هذه الحزمة باستخدام أداة إدارة حزم ‎.deb البرمجية dpkg، وذلك بتنفيذ الأوامر التالية في موجه أوامر لينكس: $ sudo dpkg -i proxysql_* حيث استُخدمت الراية ‎-i للدلالة على رغبتنا بتنصيب الحزمة من ملف محدد. ثم نقوم بعد انتهاء عملية التنصيب بحذف ملف الحزمة المُحمّل لعدم الحاجة إليه بعد الآن، وذلك بتنفيذ الأمر التالي: $ rm proxysql_* نحتاج الآن لتطبيق عميل لقاعدة البيانات MySQL ليتصل مع نسخة ProxySQL المُنصّبة، ذلك لأن ProxySQL يستخدم واجهة تخاطب متوافقة مع MySQL من أجل مهام الإدارة. لذا سنستخدم موجه أوامر MySQL، والذي هو جزء من الحزمة mysql-client المتوفرة على مخازن حزم أوبنتو. لكن قبل البدء بتنصيب هذه الحزمة يجب أن نحدّث مستودع الحزم لضمان تحميل وتنصيب آخر إصدار من هذه الحزمة، وذلك بتنفيذ الأمر التالي: $ sudo apt-get update ثم نقوم بتنصيب الحزمة mysql-client، وذلك بتنفيذ الأمر التالي: $ sudo apt-get install mysql-client أصبح لدينا الآن جميع متطلبات تشغيل ProxySQL، غير أن هذه الخدمة لا تُشَّغل آليًا بعد التنصيب، لذا يتوجب علينا تشغيلها يدويًا وذلك بتنفيذ الأمر التالي: $ sudo systemctl start proxysql سيعمل ProxySQL الآن بإعداداته الافتراضية، والتي يمكن عرضها بتنفيذ الأمر التالي: $ systemctl status proxysql فنحصل على الخرج التالي في نافذة موجه الأوامر: ● proxysql.service - LSB: High Performance Advanced Proxy for MySQL Loaded: loaded (/etc/init.d/proxysql; bad; vendor preset: enabled) Active: active (running) since Thu 2017-12-21 19:19:20 UTC; 5s ago Docs: man:systemd-sysv-generator(8) Process: 12350 ExecStart=/etc/init.d/proxysql start (code=exited، status=0/SUCCESS) Tasks: 23 Memory: 30.9M CPU: 86ms CGroup: /system.slice/proxysql.service ├─12355 proxysql -c /etc/proxysql.cnf -D /var/lib/proxysql └─12356 proxysql -c /etc/proxysql.cnf -D /var/lib/proxysql حيث تدلّ العبارة active (running) على أن ProxySQL مُنصَّب وفي حالة عمل. في الخطوة التالية سنقوم بزيادة الأمان، وذلك بإعداد كلمة السر المستخدمة للدخول إلى الواجهة التخاطبية لإدارة ProxySQL. الخطوة الثانية- إعداد كلمة سر مدير ProxySQL يستخدم ProxySQL في أول مرة يتم تشغيله فيها بعد التنصيب ملف الإعدادات القادم مع الحزمة، وذلك من أجل التهيئة الابتدائية لجميع إعداداته بالقيم الافتراضية، إذ يقوم ProxySQL بعد عملية التهيئة هذه بحفظ هذه الإعدادات في قاعدة البيانات، والتي يمكن إدارتها وتعديلها عن طريق موجه أوامر MySQL. لذا يجب عند إعداد كلمة سر مدير ProxySQL الاتصال بقاعدة البيانات الخاصة بالإعدادات لتعديل الإعدادات الموافقة. لإعداد كلمة السر سنقوم في البداية بالدخول إلى الواجهة التخاطبية لإدارة ProxySQL، وذلك بتنفيذ الأمر التالي: $ mysql -u admin -p -h 127.0.0.1 -P 6032 --prompt='ProxySQLAdmin> ' ‎-u: يُستخدم هذا العلَم لتحديد اسم المستخدم الذي يريد القيام بالمهام الإدارية مثل تغيير الإعدادات، وبما أنه لم يتم بعد إضافة أي مستخدم، لذا تم استخدام اسم المستخدم الافتراضي admin. ‎-h: يُستخدم هذا العلَم لتحديد المضيف المُراد الاتصال به، وبما أننا نريد الاتصال بالواجهة التخاطبية لإدارة ProxySQL المحلي لذا استخدمنا المضيف المحلي 127.0.0.1. ‎-P: يُستخدم هذا العلَم لتحديد منفذ الاتصال بالواجهة التخاطبية لإدارة ProxySQL، حيث تَستخدم هذه الواجهة التخاطبية المنفذ 6032. ‎--prompt: وهو علَم اختياري لتغيير الموجِّه الافتراضي mysql>‎، حيث قمنا هنا بتغييره إلى ProxySQLAdmin>‎ لتوضيح أننا اتصلنا بالواجهة التخاطبية لإدارة ProxySQL، وذلك لتجنب الالتباس لاحقًا عند الاتصال أيضًا بخوادم قاعدة البيانات MySQL. عند تنفيذ الأمر السابق سيطلب منا موجه الأوامر إدخال كلمة سر الدخول إلى الواجهة التخاطبية لإدارة ProxySQL، وبما أننا لم نقم بإعدادها بعد، لذا سنُدخل كلمة السر الافتراضية admin. عند نجاح عملية الدخول إلى الواجهة التخاطبية لإدارة ProxySQL، يتغيّر موجه أوامر النظام إلى الموجه ProxySQLAdmin>‎ الخاص بالواجهة التخاطبية لإدارة ProxySQL كما يلي: ProxySQL administration console prompt Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 2 Server version: 5.5.30 (ProxySQL Admin Module) Copyright (c) 2000، 2017، Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. ProxySQLAdmin> ثم نقوم بتغيير كلمة السر مدير ProxySQL، وذلك بتنفيذ الأمر التالي في موجه أوامر الواجهة التخاطبية لإدارة ProxySQL: ProxySQLAdmin> UPDATE global_variables SET variable_value='admin:password' WHERE variable_name='admin-admin_credentials'; Output Query OK، 1 row affected (0.00 sec) حيث تمّ استخدام الأمر UPDATE من أجل تغيير كلمة السر password للحساب الإداري admin الموجودة في المتغير admin-admin_credentials ضمن قاعدة البيانات global_variables. طبعًا يجب استبدال password في الأمر السابق بكلمة سر قوية قبل تنفيذه. لا تدخل عملية تغيير كلمة السر حيِّز التنفيذ مباشرة، وذلك نتيجة بنية نظام الإعدادات الخاص بالخادم ProxySQL، والذي يتكون من ثلاث طبقات منفصلة هي: طبقة الذاكرة MEMORY: وهي عبارة عن قواعد بيانات الإعدادات المُحمّلة في الذاكرة والتي يتم التفاعل معها والتعديل عليها مباشرة من خلال موجه أوامر الواجهة التخاطبية لإدارة ProxySQL. طبقة وقت التشغيل RUNTIME: يَستعمل ProxySQL هذه الطبقة لتفعيل الإعدادات المعدَّلة ودخولها حيز التنفيذ مباشرة. طبقة القرص DISK: وهي عبارة عن قاعدة بيانات محفوظة على القرص الصلب والتي يتم فيها حفظ الإعدادات، حيث تُحمَّل هذه الإعدادات في طبقة الذاكرة عند إقلاع النظام، وبالتالي تضيع أي تعديلات تم إجرائها على هذه الإعدادات في طبقة وقت التشغيل، وذلك أثناء إعادة تشغيل النظام إن لم يتم حفظها في طبقة القرص. أي أن التعديلات التي قمنا بإجرائها على كلمة السر مازالت في طبقة الذاكرة، ولتدخل حيز التنفيذ يجب نقلها إلى طبقة وقت التشغيل، وذلك بتنفيذ الأمر التالي موجه أوامر الواجهة التخاطبية لإدارة ProxySQL: ProxySQLAdmin> LOAD ADMIN VARIABLES TO RUNTIME; ثم يجب القيام بحفظها في طبقة القرص كي نحافظ عليها بشكل دائم، وذلك بتنفيذ الأمر التالي موجه أوامر الواجهة التخاطبية لإدارة ProxySQL: ProxySQLAdmin> SAVE ADMIN VARIABLES TO DISK; حيث استُخدم الأمر ADMIN من أجل التعامل مع المتغيرات المتعلقة فقط بموجه أوامر الواجهة التخاطبية لإدارة ProxySQL. هذا ويستخدم ProxySQL أوامر مشابهة للتي يستخدمها خادم MySQL، في التعامل مع الأقسام الأخرى من الإعدادات، والتي سيتم استخدامها لاحقًا في هذه المقالة. الآن وبعد أن تم تنصيب ProxySQL وإعداد كلمة سر مدير النظام، سنقوم بإعداد ثلاث عُقد MySQL ليتمكن ProxySQL من مراقبتها. الخطوة الثالثة- إعداد المراقبة في MySQL يجب أن يكون ProxySQL قادرًا على الاتصال بعُقد MySQL ليتمكن من تقدير حالتها، ولتنفيذ ذلك يجب أن يكون قادرًا على الاتصال بكل خادم عن طريق مستخدم مخصص. لذا سنقوم بإعداد المستخدم الضروري في عُقد MySQL وتنصيب وظائف SQL إضافية، والتي تسمح لخادم ProxySQL بالاستعلام عن حالة مجموعة التناسخ المتماثل. وبما أن مجموعة التناسخ المتماثل قد تم إعدادها مسبقًا، لذا يجب أن تُطبَّق الخطوات التالية على عضو وحيد من المجموعة. نفتح نافذة موجه أوامر نظام لينكس ثانية، ثم نسجل الدخول إلى الخادم الذي يحوي أحد عُقد MySQL، وذلك بتنفيذ الأمر التالي: $ ssh sammy@your_mysql_server_ip_1 ثم نحمل ملف SQL الذي يحتوي على بعض الوظائف الضرورية لدعم عمل مجموعة التناسخ المتماثل الخاصة بالخادم الوكيل ProxySQL، وذلك بتنفيذ الأمر التالي في موجه الأوامر: $ curl -OL https://gist.github.com/lefred /77ddbde301c72535381ae7af9f968322/raw /5e40b03333a3c148b78aa348fd2cd5b5dbb36e4d/addition_to_sys.sql ملاحظة: إن هذه الملف مُوفَّر من قبل مطوري ProxySQL غير أنه موجود ضمن مخزن GitHub شخصي، مما يعني أنه قد يُحذف أو يصبح قديمًا. لكنه قد يُضاف في المستقبل لمخزن ProxySQL الرسمي على شكل ملف له إصدار. ولمزيد من المعلومات حول هذا الملف يمكن قراءة المقال التالي: native ProxySQL support for MySQL group replication. يمكن رؤية محتويات هذا الملف بتنفيذ الأمر التالي: $ less addition_to_sys.sql ثم نقوم بتنفيذ الأمر التالي على الملف، حيث سيطلب منا موجه أوامر MySQL إدخال كلمة السر المستخدم الجذر root: $ mysql -u root -p < addition_to_sys.sql في حال نجاح عملية تنفيذ الأمر السابق، فإنه لن يظهر أي خرج في نافذة موجه الأوامر. وتصبح جميع عُقد MySQL قادرة على تأمين الوظائف الضرورية لتمكين قدرة ProxySQL على معرفة حالة مجموعة التناسخ المتماثل. والآن نحتاج لإنشاء مستخدم مخصص ليستخدمه ProxySQL في مراقبة سلامة نسخ البيانات. لكن علينا في البداية الدخول إلى موجه أوامر MySQL والذي سيطلب منا مرة أخرى إدخال كلمة سر المستخدم الجزر root: $ mysql -u root -p نقوم الآن بإنشاء المستخدم المخصص والذي سنسميه monitor، وذلك بتنفيذ الأمر التالي في موجه أوامر MySQL بعد استبدال كلمة السر monitorpassword بأخرى قوية: (member1)mysql> CREATE USER 'monitor'@'%' IDENTIFIED BY 'monitorpassword'; ثم نقوم بمنح هذا المستخدم صلاحية الاستعلام عن حالة خوادم MySQL، وذلك بتنفيذ الأمر: (member1)mysql> GRANT SELECT on sys.* to 'monitor'@'%'; وأخيرًا نُطبِّق التعديلات لتصبح سارية المفعول، وذلك بتنفيذ الأمر التالي: (member1)mysql> FLUSH PRIVILEGES; وبما أننا نعمل ضمن مجموعة التناسخ المتماثل، فإن إضافة مستخدم مخصص لمراقبة حالة أحد عُقد المجموعة، سيُطبَّق على جميع العُقد الأخرى في المجموعة. سيتم في الخطوة التالية تزويد ProxySQL بمعلومات المستخدم المخصص للمراقبة، ليتمكن ProxySQL من الدخول إلى عُقد MySQL. الخطوة الرابعة- إعداد المراقبة في ProxySQL سنقوم بإعداد ProxySQL ليستخدم مستخدم جديد أثناء مراقبة عُقد MySQL، وذلك عن طريق تحديث قيمة المتغيّر الموافق. وذلك بشكل مشابه لطريقة إعداد كلمة سر مدير ProxySQL في الخطوة الثانية. ننتقل إلى موجه أوامر الواجهة التخاطبية لإدارة ProxySQL، ثم نحدّث قيمة المتغير mysql-monitor_username بقيم حساب المستخدم المخصص لمراقبة عُقد MySQL، وذلك بتنفيذ الأمر: ProxySQLAdmin> UPDATE global_variables SET variable_value='monitor' WHERE variable_name='mysql-moniter_username'; ولكي يأخذ هذا التحديث حيّز التنفيذ، يجب تطبيقه على طبقة وقت التشغيل ثم حفظه في طبقة القرص، وذلك بتنفيذ الأوامر التالية في موجه أوامر الواجهة التخاطبية لإدارة ProxySQL: ProxySQLAdmin> LOAD MYSQL VARIABLES TO RUNTIME; ProxySQLAdmin> SAVE MYSQL VARIABLES TO DISK; حيث استخدمنا الأمر MYSQL بدل ADMIN عند تحديث قيمة المتغير، لأننا نتعامل هنا مع متغيرات إعداد MySQL. وهكذا تم إعداد ProxySQL بحساب المستخدم المراقب، وسيتم في الخطوة التالية إضافة عُقد MySQL إلى ProxySQL. الخطوة الخامسة- إضافة عُقد MySQL إلى ProxySQL لجعل ProxySQL مدركاً لعُقد MySQL، يجب إخباره بطريقة توزُّع هذه العُقد في المجموعات المضيفة، والتي هي عبارة عن مجموعة محددة من العُقد. وتعرَّف كل مجموعة مضيفة برقم موجب مثل 1 أو 2. حيث تُستخدم المجموعات المضيفة من أجل توجيه استعلامات SQL المختلفة إلى مجموعات مختلفة من المضيفات عند قيام ProxySQL بتوجيه الاستعلامات. يتم في إعدادات التناسخ الثابتة تعيين المجموعات المضيفة بشكل اعتباطي، غير أن مجموعة التناسخ المتماثل الخاصة بالخادم ProxySQL تقوم آليًا بتقسيم جميع العُقد الموجودة فيها إلى أربع مجموعات مضيفة وذلك حسب حالتها كما يلي: مجموعة عُقد الكتابة: وهي عبارة عن مجموعة عُقد MySQL التي تقبل الاستعلامات الخاصة بتغيير البيانات. حيث يراعي ProxySQL المحافظة على العدد الأعظمي المعرَّف من العقد الرئيسية في هذه المجموعة. مجموعة عُقد الكتابة الاحتياطية: وهي كذلك الأمر مجموعة عُقد MySQL التي تقبل الاستعلامات الخاصة بتغيير البيانات، غير أنه لا يتم تعيينها كعقد كتابة إلا في حال فشل أحد عُقد مجموعة الكتابة. حيث يضع ProxySQL في هذه المجموعة العُقد الرئيسة المتبقية عند تجاوز عدد العُقد الرئيسية العدد الأعظمي المطلوب في مجموعة الكتابة. مجموعة عُقد القراءة: وهي مجموعة العُقد التي لا تقبل الاستعلامات الخاصة بتغيير البيانات، ويتم استخدمها فقط لقراءة البيانات. ولا يضع ProxySQL إلا العُقد الثانوية في هذه المجموعة. مجموعة العُقد المفصولة: وتتضمن هذه المجموعة على العُقد الرديئة من حيث الاتصال ونقل البيانات. إن المعرِّف الرقمي لكل مجموعة مضيفة لا يتم تحديده آليًا، لذا يجب إخبار ProxySQL بالمعرِّف الرقمي الذي سيتم استخدامه لكل مجموعة. سنستخدم في حالتنا هنا المعرِّف 1 لمجموعة العُقد المفصولة، و المعرِّف 2 لمجموعة عُقد الكتابة، والمعرِّف 3 لمجموعة عُقد القراءة، والمعرِّف 4 لمجموعة عُقد الكتابة الاحتياطية. ولتطبيق هذه المعرّفات، سنقوم بإنشاء صف بهذه المتغيرات (المجموعات المضيفة) وقيمها الموافقة (المعرّفات الرقمية) في جدول الإعدادات mysql_group_replication_hostgroups، وذلك بتنفيذ الأمر التالي في موجه أوامر الواجهة التخاطبية لإدارة ProxySQL: ProxySQLAdmin> LOAD INSERT INTO mysql_group_replication_hostgroups (writer_hostgroup، backup_writer_hostgroup، reader_hostgroup، offline_hostgroup، active، max_writers، writer_is_also_reader، max_transactions_behind) VALUES (2، 4، 3، 1، 1، 3، 1، 100); تم في الأمر السابق إعداد متغيرات إضافية ضمن صف هي: active: وهو المتغيّر الخاص بتمكين ProxySQL من مراقبة المجموعات المضيفة، حيث تم إسناده بالقيمة 1 (تمكين). max_writers: وهو المتغير الخاص بتحديد العدد الأعظمي من عُقد الكتابة، حيث تم إسناده بالقيمة 3 كون مجموعة التناسخ المتماثل الخاصة بنا من النوع multi-primary، أي قمنا بتعيين جميع العُقد الثلاثة كعُقد كتابة. writer_is_also_reader: يُستخدم لتفعيل القراءة في عُقد الكتابة. حيث تم إسناده بالقيمة 1 وذلك لإعلام ProxySQL باستخدام جميع عُقد القراءة كعُقد كتابة أيضًا. max_transactions_behind: يُستخدم لتحديد العدد الأعظمي من محاولات الاتصال قبل تصنيف العُقدة كعُقدة مفصولة. ملاحظة: بما أننا نستخدم في مثالنا هنا مجموعة التناسخ المتماثل ذات العُقد الرئيسية المتعددة والتي تستطيع جميع عُقدها الكتابة إلى قاعدة البيانات، لذا سوف نوازن تحميل جميع استعلامات SQL عبر مجموعة عُقد الكتابة. أما في الأنواع الأخرى من مجموعات التناسخ المتماثل، يقوم التقسيم بين عُقد الكتابة (الرئيسية) وعُقد القراءة (الثانوية)، بتوجيه استعلامات القراءة إلى مجوعات مضيفة مختلفة عن المجموعات المضيفة الخاصة باستعلامات الكتابة، غير أن ProxySQL لا يقوم بمعملية التوجيه هذه آليًا، لذا يجب في هذه الحالة إعداد توجيه الاستعلامات باستخدام القواعد. بما أن ProxySQL يعلم الآن طريقة توَّزع عُقد MySQL ضمن المجموعات المضيفة، لذا أصبح بمقدورنا الآن إضافة خوادم MySQL الموافقة لهذه العُقد إلى قائمة الخوادم المرتبطة بالخادم الوكيل ProxySQL. وذلك من خلال إدخال INSERT عنوان IP واسم المجموعة المضيفة الأولية لكل خادم إلى الجدول mysql_servers، والمتضمّن على لائحة بخوادم MySQL التي يستطيع ProxySQL التفاعل معها. وذلك بتنفيذ الأوامر التالية في موجه أوامر الواجهة التخاطبية لإدارة ProxySQL بعد استبدال عناوين IP الخوادم بالقيمة الحقيقية: ProxySQLAdmin> INSERT INTO mysql_servers(hostgroup_id، hostname، port) VALUES (2، '203.0.113.1'، 3306); ProxySQLAdmin> INSERT INTO mysql_servers(hostgroup_id، hostname، port) VALUES (2، '203.0.113.2'، 3306); ProxySQLAdmin> INSERT INTO mysql_servers(hostgroup_id، hostname، port) VALUES (2، '203.0.113.3'، 3306); حيث أُسنِدت القيمة 2 للمعامل hostgroup_id لجعل جميع هذه الخوادم عُقد كتابة، كما تمّ تعيين المنفذ 3306 لجميع خوادم MySQL. ولكي يأخذ هذا التحديث حيّز التنفيذ، يجب تطبيقه على طبقة وقت التشغيل ثم حفظه في طبقة القرص، وذلك بتنفيذ الأوامر التالية في موجه أوامر الواجهة التخاطبية لإدارة ProxySQL: ProxySQLAdmin> LOAD MYSQL VARIABLES TO RUNTIME; ProxySQLAdmin> SAVE MYSQL VARIABLES TO DISK; سيقوم ProxySQL الآن بتوزيع عُقد MySQL الخاصة بنا ضمن المجموعات المضيفة كما هو محدد. وللتأكد من ذلك سنقوم بالاستعلام SELECT عن الجدول runtim330e_mysql_servers والذي يعرض الحالة الآنية لقائمة خوادم MySQL المرتبطة بالخادم ProxySQL، وذلك بتنفيذ الأمر التالي: ProxySQLAdmin> LOAD MYSQL VARIABLES TO RUNTIME; Output +--------------+-------------+--------+ | hostgroup_id | hostname | status | +--------------+-------------+--------+ | 2 | 203.0.113.1 | ONLINE | | 2 | 203.0.113.2 | ONLINE | | 2 | 203.0.113.3 | ONLINE | | 3 | 203.0.113.1 | ONLINE | | 3 | 203.0.113.2 | ONLINE | | 3 | 203.0.113.3 | ONLINE | +--------------+-------------+--------+ 6 rows in set (0.01 sec) نلاحظ من الجدول أنه تم عرض جميع الخوادم في كل من المجموعة المضيفة ذات المعرِّف 2 والمجموعة المضيفة ذات المعرِّف 3، وهذا يدلّ على أن جميع الخوادم هي عُقد كتابة وقراءة في نفس الوقت. كما نلاحظ أن جميع الخوادم بحالة ONLINE أي أنها جميعها بحالة عمل. لكن قبل أن نتمكن من استعمالها، يجب علينا إعداد متطلبات ولوج المستخدم إلى قاعدة البيانات MySQL في كل عُقدة. الخطوة السادسة- إنشاء مستخدمي قاعدة البيانات MySQL يلعب ProxySQL دور موازن تحميل، حيث يقوم المستخدمون بالاتصال بالخادم ProxySQL والذي يقوم بدوره بتمرير هذا الاتصال إلى عُقدة MySQL المختارة. هذا ويتصل ProxySQL بكل عُقدة عن طريق متطلبات الولوج التي استخدمها المستخدم للدخول إلى ProxySQL. لنتمكن من الولوج إلى قواعد البيانات الكائنة في عُقد مجموعة التناسخ، نحتاج لإنشاء حساب مستخدم بنفس متطلبات الولوج الخاصة بالخادم ProxySQL ومنح هذا المستخدم الصلاحيات الضرورية. كما هو الحال في الخطوة الثالثة، يجب أن تُطبّق الخطوات التالية على عضو وحيد من مجموعة التناسخ المتماثل، حيث يمكننا اختيار أي عضو نريد. ننتقل إلى موجه أوامر MySQL، ثم نُنشئ مستخدم جديد اسمه playgrounduser وكلمة سره playgrounduser، وذلك بتنفيذ الأمر التالي: (member1)mysql> CREATE USER 'playgrounduser'@'%' IDENTIFIED BY 'playgroundpassword'; ثم نمنح هذا المستخدم صلاحيات الولوج الكاملة إلى قاعدة البيانات playground، وذلك بتنفيذ الأمر التالي في موجه أوامر MySQL: (member1)mysql> GRANT ALL PRIVILEGES on playground.* to 'playgrounduser'@'%'; ثم نُطبِّق التعديلات، وننهي موجه أوامر MySQL كما يلي: (member1)mysql> FLUSH PRIVILEGES; (member1)mysql> EXIT; للتأكّد من أنه تم إنشاء المستخدم بشكل صحيح، سنقوم باختبار قدرته على الولوج إلى قاعدة البيانات الكائنة في عُقدة MySQL بواسطة متطلبات الولوج التي تم إعدادها، وذلك بإعادة فتح موجه أوامر لينكس والدخول إلى موجه أوامر MySQL بحساب المستخدم الذي تم إنشائه، حيث سيطلب موجه الأوامر إدخال كلمة السر الخاصة بهذا المستخدم: $ mysql -u playgrounduser -p وبعد نجاح الدخول إلى موجه أوامر MySQL بحساب المستخدم playgrounduser، ننفذ استعلام تجريبي على قاعدة البيانات playground، وذلك كما يلي: (member1)mysql> SHOW TABLES FROM playground; Output +----------------------+ | Tables_in_playground | +----------------------+ | equipment | +----------------------+ 1 row in set (0.00 sec) فنلاحظ ظهور لائحة الجداول الموجودة في قاعدة البيانات، حيث تحوي على الجدول equipment الذي تم إنشائه سابقًا، مما يدل على أنه تم إنشاء المستخدم بشكل صحيح على عُقد MySQL. نستطيع الآن إنهاء موجه أوامر MySQL بتنفيذ الأمر EXIT، لكننا سنُبقي عليه متصلًا بالخادم لاستخدامه لاحقًا في تنفيذ اختبارات الخطوة الأخيرة. نحتاج الآن لإنشاء مستخدم موافق في خادم ProxySQL. الخطوة السابعة- إنشاء مستخدم ProxySQL إن آخر خطوة في الإعدادات هو سماح الاتصال بالخادم ProxySQL باستخدام حساب المستخدم playgrounduser، ومرور هذا الاتصال عبره إلى عُقد MySQL. لتحقيق ذلك نحتاج لإعداد المتغيرات الموجودة في الجدول mysql_users والتي تحتفظ بمعلومات حساب المستخدم. وذلك بإدخال اسم المستخدم (في حالتنا playgrounduser) وكلمة مروره ومعرِّف المجموعة المضيفة الافتراضية (في حالتنا المعرّف 2 الموافق لمجموعة الكتابة) في قاعدة بيانات الإعدادات، من خلال موجه أوامر الواجهة التخاطبية لإدارة ProxySQL: ProxySQLAdmin> INSERT INTO mysql_users(username، password، default_hostgroup) VALUES ('playgrounduser'، 'playgroundpassword'، 2); ولكي يأخذ هذا التحديث حيّز التنفيذ، يجب تطبيقه على طبقة وقت التشغيل ثم حفظه في طبقة القرص، وذلك بتنفيذ الأوامر التالية في موجه أوامر الواجهة التخاطبية لإدارة ProxySQL: ProxySQLAdmin> LOAD MYSQL VARIABLES TO RUNTIME; ProxySQLAdmin> SAVE MYSQL VARIABLES TO DISK; للتأكد من أننا قادرين على الاتصال بقاعدة بيانات عُقد MySQL باستخدام حساب المستخدم الذي تم إنشاؤه، سنقوم بفتح نافذة موجه أوامر لينكس أخرى ثم نتصل بخادم ProxySQL باستخدام قناة الاتصال SSH، مع إبقاء موجه أوامر الواجهة التخاطبية لإدارة ProxySQL لأننا سنحتاجه لاحقًا. $ ssh sammy@your_proxysql_server_ip_1 يتنصّت ProxySQL على المنفذ 6033 للاتصالات القادمة من العملاء، لذا سنحاول الاتصال بقاعدة البيانات الحقيقية (ليس بالواجهة الإدارية) باستخدام اسم المستخدم playgrounduser وكلمة مرورهplaygroundpassword (التي سيطلبها موجه الأوامر) والمنفذ 6033: $ mysql -u playgrounduser -p -h 127.0.0.1 -P 6033 --prompt='ProxySQLClient> ' حيث تم استبدال الموجه الافتراضي بالموجه ProxySQLClient>‎ وذلك من أجل تمييزه عن موجه الواجهة التخاطبية لإدارة ProxySQL، كونه سنستخدم كلاهما في الإعدادات النهائية. وعند نجاح عملية الاتصال سيظهر موجه الأوامر ProxySQLClient>‎ للدلالة على أن الخادم ProxySQL قد قبل حساب المستخدم playgrounduser: ProxySQL client prompt Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 31 Server version: 5.5.30 (ProxySQL) Copyright (c) 2000، 2017، Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help.Type '\c' to clear the current input statement. ProxySQLClient> سنقوم بتنفيذ تعبير برمجي بسيط للتأكد من أن الخادم ProxySQL سيتصل بأحد عُقد MySQL، حيث يقوم هذا التعبير البرمجي بالاستعلام في قاعدة البيانات عن اسم المضيف الذي يعمل عليه الخادم، وتكون نتيجة تنفيذ هذا التعبير عبارة عن خرج وحيد يتضمن على اسم مضيف الخادم: ProxySQLClient> SELECT @@hostname; Output +------------+ | @@hostname | +------------+ | member1 | +------------+ 1 row in set (0.00 sec) سيتم بناء على إعداداتنا توجيه الاستعلام من قبل الخادم ProxySQL إلى واحد من عُقد MySQL الثلاث المُسندة للمجموعة المضيفة الخاصة بالكتابة. وتكون نتيجة الاستعلام member1 والذي هو أحد مضيفات عُقد MySQL. وهكذا تم الانتهاء من الإعدادات التي تسمح بعمل ProxySQL كموازن تحميل للاتصالات بين عُقد MySQL. سنقوم في الخطوة الثامنة والأخيرة بالتحقق من قدرة ProxySQL على تنفيذ التعابير البرمجية الخاصة بالقراءة والكتابة في قاعدة البيانات حتى في حال فشل أحد العُقد. الخطوة الثامنة- التحقق من إعدادات ProxySQL لقد تحققنا سابقًا من أن الاتصال يعمل بشكل سليم بين ProxySQL وعُقد MySQL، لذا ستكون الاختبارات الأخيرة للتأكُّد من أن أذونات قاعدة البيانات تسمح بتنفيذ التعابير البرمجية الخاصة بالقراءة والكتابة القادمة من الخادم ProxySQL، والتأكُّد من أن هذه التعابير قابلة للتنفيذ حتى في حال فشل بعض عُقد المجموعة. سنقوم بتنفيذ تعبير القراءة SELECT في موجه أوامر عميل ProxySQL للتحقق من قدرتنا على قراءة البيانات من قاعدة البيانات playground، وذلك كما يلي: ProxySQLClient> SELECT * FROM playground.equipment; Output +----+--------+-------+--------+ | id | type | quant | color | +----+--------+-------+--------+ | 3 | slide | 2 | blue | | 10 | swing | 10 | yellow | | 17 | seesaw | 3 | green | +----+--------+-------+--------+ 3 rows in set (0.00 sec) نلاحظ أن خرج تنفيذ التعبير السابق عبارة عن جدول equipment يحوي على ثلاث مكونات، والذي تم إنشاؤه سابقاً في قاعدة البيانات playground، وهذا يدل على نجاح عملية القراءة من قاعدة بيانات MySQL عن طريق الخادم ProxySQL. والآن سنحاول الكتابة في قاعدة البيانات، وذلك بتنفيذ تعبير الكتابة INSERT لكتابة بيانات جديدة في الجدول equipment الموجود ضمن قاعدة البيانات playground، وذلك كما يلي: ProxySQLClient> INSERT INTO playground.equipment (type، quant، color) VALUES ("drill"، 5، "red"); وللتحقق من أنه تم كتابة البيانات السابقة في قاعدة البيانات playground، نعيد تنفيذ تعبير القراءة SELECT السابق كما يلي: ProxySQLClient> SELECT * FROM playground.equipment; Output +----+--------+-------+--------+ | id | type | quant | color | +----+--------+-------+--------+ | 3 | slide | 2 | blue | | 10 | swing | 10 | yellow | | 17 | seesaw | 3 | green | | 24 | drill | 5 | red | +----+--------+-------+--------+ 4 rows in set (0.00 sec) نلاحظ من الخرج ظهور مكون جديد في الجدول equipment الموجود في قاعدة البيانات، وهذا يدل على نجاح عملية الكتابة في قاعدة بيانات MySQL عن طريق الخادم ProxySQL. وهكذا تأكّدنا من قدرة الخادم ProxySQL على استخدام قاعدة البيانات بشكل كامل، لكن ماذا يحصل في حال فشل أحد خوادم MySQL. سنقوم الآن بمحاكاة فشل أحد خوادم MySQL، وذلك بإيقاف عملية mysql من موجه أوامر أحد خوادم MySQL كما يلي: $ systemctl stop mysql بعد توقف أحد خوادم MySQL، سنحاول ثانيةً الاستعلام عن البيانات الموجودة في الجدول equipment من موجه أوامر عميل ProxySQL كما يلي: ProxySQLClient> SELECT * FROM playground.equipment; فنلاحظ أن الخرج لم يتغير، وهذا يدل على أن ProxySQL لاحظ فشل أحد عُقد MySQL، وقام بالانتقال إلى عُقدة أخرى سليمة لتنفيذ عملية الاستعلام عن البيانات الموجودة في قاعدة بيانات MySQL. هذا ويمكننا التحقق من ذلك عن طريق الاستعلام عن الجدول runtime_mysql_servers من موجه أوامر الواجهة التخاطبية لإدارة ProxySQL، كما ورد في الخطوة الخامسة: ProxySQLAdmin> SELECT hostgroup_id، hostname، status FROM runtime_mysql_servers; Output +--------------+-------------+---------+ | hostgroup_id | hostname | status | +--------------+-------------+---------+ | 1 | 203.0.113.1 | SHUNNED | | 2 | 203.0.113.2 | ONLINE | | 2 | 203.0.113.3 | ONLINE | | 3 | 203.0.113.2 | ONLINE | | 3 | 203.0.113.3 | ONLINE | +--------------+-------------+---------+ 6 rows in set (0.01 sec) نلاحظ من الخرج أن عُقدة MySQL التي قمنا بإيقافها قد أصبحت SHUNNED، وهذا يعني أنها غير قابلة للوصول مؤقتًا، لذا سيتم توزيع كل النقل بين العُقدتين المتبقيتين بحالة عمل. سيقوم ProxySQL بمراقبة حالة العُقدة المتوقفة عن العمل بشكل مستمر، ويعيدها للحالة online في حال عادت للعمل، أو يعتبرها مفصولة offline في حال تجاوزت زمن الانتظار المحدد في الخطوة الخامسة (في المتغير max_transactions_behind). سنقوم الآن باختبار مراقبة ProxySQL لحالة عُقد MySQL، وذلك بإعادة تشغيل خادم MySQL المتوقّف، وبالتالي إعادة العُقدة المتوقّفة إلى العمل ثانيةً: $ systemctl start mysql ثم ننتظر قليلًا ونعيد الاستعلام عن الجدول runtime_mysql_servers من موجه أوامر الواجهة التخاطبية لإدارة ProxySQL: ProxySQLAdmin> SELECT hostgroup_id، hostname، status FROM runtime_mysql_servers; Output +--------------+-------------+--------+ | hostgroup_id | hostname | status | +--------------+-------------+--------+ | 2 | 203.0.113.1 | ONLINE | | 2 | 203.0.113.2 | ONLINE | | 2 | 203.0.113.3 | ONLINE | | 3 | 203.0.113.1 | ONLINE | | 3 | 203.0.113.2 | ONLINE | | 3 | 203.0.113.3 | ONLINE | +--------------+-------------+--------+ 6 rows in set (0.01 sec) نلاحظ من الخرج أن ProxySQL لاحظ فورًا عودة العُقدة للعمل، وقام بإعادة حالتها إلى ONLINE. يمكنك إعادة هذا الاختبار على عُقدة أخرى (أو اثنين منها)، والتحقق من أن وجود عُقدة واحدة على الأقل بحالة عمل، كافي لاستخدام قاعدة البيانات بحرية في عمليتي القراءة والكتابة. ملخص تم في هذه المقالة شرح طريقة إعداد الخادم الوكيل ProxySQL لموازنة تحميل استعلامات SQL عبر العديد من عُقد MySQL القادرة على الكتابة ضمن بنية مجموعة التناسخ المتماثل ذات العُقد الرئيسية المتعددة. حيث يساعد هذا النوع من الإعدادات على تحسين أداء قواعد البيانات الكثيرة الاستخدام، عن طريق توزيع الحمل عبر العديد من الخوادم، كما توفر قابلية الانتقال الآلي إلى الخوادم المتاحة عند فشل أحدها. لم يتم في هذه المقالة تغطية إلاّ البنية القائمة على عُقدة واحدة كمثال. إلا أن إمكانيات ProxySQL الجبارة في الحفاظ على الاستعلامات والتوجيه وتحليل الأداء تعمل كذلك الأمر على الكثير من البنى الأخرى. يمكنك الاضطلاع على المزيد حول ميزات ProxySQL وطريقة استخدامه في حل العديد من مشاكل إدارة قواعد البيانات في مدونة ProxySQL الرسمية. ترجمة المقال بتصرف للمقال How to Use ProxySQL as a Load Balancer for MySQL on Ubuntu 16.04 لصاحبته Mateusz Papiernik
  15. نشرح طريقة تثبيت Monit على نظام أوبنتو. وسنشرح كمثال كيفية إعداد Monit لمراقبة وإعادة تشغيل Nginx في حال توقفه. قسم DevOps في أكاديمية حسوب غني بالمقالات المفيدة للتعامل مع الخوادم.
  16. نشرح طريقة تثبيت وإعداد خادم Nginx على توزيعة أوبنتو، وسنستعمله لتخديم صفحات HTML الخاصة بنا. لتثبيت خادم أباتشي راجع فيديو تثبيت وضبط خادم Apache في أكاديمية حسوب. قسم خوادم الويب في أكاديمية حسوب غني بالمقالات المفيدة للتعامل معها.
  17. PostgreSQL، هو نظام متطور مفتوح المصدر، كائنيّ الارتباط-Object Relational ﻹدارة قواعد البيانات، وهو نظام قابل للتوسع، بمعنى أنه يستطيع معالجة اﻷحمال المختلفة بدءًا من تطبيقات جهاز واحد إلى خدمات الويب التجارية التي تتعامل مع مستخدمين كثر في نفس الوقت. وهذا النظام Transactional أي يعامل النقل المتسلسل للبيانات -مثل تحديث قاعدة البيانات- كوحدة واحدة لضمان سلامتها، ويحقق خصائص ACID (Atomicity – Consistency – Isolation – Durability). وكذلك يدعم قسمًا كبيرًا من معايير SQL. فائدة: خصائص ACID هي أربعة خصائص يجب توافرها في تعاملات قواعد البيانات، وهي الذرية-Atomicity -أن تُنفَّذ العملية كوحدة واحدة-، والتناسق-Consistency، والعزل-Isolation، والثبات-Durability. ويوفر PostgreSQL العديد من المزايا مثل: الاستعلامات المعقدة-Complex Queries المفاتيح الأجنبية-Foreign Keys المشاهدات القابلة للتحديث-Updatable Views سلامة عمليات نقل البيانات-Transactional Integrity التحكم في التزامن متعدد الإصدارات-Multiversion Concurrency Control وذكرنا قبل قليل أنه قابل للتمدد والتوسع بواسطة مستخدميه عبر إضافة دوال-Functions جديدة، ومشغّلات-operators، وأنواع بيانات، وطرق فهرسة، ولغات إجرائية-Procedural Languages. ويقدّم PostgreSQL طرقًا عديدة لتكرار قاعدة بيانات، وسنتعلم في هذا الدليل كيفية إعداد تكرار من نوع (الرئيسي-Master/الثانوي-Slave)، وهي عملية مزامنة بين قاعدتي بيانات من خلال النسخ من قاعدة بيانات على خادم (الرئيسي) إلى قاعدة بيانات أخرى في خادم آخر (الثانوي)، وسننفذ هذه العملية على خادم يعمل بتوزيعة أوبنتو 16.04. المتطلبات أن يكون PostgreSQL 9.6 مثبتًا على خادم أوبنتو 16.04 إعداد UFW ثبّت جدار الحماية الناري غير المعقّد-Uncomplicated Firewall على خوادم أوبنتو، وهو أداة ﻹدارة جدار الحماية المعتمِد على iptables. استخدم الأمر التالي في الطرفية: # apt-get install -y ufw واﻵن، أضف PostgreSQL وخدمة SSH إلى جدار الحماية، عبر تنفيذ اﻷمر التالي: # ufw allow ssh # ufw allow postgresql فعّل جدار الحماية: # ufw enable إعداد خادم PostgreSQL الرئيسي سيمتلك الخادم الرئيسي صلاحيات القراءة والكتابة لقاعدة البيانات، وسيكون هو القادر على نقل البيانات إلى الخادم الثانوي. • افتح محررًا نصيًا وعدّل إعدادات PostgreSQL الرئيسية كما يلي: (ملاحظة: استبدل EDITOR$ بالمحرر النصي الذي تفضّله) # $EDITOR /etc/postgresql/9.6/main/postgresql.conf أزل التعليق (#) من سطر listen_addresses وأضف عنوان IP للخادم الرئيسي: listen_addresses = 'master_server_IP_address' واﻵن، أزل التعليق من سطر wal_level لتغيير قيمته: wal_level = hot_standby وأزل التعليق من السطر التالي كي تستخدم المزامنة المحلية-Local Syncing لمستوى المزامنة "Synchronization Level" synchronous_commit = local ثم أزل التعليق من السطرين التاليين، وعدلهما كما يلي، بما أننا نستخدم خادمين: max_wal_senders = 2 wal_keep_segments = 10 واﻵن احفظ الملف وأغلقه. عدّل ملف pg_hba.conf من أجل إعدادات التوثيق-Authentication، كما يلي: افتح الملف عبر هذا الأمر: # $EDITOR /etc/postgresql/9.6/main/pg_hba.conf الصق الإعدادات التالية: # Localhost host replication replica 127.0.0.1/32 md5 # PostgreSQL Master IP address host replication replica master_IP_address/32 md5 # PostgreSQL SLave IP address host replication replica slave_IP_address/32 md5 احفظ الملف وأغلقه، ثم أعد تشغيل PostgreSQL باستخدام systemctl # systemctl restart postgresql إنشاء مستخدم من أجل التكرار سننشئ مستخدم PostgreSQL من أجل عملية التكرار، فسجّل الدخول أولًا إلى حساب المستخدم المسمّىpostgres وافتح صدفة PostgreSQL، من خلال الأوامر التالية: # su - postgres $ psql أنشئ مستخدمًا جديدًا: postgres=# CREATE USER replica REPLICATION LOGIN ENCRYPTED PASSWORD 'usr_strong_pwd'; أغلق الصَّدَفة، وهكذا تنتهي إعدادات الخادم الرئيسي. إعداد الخادم الثانوي لن تكون للخادم الثانوي صلاحيات الكتابة في قاعدة البيانات، وستكون وظيفته الوحيدة هي استقبال البيانات من الخادم الرئيسي، أي ستكون له صلاحية القراءة فقط. • سنوقف أولًا خدمة PostgreSQL: # systemctl stop postgresql افتح ملف الإعدادات الرئيسية لـ PostgreSQL: # $EDITOR /etc/postgresql/9.6/main/postgresql.conf أزل التعليق من سطر listen_addresses وغيّر قيمته: listen_addresses = 'slave_IP_address' أزل التعليق من سطر wal_level وغيّره كما يلي: wal_level = hot_standby وأزل التعليق أيضًا من سطر synchronous_commit كما في الخادم الرئيسي للاستفادة من المزامنة المحلية-local syncing: synchronous_commit = local ثم أزل التعليق من السطرين التاليين وغيّر قيمهما كما يلي: max_wal_senders = 2 wal_keep_segments = 10 أزل التعليق من السطر التالي وغيّر قيمته كما يلي من أجل تفعيل hot_standby للخادم الثانوي: hot_standby = on احفظ الملف وأغلقه. نسخ البيانات من الخادم الرئيسي إلى الثانوي لكي نزامن بيانات الخادم الرئيسي مع الثانوي، فيجب أن يحل المجلد الأساسي “main” في الخادم الرئيسي محل المجلد الرئيسي في الخادم الثانوي، ونفعل هذا كما يلي: • سجل الدخول إلى مستخدم postgres: # su – postgres خذ نسخة احتياطية من مجلد البيانات الفعلي: $ cd/var/lib/postgresql/9.6/ $ mv main main_bak أنشئ مجلد أساسيًا جديدًا: $ mkdir main/ غيّر صلاحياته: $ chmod 700 main وهنا، انسخ المجلد الأساسي من الخادم الرئيسي إلى الخادم الثانوي باستخدام pg_basebackup: # pg_basebackup -h master_IP_address -U replica -D /var/lib/postgresql/9.6/main /-P –xlog وحين ينتهي النسخ، أنشئ ملف recovery.conf داخل المجلد الأساسي "main” وانسخ المحتوى التالي فيه: standby_mode = 'on' primary_conninfo = 'host=10.0.15.10 port=5432 user=replica password=usr_strong_pwd' trigger_file = '/tmp/postgresql.trigger.5432' واﻵن، احفظ الملف وأغلقه، ثم غير صلاحياته كما يلي: # chmod 600 recovery.conf شغّل خدمة PostgreSQL: # systemctl start postgresql وهنا تنتهي إعدادات الخادم الثانوي. الخلاصة لقد رأينا في هذا الدليل المبسّط كيفية ضبط تكرار Master/Slave في PostgreSQL عبر استخدام خادمين يعملان بأوبنتو. وهذه الطريقة في التكرار ما هي إﻻ إحدى طرق عديدة يوفرها نظام PostgreSQL لإدارة قواعد البيانات. ترجمة -بتصرف- لمقال PostgreSQL Replication on Ubuntu Tutorial لصاحبه Giuseppe Molica
  18. نحن نبني أغلب أعمالنا على خوادم مبنية على Apache أو NGNIX، وربما حان الوقت لتجربة خادم ويب جديد بدأ يحصد شعبية بسبب بساطته، وهو خادم Caddy. وقد أُطلق هذا الخادم لأول مرة في 2015 مكتوبًابالكامل بلغة Go، وتعتمد تهيئته على caddyfile، وهي ملفات يسهل كتابتها وإدارتها كما سنرى في هذا المثال، وما حمّسنا له حقيقة هو أنه يتكامل مع Let’s Encrypt بشكل افتراضي ودون أي تهيئة يدوية. مزايا Caddy Automatic HTTPS مفعّلة افتراضيًا من خلال Let’s Encrypt. HTTP/2 افتراضيًا. Static Files في مجلد العمل الحالي. كل أنواع الخوادم، والموجّهات-directives، ومزودو DNS، ومزايا أخرى، كل ذلك موجود في صورة إضافات. يمكن استخدامه كمكتبة في برامج أخرى بلغة Go. يمكن تهيئته ليشغّل أوامر خاصة بالنظام عند بدء التشغيل أو إيقافه. ملف تنفيذي واحد لا يحتاج إلى اعتماديات إلا فيما يتعلق بالنواة-kernel. كل هؤلاء إضافة إلى مزايا أخرى عديدة، أما الآن فسنلقي نظرة على كيفية تثبيته واستخدامه على خادم أوبنتو 16.04. تثبيت خادم ويب Caddy يوفّر Caddy شفرة نصية-script للتثبيت، تحمّل وتثبت الملف التنفيذي له -فهو لا يحتاج إلى اعتماديات كما ذكرنا-، نفذ الأمر التالي لتنفيذ الشفرة: $ curl https://getcaddy.com | bash وستسألك الشفرة أثناء التثبيت عن كلمة المرور من أجل الحصول على صلاحيات إدارية، فيكون الخرج هكذا: % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 5593 100 5593 0 0 3696 0 0:00:01 0:00:01 --:--:-- 3696 Downloading Caddy for linux/amd64... https://caddyserver.com/download/linux/amd64?plugins= Download verification OK Extracting... Putting caddy in /usr/local/bin (may require password) [sudo] password for gmolica: Caddy 0.10.6 Successfully installed ستتغير gmolica إلى اسم المستخدم الخاص بك طبعًا، وسيكون Caddy مثبتًا وجاهزًا بمجرد انتهاء الشفرة من عملها. جدير بالذكر أن عملية التثبيت لن تطبق إعدادات أو تهيئة على مستوى النظام-system wide، لذا سيكون عليك تنفيذ هذا الجزء، كما سنرى فيما يلي. تهيئة Caddy سيعتبر Caddy أن المجلد الجذر للموقع هو المجلد الذي نفّذته منه، فإن نفّذت Caddy من مجلد $HOME فسيستخدمه كمجلد جذر له، وهذا يعني بعبارة أخرى أن من السهل استخدام Caddy في العمل على المواقع محلّيًا. - لبدء Caddy: $ caddy ستظهر الطرفية الرسالة التالية: Activating privacy features... done. http://:2015 WARNING: File descriptor limit 1024 is too low for production servers. At least 8192 is recommended. Fix with "ulimit -n 8192". لاحظ أن Caddy يعمل على مضيف محلي-localhost، في منفذ 2015. قد يؤدي فتح صفحة http://your_server_IP:2015 -استبدل عنوان خادمك بـyour server IP-إلى صفحة خطأ 404، هذا بسبب أن المجلد الذي يستخدمه Caddy لا يحتوي على موقع، فيجب أن ننشئ تلك المجلدات المطلوبة أولًا: إنشاء المجلدات المطلوبة أولًا، ننشئ مجلدًا يحتوي ملف caddyfile الأساسي: # mkdir /etc/caddy نغير ملكيته إلى المستخدم الجذر ومجموعته إلى www-data: # chown -R root:www-data /etc/caddy أنشئ مجلدًا ثانيًا ليخزن فيه Caddy شهادات SSL والمفاتيح الخاصة: # mkdir /etc/ssl/caddy غير مالكه إلى www-data: # chown -R www-data /etc/ssl/caddy غيّر صلاحياته كما يلي: # chmod 0770 /etc/ssl/caddy والآن أنشئ المجلد الذي سيحتوي الموقع: # mkdir /var/www وغيّر مالكه إلى www-data: # chown www-data:www-data /var/www تحميل ملف Caddy Unit لن يثبّت Caddy نفسه افتراضيًا كخدمة systemd، لكنه يوفّر رسميًا ملف unit، حمّله بالأمر التالي: # curl -s https://raw.githubusercontent.com/mholt/caddy/master/dist/init/linux-systemd/caddy.service -o /etc/systemd/system/caddy.service بفتح الملف، سنلاحظ هذه السطور: ; Letsencrypt-issued certificates will be written to this directory. Environment=CADDYPATH=/etc/ssl/caddy ; Always set "-root" to something safe in case it gets forgotten in the Caddyfile. ExecStart=/usr/local/bin/caddy -log stdout -agree=true -conf=/etc/caddy/Caddyfile -root=/var/tmp لاحظ مسارات المجلدات في تلك السطور، لهذا قد أنشأنا المجلدات قبل قليل. والآن أنشئ ملفًا فارغًا باسم caddyfile: # sudo touch /etc/caddy/Caddyfile نفّذ الأمر التالي كي يعمل Caddy عند الإقلاع: # systemctl daemon-reload # systemctl enable caddy تفقد حالته بهذا الأمر: # systemctl status caddy يجب أن يكون الخرج هكذا: ---------------------------------- â caddy.service - Caddy HTTP/2 web server Loaded: loaded (/etc/systemd/system/caddy.service; enabled; vendor preset: en Active: inactive (dead) Docs: https://caddyserver.com/docs السماح باتصالات HTTP وHTTPS سنسمح لاتصالات HTTP وHTTPS عبر UFW (Uncomplicated Firewall)، كي يتمكن Caddy من خدمة المستخدمين بشكل سليم، نفّذ هذه الأوامر في الطرفية للسماح بهذه الاتصالات: # ufw allow http # ufw allow https اختبار Caddy آخر خطوة هي اختبار Caddy للتأكد أن كل شيء تم بشكل سليم: تعديل Caddyfile لقد أنشأنا ملف caddyfile فارغ من قبل، الآن سنبدأ الكتابة فيه: - افتح الملف باستخدام المحرر النصي الذي تفضّله: # $EDITOR /etc/caddy/Caddyfile الصق هذا المحتوى في الملف: example.com { root /var/www gzip tls gmolica@example.com } ملاحظة: سطر tls يحتوي على عنوان بريد يستخدمه Caddy ليحصل على شهادات SSL من Let’s Encrypt. - احفظ الملف وأغلقه. - شغّل Caddy: # systemctl start caddy أنشئ صفحة ويب سننشئ صفحة ويب لاختبار Caddy: $ echo '<h1>Website using Caddy</h1>' | sudo tee /var/www/index.html استخدم نفس الجذر الذي ثبتنا فيه ملف caddyfile. خاتمة لقد رأينا الآن كيفية تثبيت واستخدام Caddy، ولاحظنا كيفية سهولة التثبيت وإنشاء ملف caddyfile لتخصيص سلوك الخادم. لاحظ أن سهولة الاستخدام يتبيّن فضلها في بيئات التشغيل المعقدة. ترجمة -بتصرف- لمقال Caddy Web Server On Ubuntu 16.04 لصاحبه Giuseppe Molica
  19. تزداد شعبية Go، وهي لغة برمجة حديثة تطوّرها شركة Google، تزداد كثيرا في التطبيقات والشركات؛ كما توفّر مجموعة متناسقة من المكتبات البرمجية. يشرح هذا الدرس خطوات تثبيت الإصدار 1.8 (الإصدار المستقر الأحدث حتى الآن) على توزيعة لينكس أوبونتو 16.04. سننفّذ في الخطوة الأخيرة من هذا الدرس تطبيق “أهلا بالعالم” صغيرا للتأكد من تثبيت مصرّف اللغة Compiler وعمله. المتطلّبات يفترض هذا الدرس توفّر نظام أوبونتو 16.04 معدًّا للعمل مع مستخدم إداري غير المستخدم الجذر بالطريقة التي يشرحها الإعداد الابتدائي لخادوم أوبونتو. الخطوة الأولى: تثبيت Go نبدأ بتثبيت Go على الخادوم. اتّصل - إن دعت الحاجة لذلك - بالخادوم عن طريق SSH: ssh sammy@your_server_ip اذهب إلى صفحة التنزيلات على الموقع الرسمي لـGo واعثُر على رابط الملف المضغوط لآخر إصدار مستقر، مع قيمة تجزئة SHA256 الخاصة به. تأكد من أنك في المجلّد الشخصي للمستخدم ثم نزّل الإصدار انطلاقا من الرابط الذي تحصّلت عليه في الفقرة الماضية: cd ~ curl -O https://storage.googleapis.com/golang/go1.8.3.linux-amd64.tar.gz استخدم الأمر sha256sum للتحقّق من الملف المضغوط: sha256sum go1.8.3.linux-amd64.tar.gz مثال على المُخرجات: 1862f4c3d3907e59b04a757cfda0ea7aa9ef39274af99a784f5be843c80c6772 go1.8.3.linux-amd64.tar.gz ستحصُل على قيمة تجزئة Hash مثل تلك الموجودة في المُخرجات السابقة. تأكد من أنها توافق قيمة التجزئة الخاصة بالملف التي تحصّلت عليها من صفحة التنزيلات. سنستخدم الآن الأمر tar لفك ضغط الملف. يطلُب الخيار x استخراج محتوى الملف المضغوط، يُظهر الخيار v مخرجات مفصَّلة ويحدّد الخيار f أننا سنمرّر للأمر tar اسم الملف المضغوط: tar xvf go1.6.linux-amd64.tar.gz ستحصُل الآن على مجلّد باسم go في المجلّد الشخصي للمستخدم. نفّذ الأمرين التاليين لتعديل ملكية المجلّد go ثم نقله إلى المسار usr/local/ : sudo chown -R root:root ./go sudo mv go /usr/local ملحوظة: المسار usr/local/go/ هو المسار المنصوح به رسميا لتثبيت Go إلا أن بعض الحالات قد تتطلّب تثبيته على مسار مختلف. الخطوة الثانية: ضبط مسارات Go سنضبُط في هذه الخطوة المسارات الخاصّة بـGo في بيئة النظام. نفتح الملف profile./~ لتحريره: sudo nano ~/.profile نضيف السطرين التاليّين في نهاية الملف لضبط قيمة المتغيّر GOPATH، الذي يحدّد المسار الذي يجب على المصرّف البحثُ فيه عن الملفات المكتوبة بـGo، ولإضافة هذا المسار إلى متغيّر النظام PATH: export GOPATH=$HOME/work export PATH=$PATH:/usr/local/go/bin:$GOPATH/bin أضف الأسطر أدناه إلى الملف بدلا من الأسطر السابقة إن اخترت مسارا غير الذي اخترناه لتثبيت Go. يفترض المثال أن Go مثبَّت في المجلّد الشخصي للمستخدم: export GOROOT=$HOME/go export GOPATH=$HOME/work export PATH=$PATH:$GOROOT/bin:$GOPATH/bin نغلق الملف بعد التحرير ونعتمد التغيير بتنفيذ الأمر source: source ~/.profile الخطوة الثالثة: اختبار التثبيت نتأكّد بعد أن ثبّتنا Go وضبطنا مساراته من عمله. أنشئ مجلّدا جديدا لحفظ ملفات Go. مسار هذا الملف هو نفس المسار الذي حدّدناه في المتغيّر GOPATHضمن الخطوة السابقة: mkdir $HOME/work أنشئ مجلّدات مشاريع Go ضمن هذا المجلد كما في المثال التالي. يمكنك إبدال user في المسار أدناه باسم المستخدم الخاصّ بك على GitHub إن كنت تخطّط لاستخدام Git لإيداع شفرتك البرمجية على GitHub. إن لم تكن تخطّط لذلك فيمكن اختيار تسميات أخرى مثل my_project. mkdir -p work/src/github.com/user/hello ننشئ ملفّ Go بسيطا للتجربة، ونسميه hello: nano ~/work/src/github.com/user/hello/hello.go ألصق شفرة Go التالية ضمن محرّر النصوص. تستخدم هذه الشفرة حزمة main في Go، تستورد مكتبة fmt لدوالّ الإدخال والإخراج وتضبُط دالة جديدة لطباعة الجملة hello, world. package main import "fmt" func main() { fmt.Printf("hello, world\n") } يطبع البرنامج السابق عند تنفيذه بنجاح العبارة hello, world، وهو ما يدلّ على نجاح تصريف Compiling شفرة Go. احفظ الملف ثم أغلقه؛ ثم صرّفه باستدعاء الأمر go install: go install github.com/user/hello يمكننا الآن تشغيل البرنامج بتنفيذ الأمر hello: hello إن تمّ كل شيء على ما يُرام فستُطبَع العبارة hello, world. يمكنك معرفة أين يوجد الملف التنفيذي للبرنامج (ناتج التصريف) بتمرير اسمه إلى الأمر which: which hello مثال على المُخرجات: /home/user/work/bin/hello خاتمة يصبح لديك بعد تنزيل حزمة Go وتثبيتها وضبط مساراتها نظام جاهز لاستخدامه في التطوير بلغة Go. يمكنك الآن البدء بتعلم كتابة البرامج بهذه اللغة، راجع قسم البرمجة بلغة Go للمزيد. ترجمة - بتصرّف - للمقال How to Install Go 1.6 on Ubuntu 16.04 لصاحبه Brennen Bearnes.
  20. بروتوكول نقل الملفات FTP (اختصار للعبارة File Transfer Protocol) هو بروتوكول شبكي كان شائعًا جدًا فيما قد سلف لنقل الملفات بين الخادوم والعميل، لكن استبدلته الطرائق الأكثر أمانًا وسرعةً لنقل الملفات، فكثيرٌ من مستخدمي الإنترنت يتوقعون تنزيل الملفات مباشرةً من متصفح الويب عبر بروتوكول http (أو https)، أما مستخدمي سطر الأوامر فيستعملون بروتوكولات أكثر أمانًا مثل scp أو sFTP. لكن ما يزال بروتوكول FTP مستخدمًا في التطبيقات القديمة أو للحالات التي لها متطلبات خاصة، فلو كنتَ تستطيع اختيار ما هو البروتوكول الذي ستستخدمه، فأنصحك بالنظر في بقية الخيارات الحديثة؛ لكن إذا كنت تحتاج إلى استخدام FTP فخادوم vsftpd هو خيارٌ ممتازٌ إذ إنَّ أداءه ممتاز وآمن ومستقر، ويوفِّر قدرًا كبيرًا من الحماية ضد كثيرٍ من المشاكل الأمنية الموجودة في خودايم FTP الأخرى، إضافةً إلى أنه الخادوم الافتراضي لخدمة FTP للعديد من توزيعات لينكس. سنتعلم في هذا الدرس كيفية ضبط خادوم vsftpd للسماح للمستخدمين برفع ملفاتهم إلى مجلد المنزل الخاص بهم باستخدام بروتوكول FTP مع تأمين معلومات الدخول عبر تشفير SSL/TLS. المتطلبات المسبقة خادوم أوبنتو 16.04 مع وصول إلى مستخدم يملك امتيازات الجذر عبر الأمر sudo: إذ سنُطبِّق الأوامر المذكورة في هذا الدرس عبر مستخدمٍ ليس جذرًا لكنه يمتلك امتيازات الجذر عبر الأمر sudo. يمكنك إنشاء مستخدم له امتيازات الجذر باستخدام الأمر sudo باتباع درس «الإعداد الابتدائي لخادوم أوبنتو 14.04](https://academy.hsoub.com/devops/servers/الإعداد-الابتدائي-لخادوم-أوبنتو-1404-r4/)». يمكننا أن نبدأ بتطبيق هذا الدرس بعد أن يكون الخادوم جاهزًا. الخطوة الأولى: تثبيت vsftpd سنبدأ بتحديث فهرس الحزم في خادومنا ثم تثبيت خادوم vsftpd: sudo apt-get update sudo apt-get install vsftpd عند إكمال التثبيت، فسننسخ ملف الضبط الافتراضي لنأخذ نسخةً احتياطيةً منه، ولنعدِّل الضبط كما نشاء. sudo cp /etc/vsftpd.conf{,.orig} بعد أن أخذنا نسخةً احتياطيةً من ملف الضبط، فحان الوقت الآن لإعداد الجدار الناري. الخطوة الثانية: فتح المنافذ الضرورية في الجدار الناري سنتحقق أولًا من حالة الجدار الناري لنرى إن كان مفعلًا أم لا، فإذا كان مفعلًا فعلينا السماح باتصالات FTP عبره لكي لا نواجه مشاكل عندما نجرِّب الخادوم. sudo ufw status نجد من الناتج الآتي أنَّ خدمة SSH مسموحٌ لها فقط: Status: active To Action From -- ------ ---- OpenSSH ALLOW Anywhere OpenSSH (v6) ALLOW Anywhere (v6) لاحظ أنَّ الناتج قد يكون مختلفًا عندك، فقد لا توجد أيّة قواعد لجدارك الناري أو لديك قواعد إضافية. ولمّا كان الجدار الناري لا يسمح إلا لاتصالات SSH فعلينا إضافة قواعد للسماح لاتصالات FTP، وسنحتاج إلى فتح المنفذين 20 و 21 لخدمة FTP، والمنفذ 990 لنستعمله لاحقًا عندما نضبط تشفير TLS، والمنافذ من 40000 إلى 50000 كمنافذ غير المباشرة (passive ports) التي نخطط لضبطها لاحقًا في ملف الضبط: sudo ufw allow 20/tcp sudo ufw allow 21/tcp sudo ufw allow 990/tcp sudo ufw allow 40000:50000/tcp sudo ufw status يجب أن تبدو قواعد الجدار الناري كما يلي: Status: active To Action From -- ------ ---- OpenSSH ALLOW Anywhere 990/tcp ALLOW Anywhere 20/tcp ALLOW Anywhere 21/tcp ALLOW Anywhere 40000:50000/tcp ALLOW Anywhere OpenSSH (v6) ALLOW Anywhere (v6) 20/tcp (v6) ALLOW Anywhere (v6) 21/tcp (v6) ALLOW Anywhere (v6) 990/tcp (v6) ALLOW Anywhere (v6) 40000:50000/tcp (v6) ALLOW Anywhere (v6) يمكننا الانتقال إلى الخطوة التالية بعد تثبيتنا لخادوم vsftpd وفتح المنافذ الضرورية. الخطوة الثالثة: تهيئة مجلد المنزل للمستخدم سنُنشِئ في هذا الدرس مستخدمًا جديدًا، لكن قد يكون لديك مستخدم موجود في نظامك ويحتاج إلى وصول FTP، وسنحرص على الحفاظ على وصول المستخدم إلى بياناته، لكن مع ذلك أنصحك بإنشاء مستخدم جديد إلى أن تضبط الخادوم وتجرّبه. سنُنشِئ بدايةً مستخدمًا جديدًا للتجربة: sudo adduser sammy أسنِد كلمة المرور إلى الحساب عند طلبها، ويمكنك تجاهل بقية الأسئلة بالضغط على زر Enter. تكون خدمة FTP أكثر أمانًا إذا كان المستخدمون محدودين بمجلدٍ معيّن، ويمكن لخادوم vsftpd فعل ذلك باستخدام chroot، فعند تفعيل chroot للمستخدمين المحليين، فلن يسمح لهم بالوصول إلى شيءٍ خارج مجلد المنزل الخاص بهم افتراضيًا، لكن خادوم vsftpd يحاول تأمين المجلد بعدم السماح بالكتابة عليه من قبل المستخدم (عبر سطر الأوامر)، ولا بأس بذلك للمستخدمين الجدد الذين يجب أن يتصلوا عبر FTP فقط، لكن إذا كان لدينا مستخدم موجود مسبقًا ويجب أن يستطيع الكتابة إلى مجلد المنزل الخاص به عبر سطر الأوامر فهذا لن يكون مناسبًا أبدًا. وبدلًا من إزالة إذن الكتابة من مجلد المنزل، فسنُنشِئ مجلد ftp لكي يكون chroot وسنُنشِئ داخله مجلد files يمكن الكتابة عليه ليحتوي على الملفات. لنُنشِئ مجلد ftp ونضبط ملكيته ونحذف إذن الكتابة منه بالأوامر الآتية: sudo mkdir /home/sammy/ftp sudo chown nobody:nogroup /home/sammy/ftp sudo chmod a-w /home/sammy/ftp لنتأكد من الأذونات: sudo ls -la /home/sammy/ftp الناتج: total 8 4 dr-xr-xr-x 2 nobody nogroup 4096 Aug 24 21:29 . 4 drwxr-xr-x 3 sammy sammy 4096 Aug 24 21:29 .. لنُنشِئ الآن المجلد الذي يحتوي على الملفات التي ستُرفَع ونضبط ملكيته إلى المستخدم: sudo mkdir /home/sammy/ftp/files sudo chown sammy:sammy /home/sammy/ftp/files لنتحقق أيضًا من أذونات المجلد files: sudo ls -la /home/sammy/ftp الناتج: total 12 dr-xr-xr-x 3 nobody nogroup 4096 Aug 26 14:01 . drwxr-xr-x 3 sammy sammy 4096 Aug 26 13:59 .. drwxr-xr-x 2 sammy sammy 4096 Aug 26 14:01 files وفي النهاية، لنضف ملفًا باسم test.txt لكي نستخدمه عند التجربة لاحقًا: echo "vsftpd test file" | sudo tee /home/sammy/ftp/files/test.txt بعد أن أصبح مجلد ftp آمنًا، وأعطينا المستخدم الأذونات اللازمة على مجلد files، فيمكننا الاهتمام الآن بموضوع الضبط. الخطوة الرابعة: ضبط وصول FTP خطتنا هي السماح للمستخدم الذي يملك وصولًا محليًا إلى سطر الأوامر بالاتصال عبر FTP، وهنالك خيارا ضبط رئيسيان مضبوطان في ملف vsftpd.conf. لنبدأ أولًا بفتح ملف الضبط للتأكد أنَّ التعليمات المذكورة فيه تُطابِق ما يلي: sudo nano /etc/vsftpd.conf محتوى الملف: . . . # Allow anonymous FTP? (Disabled by default). anonymous_enable=NO # # Uncomment this to allow local users to log in. local_enable=YES . . . علينا الآن تغيير بعض القيم في الملف، ولكي نسمح للمستخدم برفع الملفات فسنزيل رمز التعليق قبل التعليمة write_enable لكي يصبح السطر كما يلي: . . . write_enable=YES . . . سنُزيل رمز التعليق قبل التعليمة chroot_local_user لمنع المستخدم الذي يتصل عبر FTP من الوصول إلى أيّة ملفات خارج المجلد المضبوط: . . . chroot_local_user=YES . . . علينا إضافة التعليمة user_sub_token لكي نستطيع وضع اسم المستخدم في مسار local_root، وهذا لكي يعمل الضبط دون مشاكل لهذا المستخدم ولأي مستخدم آخر قد نضيفه مستقبلًا: user_sub_token=$USER local_root=/home/$USER/ftp سنُحدِّد مجال المنافذ المستخدم لاتصالات FTP غير المباشرة (passive FTP) لكي نحرص على توافر اتصالات كافية: pasv_min_port=40000 pasv_max_port=50000 تذكر أننا فتحنا هذه المنافذ سابقًا في الجدار الناري، أي لو استخدمتَ مجالًا مختلفًا عمّا سبق فاحرص على تحديث ضبط الجدار الناري بما يتوافق مع ذلك. ولأننا نخطط للسماح بوصول إلى FTP لمستخدمين معينين، فسنعدِّل في الضبط لكي نسمح بالوصول إلى قائمة معيّنة من المستخدمين: userlist_enable=YES userlist_file=/etc/vsftpd.userlist userlist_deny=NO التعليمة userlist_deny تُحدِّد ما الذي يجب فعله مع المستخدمين المذكورين في القائمة، فلو ضُبِطَت إلى YES فسيمنعون من الوصول إلى FTP، وإذا كانت NO فلن يسمح بالوصول إلى FTP إلا للمستخدمين المذكورين في القائمة. بعد أن تنتهي من إضافة الأسطر السابق فاحفظ الملف واخرج من المحرر النصي. علينا الآن إنشاء ملف القائمة وإضافة اسم المستخدم إليه، يمكننا استخدام الخيار ‎-a الخاص بالأمر tee لإسناد السطر إلى نهاية الملف: echo "sammy" | sudo tee -a /etc/vsftpd.userlist لنتأكد من محتوى الملف: cat /etc/vsftpd.userlist الناتج: sammy أعد تشغيل الخادوم لتطبيق التغييرات التي أجريناها في ملف الضبط: sudo systemctl restart vsftpd نحن جاهزون الآن للتجربة. الخطوة الخامسة: تجربة الوصول إلى FTP ضبطنا الخادوم للسماح للمستخدم sammy فقط بالوصول إلى FTP، لنتأكد من صحة ذلك. يجب ألّا يُسمَح للاتصال من المستخدمين المجهولين (anonymous users)، إذ عطلنا ذلك في الضبط، وسنجرِّب ذلك بمحاولة الاتصال بشكل مجهول، فإذا كان ضبطنا صحيحٌ فيجب ألّا يسمح لنا بالوصول إلى الخادوم: ftp -p 203.0.113.0 الناتج: Connected to 203.0.113.0. 220 (vsFTPd 3.0.3) Name (203.0.113.0:default): anonymous 530 Permission denied. ftp: Login failed. Ftp> أغلِق الاتصال: bye يجب ألّا يتمكن أيّ مستخدمٍ عدا sammy من الاتصال: وسنتحقق من ذلك عبر وضع اسم المستخدم الذي يملك امتيازات الجذر، ويجب ألّا يُسمَح له أيضًا قبل أن يُطلَب منه إدخال كلمة المرور: ftp -p 203.0.113.0 الناتج: Connected to 203.0.113.0. 220 (vsFTPd 3.0.3) Name (203.0.113.0:default): sudo_user 530 Permission denied. ftp: Login failed. Ftp> أغلِق الاتصال: bye يجب أن يتمكن المستخدم sammy من الاتصال، ومن قراءة وكتابة الملفات، لذا لنجرِّب ذلك: ftp -p 203.0.113.0 الناتج: Connected to 203.0.113.0. 220 (vsFTPd 3.0.3) Name (203.0.113.0:default): sammy 331 Please specify the password. Password: your_user's_password 230 Login successful. Remote system type is UNIX. Using binary mode to transfer files. Ftp> سندخل إلى المجلد files، ثم سنستعمل الأمر get لنقل ملف التجربة الذي أنشأناه سابقًا إلى جهازنا المحلي: cd files get test.txt الناتج: 227 Entering Passive Mode (203,0,113,0,169,12). 150 Opening BINARY mode data connection for test.txt (16 bytes). 226 Transfer complete. 16 bytes received in 0.0101 seconds (1588 bytes/s) ftp> سنحاول الآن إعادة رفع الملف باسمٍ جديد للتأكد من إمكانية الكتابة على المجلد: put test.txt upload.txt الناتج: 227 Entering Passive Mode (203,0,113,0,164,71). 150 Ok to send data. 226 Transfer complete. 16 bytes sent in 0.000894 seconds (17897 bytes/s) أغلِق الاتصال: bye بعد أن تأكدنا أنَّ الخادوم يعمل كما ضبطناه، فيمكننا إتباع إجراءات إضافية لتأمين الخادوم. الخطوة السادسة: جعل عمليات النقل آمنة لما كان بروتوكول FTP لا يشفِّر أيّة بيانات عند نقلها، بما في ذلك معلومات المستخدم، فعلينا تفعيل تشفير SSL/TLS لتأمين تلك البيانات، وأوّل خطوة هي إنشاء شهادات SSL لاستخدامها مع vsftpd. سنستخدم openssl لإنشاء شهادة جديدة، ونستخدم الخيار ‎-days لجعلها صالحةً لمدة سنة، وسنضيف –في الأمر نفسه– مفتاح ‎2048-bit RSA خاص، ثم بإسناد القيمة ذاتها إلى الخيارين ‎-keyout و ‎-out فستكون الشهادة والمفتاح الخاص في الملف نفسه. هذا هو الأمر الذي سنُطبِّقه: sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/vsftpd.pem -out /etc/ssl/private/vsftpd.pem سيُطلَب منّا توفير معلومات عن الشهادة التي سنُنشِئها، ضع المعلومات الخاصة بك عند الإجابة عن الأسئلة: Generating a 2048 bit RSA private key ............................................................................+++ ...........+++ writing new private key to '/etc/ssl/private/vsftpd.pem' ----- You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [AU]:US State or Province Name (full name) [Some-State]:NY Locality Name (eg, city) []:New York City Organization Name (eg, company) [Internet Widgits Pty Ltd]:Hsoub Organizational Unit Name (eg, section) []: Common Name (e.g. server FQDN or YOUR name) []: Email Address []: بعد أن أنشأنا الشهادات، فعلينا الآن تعديل ضبط vsftpd مجددًا: sudo nano /etc/vsftpd.conf ستجد قرب نهاية الملف سطرين يبدآن بالسابقة rsa_‎، أضف قبلهما رمز التعليق ليصبحا كما يلي: # rsa_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem # rsa_private_key_file=/etc/ssl/private/ssl-cert-snakeoil.key أضف السطرين الآتيين بعدهما، اللذان يشيران إلى الشهادة والمفتاح الخاص اللذين أنشأناهما سابقًا: rsa_cert_file=/etc/ssl/private/vsftpd.pem rsa_private_key_file=/etc/ssl/private/vsftpd.pem علينا الآن جعل استخدام SSL إجباريًا، مما يمنع العملاء غير القادرين على التعامل مع تشفير TLS من الاتصال بخادومنا، وهذا ضروري للحرص على تشفير جميع المعلومات المنقولة لكن قد يجبر المستخدم على تغيير عميل الاتصال. عدِّل قيمة التعليمة ssl_enable إلى YES: ssl_enable=YES أضف بعد ذلك الأسطر الآتية لمنع الاتصالات المجهولة عبر SSL، ولإجبار استخدام SSL لتسجيل الدخول ولنقل البيانات: allow_anon_ssl=NO force_local_data_ssl=YES force_local_logins_ssl=YES علينا ضبط الخادوم استخدام TLS بدلًا من SSL عبر إضافة الأسطر الآتية: ssl_tlsv1=YES ssl_sslv2=NO ssl_sslv3=NO علينا بعد ذلك إضافة تعليمتين إضافيتين، الأولى تسمح بعدم استخدام SSL عند إعادة استخدام الجلسة (session reuse) لأنها لا تعمل مع أغلبية عملاء FTP، وسنطلب استخدام حزم عالية التشفير، وهذا يعني أنَّ طول المفتاح أكبر أو يساوي 128 بت: require_ssl_reuse=NO ssl_ciphers=HIGH بعد أن تنتهي من التعديلات السابقة، فاحفظ الملف وأغلق المحرر. علينا الآن إعادة تشغيل الخادوم لتأخذ التعديلات مجراها: sudo systemctl restart vsftpd لم نعد نتمكن الآن من استخدام عميل FTP غير الآمن الذي يعمل من سطر الأوامر، فلو جربناه فسنشاهد الناتج الآتي: ftp -p 203.0.113.0 Connected to 203.0.113.0. 220 (vsFTPd 3.0.3) Name (203.0.113.0:default): sammy 530 Non-anonymous sessions must use encryption. ftp: Login failed. 421 Service not available, remote server has closed connection ftp> سنتحقق من الاتصال في الخطوة القادمة باستخدام عميل يدعم تشفير TLS. الخطوة السابعة: تجربة الاتصال عبر TLS باستخدام FileZilla أغلبية عملاء FTP الحديثين يدعمون تشفير TLS، وسنشرح كيفية الاتصال عبر عميل FileZilla لأنه يعمل على جميع أنظمة التشغيل؛ راجع توثيق عميلك المفضل لتعرف كيف يمكن الاتصال عبر TLS فيه. عندما تفتح برنامج FileZilla فسنجد أيقونة Site Manager تحت قائمة File مباشرةً، أي أنَّها أوّل أيقونة في الشريط العلوي. اضغط عليها: ستُفتَح نافذة جديدة، اضغط فيها على زر «New Site» في الركن السفلي الأيسر: ستجد ظهور «New site» تحت أيقونة «My Sites»، يمكنك تسمية الموقع الآن أو إعادة تسميته لاحقًا بالضغط على زر «Rename». عليك أن تملأ حقل «Host» بعنوان IP أو اسم نطاق الموقع، وعليك أن تختار «Require explicit FTP over TLS» في قائمة «Encryption» أما لخيار «Logon Type» فاختر «Ask for password»، ثم أدخِل اسم المستخدم في حقل «User»: اضغط على زر «Connect» في أسفل النافذة، وستُسأل عن كلمة مرور المستخدم: اضغط على «OK» لتتصل، يجب أن يكون اتصالك مع الخادوم مشفرًا بتشفير TLS/SSL. بعد أن تقبل الشهادة، فانقر نقرًا مزدوجًا على مجلد files واسحب الملف upload.txt وأفلته في القسم اليساري من البرنامج لكي تبدأ بتنزيله: بعد ذلك، يمكنك أن تنقر بالزر الأيمن على الملف المحلي وتعيد تسميته إلى upload-tls.txt وتسحبه مجددًا إلى الخادوم لكي ترفعه عليه. لقد تمكنا من تنزيل الملفات ورفعها بأمان مع تفعيل تشفير SSL/TLS. الخطوة الثامنة: تعديل الوصول إلى سطر الأوامر (خطوة اختيارية) إن لم تتمكن من استخدام تشفير TLS بسبب محدوديات العميل، فيمكنك تأمين الخادوم قليلًا بمنع مستخدم FTP من تسجيل الدخول إلى سطر الأوامر، إحدى الطرائق البسيطة لفعل ذلك هي إنشاء صدفة (shell) خاصة. أكرِّر أنَّ الخطوة السابقة لا توفِّر أيّ تشفير، وإنما الغرض منها هو تقليل الوصول إلى حسابات المستخدمين المسموح لهم بالاتصال عبر FTP فقط. علينا أولًا إنشاء ملف باسم ftponly في مجلد ‎/bin: sudo nano /bin/ftponly سنضيف الآن رسالةً تخبر المستخدم أنَّه ليس قادرًا على تسجيل الدخول، أضف ما يلي يلي إلى الملف: #!/bin/sh echo "This account is limited to FTP access only." عدِّل الأذونات لجعل الملف قابلًا للتنفيذ: sudo chmod a+x /bin/ftponly افتح الملف الذي يضم قائمةً بالصدفات (shells) الصالحة للاستخدام في النظام: sudo nano /etc/shells وأضف في نهاية الملف: . . . /bin/ftponly عدِّل الصدفة الافتراضية للمستخدم عبر الآمر الآتي: sudo usermod sammy -s /bin/ftponly جرِّب الآن تسجيل الدخول بحساب المستخدم sammy: ssh sammy@203.0.113.0 ستجد رسالةً شبيهةً بالرسالة الآتية: This account is limited to FTP access only. Connection to 203.0.113.0 closed. هذا يؤكد أنَّ المستخدم غير قادر على تسجيل الدخول إلى الخادوم عبر الأمر ssh، ويُسمَح له بالوصول إلى FTP فقط. الخلاصة لقد شرحنا في هذا الدرس كيفية ضبط خادوم FTP للمستخدمين الذين يملكون حسابًا محليًا على النظام، أما إذا أردتَ استخدام مصدر خارجي للاستيثاق، فيمكنك إلقاء نظرة على دعم خادوم vsftpd للمستخدمين الوهميين (virtual users). هنالك خياراتٌ واسعة لدعم استخدام PAM مما يجعلك قادرًا على إدارة المستخدمين في نظام استيثاق مختلف مثل LDAP أو Kerberos. ترجمة –وبتصرّف– للمقال How To Set Up vsftpd for a User’s Directory on Ubuntu 16.04لصاحبته Melissa Anderson
  21. من المهم جدًا الحفاظ على دقة وقت النظام، سواءً فعلنا ذلك للحرص على دقة ترتيب السجلات (logs) أو أنَّ تحديثات قاعدة البيانات ستُطبَّق دون مشاكل؛ فإذا كان الوقت المضبوط على النظام غير صحيح، فقد يسبب ذلك أخطاءً أو تلفًا في البيانات أو مشاكل أخرى يصعب معرفة سببها بسهولة. ميزة مزامنة الوقت مضمّنةٌ ومفعّلةٌ في أوبنتو 16.04 افتراضيًا عبر خدمة timesyncd، وسنلقي في هذا الدرس نظرةً على الأوامر الأساسية المتعلقة بالوقت، ونتأكد أنَّ خدمة timesyncd مفعّلة، ونتعلم كيفية تثبيت خدمة بديلة لمزامنة الوقت والتاريخ. المتطلبات المسبقة يجب أن تملك قبل اتباع تعليمات هذا الدرس خادومًا يعمل بنظام أوبنتو 16.04 مع مستخدم ليس جذرًا لكنه يملك امتيازات الجذر عبر الأمر sudo؛ انظر إلى درس الإعداد الابتدائي لخادوم أوبنتو 14.04» لمزيدٍ من المعلومات. تعلّم الأوامر الأساسية للتعامل مع الوقت إنَّ أبسط الأوامر لمعرفة ما هو الوقت الحالي في نظامك هو date، يمكن لأي مستخدم كتابة هذا الأمر للحصول على الوقت والتاريخ الحاليين: date مثال على الناتج: Wed Apr 26 17:44:38 UTC 2017 من المرجح أنَّ المنطقة الزمنية المستعملة في خادومك هي UTC كما هو ظاهر في المثال أعلاه، كلمة UTC هي اختصار لعبارة Coordinated Universal Time (التوقيت العالمي الموحد) وهو الوقت عند مبدأ خطوط الطول، واستعمال توقيت UTC سيسهل عليك العمل إذا كانت خواديمك تمتد لأكثر من منطقة زمنية وحيدة. إذا أردت تغيير المنطقة الزمنية لأي سببٍ من الأسباب، فيمكنك استخدام الأمر timedatectl لفعل ذلك. اعرض أولًا قائمةً بالمناطق الزمنية المتاحة: timedatectl list-timezones ستُعرَض قائمة بجميع المناطق الزمنية، يمكنك الضغط على زر Space للتمرير إلى الأسفل وزر b للتمرير إلى الأعلى؛ وبعد أن تعثر على المنطقة الزمنية الصحيحة فدوِّنها عندك ثم اضغط على q للخروج من القائمة. يمكنك الآن ضبط القائمة الزمنية باستخدام الأمر timedatectl set-timezone، احرص على وضع منطقتك الزمنية بدلًا من تلك المذكورة في الأمر الآتي؛ لاحظ أنَّك ستحتاج إلى استخدام الأمر sudo مع الأمر timedatectl لإجراء هذا التعديل: sudo timedatectl set-timezone America/New_York يمكنك التحقق من التغييرات بتشغيل الأمر date مجددًا: date الناتج: Wed Apr 26 13:55:45 EDT 2017 يجب أن يشير الاختصار المذكور في الأمر السابق إلى المنطقة الزمنية التي اخترتها. تعلمنا كيف نتحقق من الوقت الحالي وكيف نضبط المناطق الزمنية، وسنتعلم الآن كيف نتأكد من مزامنة الوقت في نظامنا. التحكم بخدمة timesyncd بواسطة timedatectl كانت أغلبية عمليات مزامنة الوقت تتم عبر خدمة بروتوكول وقت الشبكة (Network Time Protocol daemon) ntpd، أي سيتصل الخادوم إلى مجموعة من خواديم NTP التي توفر الوقت بدقة كبيرة. لكن توزيعة أوبنتو تستعمل timesyncd بدلًا من ntpd لمزامنة الوقت، إذ تتصل خدمة timesyncd إلى خواديم الوقت نفسها وتعمل العمل نفسه تقريبًا، لكنها أخف وتندمج اندماجًا أفضل مع systemd وطريقة العمل الداخلية في توزيعة أوبنتو. يمكنك الحصول على حالة خدمة timesyncd بتشغيل الأمر timedatectl دون معاملات، ولن تحتاج إلى استخدام sudo في هذا الموضع: timedatectl الناتج: Local time: Wed 2017-04-26 17:20:07 UTC Universal time: Wed 2017-04-26 17:20:07 UTC RTC time: Wed 2017-04-26 17:20:07 Time zone: Etc/UTC (UTC, +0000) Network time on: yes NTP synchronized: yes RTC in local TZ: no سيطبع الأمر السابق الوقت المحلي والوقت العالمي (والذي يساوي الوقت المحلي في حال لم تغيّر المنطقة الزمنية)، وبعض معلومات عن حالة وقت الشبكة. السطر Network time on: yes يعني أنَّ خدمة timesyncd مفعّلة، والسطر NTP synchronized: yes يشير إلى نجاح مزامنة الوقت. إذا لم تكن خدمة timesyncd مفعلةً، فشغِّلها باستعمال الأمر timedatectl: sudo timedatectl set-ntp on شغِّل الأمر timedatectl مجددًا للتأكد من حالة وقت الشبكة؛ لاحظ أنَّ عملية التزامن تحتاج إلى بعض الوقت، لكن في النهاية يجب أن تكون قيمة السطرين Network time on:‎ و NTP synchronized:‎ تساوي yes. التحويل إلى خدمة ntpd على الرغم من أنَّ خدمة timesyncd مناسبة لغالبية الاحتياجات، لكن بعض التطبيقات حساسةٌ جدًا لأدنى اضطراب في الوقت ومن المستحسن استعمال ntpd في هذه الحالات، لأنه يستعمل تقنيات معقدة لإبقاء الوقت في النظام مزامنًا دومًا. علينا إيقاف خدمة timesyncd قبل تثبيت ntpd: sudo timedatectl set-ntp no للتأكد من إيقاف خدمة timesyncd: timedatectl ابحث عن السطر Network time on: no الذي يعني أنَّ خدمة timdsyncd متوقفة؛ يمكننا الآن تثبيت حزمة ntp باستعمال الأداة apt-get: sudo apt-get install ntp يجب أن يعمل خادوم ntpd تلقائيًا بعد التثبيت، يمكنك عرض حالة خدمة ntpd للتأكد أنَّ كل شيءٍ على ما يرام: sudo ntpq -p الناتج: remote refid st t when poll reach delay offset jitter ============================================================================== 0.ubuntu.pool.n .POOL. 16 p - 64 0 0.000 0.000 0.000 1.ubuntu.pool.n .POOL. 16 p - 64 0 0.000 0.000 0.000 2.ubuntu.pool.n .POOL. 16 p - 64 0 0.000 0.000 0.000 3.ubuntu.pool.n .POOL. 16 p - 64 0 0.000 0.000 0.000 ntp.ubuntu.com .POOL. 16 p - 64 0 0.000 0.000 0.000 -makaki.miuku.ne 210.23.25.77 2 u 45 64 3 248.007 -0.489 1.137 -69.10.161.7 144.111.222.81 3 u 43 64 3 90.551 4.316 0.550 +static-ip-85-25 130.149.17.21 2 u 42 64 3 80.044 -2.829 0.900 +zepto.mcl.gg 192.53.103.108 2 u 40 64 3 83.331 -0.385 0.391 ntpq هي أداة لطلب (query) معلومات حول خدمة ntpd، والخيار ‎-p يطلب معلومات حول خواديم NTP ‏(peers) التي اتصلت خدمة ntpd بها. قد يختلف الناتج عندك قليلًا، لكن يجب أن تتضمن القائمة على خواديم أوبنتو الافتراضية إضافةً إلى غيرها. أبقِ في ذهنك أنَّ خدمة ntpd تحتاج إلى بضع دقائق لتهيئة الاتصالات… الخلاصة رأينا في هذا الدرس طريقة عرض وقت النظام، وكيفية تغيير المناطق الزمنية، وطريقة التعامل مع خدمة timesyncd الموجودة افتراضيًا في أوبنتو، إضافةً إلى طريقة تثبيت ntpd. إذا كان نظامك ذو احتياجات خاصة لم نشرحها في هذا الدرس، فأنصحك بالرجوع إلى توثيق NTP الرسمي، وألقِ نظرةً على مشروع NTP Pool الذي هو مجموعةٌ من المتطوعين الذين يوفرون جزءًا كبيرًا من البنية التحتية التي يحتاج لها بروتوكول NTP في العالم. ترجمة –وبتصرّف– للمقال How To Set Up Time Synchronization on Ubuntu 16.04لصاحبه Brian Boucheron حقوق الصورة البارزة محفوظة لـ Freepik
  22. تعرّفنا في الجزأين السابقيْن من هذا الدليل على كيفية عرض معلومات عن مساحات التخزين وإنشاء مساحات تخزين جديدة وتحجيمها. سنكمل في هذا الجزأ - الأخير من الدليل - ما تعلمناه سابقا ونتعرّف على المهمة الأخيرة من بين المهمّات الأساسية في إدارة التخزين بآلية LVM. تنبيه: تأكّد من أنّ الأجهزة التّي تودّ تطبيق الأوامر المذكورة في هذا الدرس عليها لا تحتوي على بيانات مُهمّة. استخدام هذه الأجهزة مع LVM سيؤدّي إلى الكتابة فوق المحتويات الحاليّة. يُفضَّل أن تختبر الخطوات المعروضة أدناه في آلة افتراضية أو على خادوم خاصّ بأغراض التجربة والاختبار. إزالة أو تقليص مُكوّنات LVM بما أن تقليص مساحة التّخزين قد يؤدي إلى فقدان البيانات، فإجراءات تقليص المساحة المتوفّرة، سواءٌ بتقليص حجم أو حذف المكوّنات، أكثر تعقيدًا من بقية المهامّ. تخفيض حجم وحدة تخزين منطقيّة لتقليص وحدة تخزين منطقيّة، يجب عليك أولا أخذ نسخة احتياطية من بياناتك. فبما أن هذه العمليّة تقلّص مساحة التّخزين المُتوفّرة فإن أي خطأ يُمكن له أن يُؤدي إلى فقدان البيانات. إذا كنت جاهزا، تأكّد من حجم المساحة المُستخدمة حاليّا: df -h المُخرج: Filesystem Size Used Avail Use% Mounted on . . . /dev/mapper/LVMVolGroup-test 4.8G 521M 4.1G 12% /mnt/test في هذا المثال، يبدو بأنّنا نستخدم حاليّا حوالي 521M من المساحة. استعمل هذه المعلومة لتحديد الحجم الذي تريد تقليص وحدة التخزين إليه. تاليّا، أزل تركيب نظام الملفّات. فعلى عكس التوسيعات، يجب عليك تقليص مساحة نظام الملفّات أثناء إزالة التركيب: cd ~ sudo umount /dev/LVMVolGroup/test بعد إزالة التركيب، تأكّد من أن نظام الملفّات في حالة جيّدة. مرّر نوع نظام الملفّات عبر الخيار -t. سنستعمل الخيار -f للتّحقّق من أن كل شيء على ما يرام حتى ولو بدا كذلك: sudo fsck -t ext4 -f /dev/LVMVolGroup/test بعد التّحقّق من سلامة نظام الملفّات، يُمكنك تقليص مساحته باستخدام الأدوات الخاصّة، في حالة Ext4، فالأمر سيكون resize2fs. مرّر الحجم النّهائي لنظام الملفّات. تنبيه: أكثر خيار أمانا هو تمرير حجم نهائي أكبر بكثير من الحجم المُستخدم حاليا. أعط نفسك مساحة أمان لتجنّب فقدان البيانات وتأكّد من إنشاء نسخ احتياطيّة. sudo resize2fs -p /dev/LVMVolGroup/test 3G حالما تنتهي العمليّة، قلّص حجم وحدة التّخزين المنطقيّة عبر تمرير نفس الحجم (3G في هذه الحالة) إلى الأمر lvresize عبر الخيار -L. sudo lvresize -L 3G LVMVolGroup/test ستستقبل تنبيها حول فقدان البيانات، إن كنت جاهزا، فاكتب y للاستمرار. بعد تقليص حجم وحدة التّخزين المنطقيّة، تحقّق من سلامة نظام الملفّات مُجدّدا: sudo fsck -t ext4 -f /dev/LVMVolGroup/test إن سار كلّ شيء على ما يرام، فستستطيع إعادة وصل نظام الملفّات بالأمر المُعتاد: sudo mount /dev/LVMVolGroup/test /mnt/test ينبغي الآن على وحدة التّخزين المنطقيّة أن تُقلّص إلى الحجم المُحدّد. حذف وحدة تخزين منطقيّة إن لم تعد بحاجة إلى وحدة تخزين منطقيّة، يُمكنك حذفها باستعمال الأمر lvremove. أولا، أزل تركيب وحدة التخزين: cd ~ sudo umount /dev/LVMVolGroup/test بعدها، احذف وحدة التخزين بالأمر التّالي: sudo lvremove LVMVolGroup/test سيُطلب منك تأكيد العمليّة، إن كنت متأكّدا من رغبتك في حذف وحدة التّخزين، فاكتب y. حذف مجموعة تخزين لحذف مجموعة تخزين كاملة، بما في ذلك جميع وحدات التّخزين المنطقيّة المتواجدة بها، استعمل الأمر vgremove. قبل حذف مجموعة تخزين، عليك حذف وحدات التّخزين بداخلها بالعمليّة أعلاه. أو على الأقل، تأكّد من إزالة تركيب جميع وحدات التّخزين بداخل المجموعة: sudo umount /dev/LVMVolGroup/www sudo umount /dev/LVMVolGroup/projects sudo umount /dev/LVMVolGroup/db بعدها يُمكنك حذف مجموعة التّخزين عبر تمرير اسمها إلى الأمر vgremove: sudo vgremove LVMVolGroup سيُطلب منك تأكيد عمليّة حذف المجموعة. إذا كانت هناك أية وحدات تخزين منطقيّة مُتبقيّة، ستُسأل عن تأكيد حذفها واحدة واحدة قبل حذف المجموعة. حذف وحدة تخزين ماديّة إن أردت إزالة وحدة تخزين ماديّة من إدارة LVM، فسيعتمد الإجراء المطلوب على ما إذا كانت الوحدة مُستخدمة من طرف LVM أو لا. إن كانت وحدة التّخزين الماديّة مُستخدَمة، سيتوجّب عليك نقل المداءات الماديّة على الجهاز إلى مكان آخر. سيتطلّب ذلك وجود وحدات تخزين ماديّة أخرى لتحتضن المداءات الماديّة. إن كنت تستعمل أنواعا مُعقّدة من وحدات التّخزين المنطقيّة، فقد يتوجّب عليك الحصول على المزيد من وحدات التّخزين الماديّة حتى ولو كانت لديك مساحة تخزين كافيّة. إن كان لديك عدد كاف من وحدات التّخزين الماديّة في مجموعة التّخزين لاحتضان المداءات الماديّة، فانقلها إلى خارج وحدة التّخزين الماديّة التي ترغب في إزالتها عبر كتابة ما يلي: sudo pvmove /dev/sda يُمكن لهذه العمليّة أن تأخذ وقتا طويلا حسب حجم وحدات التّخزين وكميّة البيانات التي يتوجب نقلها. حالما تنتقل المداءات إلى وحدات تخزين أخرى، يُمكنك حذف وحدة التّخزين الماديّة من مجموعة التّخزين عبر الأمر التّالي: sudo vgreduce LVMVolGroup /dev/sda هذه العمليّة كفيلة بإزالة وحدات التّخزين التي أُخلِيت من مجموعة التّخزين. بعد انتهاء العمليّة، يُمكنك حذف علامة وحدة التّخزين الماديّة من جهاز التّخزين عبر الأمر: sudo pvremove /dev/sda ينبغي الآن أن تتمكّن من استعمال جهاز التّخزين المُزال لأغراض أخرى أو إزالته من النّظام بالكامل. ختاما إلى هذه النّقطة، يجب أن يكون لديك فهم لكيفيّة إدارة أجهزة التّخزين على أوبونتو 16.04 مع LVM. يجب أن تعرف كيفيّة الحصول على معلومات عن مكوّنات LVM، كيفيّة استخدام LVM لتركيب نظام تخزين خاص بك، وكيفيّة تعديل وحدات التّخزين لتلبيّة حاجاتك. يُمكنك اختبار هذه المبادئ في بيئة آمنة لفهم أعمق حول آليّة عمل LVM ومكوّناته. ترجمة – بتصرّف - للمقال How To Use LVM To Manage Storage Devices on Ubuntu 16.04 لكاتبه Justin Ellingwood.
  23. بعد أن تعرّفنا في الجزء السابق على كيفية عرض معلومات عن مختلف العناصر في LVM، سنتطرّق في هذا الجزء من الدليل إلى كيفية التحكم في هذه المكوّنات بإنشاء مكوّنات جديدة أو إعادة تحجيم (توسيع أو تقليص) مكوّنات موجودة. إنشاء أو توسيع مكوّنات LVM سنتحدّث في هذه الفقرات عن كيفيّة إنشاء وتوسيع وحدات التّخزين الماديّة والمنطقيّة وكذا مجموعات التّخزين. إنشاء وحدات تخزين ماديّة من أجهزة تخزين خام لاستعمال أجهزة التّخزين مع LVM، يجب عليها أولا أن تُعلّم على أنها وحدات تخزين ماديّة. ما يُحدّد إمكانيّة استخدام الجهاز داخل مجموعة تخزين. أولا، استعمل الأمر lvmdiskscan لإيجاد جميع أجهزة التّخزين التي يُمكن لـLVM رؤيتها واستخدامها: sudo lvmdiskscan المُخرج: /dev/ram0 [ 64.00 MiB] /dev/sda [ 200.00 GiB] /dev/ram1 [ 64.00 MiB] . . . /dev/ram15 [ 64.00 MiB] /dev/sdb [ 100.00 GiB] 2 disks 17 partitions 0 LVM physical volume whole disks 0 LVM physical volumes في المُخرج أعلاه، بتجاهل أجهزة /dev/ram*، يُمكننا رؤية الأجهزة التّي يُمكن تحويلها إلى وحدات تخزين ماديّة لـLVM. تنبيه: تأكّد من أنّ الأجهزة التّي ترغب باستعمالها مع LVM لا تحتوي على أيّة بيانات مُهمّة. استخدام هذه الأجهزة مع LVM سيؤدّي إلى الكتابة فوق المحتويات الحاليّة. إذا كنت تمتلك بيانات مهمّة على خادومك فأنشئ نسخا احتياطية قبل الاستمرار في تطبيق الدّرس. لجعل أجهزة التّخزين وحدات تخزين ماديّة خاصّة بـLVM، استعمل الأمر pvcreate. يُمكنك تمرير عدّة أجهزة في نفس الوقت: sudo pvcreate /dev/sda /dev/sdb هذا الأمر سيكتب ترويسة LVM على جميع الأجهزة الهدف لتخصيصها كوحدات تخزين LVM ماديّة. إنشاء مجموعة تخزين من وحدات التّخزين الماديّة لإنشاء مجموعة تخزين جديدة من وحدات التّخزين الماديّة، استعمل الأمر vgcreate. سيتوجّب عليك تمرير اسم للمجموعة متبوعا بوحدة تخزين ماديّة واحدة على الأقل: sudo vgcreate volume_group_name /dev/sda استبدل volume_group_name باسم من اختيارك لمجموعة التّخزين. سينشئ المثال أعلاه مجموعة تخزين انطلاقا من وحدة تخزين ماديّة واحدة فقط. يُمكنك تمرير أكثر من وحدة تخزين ماديّة عند إنشاء المجموعة إن أردت ذلك: sudo vgcreate volume_group_name /dev/sda /dev/sdb /dev/sdc عادة ستحتاج إلى مجموعة تخزين واحدة فقط لكل خادوم. بحيث يُمكنك إضافة أي مساحة تخزين إضافيّة لمنطقة مُوحّدة ثمّ تخصيص وحدات تخزين منطقيّة منها. الحاجة إلى استخدام أحجام مداءات مُختلفة من الأسباب التّي قد تدفعك إلى إنشاء أكثر من مجموعة تخزين واحدة. في العادة، لن يتوجّب عليك تحديد حجم المدى (الحجم المبدئي هو 4M ويُعدّ كافيّا لمُعظم الاستخدامات)، لكنّ إن أردت، يُمكنك تحديد حجم المداءات عند إنشاء مجموعة التّخزين باستعمال الخيار -s: sudo vgcreate -s 8M volume_group_name /dev/sda سينشئ هذا الأمر مجموعة تخزين مع حجم مداءات يُساوي 8M. إضافة وحدة تخزين ماديّة إلى مجموعة تخزين موجودة مُسبقا لتوسيع مجموعة تخزين عبر إضافة وحدات تخزين ماديّة، استخدم الأمر vgextend. يأخذ هذا الأمر مجموعة تخزين متبوعة بوحدات التّخزين الماديّة التّي ترغب بإضافتها إلى المجموعة. يُمكنك كذلك تمرير أكثر من جهاز في نفس الوقت إن أردت: sudo vgextend volume_group_name /dev/sdb ستُضاف وحدة التّخزين الماديّة إلى مجموعة التّخزين موسّعة بذلك مساحة التّخزين المُتوفّرة على المجموعة. إنشاء وحدة تخزين منطقيّة بحجم مُحدّد لإنشاء وحدة تخزين منطقيّة من مجموعة تخزين، استعمل الأمر lvcreate. حدّد حجم وحدة التّخزين المنطقيّة باستخدام الخيار -L، وحدّد اسما عبر الخيار -n، ومرّر مجموعة التّخزين الأم. على سبيل المثال، لإنشاء وحدة تخزين منطقيّة تُسمّى test من مجموعة تخزين تُسمّى LVMVolGroup، اكتب: sudo lvcreate -L 10G -n test LVMVolGroup على افتراض أنّ بمجموعة التّخزين مساحة تخزين فارغة توافق حجم وحدة التّخزين، فإنشاء وحدة التّخزين الجديدة سيتمّ بنجاح. إنشاء وحدة تخزين منطقيّة من كامل باقي المساحة الفارغة إن أردت إنشاء وحدة تخزين من باقي المساحة الفارغة على مجموعة تخزين، استعمل الأمر vgcreate مع الخيار -n لتحديد اسم لها ثمّ مرّر مجموعة التّخزين كما في السّابق. عوضا عن تمرير حجم مُعيّن، استعمل الخيار -l 100%FREE لتحديد بقيّة المساحة الفارغة في المجموعة: sudo lvcreate -l 100%FREE -n test2 LVMVolGroup إنشاء وحدات تخزين منطقيّة مع خيارات مُتقدّمة يُمكنك إنشاء وحدات تخزين منطقيّة مع خيارات مُتقدّمة كذلك. التّالي بعض من الخيارات التي يُمكن أن تأخذها بعين الاعتبار: --type: يقوم هذا الخيار بتحديد نوع وحدة التّخزين المنطقيّة ما يُحدّد كيفيّة تخصيص مساحة له. بعض من هذه الأنواع لن تكون مُتوفّرة إن لم يكن لديك الحدّ الأدنى من وحدات التّخزين الماديّة التي يتطلّبها النّوع. بعض من أكثر هذه الأنواع شيوعا هي كما يلي: linear: النّوع المبدئي. أجهزة التّخزين المُستخدمة ستُضاف بعضها على بعض واحدا تلو الآخر. striped: مُشابه لـRAID 0، تُقسّم البيانات إلى قطع صغيرة وتُنشر على شكل قوس على وحدات التّخزين الماديّة المُستعملة. ما يؤدّي إلى تحسينات في الأداء، لكن يُمكن أن يؤدي إلى زيادة في قابليّة إصابة البيانات. لتحديد هذا النّوع، يجب عليك تمرير الخيار -i ويتطلّب وحدتي تخزين ماديّتين على الأقل. raid1: إنشاء وحدة تخزين RAID 1 مُنعكسة Mirrored. مبدئيًّا، سيكون للانعكاس نُسختان، لكن يُمكنك تحديد عدد أكبر عبر الخيار -m المشروح أسفله. هذا الخيار يتطلّب وحدتي تخزين ماديّتين على الأقل. raid5: إنشاء وحدة تخزين RAID 5. يتطلّب ثلاثة وحدات تخزين ماديّة على الأقل. raid6: إنشاء وحدة تخزين RAID 6. يتطلّب أربعة وحدات تخزين ماديّة على الأقل. -m: يحدّد عدد نُسخ البيانات الإضافيّة. إن مرّرت القيمة 1 فهذا يعني بأنّ نُسخة واحدة إضافيّة من البيانات ستُصان، بحيث يكون لديك مجموعتان من نفس البيانات. -i: يُحدّد عدد الشّرائط Stripes. هذا الخيار مطلوب للنوع striped، ويُمكن أن يُؤثّر على بعض خيارات RAID الأخرى. -s: يُحدّد بأنّ أخذ لقطة يجب أن يتمّ على مُستوى وحدة التّخزين المنطقيّة الحاليّة عوضا عن إنشاء وحدة تخزين منطقيّة جديدة ومُستقلّة. سنلقي نظرة على بضعة أمثلة لهذه الخيارات لنرى حالات الاستخدام الشّائعة. لإنشاء وحدة تخزين شريطيّة Striped volume، يجب عليك تحديد شريطين على الأقل. هذه العمليّة تحتاج إلى وحدتي تخزين ماديّتين على الأقل مع مساحة تخزين متوافقة مع الحجم المُراد: sudo lvcreate --type striped -i 2 -L 10G -n striped_vol LVMVolGroup لإنشاء مساحة تخزين مُنعكسة Mirrored volume، استخدم النّوع raid1. إن أردت أكثر من مجموعتي بيانات، استعمل الخيار -m. المثال التّالي يستعمل -m 2 لإنشاء ثلاث مجموعات من البيانات (يعتبر LVM بأنّها مجموعة واحدة من البيانات مع انعكاسين). ستحتاج إلى ثلاثة وحدات تخزين ماديّة على الأقل لنجاح العمليّة: sudo lvcreate --type raid1 -m 2 -L 20G -n mirrored_vol LVMVolGroup لإنشاء لقطة لوحدة تخزين ما، يجب عليك تحديد وحدة التّخزين المنطقيّة الأصل التي ستأخذ منها اللقطة وليس كامل مجموعة التّخزين. لا تحجز اللقطات الكثير من المساحة في البدء، لكنّ حجمها يزداد كلّما أُجرِيَت تغييرات على وحدة التّخزين المنطقيّة الأصليّة. عند إنشاء لقطة ما، فالحجم المُخصّص يكون أقصى حدّ يُمكن للقطة أن تصل إليه (اللقطات التي تزيد عن هذا الحجم مُعطّلة وغير قابلة للاستخدام؛ لكن يُمكن توسيع اللقطات التي تقترب من هذا الحجم): sudo lvcreate -s -L 10G -n snap_test LVMVolGroup/test تنبيه: لإعادة وحدة تخزين إلى الحالة التي تتواجد بها اللقطة، استخدم الأمر lvconvert --merge: sudo lvconvert --merge LVMVolGroup/snap_test سيقوم هذا الأمر بإعادة اللقطة إلى الحالة التي كانت عليها عندما تمّ إنشاؤها. كما ترى، هناك العديد من الخيارات التي يُمكن لها أن تُغيّر طريقة عمل وحدة التخزين المنطقيّة بشكل كبير. زيادة حجم وحدة تخزين منطقيّة المرونة في التّعامل مع وحدات التّخزين المنطقيّة من أكثر المميّزات المتوفّرة في LVM. إذ يُمكنك بسهولة تعديل عدد أو حجم وحدات التّخزين المنطقيّة دون إيقاف النّظام. لزيادة حجم وحدة تخزين منطقيّة أنشئت مُسبقا، استعمل الأمر lvresize. مرّر قيمة إلى الخيار -L لتحديد حجم جديد. يُمكنك كذلك استخدام أحجام نسبيّة عبر الرّمز +. في هذه الحالة سيقوم LVM بإضافة الكميّة المُحدّدة إلى الحجم الكلي لوحدة التّخزين. لتعديل حجم نظام الملفّات المُستخدم على وحدة التّخزين بشكل آلي، استعمل الخيار --resizefs. لتحديد اسم صحيح لوحدة التّخزين التي ترغب بتوسيعها، سيتوجّب عليك تحديد مجموعة التّخزين، ثمّ رمز / متبوعا باسم وحدة التّخزين المنطقيّة: sudo lvresize -L +5G --resizefs LVMVolGroup/test في هذا المثال، سيتمّ زيادة 5G لكل من وحدة التّخزين test ونظام الملفّات المُستخدم. إن أردت توسيع نظام الملفّات يدويًّا، يُمكنك حذف الخيار --resizefs واستعمال أداة توسيع نظام الملفّات الخاصّة. مثلا، لو كان نظام الملفّات هو Ext4 فيُمكن أن تكتب: sudo lvresize -L +5G LVMVolGroup/test sudo resize2fs /dev/LVMVolGroup/test سيكون لهذه العمليّة نفس تأثير ما سبق. ترجمة – بتصرّف - للمقال How To Use LVM To Manage Storage Devices on Ubuntu 16.04 لكاتبه Justin Ellingwood.
  24. مُقدّمة LVM اختصار لعبارة Logical Volume Management، عبارة عن تقنيّة لإدارة أجهزة التّخزين تُمكّن المُستخدمين من توحيد وتجريد التّخطيط الماديّ لمكونات أجهزة التّخزين، لإدارتها بسهولة ومرونة. يُمكن استعمال النّسخة الحاليّة LVM2 بالاعتماد على إطار العمل الخاصّ بربط الأجهزة في نواة لينكس لجمع أجهزة التّخزين المُتوفّرة في مجموعات وتخصيص وحدات منطقيّة Logical units من المساحة المُركّبة حسب الطّلب. سنتعرّف في هذا الدليل على كيفية استخدام LVM لإدارة أجهزة التّخزين الخاصّة بك. سنرى كيفيّة عرض معلومات حول وحدات التّخزين وأهداف مُحتملة، كيفيّة إنشاء ومحو مُختلف أنواع وحدات التّخزين، وكيفيّة تعديل وحدات تخزينيّة متواجدة عبر إعادة تخصيص حجم لها وتحويلها. سنعتمد على Ubuntu 16.04 لأمثلة على تنفيذ هذه العمليّات. المُتطلّبات لمُتابعة الدّرس، يجب أن تكون قادرا على الوصول إلى خادوم Ubuntu 16.04. ستحتاج إلى مُستخدم ذي صلاحيّات sudo مع ضبط مُسبق لتمكينه من تنفيذ مهام إداريّة، غير المستخدم الجذر root. لأخذ فكرة حول مكوّنات LVM ومبادئه ولاختبار إعداد بسيط باستخدام LVM، اتّبع درس مدخل إلى LVM قبل الشّروع في هذا الدّرس. إن كنت جاهزا، ادخل إلى خادومك باستخدام حساب المُستخدم ذي صلاحيّات sudo. ملحوظة: يُفضَّل إن كانت هذه أول مرة تتعامل فيها مع LVM أو إن لم تكن متأكّدا من ما تريد فعله أن تختبر الخطوات المعروضة في هذا الدليل في آلة افتراضية أو على خادوم خاصّ بأغراض التجربة والاختبار. قد يؤدّي تنفيذ أوامر بطريقة غير صحيحة إلى ضياع البيانات. عرض معلومات حول وحدات التّخزين الماديّة، مجموعات التّخزين، ووحدات التّخزين المنطقيّة من المُهمّ أن تكون قادرا على الحصول على معلومات حول مُختلف مُكوّنات LVM في نظامك بسهولة. لحسن الحظّ، توفّر حزمة أدوات LVM كميّة وفيرة من الأدوات لعرض معلومات حول كلّ طبقة من طبقات كومة LVM. عرض معلومات حول جميع أجهزة التّخزين الكتليّة المتوافقة مع LVM لعرض جميع أجهزة التّخزين الكتليّة التي يُمكن لـLVM إدارتها، استخدم الأمر lvmdiskscan: sudo lvmdiskscan المُخرَج: /dev/ram0 [ 64.00 MiB] /dev/sda [ 200.00 GiB] /dev/ram1 [ 64.00 MiB] . . . /dev/ram15 [ 64.00 MiB] /dev/sdb [ 100.00 GiB] 2 disks 17 partitions 0 LVM physical volume whole disks 0 LVM physical volumes بتجاهل أجهزة /dev/ram* (التي تُعتبر جزءا من قرص الذاكرة العشوائيّة في لينكس)، يُمكننا مُلاحظة الأجهزة التي يُمكن استخدامها لتشكيل وحدات تخزين ماديّة لـLVM. ستكون هذه الخطوة في الغالب أول خطوة لتحديد أجهزة تخزين لاستعمالها مع LVM. عرض معلومات عن وحدات التّخزين الماديّة تُكتَب ترويسة Header على أجهزة التّخزين لتعليمها على أنها مكوّنات يُمكن لـLVM استخدامها. الأجهزة التي تحمل ترويسة تُسمّى بوحدات التّخزين الماديّة Physical Volumes. يُمكنك عرض جميع أجهزة التّخزين الماديّة على جهازك عبر استخدام الأمر lvmdiskscan مع خيار -l، ما سيُرجع وحدات التّخزين الماديّة فقط في نتيجة تنفيذ الأمر: sudo lvmdiskscan -l المُخرج: WARNING: only considering LVM devices /dev/sda [ 200.00 GiB] LVM physical volume /dev/sdb [ 100.00 GiB] LVM physical volume 2 LVM physical volume whole disks 0 LVM physical volumes الأمر pvscan مُشابه لما سبق، إذ يبحث عن جميع وحدات التّخزين الماديّة الخاصّة بـLVM. إلّا أنّ تنسيق المُخرج مُختلف نوعا ما، إذ يعرض معلومات إضافيّة: sudo pvscan المُخرج: PV /dev/sda VG LVMVolGroup lvm2 [200.00 GiB / 0 free] PV /dev/sdb VG LVMVolGroup lvm2 [100.00 GiB / 10.00 GiB free] Total: 2 [299.99 GiB] / in use: 2 [299.99 GiB] / in no VG: 0 [0 ] إن كنت ترغب بالحصول على المزيد من المعلومات، فاستعمال الأمرين pvs وpvdisplay خيار أفضل. يتميّز الأمر pvs بقابليّة تخصيصه وإمكانيّة استخدامه لعرض المعلومات في عدّة أشكال وتنسيقات مُختلفة. ولأنّ مُخرجات الأمر قابلة للتّخصيص، فاستخدامه شائع في السكريبتات أو عند الحاجة إلى أتمتة الأمور Automation. تُوفّر المُخرجات الأساسيّة للأمر خلاصة مُفيدة مُشابهة لما سبق: sudo pvs المُخرج: PV VG Fmt Attr PSize PFree /dev/sda LVMVolGroup lvm2 a-- 200.00g 0 /dev/sdb LVMVolGroup lvm2 a-- 100.00g 10.00g لمعلومات أكثر إسهابا وقابليّة للقراءة، فالأمر pvdisplay عادة ما يكون خيارا أفضل: sudo pvdisplay المُخرج: --- Physical volume --- PV Name /dev/sda VG Name LVMVolGroup PV Size 200.00 GiB / not usable 4.00 MiB Allocatable yes (but full) PE Size 4.00 MiB Total PE 51199 Free PE 0 Allocated PE 51199 PV UUID kRUOyU-0ib4-ujPh-kAJP-eeQv-ztRL-4EkaDQ --- Physical volume --- PV Name /dev/sdb VG Name LVMVolGroup PV Size 100.00 GiB / not usable 4.00 MiB Allocatable yes PE Size 4.00 MiB Total PE 25599 Free PE 2560 Allocated PE 23039 PV UUID udcuRJ-jCDC-26nD-ro9u-QQNd-D6VL-GEIlD7 كما ترى، فالأمر pvdisplay أسهل أمر للحصول على معلومات مُفصّلة عن وحدات التّخزين الماديّة. لاستكشاف المدااءات المنطقيّة المُرتبطة بكلّ وحدة تخزين، مرّر الخيار -m إلى الأمر pvdisplay: sudo pvdisplay -m المُخرج: --- Physical volume --- PV Name /dev/sda VG Name LVMVolGroup PV Size 200.00 GiB / not usable 4.00 MiB Allocatable yes PE Size 4.00 MiB Total PE 51199 Free PE 38395 Allocated PE 12804 PV UUID kRUOyU-0ib4-ujPh-kAJP-eeQv-ztRL-4EkaDQ --- Physical Segments --- Physical extent 0 to 0: Logical volume /dev/LVMVolGroup/db_rmeta_0 Logical extents 0 to 0 Physical extent 1 to 5120: Logical volume /dev/LVMVolGroup/db_rimage_0 Logical extents 0 to 5119 . . . يُمكن لهذا الأمر أن يكون مُفيدا لك عند الرّغبة في تحديد أي بيانات تتواجد في أي من الأقراص الماديّة لأغراض إداريّة. عرض معلومات عن مجموعات التّخزين Volume Groups يحتوي LVM على العديد من الأدوات التّي يُمكن بها عرض معلومات حول مجموعات التّخزين. يُستعملُ الأمر vgscan لفحص النّظام عن مجموعات التّخزين المتوفّرة. بالإضافة إلى إعادة بناء ملفّ التّخبئة Cache عند الحاجة. ويُعدّ أمرا جيّدا للاستخدام عند استيراد مجموعة تخزين إلى نظام جديد: sudo vgscan المُخرج: Reading all physical volumes. This may take a while... Found volume group "LVMVolGroup" using metadata type lvm2 المُخرج لا يُعطي الكثير من المعلومات، لكن يجب عليه أن يكون قادرا على إيجاد جميع مجموعات التّخزين على النّظام. لعرض المزيد من المعلومات، فالأمران vgs و vgdisplay مُتوفّران لذلك. تماما مثل مثيله المُخصّص لوحدات التّخزين الماديّة، فالأمر vgs مُتعدّد الاستعمالات ويُمكن له أن يعرض كميّة ضخمة من المعلومات في أشكال مُتعدّدة. ولأنّ إمكانيّة تخصيص مُخرجات الأمر عاليّة المرونة، فاستخدامه في برمجة السكريبتات والأتمتة أمر شائع. على سبيل المثال، من الأمور المُفيدة التي يُمكنك فعلها هي تخصيص المُخرج ليعرض فقط الأجهزة الماديّة ومسار وحدات التّخزين المنطقيّة: sudo vgs -o +devices,lv_path المُخرج: VG #PV #LV #SN Attr VSize VFree Devices Path LVMVolGroup 2 4 0 wz--n- 299.99g 10.00g /dev/sda(0) /dev/LVMVolGroup/projects LVMVolGroup 2 4 0 wz--n- 299.99g 10.00g /dev/sda(2560) /dev/LVMVolGroup/www LVMVolGroup 2 4 0 wz--n- 299.99g 10.00g /dev/sda(3840) /dev/LVMVolGroup/db LVMVolGroup 2 4 0 wz--n- 299.99g 10.00g /dev/sda(8960) /dev/LVMVolGroup/workspace LVMVolGroup 2 4 0 wz--n- 299.99g 10.00g /dev/sdb(0) /dev/LVMVolGroup/workspace لمُخرج أكثر إسهابا وقابليّة للقراءة، فالأمر vgdisplay عادة ما يكون خيارا أفضل. إضافة الخيار -v يُوفّر كذلك معلومات حول وحدات التّخزين الماديّة التّي تُشكّل مجموعة التّخزين، بالإضافة إلى وحدات التّخزين المنطقيّة التي تمّ إنشاءها باستخدام مجموعة التّخزين: sudo vgdisplay -v المُخرج: Using volume group(s) on command line. --- Volume group --- VG Name LVMVolGroup . . . --- Logical volume --- LV Path /dev/LVMVolGroup/projects . . . --- Logical volume --- LV Path /dev/LVMVolGroup/www . . . --- Logical volume --- LV Path /dev/LVMVolGroup/db . . . --- Logical volume --- LV Path /dev/LVMVolGroup/workspace . . . --- Physical volumes --- PV Name /dev/sda . . . PV Name /dev/sdb . . . الأمر vgdisplay مُفيد لقُدرته على الرّبط بين المعلومات حول مُختلف عناصر كومة LVM. عرض معلومات حول وحدات التّخزين المنطقيّة يمتلك LVM مجموعة من الأدوات لعرض معلومات عن وحدات التّخزين المنطقيّة كذلك. كما الحال مع مُكوّنات LVM الأخرى، يُمكن استعمال الأمر lvscan لفحص النّظام وعرض معلومات وجيزة حول وحدات التّخزين المنطقيّة التي يجدها: sudo lvscan المُخرج: ACTIVE '/dev/LVMVolGroup/projects' [10.00 GiB] inherit ACTIVE '/dev/LVMVolGroup/www' [5.00 GiB] inherit ACTIVE '/dev/LVMVolGroup/db' [20.00 GiB] inherit ACTIVE '/dev/LVMVolGroup/workspace' [254.99 GiB] inherit لمعلومات أكثر كمالا، يُمكنك استخدام الأمر lvs الذي يتمتّع بمرونة وقوّة بالإضافة إلى سهولة استخدامه في السكربتات: sudo lvs المُخرج: LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert db LVMVolGroup -wi-ao---- 20.00g projects LVMVolGroup -wi-ao---- 10.00g workspace LVMVolGroup -wi-ao---- 254.99g www LVMVolGroup -wi-ao---- 5.00g لإيجاد عدد شرائط Stripes وحدة التّخزين المنطقيّة ونوعها، استعمل الخيار --segments: sudo lvs --segments المُخرج: LV VG Attr #Str Type SSize db LVMVolGroup rwi-a-r--- 2 raid1 20.00g mirrored_vol LVMVolGroup rwi-a-r--- 3 raid1 10.00g test LVMVolGroup rwi-a-r--- 3 raid5 10.00g test2 LVMVolGroup -wi-a----- 2 striped 10.00g test3 LVMVolGroup rwi-a-r--- 2 raid1 10.00g يُمكن الحصول على أكثر مُخرج قابل للقراءة عبر الأمر lvdisplay. عند إضافة الخيار -m، فستعرض الأداة معلومات حول مكوّنات وحدة التّخزين المنطقيّة وكيفيّة توزيعها: sudo lvdisplay -m المُخرج: --- Logical volume --- LV Path /dev/LVMVolGroup/projects LV Name projects VG Name LVMVolGroup LV UUID IN4GZm-ePJU-zAAn-DRO3-1f2w-qSN8-ahisNK LV Write Access read/write LV Creation host, time lvmtest, 2016-09-09 21:00:03 +0000 LV Status available # open 1 LV Size 10.00 GiB Current LE 2560 Segments 1 Allocation inherit Read ahead sectors auto - currently set to 256 Block device 252:0 --- Segments --- Logical extents 0 to 2559: Type linear Physical volume /dev/sda Physical extents 0 to 2559 . . . كما تُلاحظ من الجزء السّفلي للمُخرج أعلاه، فوحدة التّخزين المنطقيّة /dev/LVMVolGroup/projects متواجدة بالكامل على وحدة التّخزين الماديّة /dev/sda في هذا المثال. هذه المعلومة مُفيدة إن كنت ترغب بإزالة جهاز التّخزين المُعتمد عليه وتريد نقل البيانات إلى مكان مُحدّد. رأينا في هذا الجزء من الدليل كيفية عرض معلومات عن مختلف المكوّنات في LVM. سنكمل في الأجزاء التالية بقيّة المهام الإدارية. ترجمة – بتصرّف - للمقال How To Use LVM To Manage Storage Devices on Ubuntu 16.04 لكاتبه Justin Ellingwood.
  25. يتناول هذا المقال تثبيت بيئة تطوير Ruby on Rails على الإصدار 16.04 من أوبونتو. في أغلب الأحوال ستُنفَّذ الشفرة البرمجيّة التي تكتبها على خادوم لينكس، وأوبونتو هي إحدى توزيعات لينكس الأسهل استخداما وتوجد الكثير من الموارد عنها على الشبكة. تثبيت Ruby أول ما يجب علينا فعله هو تثبيت الاعتماديات Dependencies التي يحتاجها Ruby للعمل. نبدأ أولا بتحديث فهرس الحزم ثم تثبيت الاعتماديّات: sudo apt update sudo apt install git-core curl zlib1g-dev build-essential libssl-dev libreadline-dev libyaml-dev libsqlite3-dev sqlite3 libxml2-dev libxslt1-dev libcurl4-openssl-dev python-software-properties libffi-dev nodejs الخطوة الموالية هي تثبيت Ruby. توجد طرق عدّة للتثبيت، سنستخدم rbenv وهي أداة خفيفة وسريعة لإدارة إصدارات Ruby. نبدأ بتثبيت rbenv : cd git clone https://github.com/rbenv/rbenv.git ~/.rbenv echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc echo 'eval "$(rbenv init -)"' >> ~/.bashrc exec $SHELL الأداة rbenv جاهزة الآن. سنثبّت ruby-build وهي إضافة تعمل مع الأداة rbenv وتتيح تثبيت إصدارات عدّة من Ruby في مجلّدات مختلفة على نفس النظام. git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build echo 'export PATH="$HOME/.rbenv/plugins/ruby-build/bin:$PATH"' >> ~/.bashrc exec $SHELL ثم نثبّت الإصدار 2.4.0 من Ruby: TMPDIR=~/tmp/ rbenv install 2.4.0 rbenv global 2.4.0 يُثبّت الأمر الأول الإصدار المطلوب ضمن مجلّد العمل حيث نُفِّذ الأمر؛ في ما يضبط الأمر الثاني إصدار Ruby المبدئي، أي الإصدار الذي سيُستخدَم عند عدم تحديد إصدار. للتأكد من تثبيت Ruby والإصدار المثبّت ننفذ الأمر: ruby -v الذي يُظهر نتيجة تشبه التالي: ruby 2.4.0p0 (2016-12-24 revision 57164) [x86_64-linux] الخطوة الأخيرة هي تثبيت Bundler الذي يوفّر بيئة تطوير متجانسة لـ Ruby عبر تتبّع الاعتماديات وتثبيت الإصدارات المطلوبة منها بالضبط: gem install bundler وتنفيذ الأمر لأخذ التثبيت الجديد في الحسبان: rbenv rehash تثبيت Rails يتضمّن إطار العمل Rails الكثير من الاعتماديات، لذا سنحتاج لبيئة تنفيذ JavaScript مثل NodeJS التي ستمكّننا من استخدام مكتبات تتيح إمكانيّة جمع وضغط ملفات جافاسكريبت من أجل الحصول على بيئة تطوير أسرع. نثبّت NodeJS من المستودع الرسمي على النحو التالي: curl -sL https://deb.nodesource.com/setup_4.x | sudo -E bash - sudo apt install -y nodejs ثم نثبّت Rails: gem install rails -v 5.0.1 ثم ننفذ الأمر التالي ليمكننا استخدام Rails: rbenv rehash Rails مثبّت الآن، يمكننا التأكّد من ذلك بتنفيذ الأمر التالي الذي يُظهر رقم الإصدار المثبت: rails -v إعداد قاعدة بيانات MySQL يأتي Rails مبدئيا بقاعدة بيانات sqlite3؛ إلا أن هذا النوع من قواعد البيانات لا يناسب تطبيقات كثيرة. يمكن في هذه الحالة إعداد Rails للعمل مع قاعدة بيانات MySQL (أو PostgreSQL). نثبّت خادوم وعميل MySQL من المستودعات الرسمية لأوبونتو: sudo apt install mysql-server mysql-client libmysqlclient-dev سيُطلَب منك خلال التثبيت إنشاءُ كلمة سر خاصة بالحساب الإداري root (انتبِه إلى أنّه حساب خاص بنظام MySQL لإدارة قواعد البيانات، وليس لنظام التشغيل أوبونتو). تتضمّن الحزمة libmysqlclient-dev الملفات الضرورية لتثبيت الاعتماديّات التي يحتاجها Rails للاتصال بقاعدة بيانات MySQL. ننفّذ بعد تثبيت MySQL الأمريْن التاليّيْن لتحضير قاعدة البيانات لبيئة الإنتاج (يمكنك تجاوز هذه الخطوة إن كنت تثبّت Rails على حاسوب شخصي): sudo mysql_install_db sudo mysql_secure_installation سيُطلب منك النّظام إدخال كلمة سرّ الحساب الجذر في MySQL؛ ثمّ يسألك ما إذا كنتَ تُريد تغييرها. أدخل حرف n (دلالةً على “no” أي “لا”) إن لم تكن ترغبُ في ذلك. بالنسبة لبقية الأسئلة يمكنك قبول القيم المبدئية بالنقر على زرّ Enter. أول تطبيق Rails حان الوقت الآن لتشغيل أول تطبيق Ruby on Rails. ننشئ تطبيقا باسم myapp يستخدم قاعدة البيانات MySQL: rails new myapp -d mysql انتظر اكتمال إنشاء التطبيق الذي قد يستغرق وقتا، ثم انتقل إلى مجلد التطبيق: cd myapp عدّل الملف config/database.yml بإضافة كلمة سر الحساب الإداري لقاعدة البيانات (أعددناها أثناء تثبيت MySQL، يمكنك تركها فارغة إن لم تكن أعددتَ كلمة سر لـ MySQL): default: &default adapter: mysql2 encoding: utf8 pool: 5 username: root password: socket: /var/run/mysqld/mysqld.sock اكتب كلمة السر أمام التعليمة password ضمن المقطع السابق الموجود أعلى الملف بعد التعليقات الأولى (تبدأ التعليقات بالعلامة #)؛ ثم نفّذ الأمر التالي لإنشاء قاعدة البيانات التي سيعمل عليها التطبيق: rake db:create النتيجة: Created database 'myapp_development' Created database 'myapp_test' إن واجهك خطأ Access denied for user 'root'@'localhost' (using password: NO) فهذا يعني أنك لم تكتب كلمة السر بطريقة صحيحة. نشغل خادوم التطوير: rails server يمكنك بعد تشغيل خادوم التطوير إدخال العنوان http://localhost:3000/ في المتصفح لمعاينة صفحة التطبيق المبدئي في Rails. إعداد Git هذه الخطوة اختيارية ولكنه تفيدك إن كنت تخطّط لاستعمال Git لإدارة إصدارات المشروع وربطه بحسابك على Github. أبدل YOUR NAME وYOUR@EMAIL.com في الأوامر أدناه على التوالي باسمك والبريد الذي استخدمته للتسجيل على Github. git config --global color.ui true git config --global user.name "YOUR NAME" git config --global user.email "YOUR@EMAIL.com" ssh-keygen -t rsa -b 4096 -C "YOUR@EMAIL.com" يُولّد الأمر الأخير في الأوامر أعلاه زوج مفاتيح SSH سنستخدمها في ما بعد للاتصال بحسابنا على Github. يضع الأمر ssh-keygen مبدئيا زوج المفاتيح على المسار ssh./~. نأخذ المفتاح العمومي الذي يوجد بملف المفتاح ذي الامتداد pub، ويُسمّى مبدئيا id_rsa.pub وننسخه ضمن مفاتيح SSH على حسابنا في Github الموجودة هنا. انقر على الزّر New SSH Key، أعط للمفتاح اسما تختاره ثم ألصق في الحقل الثاني محتوى الملف ssh/id_rsa.pub/~ الذي يمكن الحصول عليه بالأمر التالي، ثم انقر على زرّ Add SSH Key لاعتماد المفتاح: cat ~/.ssh/id_rsa.pub يمكنك التأكد من نجاح العملية بتنفيذ الأمر التالي: ssh -T git@github.com يجب أن تظهر لك رسالة تشبه التالي (يُذكَر فيها اسم حسابك على Github): Hi Zeine77! You've successfully authenticated, but GitHub does not provide shell access. ترجمة - بتصرّف - للمقال Setup Ruby On Rails on Ubuntu 16.04 Xenial Xerus.