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



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

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

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

نوع المُحتوى


التصنيفات

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

التصنيفات

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

التصنيفات

  • تجربة المستخدم
  • الرسوميات
    • إنكسكيب
    • أدوبي إليستريتور
    • كوريل درو
  • التصميم الجرافيكي
    • أدوبي فوتوشوب
    • أدوبي إن ديزاين
    • جيمب
  • التصميم ثلاثي الأبعاد
    • 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

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

  1. 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
  2. عندما تُنشئ خادم أوبونتو 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
  3. 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.
  4. 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.
  5. 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.
  6. 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.
  7. عند إنشاءك خادم أوبونتو 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.
  8. حاوية لينكس (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.
  9. 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
  10. نشرح طريقة تثبيت Monit على نظام أوبنتو. وسنشرح كمثال كيفية إعداد Monit لمراقبة وإعادة تشغيل Nginx في حال توقفه. قسم DevOps في أكاديمية حسوب غني بالمقالات المفيدة للتعامل مع الخوادم.
  11. نشرح طريقة تثبيت وإعداد خادم Nginx على توزيعة أوبنتو، وسنستعمله لتخديم صفحات HTML الخاصة بنا. لتثبيت خادم أباتشي راجع فيديو تثبيت وضبط خادم Apache في أكاديمية حسوب. قسم خوادم الويب في أكاديمية حسوب غني بالمقالات المفيدة للتعامل معها.
  12. 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
  13. نحن نبني أغلب أعمالنا على خوادم مبنية على 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
  14. تزداد شعبية 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.
  15. بروتوكول نقل الملفات 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
  16. من المهم جدًا الحفاظ على دقة وقت النظام، سواءً فعلنا ذلك للحرص على دقة ترتيب السجلات (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
  17. تعرّفنا في الجزأين السابقيْن من هذا الدليل على كيفية عرض معلومات عن مساحات التخزين وإنشاء مساحات تخزين جديدة وتحجيمها. سنكمل في هذا الجزأ - الأخير من الدليل - ما تعلمناه سابقا ونتعرّف على المهمة الأخيرة من بين المهمّات الأساسية في إدارة التخزين بآلية 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.
  18. بعد أن تعرّفنا في الجزء السابق على كيفية عرض معلومات عن مختلف العناصر في 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.
  19. مُقدّمة 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.
  20. يتناول هذا المقال تثبيت بيئة تطوير 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.
  21. توجد بعض الإعدادات التي يجب إجراؤها في البداية كجزء من عملية التثبيت الأولية عند إنشاء خادوم جديد. تؤدي هذه الخطوات إلى تعزيز أمان وقابلية استخدام Usability خادومك ممّا يعطيك أساسًا صلبا للإجراءات اللاحقة. الخطوة الأولى - الولوج Login إلى الحساب الجذر Root يتوجّب عليك، للولوج إلى خادومك، معرفة عنوان IP العمومي Public IP Address إضافةً إلى كلمة سر حساب المستخدم الجذر. إن لم تكن قمتَ بالولوج إلى خادومك من قبل فبإمكانك الاطّلاع على الدرس أساسيات وخيارات الاتصال بخادوم عن بعد باستخدام SSH (البرنامج المسؤول عن الاتصال بالخادوم عن بعد)، الذي يُغطي هذه العملية بالتفصيل. ابدأ بالاتصال بخادومك عن طريق الأمر التّالي (أبدِل الكلمة البارزة بعنوان IP خادومك العمومي): ssh root@SERVER_IP_ADDRESS أكمِل عملية الولوج بقبول التحذيرات حول موثوقية المستضيف Host authenticity في حال ظهورها، وإعطاء معلومات التحقق (كلمة السّر أو المفتاح السري). سيُطلب منك تبديل كلمة سر حساب المستخدِم الجذر إن كانت هذه أول مرة تلِج إلى الخادوم باستخدام كلمة السر. حول المستخدم الجذر المستخدم الجذر هو المُدير في أنظمة لينوكس، ولديه امتيازات Privileges واسعة جدًًا. عمليًا، يُنصَح بعدم استخدام الحساب الجذر في الأمور الاعتيادية، فالصلاحيات الواسعة التي يتمتع بها تُتيح إحداث تغييرات - قد تكون مدمِّرة - في النظام . وليسَ نادرا أن يحدث ذلك بشكل غير مقصود. الخطوة الموالية ستكون إنشاء حساب مستخدم بديل بمجال تأثير محدود للقيام بالعمل اليومي. ستتعلّم أيضًا كيفية الحصول على امتيازات أكبر عندما تحتاج إليها. الخطوة الثانية - إنشاء مستخدم جديد بعد الولوج باستخدام الحساب الجذر تُصبِح على استعداد لإضافة الحساب الجديد الذي سنلِج باستخدامه من الآن فصاعدا. يُنشئ المثال التالي مستخدما باسم "demo"، أبدِلهُ باسم المستخدم الذي تراه مناسِبا: adduser demo ستُطرَح عليك بعض الأسئلة، بدءًا بكلمة سرالحساب. أدخِل كلمة سر قوية. يُمكنك تعبئة بقية المعلومات الإضافية حسب رغبتك. اضغط على زر Enter في لوحة المفاتيح لتجاوز أي حقل لا تودّ تعبئته. الخطوة الثالثة - امتيازات الجذر لدينا الآن حساب مستخدم جديد بامتيازات حساب عادي. سنحتاج في بعض الأحيان إلى القيام ببعض الأعمال الإدارية التي تتطلّب امتيازات الجذر. نستطيع إعداد "مستخدم أعلى" Super user لتجنب الخروج من الحساب العادي والولوج بالحساب الجذر أثناء القيام بالمهام الإدارية. المستخدم الأعلى هو مستخدم عادي ولكنه يستطيع الحصول على امتيازات المستخدم الجذر مؤقتا عن طريق كتابة sudo أمام الأوامر التي يطلب تنفيذها. يتوجّب علينا إضافة المستخدم الجديد إلى مجموعة المستخدمين Users group sudo حتى يتسنى له الحصول على الامتيازات الإدارية. يُسمَح - في الإعداد الافتراضي لأوبنتو 14.04 - للمستخدمين الأعضاء في مجموعة sudo باستخدام أمر sudo. نفّذ باستخدام الحساب الجذر، الأمر التالي لإضافة المستخدم الجديد إلى المجموعة sudo (أبدِل الكلمة البارزة بالاسم الذي اخترتَه للمستخدم الجديد): gpasswd -a demo sudo يُمكِن للمستخدِم الجديد الآن تنفيذ أوامر بامتيازات المستخدِم الأعلى. الخطوة الرابعة - إضافة الاستيثاق عن طريق المفتاح العمومي Public Key Authentication (يوصى بهذه الخطوة) الخطوة التالية في تأمين خادومك هي إعداد مفتاح عمومي Public Key للمستخدم الجديد. هذا الإعداد سيرفع من أمان خادومك بطلب مفتاح SSH سري للولوج. توليد زوج من المفاتيح سيتوجّب عليك توليد زوج مفاتيح (مفتاح عمومي وآخر سرّي). إن كان لديك مفتاح عمومي ترغب في استخدامه تجاوز إلى خطوة نسخ المفتاح العمومي. لتوليد زوج مفاتيح جديدة نفِّذ الأمر التالي على الطّرفيةTerminal محليًّا (على حاسوبك الشخصي): ssh-keygen ستظهر لك مُخرجات شبيهة بما يلي (localuser هنا هو اسم المستخدم الذي يُنفِّذ الأمر): Generating public/private rsa key pair. Enter file in which to save the key (/Users/localuser/.ssh/id_rsa): اضغط زر Enter على لوحة المفاتيح لقبول اسم ومسار حفظ الملف، أو أدخل مسارا لملف جديد. سيُطلب منك بعدها إدخال عبارة سر Passphrase لتأمين المفتاح. عبارة السّر اختيارية ويُمكنك تجاوزها وتركها خاوية. ملحوظة: عند ترك عبارة السر خاوية يُمكن استخدام المفتاح السري للاستيثاق دون الحاجة لإدخال عبارة سر، أما في حال إنشاء عبارة سر فستحتاج للإثنين (عبارة السر والمفتاح السري) للولوج. إنشاء عبارة سر يُعطي أمانا أكبر ولكن لكل من الطريقتين (المفتاح السري وحده أو مع عبارة سر) استخداماتُها، كما أنهما أكثر أمانا من الاستيثاق الأساسي عن طريق كلمة سر. حصلنا الآن على مفتاح سري (id_rsa)، وآخر عمومي (id_rsa.pub) يوجدان في المجلَّد ssh. الموجود في المجلّد الشخصي للمستخدم localuser. تذكَّر أنه لا يجوز على الإطلاق مُشاركة المفتاح السري مع أي شخص لا يحق له الاتصال بخواديمك. نسخ المفتاح العمومي بعد توليد المفتاح العمومي محليًّا ننقلهُ إلى الخادوم. استخدم الأمر التالي لإظهار مفتاحك العمومي (أبدِل مسار الملف في حال غيّرت مسار الحفظ أثناء توليد المفتاح) cat ~/.ssh/id_rsa.pub سيظهر مفتاحك العمومي الذي يُشبه شكلُه التالي: ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDBGTO0tsVejssuaYR5R3Y/i73SppJAhme1dH7W2c47d4gOqB4izP0+fRLfvbz/tnXFz4iOP/H6eCV05hqUhF+KYRxt9Y8tVMrpDZR2l75o6+xSbUOMu6xN+uVF0T9XzKcxmzTmnV7Na5up3QM3DoSRYX/EP3utr2+zAqpJIfKPLdA74w7g56oYWI9blpnpzxkEd3edVJOivUkpZ4JoenWManvIaSdMTJXMy3MtlQhva+j9CgguyVbUkdzK9KKEuah+pFZvaugtebsU+bllPTB0nlXGIJk98Ie9ZtxuY3nCKneB+KjKiXrAvXUPCI9mWkYS/1rggpFmu3HbXBnWSUdf localuser@machine.local حدّد المفتاح العمومي وانسخه إلى الحافِظة Clipboard. إضافة المفتاح العمومي إلى المستخدم الجديد على الخادوم يجب إضافة مفتاح SSH إلى ملف خاص يوجد بالمجلد الشخصي للمستخدِم على الخادوم حتى يتسنى له استعمالُه للاستيثاق. استعمل الأمر التالي - على الخادوم - للانتقال من المستخدِم الجذر إلى المستخدِم الذي أنشأناه في الخطوات الأولى من هذا الدّليل (أبدِل demo باسم المستخدِم الذي اخترتَه): su - demo ستُنقَل بعدَ الولوج إلى الخادوم إلى ملف المستخدم الشخصي. أنشئ مجلَّدا فرعيا جديدا في المجلّد الشخصي باسم ssh. (النقطة جزء من الاسم) مع تقييد الأذون Permissions عن طريق الأوامر التالية: mkdir .ssh chmod 700 .ssh سنُنشئ الآن ملفًا باسم authorized_keys مع فتحه عن طريق محرِّر نصوص. سنستخدِم محرِّر Nano للتعديل على الملف، كما في الأمر التالي: nano .ssh/authorized_keys ثم نأتي لإدراج المفتاح العمومي في الملف عن طريق لصقه في المحرِّر. اضغط على الزريْن CTRL و X معًا في لوحة المفاتيح للخروج من المحرِّر ثم زر Y لحفظ التغييرات وEnter لتأكيد اسم الملف. نُقيّد الأذون على الملف authorized_keys عن طريق الأمر: chmod 600 .ssh/authorized_keys للعودة إلى المستخدِم الجذر ننفِّذ الأمر التالي: exit بإمكانك الآن الولوج إلى حساب المستخدم الجديد عن طريق SSH باستخدام المفتاح السري. الخطوة الخامسة - إعداد SSH يُمكننا، بعد أن أنشأنا حسابَ مستخدم جديدًا، زيادة تأمين الخادوم عن طريق تغيير إعداد SSH . نبدأ بفتح ملف الإعدادات بواسطة محرِّر نصوص مع استعمال المستخدِم الجذر: nano /etc/ssh/sshd_config تغيير منفذ Port الاتصال عن طريق SSH (اختياري) أولى التغييرات ستكون تعديل المنفذ الذي يستخدمه SSH للاتصال بالخادوم. ابحث عن السّطر التالي: Port 22 عند تغيير هذا الرقم إلى آخر بين 1025 و 65536 فإن خدمة SSH ستستخدم المنفذ الجديد للاتصال بالخادوم بدلا من المنفذ الافتراضي (22). يُحاول بعض المستخدمين غير المسموح لهم بالولوج استعمال منفذ SSH الافتراضي الوصول إلى الخادوم. تغيير المنفذ يعني إضافة خطوات جديدة أمام هذا النوع من المستخدمين لأنه يضطرهم إلى تجربة منافذ عديدة لمعرفة أيها يُستخدم من طرف SSH. يجب عند تغيير منفذ SSH تذكر رقم المنفذ الجديد حتى يُمكن الاتصال عن بعد بالخادوم. سنُغيِّر منفذ SSH إلى 4444. يعني هذا أنه يتوجب إخبار الخادوم عند الاتصال برقم المنفذ المُستخدَم لكي لا يستخدم المنفذ الافتراضي، وهو ما سنشرحه لاحقا. Port 4444 تقييد ولوج المستخدم الجذر عبر SSH بعد تغيير منفذ SSH نبحث عن السّطر التالي: PermitRootLogin yes يُتيح هذا السطر إمكانية السماح للمستخدم الجذر أو منعه من الولوج عن طريق SSH. يُعتبَر هذا الإجراء أكثر أمانا حيثُ يمكن الولوج بالمستخدم العادي عن طريق SSH ثم استخدام صلاحيات المستخدم الجذر عن الحاجة. نُغيّر السطر بإبدال yes ب no لمنع المستخدم الجذر من الولوج عن بعد. PermitRootLogin no يُنصَح دائما، من أجل أمان أكبر، بتقييد ولوج المستخدم الجذر عبر SSH. بعد إنهاء التعديلات احفَظ الملف وأغلقه باستخدام الطريقة التي رأيناها سابقا (CTRL+X، ثم Y و ENTER بعد ذلك). الخطوة السادسة - إعادة تحميل SSH انتهينا الآن من تحرير الإعدادات. لأخذها في الاعتبار نُعيد تشغيل خدمة SSH عن طريق الأمر التالي: service ssh restart يجب أن نتأكد من أن الإعداد الجديد يعمل بشكل جيّد قبل الخروج، حتى لا نجد أنفسَنا في وضعية لا يُمكن فيها الولوج عن بعد إلى الخادوم. افتح نافذة جديدة لواجهة الأوامر على حاسوبك الشخصي. سنجري في النافذة الجديدة اتصالا مع الخادوم باستعمال حساب المستخدم العادي الذي أنشأناه بدلا من المستخدِم الجذر. يجب ذكر رقم منفذ الولوج إلى خادوم لا يستخدم المنفذ الافترضي للاتصال عن طريق SSH وذلك بإضافة العبارة "p 4444-" إلى أمر الاتصال حيثُ 4444 هو رقم المنفذ الجديد. للولوج إلى الخادوم عن طريق المنفَذ الذي أعددناه في الخطوة السابقة نستخدم الأمر التالي (أبدِل SERVER_IP_ADDRESS بعنوان خادومك و demo باسم المستخدِم): ssh -p 4444 demo@SERVER_IP_ADDRESS ملحوظة: لا تنسَ، إن كنت تستخدم برنامج PuTTY، تغيير إعداد المنفَذ في البرنامج حتى يتوافق مع الإعداد الحالي لخادومك. سيُطلب منك إدخال كلمة سر المستخدم الجديد ثم، بعد التحقق، ستلِج إلى المجلد الشخصي للمستخدم على الخادوم. تذكّر إضافة sudo أمام الأوامر التي ترغي في تنفيذها بصلاحيات المستخدِم الجذر: sudo command_to_run حيثُ command_to_run هو الأمر المُراد تنفيذه. إذا جرت الخطوات السّابقة كما وصفناها فإن كل شيء على ما يُرام ويُمكنك الخروج عن طريق الأمر exit ماذا بعد هذا الدرس؟ بالوصول إلى هذه النقطة فإن لدى خادومك أساسا قويا، ويُمكنك تثبيت أي برنامج ترغب فيه عليه. يُمكنك المُتابعة مع هذه السلسة بقراءة مقال خطوات إضافية موصى بها لخواديم أوبنتو 14.04 الجديدة الذي يشرح أمورا من قبيل تفعيل fail2ban للحد من فعاليّة هجمات القوة العمياء Brute force attacks، الإعدادات الأساسية للجدار الناري Firewall، بروتكول NTP وملفات الإبدال Swap. كما أنّ به روابطَ لشروح حول كيفية تثبيت وإعداد بعض تطبيقات الويب الشائعة. مقالات مثل إعداد حِزم LAMP أو LEMP جيّدة لمن يُريد استكشاف المزيد. ترجمة -وبتصرّف- للمقال: Initial Server Setup with Ubuntu 14.04 لصاحبه Justin Ellingwood.
  22. تمهيد كلما كانت صفحات الموقع أسرع تحميلًا كلما ازداد احتمال بقاء الزائر متصفحًا للموقع، وعندما تمتلئ صفحات مواقع الويب بالصور والمحتوى التفاعلي الظاهر عبر سكربتات تُحمَّل في الخلفية، فلن تكون عملية فتح «صفحة» ويب أمرًا هينًا، إذ تتضمن طلب ملفاتٍ عدِّة من خادوم الويب ملفًا ملفًا، وعملية تقليل تلك الطلبيات هي إحدى سُبُل تسريع موقعك. يمكن فعل ذلك بطرائق عدِّة، لكن إحدى أهم الخطوات التي يجب إجراؤها هي ضبط التخزين المؤقت في المتصفح (browser caching)؛ وهذا يعني إخبار المتصفح بإمكانية استخدام نسخ محلية من الملفات التي حُمِّلَت في إحدى المرات بدلًا من طلبها من الخادوم مرارًا وتكرارًا؛ ولفعل ذلك يجب إضافة ترويسات لرد HTTP ‏(HTTP response headers) تخبر المتصفح بما عليك فعله. هذا هو دور وحدة header (‏header module) في خادوم Nginx، التي يمكن استعمالها لإضافة الترويسات إلى رد HTTP، لكن دورها الأساسي يمكن في ضبط الترويسات المسؤولة عن التخزين المؤقت. سننظر في هذا الدرس إلى كيفية استخدام وحدة header لتطبيق الفكرة السابقة. المتطلبات المسبقة ستحتاج قبل إكمال قراءة هذا الدرس إلى ما يلي: خادوم أوبنتو 16.04 (أو 14.04) مضبوطٌ كما في درس «الإعداد الابتدائي لخادوم أوبنتو 14.04»، بما في ذلك إعداد حساب مستخدم عادي لكنه يملك امتيازات الجذر (root) عبر الأداة sudo. خدمة Nginx مثبّتة على خادومك باتباعك لهذا الدرس «تنصيب، إعداد واستخدام nginx كخادوم ويب». سنحتاج بالإضافة إلى وحدة header إلى وحدة map التابعة لخادوم Nginx؛ لمزيدٍ من المعلومات حول وحدة map، فاقرأ درس كيفية استخدام وحدة map على خادوم أوبنتو 16.04. الخطوة الأولى: إنشاء ملفات للتجربة سنُنشِئ في هذه الخطوة عدِّة ملفات في مجلد Nginx، إذ سنستخدم هذه الملفات لاحقًا للتحقق من سلوك خادوم Nginx الافتراضي لاختبار أنَّ التخزين المؤقت في المتصفح يعمل عملًا صحيحًا. لتقرير ما هو نوع الملفات المُخدَّمة عبر الشبكة، فلن يُحلِّل Nginx محتويات الملف لأن ذلك يستهلك وقتًا كثيرًا؛ وإنما سينظر إلى لاحقة (أو امتداد) الملف لتحديد ما هو نوع MIME التابع له، والذي سيُصرِّح عن الهدف أو الغاية من الملف. ونتيجةً لهذا السلوك، فلن يكون لمحتوى الملفات الاختبارية أيّة أهمية؛ إذ سنستطيع خداع خادوم Nginx بتسمية الملفات تسميةً صحيحةً، فقد يظن خادوم Nginx أنَّ ملفًا فارغًا يُمثِّل صورةً وآخر يُمثِّل سكربت JavaScript. لنُنشِئ ملفًا باسم test.html في مجلد Nginx الافتراضي عبر الأداة truncate (يمكنك استخدام أيّة أداة أو أمر آخر وليكن touch مثلًا). لاحقة الملف تُشير إلى أنَّه مستند HTML: sudo truncate -s 1k /var/www/html/test.html لنُنشِئ المزيد من الملفات الاختبارية بنفس الطريقة السابقة: صورة jpg وملف css وسكربت js: sudo truncate -s 1k /var/www/html/test.jpg sudo truncate -s 1k /var/www/html/test.css sudo truncate -s 1k /var/www/html/test.js الخطوة التالية هي التحقق من سلوك خادوم Nginx فيما يتعلق بإرسال ترويسات للتحكم بالتخزين المؤقت للمتصفح وذلك بتخديم الملفات التي أنشأناها أخيرًا مع الضبط الافتراضي له. الخطوة الثانية: التحقق من السلوك الافتراضي لخادوم Nginx يكون لجميع الملفات نفس سلوك التخزين المؤقت افتراضيًا. ولرؤية ذلك سنستخدم ملف HTML الذي أنشأناه في الخطوة الأولى، إلا أنَّك تستطيع إجراء هذا الاختبار على أيّ ملف من الملفات التي أنشأناها سابقًا. لنتحقق من أنَّ الملف test.html يُخدَّم ومعه المعلومات التي لها علاقة بالمدة الواجب تخزين المتصفح للملف فيها مؤقتًا. سيؤدي الأمر الآتي إلى طلب الملف من خادوم Nginx المحلي ويُظهِر ترويسات رد HTTP: curl -I http://localhost/test.html يجب أن ترى عدِّة ترويسات HTTP: HTTP/1.1 200 OK Server: nginx/1.10.0 (Ubuntu) Date: Sat, 10 Sep 2016 13:12:26 GMT Content-Type: text/html Content-Length: 1024 Last-Modified: Sat, 10 Sep 2016 13:11:33 GMT Connection: keep-alive ETag: "57d40685-400" Accept-Ranges: bytes يمكنك أن تلاحظ السطر قبل الأخير الذي يبدأ بالكلمة ETag الذي يتضمن مُعرِّفًا فريدًا للنسخة الحالية من الملف المطلوب. فإذا حاولت تنفيذ أمر curl السابق أكثر من مرة فستجد نفس قيمة ETag. أما عند استخدام متصفح ويب، فستُخزَّن قيمة ETag ثم تُرسَل إلى الخادوم عبر ترويسة If-None-Match عندما يريد المتصفح أن يطلب نفس الملف مرةً أخرى (عند تحديث الصفحة على سبيل المثال). يمكنك محاكاة ذلك في سطر الأوامر بالأمر الآتي. احرص على تغيير قيمة الترويسة If-None-Match في الأمر لتُطابِق قيمة ETag في ناتج الأمر السابق: curl -I -H 'If-None-Match: "57d40685-400"' http://localhost/test.html ستجد أنَّ الرد أصبح مختلفًا الآن: HTTP/1.1 304 Not Modified Server: nginx/1.10.0 (Ubuntu) Date: Sat, 10 Sep 2016 13:20:31 GMT Last-Modified: Sat, 10 Sep 2016 13:11:33 GMT Connection: keep-alive ETag: "57d40685-400" ردّ خادوم Nginx بحالة «‎304 Not Modified»، ولن يُرسِل الملف عبر الشبكة مجددًا، وإنما يخبر المتصفح أنَّه يستطيع إعادة استخدام الملف المُخزَّن محليًا والذي نزَّله سابقًا. ما سبق مفيدٌ لأنه يُقلِّل من التراسل الشبكي، لكنه ليس مثاليًا لتحقيق أداءٍ عالٍ نتيجةٍ للتخزين المؤقت. المشكلة مع ترويسة ETag أنَّ المتصفح سيرسل الطلبية إلى الخادوم دائمًا ويسأله إن كان بإمكانه استخدام الملف المُخزَّن مؤقتًا، وحتى لو ردّ الخادوم على المتصفح بالإيجاب بحالة 304 بدلًا من إعادة إرسال الملف مجددًا، إلا أنَّ إرسال الطلبية واستلام الرد سيستهلك وقتًا. سنستخدم في الخطوة التالية وحدة headers لإضافة معلومات للتحكم بالتخزين المؤقت. وهذا سيجعل المتصفح يُخزِّن الملفات محليًا دون أخذ إذن الخادوم أولًا. الخطوة الثالثة: ضبط ترويستَي Cache-Control و Expires إضافةً إلى ترويسة التحقق من تغيّر الملف (ETag)، هنالك ترويستان للتحكم بالتخزين المؤقت هما Cache-Control و Expires. ترويسة Cache-Control هي نسخةٌ أحدث، وفيها خياراتٌ أكثر مقارنةً بترويسة Expires وهي أفيد إن شئت التحكم بسلوك التخزين المؤقت تحكمًا دقيقًا. إذا ضُبِطَت تلك الترويسات، فهي تخبر المتصفح أنَّ الملف المطلوب يمكن أن يُخزَّن محليًا لفترةٍ زمنيةٍ معيّنة (تستطيع أن تجعل صلاحيته «للأبد»!) دون طلبه مرةً أخرى. أما إن لم تُضبَط تلك الترويسات، فسيطلب المتصفحُ الملفَ دومًا من الخادوم، متوقعًا أن يحصل على الحالة «‎200 OK» أو «‎304 Not Modified». يمكننا استخدام وحدة header لإرسال ترويسات HTTP آنفة الذكر. وحدة header هي وحدةٌ من أساس خادوم Nginx لذا لن تحتاج إلى تثبيت أيّ شيءٍ لاستخدامها. لإضافة وحدة header، افتح ملف ضبط Nginx في محرر nano أو أيّ محررٍ نصيٍ تشاء: sudo nano /etc/nginx/sites-available/default اعثر على القسم المُعَنوَنَ server، والذي يبدو كما يلي: . . . # Default server configuration # server { listen 80 default_server; listen [::]:80 default_server; . . . أضف القسمَين الآتيين: أولهما قبل قسم server لتعريف المدة الزمنية لتخزين مختلف أنواع الملفات مؤقتًا، وثانيهما داخل كتلة server الذي يضبط ترويسات التخزين المؤقت ضبطًا سليمًا: . . . # Default server configuration # # Expires map map $sent_http_content_type $expires { default off; text/html epoch; text/css max; application/javascript max; ~image/ max; } server { listen 80 default_server; listen [::]:80 default_server; expires $expires; . . . القسم الموجود قبل قسم server هو قسم map الذي يربط بين أنواع الملفات ومدة التخزين المؤقت لهذا النوع من الملفات. استعملنا عدِّة خيارات ضبط فيه: القيمة الافتراضية هي off، والتي لن تُضيف أيّة ترويسات للتحكم بالتخزين المؤقت، وهذا خيارٌ جيدٌ للمحتوى الذي لا يتطلب تخزينًا مؤقتًا. لنوع text/html سنضبط القيمة إلى epoch وهي قيمةٌ خاصةٌ التي تعني عدم التخزين المؤقت نهائيًا، مما يجبر المتصفح على السؤال إن كانت الصفحة مُحدَّثة. لنوع text/css و application/javascript -والتي هي ملفات الأنماط CSS وسكربتات JavaScript- سنضبط القيمة إلى max وهذا يعني أنَّ المتصفح سيُخزِّن هذه الملفات مؤقتًا أطول مدة يستطيعها، مما يُقلِّل عدد الطلبيات لوجود عدد كبير من هذه الملفات التي ترتبط بصفحة HTML. آخر خيار لنوع ‎~image/‎ وهو تعبيرٌ نمطيٌ (regular expression) الذي يُطابِق جميع الملفات ذات النوع الذي يحتوي على العبارة image/‎ فيه (مثل image/jpg و image/png). وكما في ملفات CSS و JS، تتواجد عادةً صورٌ كثير في مواقع الويب، ومن الجيد تخزينها محليًا، لذا ضبطنا القيمة إلى max أيضًا. التعليمة expires داخل قسم server (التي هي جزءٌ من وحدة headers) تضبط ترويسات التحكم بالتخزين المؤقت؛ حيث تستخدم القيمة المأخوذة من المتغير ‎$expires الذي يربط بين أنواع الملفات ومدة صلاحيتها. وبهذه الطريقة ستختلف الترويسات المُرسَلة اعتمادًا على نوع الملف. احفظ الملف واخرج من المُحرِّر النصي، وأعد تشغيل خادوم Nginx لتفعيل الضبط الجديد: sudo systemctl restart nginx سنتحقق في الخطوة التالية من أنَّ الضبط الجديد يعمل عملًا سليمًا. الخطوة الرابعة: اختبار التخزين المؤقت في المتصفح لنُنفِّذ نفس الأمر الذي طلبنا فيه ملف HTML في القسم السابق: curl -I http://localhost/test.html سيكون الرد مختلفًا هذه المرة، إذ يجب أن ترى ترويستين جديدتين: HTTP/1.1 200 OK Server: nginx/1.10.0 (Ubuntu) Date: Sat, 10 Sep 2016 13:48:53 GMT Content-Type: text/html Content-Length: 1024 Last-Modified: Sat, 10 Sep 2016 13:11:33 GMT Connection: keep-alive ETag: "57d40685-400" Expires: Thu, 01 Jan 1970 00:00:01 GMT Cache-Control: no-cache Accept-Ranges: bytes ترويسة Expires مرتبطة بتاريخٍ في الماضي وترويسة Cache-Control مضبوطةٌ إلى no-cache، مما يجعل المتصفح يسأل الخادوم إن توفرت نسخةٌ جديدةٌ من الملف (باستخدام ترويسة ETag كما سبق). ستجد ردًا مختلفًا عندما تُجرِّب على صورة: curl -I http://localhost/test.jpg ناتج الأمر السابق: HTTP/1.1 200 OK Server: nginx/1.10.0 (Ubuntu) Date: Sat, 10 Sep 2016 13:50:41 GMT Content-Type: image/jpeg Content-Length: 1024 Last-Modified: Sat, 10 Sep 2016 13:11:36 GMT Connection: keep-alive ETag: "57d40688-400" Expires: Thu, 31 Dec 2037 23:55:55 GMT Cache-Control: max-age=315360000 Accept-Ranges: bytes ارتبطت الترويسة Expires في هذه المرة بتاريخٍ في المستقبل البعيد، واحتوت ترويسة Cache-Control على max-age التي تخبر المتصفح كم ثانية يجب أن يُبقي على الملف. وهذا يُخبِر المتصفح أن يُخزِّن الصورة المُنزَّلة مؤقتًا لأطول مدة ممكنة، وبالتالي إذا ظهرت الصورة مرةً أخرى فستُستعمَل النسخة المحلية ولن تُرسَل الطلبية إلى الخادوم بتاتًا. يجب أن تكون النتيجة مشابهةً لملفَي test.js و test.css لأنهما ملفا JavaScript و CSS ويُضبَط لهما ترويسات التخزين المؤقت أيضًا، مَثَلُهُما كَمَثل الصور. إن ظهر عندك مثلما عرضنا في أمثلتنا، فاعلم أنَّ ترويسات التحكم بالتخزين المؤقت قد ضُبِطَت ضبطًا صحيحًا وسيستفيد موقعك من ناحية الأداء، وسيقل الحِمل على خادومك نتيجةً لتخزين المتصفح للملفات محليًا وعدم طلبها من الخادوم. عليك الآن أن تُخصِّص إعدادات التخزين المؤقت اعتمادًا على محتوى موقعك، لكن قد تجد أنَّ الضبط الذي وفرناه في هذا الدرس مناسبًا لتبدأ منه. الخلاصة يمكن أن تُستعمَل وحدة headers لإضافة أي نوع من الترويسات إلى رد HTTP، لكن من أفضل تطبيقات هذه الوحدة هو ضبط ترويسات التحكم بالتخزين المؤقت. إذ سيساعد ذلك في تحسين أداء مواقع الويب المُستضافة على خادومك، خصوصًا في الشبكات ذات زمن التأخير المرتفع (نسبيًا) مثل شبكات الهواتف المحمولة. يمكن أن يؤدي ذلك إلى تحسين ظهور موقعك في محركات البحث التي تأخذ عامل سرعة الموقع بالحسبان. حيث يُعتَبَر ضبط ترويسات التخزين المؤقت من أبزر نصائح أدوات اختبار سرعة الصفحات من Google (أقصد Google PageSpeed). لمزيدٍ من المعلومات التفصيلية عن وحدة headers، فارجع إلى توثيق Nginx الرسمي. ترجمة -وبتصرّف- للمقال How to Implement Browser Caching with Nginx’s header Module on Ubuntu 16.04 لصاحبه Mateusz Papiernik.
  23. سنتعلّم في هذا الدّرس كيفيّة استخدام HAProxy (والذي يرمز إلى الوسيط عالي التوفّر High Availability Proxy) كمُوازِن حمل عن طريق الطبقة السّابعة layer 7 load balancer من أجل تخديم تطبيقات متعدّدة من اسم مجال واحد Single Domain أو عنوان IP، بإمكان موازنة الحمل أن تزيد أداء، توفّر، ومرونة بيئتنا. تكون موازنة الحمل والوسيط العكسي للطبقة 7 ملائمة لموقعك إن أردت أن تملك اسم نطاق واحد يقوم بتخديم تطبيقات متعدّدة، حيث يمكن تحليل طلبات http لتقرّر أي تطبيق ينبغي عليه أن يستقبل حركة مرور البيانات. تمّت كتابة هذا الدّرس باستخدام ووردبريس وموقع ثابت Static website كأمثلة، ولكن يمكن استخدام مفاهيمه العامّة مع تطبيقات أخرى للحصول على تأثير مماثل. المتطلبات الأساسية قبل متابعة هذا الدّرس ينبغي عليك أن تملك تطبيقين على الأقل يعملان على خادومين منفصلين، سنستخدم موقعًا ثابتًا مستضافًا على Nginx و ووردبريس كتطبيقين لدينا، وبالإضافة للبيئة الحاليّة لديك سنقوم بإنشاء الخواديم التالية: haproxy-www: وهو خادوم HAProxy لأجل موازنة الحمل والوسيط العكسي wordpress-2: وهو خادوم الويب الثاني لووردبريس (تحتاجه فقط إن أردت موازنة حمل مكونات ووردبريس في بيئتك) web-2: خادوم ويب Nginx الثاني (تحتاجه فقط إن أردت موازنة حمل مكونات Nginx في بيئتك) إن لم يسبق لك التّعامل مع المفاهيم أو المصطلحات الأساسيّة لموازنة الحمل، مثل موازنة الحمل عن طريق الطبقة 7 أو الواجهات الخلفيّة backends أو قوائم تحكّم الوصول ACLs فهذا هو الدّرس الذي يشرح الأساسيّات: مقدّمة إلى HAProxy ومبادئ موازنة الحمل (Load Balancing). هدفنا بنهاية هذا الدّرس نريد أن نحصل على بيئة تبدو كما يلي: أي سيقوم المستخدمون لديك بالنفاذ لكلا تطبيقيك عبر http://example.com، وسيتم تمرير كل الطلبات التي تبدأ بـ http://example.com/wordpress إلى خواديم ووردبريس، ويتم تمرير جميع باقي الطلبات إلى خواديم Nginx الأساسيّة، لاحظ أنّه لا تحتاج بالضرورة لموازنة حمل تطبيقاتك حتى تظهر على مجال واحد، ولكن سنقوم بتغطية موازنة الحمل في هذا الدّرس. تثبيت HAProxy نقوم بإنشاء خادوم جديد مع الشّبكات الخاصّة، سنسمّيه في هذا الدّرس haproxy-www. نقوم بتثبيت HAProxy على الخادوم haproxy-www باستخدام apt-get: sudo apt-get update sudo apt-get install haproxy نحتاج لتمكين سكريبت التهيئة init script لـ HAProxy كي يبدأ ويتوقف HAProxy مع الخادوم لدينا: sudo vi /etc/default/haproxy نغيّر قيمة ENABLED إلى 1 لتمكين سكريبت التهيئة لـ HAProxy: ENABLED=1 نقوم بالحفظ والخروج، سيبدأ ويتوقف HAProxy الآن مع خادومنا، نستطيع أيضًا الآن استخدام الأمر service للتحكّم بـ HAProxy، فلنتحقّق من أنّه قيد التشغيل: user@haproxy-www:/etc/init.d$ sudo service haproxy status haproxy not running. نجد أنّه لا يعمل، لا مشكلة لأنّه يحتاج إلى إعداده قبل أن نتمكّن من استخدامه، فلنقم الآن بإعداد HAProxy لأجل بيئتنا. إعداد HAProxy يكون ملف إعدادات HAProxy مُقسّمًا إلى قسمين رئيسيين: العمومي Global: يقوم بتعيين المُعامِلات parameters على نطاق العمليّة الوسطاء Proxies: يتكون من المُعامِلات الافتراضيّة defaults، الاستماع listen، الواجهة الأماميّة frontend، والواجهة الخلفيّة backend. مرّة أخرى إن لم يسبق لك أن سمعت عن مفاهيم أو المصطلحات الأساسيّة لموازنة الحمل، فقم بالرجوع إلى هذا الدّرس: مقدّمة إلى HAProxy ومبادئ موازنة الحمل (Load Balancing). إعداد HAProxy: العمومي يجب أن يتم ضبط إعدادات HAProxy على الخادوم haproxy-www. في البداية لنقم بعمل نسخة من الملف haproxy.cfg الافتراضي: cd /etc/haproxy; sudo cp haproxy.cfg haproxy.cfg.orig نقوم الآن بفتح الملف haproxy.cfg باستخدام مُحرِّر نصوص: sudo vi /etc/haproxy/haproxy.cfg سنشاهد وجود قسمين معرّفين مسبقًا: global و defaults، سنلقي نظرة في البداية على بعض المعاملات القياسية default. تحت القسم defaults نبحث عن الأسطر التالية: mode http option httplog يقوم اختيار http كوضع بضبط HAProxy ليعمل كموازن حمل عن طريق الطبقة 7 (أو طبقة التطبيقات)، يعني هذا أنّ موازن الحمل سينظر إلى محتوى طلبات http ويقوم بتمريرها إلى الخادوم المناسب اعتمادًا على القواعد المعرّفة في الواجهة الأماميّة frontend، إن لم يكن هذا المفهوم مألوفًا لديك فمن فضلك اقرأ قسم أنواع موازنة الحمل في درس مقدّمة إلى HAProxy. لا تقم بإغلاق ملف الإعدادات الآن، لأنّنا سنضيف إعدادات الوسيط. إعداد HAProxy: الوسطاء إعداد الواجهة الأماميّة أول شيء نريد إضافته هو واجهة أماميّة frontend، ولأجل إعداد أساسي لوسيط عكسي وموازنة حمل عن طريق الطبقة 7 سنحتاج لتعريف قائمة تحكّم وصول ACL تُستخدَم لتوجيه حركة مرور بياناتنا إلى خواديم الواجهة الخلفيّة المناسبة، هنالك العديد من قوائم تحكّم الوصول التي يُمكن استخدامها في HAProxy، سنغطي فقط واحدة منها في هذا الدّرس (وهي path_beg)، ولأجل الحصول على قائمة كاملة من قوائم تحكّم الوصول في HAProxy قم بمراجعة التّوثيق الرسميّ: HAProxy ACLs. نضيف واجهتنا الأماميّة www في نهاية الملف، تأكّد من أن تضع عنوان IP الخاص بخادوم haproxy-www لديك بدلًا من haproxy_www_public_IP: frontend www bind haproxy_www_public_IP:80 option http-server-close acl url_wordpress path_beg /wordpress use_backend wordpress-backend if url_wordpress default_backend web-backend وهذا شرح لما يعنيه كل سطر من المقطع السابق المأخوذ من إعدادات الواجهة الأماميّة: frontend www: يُعيِّن واجهة أماميّة اسمها "www"، حيث سنستخدمها للتعامل مع حركة مرور بيانات www الواردة. bind haproxy_www_public_IP:80: ضع عنوان IP خادوم haproxy-www لديك بدلًا من haproxy_www_public_IP، يُخبر هذا السطر HAProxy أنّ هذه الواجهة الأماميّة ستتعامل مع حركة مرور بيانات الشبكة الواردة إلى عنوان IP هذا على هذا المنفذ. option http-server-close: يقوم بتمكين وضع إغلاق اتصال HTTP على الخادوم، ويحافظ على القدرة على دعم ترويسة HTTP keep-alive وتقنيّة HTTP pipelining على العميل (وهي تقنيّة لإرسال العديد من طلبات HTTP ضمن اتصال TCP وحيد بدون انتظار الموافقة لها)، يسمح هذا الخيار بأن يقوم HAProxy بمعالجة طلبات متعدّدة للعميل ضمن اتصال وحيد، والذي عادة ما يزيد من الأداء. acl url_wordpress path_beg /wordpress: يُعيِّن قائمة تحكّم وصول ACL تُدعى url_wordpress والتي تكون قيمتها صحيحة true إن كان مسار الطلب يبدأ بـ "wordpress/"، على سبيل المثال http://example.com/wordpress/hello-world. use_backend wordpress-backend if url_wordpress: يقوم بإعادة توجيه أي حركة مرور بيانات تتوافق مع قائمة تحكّم الوصول url_wordpress إلى wordpress-backend، والتي سنقوم بتعريفها قريبًا. default_backend web-backend: يُحدِّد أنّه أي حركة مرور بيانات لا تتوافق مع قاعدة use_backend سيتم تمريرها إلى web-backend، والتي سنقوم بتعريفها في الخطوة القادمة. إعداد الواجهة الخلفية Backend بعد أن تنتهي من إعداد الواجهة الأماميّة، قم الآن إضافة واجهتك الخلفيّة الأولى عن طريق إضافة الأسطر التالية، تأكّد من أن تضع عنوان IP المناسب بدلًا من web_1_private_IP: backend web-backend server web-1 web_1_private_IP:80 check وهذا شرح لما يعنيه كل سطر من المقطع السابق المأخوذ من إعدادات الواجهة الخلفيّة: backend web-backend: يُعيِّن واجهة خلفيّة تُدعى web-backend. server web-1 ... : يُعيِّن خادوم واجهة خلفيّة يُدعى web-1، مع عنوان IP الخاص (وهو الذي يجب أن تستبدله) والمنفذ الذي يستمع عليه، وهو 80 في هذه الحالة، يُخبِر الخيار check مُوازِن الحمل أن يُجري دوريًّا تحقّق من السّلامة على هذا الخادوم. بعدها أضف الواجهة الخلفيّة لتطبيق ووردبريس لديك: backend wordpress-backend reqrep ^([^\ :]*)\ /wordpress/(.*) \1\ /\2 server wordpress-1 wordpress_1_private_IP:80 check وهذا شرح لما يعنيه كل سطر من المقطع السابق المأخوذ من إعدادات الواجهة الخلفيّة: backend wordpress-backend: يُعيِّن واجهة خلفيّة تُدعى wordpress-backend. reqrep ... : يعيد كتابة الطلبات من wordpress/ إلى / عند تمرير حركة مرور البيانات إلى خواديم ووردبريس، وهو ليس ضروريًّا إن كان تطبيق ووردبريس مُثبّتًا على جذر root الخادوم ولكن نحتاج إليه لقابلية النفاذ عبر wordpress/ على خادوم HAProxy. server wordpress-1 ... : يُعيِّن خادوم واجهة خلفيّة يُدعى wordpress-1، مع عنوان IP الخاص (وهو الذي يجب أن تستبدله) والمنفذ الذي يستمع عليه، وهو 80 في هذه الحالة، يُخبِر الخيار check مُوازِن الحمل أن يُجري دوريًّا تحقّق من السّلامة على هذا الخادوم. إعدادات HAProxy: الإحصائيات Stats إن أردت تمكين إحصائيّات HAProxy، والتي قد تكون مفيدة في تحديد كيفيّة تعامل HAProxy مع حركة مرور البيانات الواردة، ستحتاج إلى إضافة الأسطر التالية إلى إعداداتك: listen stats :1936 stats enable stats scope www stats scope web-backend stats scope wordpress-backend stats uri / stats realm Haproxy\ Statistics stats auth user:password وهذا شرح لما تعنيه الأسطر غير البديهيّة من المقطع السابق المأخوذ من إعدادات listen stats: listen stats :1936: يقوم بإعداد صفحة إحصائيّات HAProxy لتكون قابلة للنفاذ على المنفذ 1936 (أي http://haproxy_www_public_IP:1936). stats scope ... : يجمع الإحصائيّات على الواجهة المُحدّدة سواء كانت أماميّة أو خلفيّة. / stats uri: يُعيِّن رابط صفحة الإحصائيّات إلى / . stats realm Haproxy\ Statistics: يقوم بتمكين الإحصائيّات وتعيين اسم الاستيثاق realm Authentication (وهو استيثاق ذو نافذة منبثقة)، يُستخدَم بالترابط مع الخيار stats auth. stats auth haproxy:password: يُعيِّن اعتمادات credentials الاستيثاق لصفحة الإحصائيّات، قم بوضع اسم المستخدم وكلمة السّر الخاصّة بك. الآن قم بالحفظ والإغلاق، عند تشغيل HAProxy تكون صفحة الإحصائيّات متوفّرة عبر الرابط http://haproxy_www_public_ip:1936/ حالما تبدأ خدمة HAProxy لديك، تكون HAProxy جاهزة الآن لتشغيلها ولكن فلنقم بتمكين التسجيل logging أولًا. تمكين تسجيل HAProxy إنّ تمكين التسجيل في HAProxy بسيط جدًّا، قم في البداية بتحرير الملف rsyslog.conf: sudo vi /etc/rsyslog.conf ثم ابحث عن السطرين التاليين وأزل التعليق عنهما لتمكين استقبال UDP syslog، يجب أن تبدو كما يلي عند الفراغ منها: $ModLoad imudp $UDPServerRun 514 $UDPServerAddress 127.0.0.1 الآن أعد تشغيل rsyslog لتمكين الإعدادات الجديدة: sudo service rsyslog restart تم تمكين تسجيل HAProxy الآن، سيتم إنشاء ملف السّجل في المسار var/log/haproxy.log/ بعد أن يتم تشغيل HAProxy. تحديث إعدادات ووردبريس الآن وقد تم تغيير رابط تطبيق ووردبريس فيجب علينا تحديث بعض الإعدادات في ووردبريس. قم بتعديل الملف wp-config.php على أي خادوم ووردبريس، هذا الملف موجود في مكان تثبيت ووردبريس (في هذا الدّرس تم تثبيته على المسار var/www/example.com/ ولكن قد يكون مختلفًا لديك): cd /var/www/example.com; sudo vi wp-config.php ابحث عن السطر الموجود في بداية الملف الذي يحتوي على ('define('DB_NAME', 'wordpress وقم بإضافة الأسطر التالية فوقه مع استبدال http://haproxy_www_public_IP: define('WP_SITEURL', 'http://haproxy_www_public_IP'); define('WP_HOME', 'http://haproxy_www_public_IP'); قم بحفظ وإغلاق الملف، تمّ الآن إعداد روابط ووردبريس لتشير إلى موازن الحمل بدلًا من خادوم ووردبريس الأصلي والتي تلعب دورها عند محاولتك النفاذ إلى لوحة تحكم ووردبريس. تشغيل HAProxy قم بتشغيل HAProxy على الخادوم haproxy-www ليتم تطبيق تغييرات الإعدادات: sudo service haproxy restart إتمام الوسيط العكسي Reverse Proxy أصبحت الآن تطبيقاتنا قابلة للوصول إليها عبر نفس المجال، example.com، عبر الوسيط العكسي للطبقة 7، ولكن لم يتم تطبيق موازنة الحمل عليها بعد، تبدو الآن البيئة لدينا كالمخطط التالي: وفقًا للواجهة الأماميّة التي عرفناها سابقًا، هذا وصف حول كيفيّة تمرير HAProxy لحركة مرور البيانات: http://example.com/wordpress: سيتم إرسال أي طلب يبدأ بـ wordpress/ إلى wordpress-backend (والذي يتكون من الخادوم wordpress-1). http://example.com/: سيتم إرسال أيّة طلبات أخرى إلى web-backend (والذي يتكون من الخادوم web-1). إن كان كل ما تريد فعله هو استضافة تطبيقات متعدّدة على مجال وحيد فقد أنجزت هذا بنجاح، أمّا إن أردت موازنة حمل تطبيقاتك أكمل قراءة الدّرس. كيفية إضافة موازنة الحمل موازنة حمل الخادوم web-1 لموازنة حمل خادوم ويب أساسي، كل ما تحتاج إليه هو إنشاء خادوم ويب جديد يمتلك إعدادات ومحتوى مطابق لخادوم الأصلي، سندعو هذا الخادوم الجديد: web-2. لديك خياران عند إنشاء الخادوم الجديد: إن كنت تملك خيار إنشاء خادوم جديد انطلاقًا من صورة web-1، فهذه هي الطريقة الأبسط لإنشاء web-2. إنشاؤه من الصفر، تثبيت نفس البرمجيّات، إعداده بشكل مماثل، ومن ثمّ نسخ محتوى جذر خادوم Nginx من web-1 إلى web-2 باستخدام rsync (اقرأ درس كيف تستخدِم Rsync لمزامنة مجلّدات بين الجهاز المحلّي والخادوم). ملاحظة: إن كل من الطريقتين السابقتين تقوم بإنشاء نسخة لمحتويات جذر الخادوم مرّة وحيدة، لذلك إن قمت بتحديث أي من الملفّات على أحد خواديمك، web-1 أو web-2، فتأكّد من مزامنة الملفّات مرّة أخرى. بعد أن يتم إعداد خادوم ويب المماثل لديك، قم بإضافته إلى web-backend ضمن إعدادات HAProxy. على الخادوم haproxy-www قم بتحرير الملف haproxy.cfg: sudo vi /etc/haproxy/haproxy.cfg ابحث عن القسم web-backend من الإعدادات: backend web-backend server web-1 web_1_private_IP:80 check وبعدها أضف الخادوم web-2 في السطر التالي: server web-2 web_2_private_IP:80 check قم بحفظ وإغلاق الملف، وأعد تحميل HAProxy لتطبيق التغييرات: sudo service haproxy reload يمتلك web-backend الآن خادومين يتعاملان مع حركة مرور البيانات غير المرتبطة بووردبريس، أي تمّ إعداد موازنة الحمل عليه بنجاح. موازنة حمل الخادوم wordpress-1 إنّ موازنة حمل تطبيق مثل ووردبريس أكثر تعقيدًا بقليل من موازنة حمل خادوم ثابت، لأنّه يجب عليك الاهتمام بأشياء مثل مزامنة الملفّات المُحمّلة ومستخدمي قواعد البيانات الإضافيّين. أكمل الخطوات الثلاث التالية لإنشاء خادوم ووردبريس الثاني wordpress-2: إنشاء خادوم تطبيق ويب الثاني. مزامنة ملفّات تطبيق الويب. إنشاء مستخدم قاعدة بيانات جديد. بعد أن تقوم بإنشاء الخادوم wordpress-2 مع إعداد قاعدة البيانات بشكل صحيح فكل ما تبقى عليك فعله هو إضافته إلى wordpress-backend ضمن إعدادات HAProxy. على الخادوم haproxy-www قم بتحرير الملف haproxy.cfg: sudo vi /etc/haproxy/haproxy.cfg ابحث عن القسم wordpress-backend من الإعدادات: backend wordpress-backend server wordpress-1 wordpress_1_private_IP:80 check وبعدها أضف الخادوم wordpress-2 في السطر التالي: server wordpress-2 wordpress_2_private_IP:80 check قم بحفظ وإغلاق الملف، وأعد تحميل HAProxy لتطبيق التغييرات: sudo service haproxy reload يمتلك web-backend الآن خادومين يتعاملان مع حركة مرور البيانات غير المرتبطة بووردبريس، أي تمّ إعداد موازنة الحمل عليه بنجاح. الخاتمة بعد أن أتممت الآن هذا الدّرس يجب أن تكون قادرًا على توسيع موازنة الحمل والوسيط العكسي لإضافة المزيد من التطبيقات والخواديم لبيئتك لجعلها تتوافق بشكل أفضل مع احتياجاتك، تذكّر أنّه لا توجد حدود لطرق إعداد بيئتك، وربّما تحتاج إلى البحث في توثيق HAProxy إن أردت متطلبات أكثر تعقيدًا. ترجمة -وبتصرّف- للمقال How To Use HAProxy As A Layer 7 Load Balancer For WordPress and Nginx On Ubuntu 14.04 لصاحبه Mitchell Anicas.
  24. طوّرت شركة Sun Microsystems نظام الملفّات الشبكي Network file system, NFS سنة 1980 من أجل السماح بتشارك الملفّات والمجلّدات بين الأنظمة الشبيهة بيونكس (لينكس ويونكس). يتيح نظام NFS للملفّات تركيب Mounting ملفّات عبر الشّبكة والتعامل معها كما لو كانت مركَّبة محليًّا على نفس النظام. فوائد نظام NFS يسمح نظام NFS بالوصول إلى الملفّات عن بعد. يستخدم بنية عميل-خادوم Client/Server معيارية لتشارك الملفّات بين جميع الأجهزة العاملة بالأنظمة الشبيهة بيونكس. ليس ضروريًّا عند استخدام NFS أن تكون الأجهزة تعمل على نفس نظام التّشغيل. يمكن ضبط حلول للتخزين المركزيّ بمساعدة نظام NFS. يعثُر المستخدمون على بياناتهم مهما كان تواجدها الفعلي. لا توجد حاجة للتحيين Refresh اليدوي للحصول على الملفّات الجديدة. تدعم الإصدارات الحديثة من NFS قوائم التحكّم في الوصول ACL. يمكن تأمينه عبر الجدران الناريّة Firewalls وKerberos (ميثاق للاستيثاق عبر الشبكة). تدخلّ الملفّات التاليّة في إعداد NFS: ملفّ etc/exports/: وهو ملفّ الإعداد الرئيس؛ تعرّف فيه - على الخادوم - جميع الملفّات والمجلّدات المشاركة. ملفّ etc/fstab/: يجب إدراج سطر لكلّ نظام ملفّات مُركَّب ضمن هذا الملفّ حتى يكون التركيب دائما (يبقى بعد إعادة التشغيل). ملفّ etc/sysconfig/nfs/: يعرّف المنافذ التي تنصت الخدمات للاتّصالات الواردة عبرها. إعداد NFS على خادوم أوبونتو سنعتمد في هذا الدرس على جهازين يعملان بإحدى توزيعات لينكس التاليّة: دبيان، أوبونتو أو ردهات. سنثبّت على أحد الجهازين خادوم NFS وعلى الثاني عميلا له كالتالي: خادوم NFS على العنوان 192.168.2.200. عميل NFS على العنوان 192.168.2.150. يمكنك استخدام VirtualBox لإعداد بيئة عمل بالمواصفات أعلاه. تثبيت الخادوم والعميل سنحتاج لتثبيت حزم NFS على الخادوم والعميل: # apt-get update # apt-get install nfs-kernel-server nfs-common ملحوظة: يمكن الاكتفاء بالحزمة nfs-common على العميل. تشير العلامة # إلى أن الأمر ينفَّذ بصلاحيّات الجذر. إعداد خادوم NFS الخطوة الأولى هي تحديد المجلّد الذي نريد مشاركته؛ سننشئ واحدا لهذا الغرض (يمكنك اختيّار مجلّد موجود مسبقا): # mkdir /nfsshare ثم نغيّر ملكيّته إلى nobody:nogroup: # chown nobody:nogroup /nfsshare غيّرنا ملكيّة الملفّ إلى المستخدم nobody الذي هو حساب لا يملك سوى الصلاحيّات الدنيا ويُستخدَم عادة لتنفيذ سكربتات غير مأمونة المصدر حتى لا تلحق أي ضرر بالنظام. هذه الخطوة ضروريّة وإلا فلن يكون بمقدورك إضافة ملفّات إلى المجلّد انطلاقا من العميل؛ إلا إذا أضفت خيار no_root_squash كما هو مشروح أدناه (لا يُنصَح بذلك). ليمكن تشاركُ المجلّد يجب أن نضيفه إلى ملفّ الإعداد etc/exports/؛ نفتح هذا الملفّ (بصلاحيّات الجذر) ثم نضيف إليه السّطر التالي: /nfsshare 192.168.2.150(rw,sync) يسمح السّطر أعلاه بتشارك المجلّد nfsshare مع العميل على العنوان 192.168.2.150 مع تحديد خيارات التشارك. يمكن أن تكون الخيارات على النحو التالي: ro: الوصول عبر وضع القراءة فقط؛ أي أن العميل يمكنه الوصول إلى الملفات المتشاركة فقط دون أن يكون قادرا على التعديل عليها أو إنشاء ملفات جديدة. rw: يمنح العميل القدرة على الوصول إلى الملفّات والتعديل عليها. sync: مزامنة التعديلات. يعني هذا أن أي تعديل سيُحفَظ فورا على نظام الملفّات؛ قد يؤثّر هذا الخيار على الأداء في حالة وجود الكثير من التغييرات المتزامنة على ملفّات كبيرة. no_subtree_check: يفحص نظام NFS مبدئيّا جميع المجلدات التي يتفرّع منها المجلّد المتشارَك من أجل التحقّق من الأذون وتفاصيل أخرى. يؤدّي تفعيل هذه الخاصيّة إلى تعطيل الفحص ممّا يحسّن من الأداء ولكنّه يؤدّي التقليل من الأمان. no_root_squash: تسمح هذه الخاصيّة للمستخدم الجذر على الجهاز العميل بالوصول إلى الملفّات المتشاركة على الخادوم بصلاحيّات الجذر على الخادوم. لا يُنصَح لأسباب أمنيّة باستخدام هذا الخيار إلا في حالات خاصّة. نطبّق الأمر exportfs بعد الانتهاء من تحرير الملفّ exports من أجل اعتماد التعديلات: # exportfs -r ثم نشغّل خدمة NFS كالتالي: # service nfs-kernel-server start إعداد عميل NFS على أوبونتو يمكننا الآن تركيب مجلّد التشارك على العميل. تأكد من أنه يمكن التواصل عبر الشبكة بين الجهاز الخادوم والعميل؛ مثلا باستخدام الأمر ping على العميل (حيثُ 192.168.2.200 هو عنوان الخادوم): $ ping 192.168.2.200 PING 192.168.2.200 (192.168.2.200) 56(84) bytes of data. 64 bytes from 192.168.2.200: icmp_seq=7 ttl=52 time=363 ms 64 bytes from 192.168.2.200: icmp_seq=8 ttl=52 time=322 ms نبدأ أولا بالبحث عن الملفّات المتشاركة عبر NFS على الخادوم: $ showmount -e 192.168.2.200 Export list for 192.168.2.200: /nfsshare 192.168.2.150 يظهر من نتيجة الأمر أعلاه أن المجلّد nfsshare/ متاح للتشارك مع العميل ذي العنوان 192.168.2.150. تركيب المجلد على العميل سننشئ على العميل مجلّدًا باسم mnt/nfs/nfsshare_mount/ ونستخدمه لتركيب المجلّد nfsshare/ على العميل (المجلّد nfsshare/ الموجود على الخادوم): # mkdir -p /mnt/nfs/nfsshare_mount # mount -t nfs 192.168.2.200:/nfsshare /mnt/nfs/nfsshare_mount يمكننا التأكد من تركيب المجلّد بتنفيذ الأمر mount والبحث عن نوع الملفّات nfs: $ mount | grep nfs 192.168.2.200:/nfsshare on /mnt/nfs/nfsshare_mount type nfs (rw,vers=4,addr=192.168.2.200,clientaddr=192.168.2.150) يمكن الآن إضافة ملفّات إلى مجلّد التشارك عبر نقطة التركيب: # touch /mnt/nfs/nfsshare_mount/testfile.txt يمكن التأكد من على الخادوم بسرد محتويات المجلّد nfsshare/. إن أردت جعل التركيب دائما (لا يزول مع إقلاع النظام) فيمكنك إضافة السطر التالي إلى ملفّ etc/fstab/: 192.168.2.200:/nfsshare /mnt/nfs/nfsshare_mount nfs defaults 0 0 نفّذ الأمر mount -a بعد تعديل ملفّ fstab لاعتماد التغييرات فورا. ملحوظة: تأكد من إدخال القيم الصحيحة في ملفّ etc/fstab/؛ وجود أخطاء في صياغة السّطر يمكن أن يؤدي إلى عدم إقلاع النظام. فصل المجلد من العميل استخدم الأمر umount إن أردت فصل المجلّد المركَّب، تُمرّضر نقطة التركيب للأمر على النحو التالي: # umount /mnt/nfs/nfsshare_mount نفّذ الأمر mount | grep nfs للتأكد من فصل المجلّد. أوامر أساسية للتعامل مع ملفات NFS في ما يلي أوامر يكثُر استخدامها أثناء التعامل مع المجلّدات المشارَكة عبر نظام NFS: showmount -e: يعرض جميع المجلّدات المتشاركة المتاحة على الجهاز. showmount -e <server-ip>: يسرد قائمة بالمجلّدات المشاركة المتاحة على الخادوم ذي العنوان server-ip. showmount -d <server-ip>: سرد المجلّدات المشاركة المتاحة على الخادوم والمجلدات المتفرعة منها. exportfs -v: يعرض قائمة بالمجلّدات المتشاركة الموجوة على الخادوم. exportfs -a: يطلب من الخادوم مشاركة الملفّات المحدّدة في الملفّ etc/exports/. exportfs -u: يعمل عكسَ عمل الأمر السابق، إذ يوقف مشاركة المجلدات المحدّدة في etc/exports/. exportfs -r: يحدّث قائمة المشاركات بعد التعديل على الملفّ etc/exports/. يمكن اعتماد هذا المقال الذي يقدّم أساسيات تشارك الملفّات عبر نظام NFS للانتقال إلى تفاصيل أكثر تقدّما بخصوص NFS والميزات التي يقدّمها. ترجمة -وبتصرّف- للمقال How to Setup NFS (Network File System) on RHEL/CentOS/Fedora and Debian/Ubuntu لصاحبه Tarunika Shrivastava.
  25. تم بشكل رسمي إطلاق الإصدار 16.04 LTS ذو الدعم طويل الأمد (الملقّب بـ Xerial Xerus) من توزيعة أوبونتو منذ عدّة أسابيع، ويتشوق الكثيرون إلى معرفة المزيد عن التغييرات التي طرأت والميزات الجديدة التي أضيفت، ويمكن القيام بذلك من خلال تثبيت نسخة نظيفة clean install أو تحديث نسخة قديمة من توزيعة لينوكس أوبونتو. سنتابع في المقال كيفية القيام بتحديث توزيعة أوبونتو من الإصدار 14.04 LTS إلى الإصدار الجديد وذلك خطوة بخطوة. تحذير: يجب أخذ الاحتياطات اللازمة وإنشاء نسخة احتياطية للبيانات كالمجلدات والمستندات والصور والكثير من الملفات الموجودة على النظام، ولا يجوز ترك الموضوع للحظ لأن في بعض الأحيان لا تجري عمليات التحديث كما هو متوقّع، وقد تصادف بعض الإشكالات التي قد تؤدي إلى تلف البيانات في حال فشلت عملية التحديث. تحديث توزيعة أوبونتو 14.04 إلى 16.04 على نسخة أوبونتو المكتبية Desktop Edition في البداية سنتحقق من أن النظام يملك آخر إصدار من البرمجيات المثبّتة، ونقوم بذلك من خلال فتح مدير تحديثات أوبونتو Ubuntu Update manager الموجود في لوحة القيادة Dashboard. رسم توضيحي 1 – البحث عن الإصدارات الجديدة لبرمجيات أوبونتو المثبّتة سيقوم مدير التحديثات بفحص النظام للتحقق فيما إذا كانت البرمجيات المثبتة تم تحديثها لآخر إصدار، وعند انتهائه يقوم بعرض قائمة بالبرمجيات التي سيتم تحديثها وتثبيت الإصدار الجديد منها. رسم توضيحي 2 - قائمة بالبرمجيات التي يتوفر إصدارات أحدث منها نقوم بالضغط على زر Install Now لتحميل وتثبيت التحديثات المعروضة. رسم توضيحي 3 - تحميل تحديثات برمجيات أوبونتو بعد انتهاء التحميل، سيتم البدء بتثبيت الإصدارات الجديدة: رسم توضيحي 4 - تثبيت تحديثات برمجيات أوبونتو بعد الانتهاء سيعُرض علينا إعادة التشغيل لإنهاء عملية تثبيت التحديثات، وسنقوم باختيار إعادة التشغيل Restart Now. رسم توضيحي 5 - إعادة التشغيل لإنهاء عملية تحديث البرمجيات أخيرًا، يمكن التحقق من أنه قد تم تثبيت جميع التحديثات على البرمجيات بفتح مدير التحديثات مجددًا ويُفترض أن تظهر الرسالة التالية التي تشير إلى عدم وجود تحديثات جديدة: رسم توضيحي 6 - جميع البرمجيات مثبتة بآخر إصداراتها سنباشر الآن بعملية تحديث التوزيعة، نقوم في البداية بفتح سطر الأوامر وتنفيذ الأمر التالي للبدء بعملية تحديث التوزيعة للإصدار الجديد 16.04 LTS: $ sudo update-manager -d تنبيه: انتبه إلى وجود مسافة ما بين update-manager و d- في الأمر السابق. بعد تنفيذ الأمر، سيطلب النظام إدخال كلمة مرور المستخدم، قم بإدخالها والضغط على مفتاح Enter وسيتم فتح مدير التحديث update-manager كما في الصورة: رسم توضيحي 7 - تحديث أوبونتو إلى الإصدار 16.04 أخيرًا، اضغط على زر Upgrade لتحديث نسخة التوزيعة. تحديث توزيعة أوبونتو 14.04 إلى 16.04 على نسخة أوبونتو الخاصة بالخوادم Server Edition سنقوم بتطبيق ذات الخطوات أيضًا، حيث سنبدأ بتحديث البرمجيات المثبتة من خلال تنفيذ الأمر: $ sudo apt-get update && sudo apt-get dist-upgrade وبعد الانتهاء قم بإعادة التشغيل لإنهاء تثبيت التحديثات: $ sudo init 6 بعد ذلك سنقوم بتثبيت حزمة update-manager-core باستخدام الأمر التالي إذا لم تكن مثبتة مسبقًا على الخادوم: $ sudo apt-get install update-manager-core بعد ذلك، سنقوم بفتح الملف etc/update-manager/release-upgrades/ باستخدام أي محرر نصوص نُفضّله (نستخدم vi في مثالنا)، وسنضيف عبارة Prompt=lts إلى نهايته كما في الصورة التالية: $ sudo vi /etc/update-manager/release-upgrades رسم توضيحي 8 - إعداد مدير تحديثات أوبونتو بعد ذلك، سنبدأ عملية التحديث بتنفيذ الأمر: $ sudo do-release-upgrade -d تنبيه: انتبه أيضًا إلى وجود مسافة ما بين do-release-upgrade و d- في الأمر السابق. رسم توضيحي 9 - عملية تحديث توزيعة أوبونتو 14.04 بعد أن يقوم مدير التحديثات بتحديد الحزم التي سيتم تحديثها وأفضل مصادر لها، سيطلب منك تأكيد العملية لذا سنقوم بالنقر على مفتاح y (الذي يشير إلى كلمة yes) ومن ثم نضغط على مفتاح Enter للبدء بعملية التحديث: رسم توضيحي 10 - تحديث أوبونتو للإصدار 16.04 سيُعرض أثناء عملية التحديث إعادة تشغيل بعض الخدمات، لذا نختار الموافقة yes حينها: رسم توضيحي 11 - إعداد الخدمات أثناء عملية تحديث توزيعة أوبونتو أخيرًا، سيُسأل فيما إذا كنا نرغب بإزالة الحزم القديمة التي تم تحديثها أو استبدالها، وسنقوم بالموافقة بالضغط على مفتاح y ومن ثم Enter. بعد انتهاء عملية التحديث نقوم بإعادة تشغيل الخادوم باستخدام الأمر: $ sudo init 6 ونكون قد انتهينا من تحديث توزيعة أوبونتو للإصدار 16.04 LTS. آمل أن تجدوا هذا الدليل مفيًدا ومساعدًا، وفي حال ظهور مشكلة أثناء العملية نظرًا لاختلاف خبرات المستخدمين أثناء عملية التحديث، فلا تترددوا بالسؤال في قسم التعليقات أدناه. ترجمة -وبتصرّف- للمقال How To Upgrade to Ubuntu 16.04 LTS from Ubuntu 14.04 LTS لصاحبه Aaron Kili.