اذهب إلى المحتوى

البحث في الموقع

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

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

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

نوع المحتوى


التصنيفات

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

التصنيفات

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

التصنيفات

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

التصنيفات

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

التصنيفات

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

التصنيفات

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

التصنيفات

  • الإنتاجية وسير العمل
    • مايكروسوفت أوفيس
    • ليبر أوفيس
    • جوجل درايف
    • شيربوينت
    • Evernote
    • Trello
  • تطبيقات الويب
    • ووردبريس
    • ماجنتو
    • بريستاشوب
    • أوبن كارت
    • دروبال
  • الترجمة بمساعدة الحاسوب
    • omegaT
    • memoQ
    • Trados
    • Memsource
  • برامج تخطيط موارد المؤسسات ERP
    • تطبيقات أودو odoo
  • أنظمة تشغيل الحواسيب والهواتف
    • ويندوز
    • لينكس
  • مقالات عامة

التصنيفات

  • آخر التحديثات

أسئلة وأجوبة

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

التصنيفات

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

ابحث في

ابحث عن


تاريخ الإنشاء

  • بداية

    نهاية


آخر تحديث

  • بداية

    نهاية


رشح النتائج حسب

تاريخ الانضمام

  • بداية

    نهاية


المجموعة


النبذة الشخصية

  1. 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
  2. إن بروتوكول ضبط المضيف ديناميكيًّا (Dynamic Host Configuration Protocol) هو خدمة شبكة تُفعِّل إسناد إعدادات الشبكة إلى الحواسيب المضيفة من خادوم بدلًا من إعداد كل مضيف شبكي يدويًا؛ حيث لا تملك الحواسيب المُعدَّة كعملاءٍ لخدمة DHCP أيّة تحكم بالإعدادات التي تحصل عليها من خادوم DHCP. إن أشهر الإعدادات الموفَّرة من خادوم DHCP إلى عملاء DHCP تتضمن: عنوان IP وقناع الشبكة.عنوان IP للبوابة الافتراضية التي يجب استخدامها.عناوين IP لخواديم DNS التي يجب استعمالها.لكن يمكن أيضًا أن يوفِّر خادوم DHCP خاصيات الضبط الآتية: اسم المضيف.اسم النطاق.خادوم الوقت.خادوم الطباعة.من مزايا استخدام DHCP هو أن أي تغييرٍ في إعدادات الشبكة -على سبيل المثال تغيير عنوان خادوم DNS- سيتم في خادوم DHCP فقط، وسيُعاد ضبط جميع مضيفي الشبكة في المرة القادمة التي سيَطلُبُ فيها عملاء DHCP معلومات الإعدادات من خادوم DHCP؛ ويُسهِّل استعمال خادوم DHCP إضافة حواسيب جديدة إلى الشبكة، فلا حاجة للتحقق من توفر عنوان IP؛ وسيقل أيضًا التضارب في حجز عناوين IP. يمكن أن يُوفِّر خادوم DHCP إعدادات الضبط باستخدام الطرق الآتية: التوزيع اليدوي (Manual allocation) عبر عنوان MACتتضمن هذه الطريقة استخدام DHCP للتعرف على عنوان مميز لعتاد كل كرت شبكة متصل إلى الشبكة، ثم سيوفِّر إعدادات ضبطٍ ثابتةً في كل مرة يتصل فيها عميل DHCP إلى خادوم DHCP باستخدام بطاقة الشبكة المعيّنة مسبقًا؛ وهذا يضمن أن يُسنَد عنوان معيّن إلى بطاقةٍ شبكيّةٍ معيّنة وذلك وفقًا لعنوان MAC. التوزيع الديناميكي (Dynamic allocation)سيُسنِد خادوم DHCP -في هذه الطريقة- عنوان IP من مجموعة من العناوين (تسمى pool، أو في بعض الأحيان range أو scope) لمدة من الزمن (يسمى ذلك بالمصطلح lease) التي تُضبَط في الخادوم، أو حتى يخبر العميل الخادوم أنه لم يعد بحاجةٍ للعنوان بعد الآن؛ وسيحصل العملاء في هذه الطريقة على خصائص الضبط ديناميكيًّا وفق المبدأ «الذي يأتي أولًا، يُخدَّم أولًا»؛ وعندما لا يكون عميل DHCP متواجدًا على الشبكة لفترة محددة، فسينتهي وقت الضبط المخصص له، وسيعود العنوان المسند إليه إلى مجموعة العناوين لاستخدامه من عملاء DHCP الآخرين؛ أي أنَّه في هذه الطريقة، يمكن «تأجير» أو استخدام العنوان لفترة من الزمن؛ وبعد هذه المدة، يجب أن يطلب العميل من الخادوم أن يعيد تأجيره إياه. التوزيع التلقائي (Automatic allocation)سيُسنِد خادوم DHCP -في هذه الطريقة- عنوان IP إسنادًا دائمًا إلى جهاز معين، ويتم اختيار هذه العنوان من مجموعة العناوين المتوفرة؛ يُضبَط عادةً DHCP لكي يُسنِد عنوانًا مؤقتًا إلى الخادوم، لكن يمكن أن يسمح خادوم DHCP بزمن تأجير «لا نهائي». يمكن اعتبار آخر طريقتين «تلقائيتَين»، ﻷنه في كل حالة يُسنِد خادوم DHCP العنوان دون تدخل إضافي مباشر، الفرق الوحيد بينهما هو مدة تأجير عنوان IP؛ بكلماتٍ أخرى، هل ستنتهي صلاحية عنوان العميل بعد فترة من الزمن أم لا. يأتي أوبنتو مع خادوم وعميل DHCP، الخادوم هو dhcpd‏ (dynamic host configuration protocol daemon)، والعميل الذي يأتي مع أوبنتو هو dhclient، ويجب أن يثبَّت على جميع الحواسيب التي تريدها أن تُعَدّ تلقائيًا، كلا البرنامجين سهلُ التثبيت، وسيبدآن تلقائيًا عند إقلاع النظام. التثبيتاكتب الأمر الآتي في مِحَث الطرفية لتثبيت dhcpd: sudo apt-get install isc-dhcp-serverربما تحتاج إلى تغيير الضبط الافتراضي بتعديل ملف ‎/etc/dhcp/dhcpd.conf ليلائم احتياجاتك والضبط الخاص الذي تريده. ربما تحتاج أيضًا إلى تعديل ‎/etc/default/isc-dhcp-server لتحديد البطاقات الشبكية التي يجب أن «يستمع» (listen) إليها عفريت dhcpd. ملاحظة: رسالة عفريت dhcpd تُرسَل إلى syslog، انظر هناك لرسائل التشخيص. الضبطربما سيربكك ظهور رسالة خطأ عند انتهاء التثبيت، لكن الخطوات الآتية ستساعدك في ضبط الخدمة: في الحالات الأكثر شيوعًا، كل ما تريد أن تفعله هو إسناد عناوين IP إسنادًا عشوائيًا، يمكن أن يُفعَل ذلك بالإعدادات الآتية: # minimal sample /etc/dhcp/dhcpd.conf default-lease-time 600; max-lease-time 7200; subnet 192.168.1.0 netmask 255.255.255.0 { range 192.168.1.150 192.168.1.200; option routers 192.168.1.254; option domain-name-servers 192.168.1.1, 192.168.1.2; option domain-name "mydomain.example"; }نتيجة الإعدادات السابقة هي ضبط خادوم DHCP لإعطاء العملاء عناوين IP تتراوح من 192.168.1.150 إلى 192.168.1.200، وسيُأجَّر عنوان IP لمدة 600 ثانية إذا لم يطلب العميل وقتًا محددًا؛ عدا ذلك، فسيكون وقت الإيجار الأقصى للعنوان هو 7200 ثانية؛ و«سينصح» الخادومُ العميلَ أن يستخدم 192.168.1.254 كبوابة افتراضية، و 192.168.1.1 و 192.168.1.2 كخادومَيّ DNS. عليك إعادة تشغيل خدمة dhcpd بعد تعديل ملف الضبط: sudo service isc-dhcp-server restartمصادرتوجد بعض المعلومات المفيدة في صفحة ويكي أوبنتو «dhcp3-server».للمزيد من خيارات ملف ‎/etc/dhcp/dhcpd.conf، راجع صفحة الدليل man dhcpd.conf.مقالة في ISC:‏ «dhcp-server».ترجمة -وبتصرف- للمقال Ubuntu Server Guide: Dynamic Host Configuration Protocol - DHCP. حقوق الصورة البارزة: Designed by Freepik.
  3. مع انتقال أدوات المطورين إلى السحاب (cloud)، يزداد عدد المتبنين لمنصات بيئة تطوير متكاملة IDE ‏(Integrated Development Environment بيئة التطوير المتكاملة) السحابيّة، فهذه المنصات يمكن الوصول إليها من أي نوع من الأجهزة الحديثة عن طريق المتصفحات، وهي توفّر مميزات مهمة عند التعاون في الوقت الحقيقي، فيوفر العمل في منصة IDE سحابيّة بيئة موحدّة للتطوير والتجربة لك ولفريقك مع تقليل مشاكل عدم توافق المنصات، فيمكنك الوصول إليها من أي نوع من الأجهزة الحديثة عن طريق المتصفحات. فـ Eclipse Theia هي منصة IDE سحابيّة قابلة للتوسع تعمل على خادم عن بعد ويمكن الوصول إليها من متصفح الويب، وشكلها يشبه Microsoft Visual Studio Code وتدعم العديد من لغات البرمجة ولديها تصميم مرن وطرفيّة (Terminal)، وما يفرّق بين Eclipse Theia من بقيّة برامج IDE السحابيّة هي قابليّة تخصيصها وزيادة مميزاتها باستخدام الملحقات المخصّصة، والتي تسمح لك بتعديل IDE السحابي حسب رغباتك. سننشر في هذا الدرس Eclipse Theia إلى خادم أوبنتو 18.04 باستخدام Docker Compose والتي هي أداة لمزامنة الحاوية، والتي ستكشفها في اسم النطاق الخاص بك باستخدام nginx-proxy والذي هو نظام تلقائي لـ Docker يبسط عملية إعداد Nginx ليعمل كوكيل عكسي (reverse proxy) للحاوية، وستأمنها باستخدام شهادة Let’s Encrypt TLS عن طريق الملحق المخصص لها. وفي النهاية ستحصل على Eclipse Theia يعمل على خادم أوبنتو 18.04 متوفّر عن طريق HTTPS يمكن للمستخدم تسجيل دخوله ليبدأ العمل عليه. المتطلبات الأساسية خادم أوبنتو 18.04 مع صلاحيات الجذر بالإضافة إلى حساب آخر عادي ليس جذر، يمكنك اعداد ذلك عن طريق اتباع هذا الدرس بالنسبة لهذا المقال، المستخدم العادي (ليس جذر) هو sammy. تثبيت Docker على خادمك، يمكنك اتباع الخطوة الأولى والثانية من هذا الدرس وللتعرّف على Docker، يمكنك الإطلاع على هذا الدرس. تثبيت Docker Compose على خادمك، يمكنك اتباع الخطوة الأول من درس تثبيت Docker Compose. اسم نطاق مسجّل بالكامل، سنستخدم في هذا درس theia.your_domain والذي يمكنك استبداله بأي اسم ستشتريه من أي موقع يوفر هذه الخدمة. سِجل DNS مع إشارة theia.your_domain إلى عنوان IP الخادم العام، يمكنك الإطلاع على المقدمة إلى DNS الخاص بـ DigitalOcean للمزيد من التفاصيل. الخطوة الأولى - نشر nginx-proxy مع Let’s Encrypt في هذا القسم، ستنشر nginx-proxy مع إضافة Let's Encrypt باستخدام Docker Compose، وسيفعّل هذا عمليّة تفعيل وتجديد شهادة TLS بشكل تلقائي، لذلك عندما تنشر Eclipse Theia، ستتمكن من الوصول إلى نطاقك عن طريق HTTPS. في هذا الدرس، سنسجل جميع الملفات في ‎~/‎eclipse-theia، أنشئ هذا المجلّد عن طريق تشغيل هذا الأمر: mkdir ~/eclipse-theia انتقل إلى هذا المجلّد عن طريق: cd ~/eclipse-theia يجب عليك حفظ إعدادات Docker Compose لـ nginx-proxy في ملف يسمى nginx-proxy-compose.yaml، أنشئه باستخدام محرّر النصوص الخاص بك: nano nginx-proxy-compose.yaml وأضف الأسطر التاليّة إليه (ملف nginx-proxy-compose.yaml): version: '2' services: nginx-proxy: restart: always image: jwilder/nginx-proxy ports: - "80:80" - "443:443" volumes: - "/etc/nginx/htpasswd:/etc/nginx/htpasswd" - "/etc/nginx/vhost.d" - "/usr/share/nginx/html" - "/var/run/docker.sock:/tmp/docker.sock:ro" - "/etc/nginx/certs" letsencrypt-nginx-proxy-companion: restart: always image: jrcs/letsencrypt-nginx-proxy-companion volumes: - "/var/run/docker.sock:/var/run/docker.sock:ro" volumes_from: - "nginx-proxy" ستعرّف هنا خدمتين سيشغلها Docker Compose وهما nginx-proxy و Let’s Encrypt، بالنسبة إلى الوكيل (proxy)، ستحدّد jwilder/nginx-proxy كصورة وستعرّف منافذ HTTP وHTTPS بالإضافة إلى الأماكن (volumes) التي يمكن الوصول إليها وقت التشغيل. الأماكن (Volumes) هي مجلدات في خادمك التي يمكن للخدمات المعرّفة الوصول إليها، والتي ستستخدمها لاحقًا في إعداد مصادقة المستخدم (user authentication)، ولفعل ذلك، ستستخدم المكان الأول من القائمة والذي سيصل مجلد ‎/etc/nginx/htpasswd المحلي إلى نفس المكان في الحاوية، وفي هذا المجلد، سيتوقع nginx-proxy إيجاد نفس الملف مسمى بنفس النطاق المستهدف، ويحتوي على بيانات تسجيل الدخول لمصادقة المستخدم في شكل htpasswd (username:hashed_password). بالنسبة للإضافة، ستضع اسم الصورة وستسمح بالوصول إلى المقبس socket الخاصة بالـ Docker عن طريق تعريف مكان (Volume)، ومن ثم ستحدد أن هذه الإضافة يجب عليها وراثة الوصول إلى الأماكن المعرّفة لـ nginx-proxy، كلا الخدمتين تملكان خيار restart يحتوي على قيمة always، والتي تأمر Docker بإعادة تشغيل الحاويات في حالة التعطل أو إعادة تشغيل النظام. أغلق الملف بعد حفظه وانشر الإعدادات عن طريق تشغيل الأمر التالي: docker-compose -f nginx-proxy-compose.yaml up -d ستمرر في الأمر السابق، اسم ملف nginx-proxy-compose.yaml إلى المعامل ‎-f لأمر docker-compose والذي يحدد الملف الذي سيعمل، وبعد ذلك، ستمرّر فعل up الذي سيشغّل الحاوية. بالنسبة إلى الراية ‎-d فهي تفعّل الوضع المنفصل (detached mode)، والذي يعني أن Docker Compose سيشغّل الحاويات في الخلفية. المخرجات النهائيّة ستشبه لهذه: Creating network "eclipse-theia_default" with the default driver Pulling nginx-proxy (jwilder/nginx-proxy:)... latest: Pulling from jwilder/nginx-proxy 8d691f585fa8: Pull complete 5b07f4e08ad0: Pull complete ... Digest: sha256:dfc0666b9747a6fc851f5fb9b03e65e957b34c95d9635b4b5d1d6b01104bde28 Status: Downloaded newer image for jwilder/nginx-proxy:latest Pulling letsencrypt-nginx-proxy-companion (jrcs/letsencrypt-nginx-proxy-companion:)... latest: Pulling from jrcs/letsencrypt-nginx-proxy-companion 89d9c30c1d48: Pull complete 668840c175f8: Pull complete ... Digest: sha256:a8d369d84079a923fdec8ce2f85827917a15022b0dae9be73e6a0db03be95b5a Status: Downloaded newer image for jrcs/letsencrypt-nginx-proxy-companion:latest Creating eclipse-theia_nginx-proxy_1 ... done Creating eclipse-theia_letsencrypt-nginx-proxy-companion_1 ... done والآن بعد أن نشرنا nginx-proxy ومرافقه Let's Encrypt باستخدام Docker Compose، سننتقل إلى إعداد Eclipse Theia على نطاقك وتأمينه. الخطوة الثانية - نشر Eclipse Thia في Docker سننشئ في هذا القسم ملف يحتوي على بيانات تسجيل الدخول التي سيستخدمها المستخدم، ومن ثم سننشر Eclipse Theia إلى خادمك باستخدام Docker Compose وسنعرضه على نطاقك الآمن باستخدام nginx-proxy. كما شرحنا في الخطوة السابقة، يتوقع nginx-proxy الحصول على بيانات تسجيل الدخول في ملف على النطاق المكشوف على شكل htpasswd ومحفوظة في مجلد ‎/etc/nginx/htpasswd في الحاوية، لا يحتاج المجلد المحلي الذي يشير إلى المجلد الافتراضي أن يكونا نفس الملف، كما حدّدنا في إعدادات nginx-proxy. لإنشاء مجموعات بيانات تسجيل الدخول، ستحتاج أولًا إلى تثبيت htpasswd عن طريق تشغيل الأمر التالي: sudo apt install apache2-utils تحتوي حزمة apache2-utils على أداة htpasswd. أنشئ مجلد ‎/etc/nginx/htpasswd عن طريق الامر التالي: sudo mkdir -p /etc/nginx/htpasswd وأنشئ ملف الذي سيحتوي على بيانات تسجيل الدخول لنطاقك: sudo touch /etc/nginx/htpasswd/theia.your_domain تذكر استبدال theia.your_domain بنطاق Eclipse Theia. لإضافة زوج اسم تسجيل الدخول وكلمة المرور، نفّذ الأمر التالي: sudo htpasswd /etc/nginx/htpasswd/theia.your_domain username استبدل username باسم المستخدم الذي ترغب في إضافته، وسيسألك مرتين عن كلمة المرور، وبعد ذلك سيضيف htpasswd اسم المستخدم وكلمة المرور المشفرة (hashed password) إلى نهاية الملف، يمكنك إعادة هذا الأمر بعدد مرات تسجيلات الدخول التي ترغب في إضافتها. والآن ستنشئ ملف إعدادات لنشر Eclipse Theia، وستخزنها في ملف يسمى eclipse-theia-compose.yaml، أنشئه باستخدام محرر النصوص الخاص بك: nano eclipse-theia-compose.yaml أضف الأسطر التاليّة في ملف ‎~/eclipse-theia/eclipse-theia-compose.yaml: version: '2.2' services: eclipse-theia: restart: always image: theiaide/theia:next init: true environment: - VIRTUAL_HOST=theia.your_domain - LETSENCRYPT_HOST=theia.your_domain عرّفت في هذه الإعدادات خدمة واحدة تسمى eclipse-theia مع خيار restart قيمته always وصورة حاوية theiaide/theia:next ولقد حدّدت init كـ true لإعلام Docker باستخدام init كمدير العمليّة الرئيسي عند تشغيل Eclipse Theia داخل الحاويّة. وبعد ذلك، ستحدّد متغيري بيئة في قسم environment وهما VIRTUAL_HOST و LETSENCRYPT_HOST فالأول سيمرر إلى nginx-proxy وسيخبره على أي نطاق يجب كشف الحاوية، وأما الآخر فسيستخدم من قبل Let's Encrypt لتحديد أي نطاق لطلب شهادات TLS، وفي العادة سيكونان نفسهما إلا لو وضع wildcard كقيمة لـ VIRTUAL_HOST. تذكر استبدال theia.your_domain مع اسم النطاق المطلوب، ومن ثم أغلق الملف بعد حفظه. والآن، انشر Eclipse Theia عن طريق كتابة الأمر: docker-compose -f eclipse-theia-compose.yaml up -d ستكون المخرجات كالتالي: ... Pulling eclipse-theia (theiaide/theia:next)... next: Pulling from theiaide/theia 63bc94deeb28: Pull complete 100db3e2539d: Pull complete ... Digest: sha256:c36dff04e250f1ac52d13f6d6e15ab3e9b8cad9ad68aba0208312e0788ecb109 Status: Downloaded newer image for theiaide/theia:next Creating eclipse-theia_eclipse-theia_1 ... done بعد ذلك في متصفحك، انتقل إلى النطاق الذي تستخدمه لـ Eclipse Theia، سيظهر لك المتصفح واجهة تسجيل الدخول، وبعد توفير البيانات الصحيحة، ستدخل إلى Eclipse Theia وسترى الواجهة الرسوميّة. يدل القفل في شريط العنوان إلى أن الإتصال مؤمن، وإذا لم ترى هذا بشكل فوري، انتظر بضعة دقائق لإصدار شهادات TLS وأعد تحميل الصفحة. والآن، يمكنك الوصول إلى IDE السحابي، ويمكنك البدء باستخدام المحرّر في الخطوة القادمة. الخطوة الثالثة - استخدام واجهة Eclipse Theia ستكتشف في هذا القسم بعض من مميزات واجهة Ecipse Theia. على الجانب الأيسر من IDE، ستجد صف عمودي من أربعة أيقونات لفتح المميزات الشائعة في اللوحة الجانبيّة. يمكنك تخصيص هذا الشريط أي يمكنك تحريك هذه المناظر (Views) لتغيير ترتيبهم أو حذفهم من الشريط. المنظر الأول بشكل افتراضي يفتح لوحة الاكتشاف (Explorer panel) والذي يوفر تصفح شجري لهيكل المشروع، يمكنك إدارة مجلداتك وملفاتك هنا من حيث إنشاء وحذف ونقل وإعادة تسميتهم حسب المطلوب. بعد إنشاء ملف جديد عن طريق قائمة File، سيُفتح ملف فارغ في علامة تبويب جديدة، وبمجرد حفظه، يمكنك رؤية اسم الملف في لوحة الاكتشاف الجانبيّة، ولإنشاء المجلدات، اضغط بالزر الأيمن على شريط Explorer وانقر على New Folder، ويمكنك توسعة المجلد عن طريق الضغط على اسمه وسحب وافلات الملفات والمجلدات إلى الأجزاء العليا من التسلسل الهرمي لتحريكهم إلى المكان الجديد. يوفر المنظر (view) التالي الوصول إلى وظائف البحث والاستبدال، ويوفّر المنظر الثالث لأنظمة التحكم بالمصدر التي قد تستخدمها، مثل Git. أما بالنسبة إلى المنظر الأخير فهو لخيار التنقيح، والذي يوفر الإجراءات الشائعة في اللوحة، ويمكنك حفظ إعدادات التنقيح في ملف launch.json. الجزء الأوسط من الواجهة هو محرّرك، والذي يمكنك فصله بعلامات التبويب لتعديل الشيفرة البرمجيّة، يمكنك تغيير منظر التعديل إلى وضع الشبكة (grid) أو إلى ملفات كل واحدة بجانب الأخرى، ومثل جميع IDE الحديثة، يدعم Eclipse Theia تسليط الضوء على الصياغة لشيفرتك البرمجيّة. يمكنك الوصول إلى الطرفيّة عن طريق ‎CTRL+SHIFT+`‎ أو عن طريق النقر على Terminal في القائمة العلويّة، وتحديد New Terminal، ستفتح الطرفية في لوحة السفليّة وستعمل في المجلد المشروع، والذي سيحتوي على جميع الملفات والمجلدات الموجودة في لوحة Explorer الجانبيّة. والآن لقد تعرّفت على واجهة Eclipse Theia مع أهم المميزات شائعة الاستخدام. الختام الآن، لديك Eclipse Theia مثبت على خادم أوبنتو 18.04 باستخدام Docker Compose وnginx-proxy، ولقد أمنته باستخدام شهادة TLS من Let’s Encrypt مجانيّة وأعددت المثيل لطلب بيانات تسجيل الدخول من المستخدم، يمكنك العمل على شيفرتك المصدريّة والوثائق بشكل فردي أو بالتعاون مع فريقك، ويمكنك تجربة بناء نسختك الخاصة من Eclipse Theia إذا احتجت إلى وظائف إضافيّة، للمزيد من المعلومات حول كيفيّة فعل ذلك، زر توثيق Theia. ترجمة -وبتصرف- للمقال How To Set Up the Eclipse Theia Cloud IDE Platform on Ubuntu 18.04 لصاحبه Savic
  4. Jenkins هو خادم أتمتة مفتوح المصدر يعمل على أتمتة المهام الفنية المتكررة التي ينطوي عليها التكامل المستمر وتقديم البرامج، Jenkins مكتوبة بلغة Java ويمكن تثبيتها من حزم أوبنتو أو عن طريق تنزيل وتشغيل ملف WAR (وهو عبارة عن مجموعة من الملفات التي تشكل تطبيق ويب كاملًا لتشغيله على خادم). في هذا المقال ستقوم بتثبيت Jenkins بإضافة مستودع حزمة ديبيان، واستخدام هذا المستودع لتثبيت الحزمة من خلال الأداة apt-get. المتطلبات الأساسية من أجل متابعة هذا المقال، ستحتاج إلى: خادم اوبنتو 18.04 فيه مستخدم يحمل صلاحيات sudo وغير جذري (non-root) ومثبت عليه جدار حماية وذلك باتباع دليل الاعداد الاولي لخادم اوبنتو18.04 نوصي بالبدء باستخدام 1 غيغابايت على الأقل من الذاكرة RAM، راجع هذه التوصيات للحصول على متطلبات التثبيت اللازمة. بتثبيت Java 8، باتباع هذا المقال. الخطوة الأولى: تثبيت Jenkins الإصدار المتوفر في متجر أوبنتو الحزم على الأغلب هو اصدار أقدم من الإصدار المتوفر في المشروع نفسه، للحصول على اخر التحديثات والميزات سوف نستخدم الحزم المصانة من قبل مشروع Jenkins نفسه. علينا أولًا إضافة مفتاح المستودع repository للنظام من خلال الأمر التالي: $ wget -q -O - https://pkg.jenkins.io/debian/jenkins.io.key | sudo apt-key add - بعد إضافة المفتاح بنجاح سيظهر النظام لك كلمة OK؛ سنضيف بعد ذلك عنوان مستودع لحزمة ديبيان إلى الملف sources.list الموجود في الخادم: $ sudo sh -c 'echo deb http://pkg.jenkins.io/debian-stable binary/ > /etc/apt/sources.list.d/jenkins.list' بعد تنفيذ الأمرين السابقين بنجاح سوف نقوم بتحديث الحزم في المستودع repository باستخدام الأمر التالي: $ sudo apt update اخيرا سنقوم بتثبيت Jenkins وكل ما تعتمد عليه: $ sudo apt install jenkins الآن Jenkins واعتماديته كلها جاهزة لذا سنقوم بتشغيل الخادم. الخطوة الثانية: بدء تشغيل خادم Jenkins سنستخدم systemctl لتشغيل خادم Jenkins: $ sudo systemctl start jenkins و لعدم إظهار الأمر لأي مخرجات سنستخدم الخيار Status لعرض حالة الخدمة للتأكد أنها قد بدأت دون مشاكل: $ sudo systemctl status jenkins إذا كان كل شيئ على ما يرام ستبدأ المخرجات بالظهور لإظهار أن الخدمة تعمل حاليا و ستبدأ تلقائيا عند الاقلاع: ● jenkins.service - LSB: Start Jenkins at boot time Loaded: loaded (/etc/init.d/jenkins; generated) Active: active (exited) since Mon 2018-07-09 17:22:08 UTC; 6min ago Docs: man:systemd-sysv-generator(8) Tasks: 0 (limit: 1153) CGroup: /system.slice/jenkins.service الآن الخدمة شغالة سنبدأ بإعداد قواعد جدار الحماية حتى نصل لها من خلال متصفح الويب لإكمال ضبطه. الخطوة الثالثة: اضبط إعدادات جدار الحماية بشكل تلقائي Jenkins يعمل على منفذ رقم 8080 لذلك سنعمل على فتح هذا المنفذ داخل جدار الحماية ufw: $ sudo ufw allow 8080 من خلال التحقق من حالة الجدار الناري يمكن رؤية القاعدة الجديدة ب ufw: $ sudo ufw status يمكنك الآن رؤية التراسل الشبكي عبر المنفذ 8080 المتاح من كل الشبكات: Status: active To Action From -- ------ ---- OpenSSH ALLOW Anywhere 8080 ALLOW Anywhere OpenSSH (v6) ALLOW Anywhere (v6) 8080 (v6) ALLOW Anywhere (v6) ملاحظة: اذا كان جدار الحماية غير فعال يجب تنفيذ الأوامر التالية للسماح ب OpenSSH وتفعيل جدار الحماية: $ sudo ufw allow OpenSSH $ sudo ufw enable بعد تثبيت Jenkin و ضبط إعدادات جدار الحماية الخاص بنا سنكمل الإعدادات المبدئية له. الخطوة الرابعة: ضبط خدمة Jenkins من أجل ضبط خدمة Jenkins علينا الدخول لصفحة الإعدادات من خلال المنفذ الافتراضي 8080 باستخدام اسم النطاق للخادم أو عنوان http://your_server_ip_or_domain:8080. ستظهر لك شاشة مقفلة من Jenkins تعرض موقع الذي تخزن فيه كلمة المرور المبدئية وتطلب إدخالها. من خلال واجهة سطر الأوامر سوف نستخدم الأمر Cat من أجل اظهار كلمة المرور: $ sudo cat /var/lib/jenkins/secrets/initialAdminPassword تتألف كلمة المرور من 32 حرف سوف نقوم بنسخها من واجهة سطر الأوامر و لصقها داخل الحقل Administrator password ثم الضغط على زر الاستمرار Continue. بعد ذلك ستظهر لك صفحة تعرض لك خيارين تثبيت الإضافات المقترحة أو تحديد إضافات معينة. اختر الخيار Install suggested plugins الذي سيبدأ عملية التنزيل مباشرة. عند الانتهاء من التثبيت، سيُطلب منك أولا إعداد المستخدم الإداري (administrative) ومن الممكن تخطي هذه الخطوة والمتابعة كمسؤول باستخدام كلمة المرور الأولية التي استخدمناها في الأعلى لكننا سنقوم بإنشاء مستخدم جديد. ملاحظة: خادم Jenkins الافتراضي غير مشفر، وبالتالي فإن البيانات المقدمة مع هذا النموذج ليست محمية. عندما تكون جاهزًا لاستخدام هذا التثبيت، اتبع هذا المقال التالي؛ سيؤدي ذلك إلى حماية بيانات المستخدم والمعلومات التي يتم إرسالها عبر واجهة الويب. ادخل اسم و كلمة المرور للمستخدم الخاص بك: ستظهر لك صفحة الضبط Instance Configuration وستطلب منك تأكيد عنوان URL المفضل لنسخة Jenkins. قم بتأكيد اسم النطاق لخادمك أو عنوان IP: بعد تأكيد المعلومات المناسبة، انقر فوق حفظ وإنهاء. سترى صفحة Jenkins is Ready!‎: انقر فوق Start using Jenkins للانتقال للوحة التحكم الرئيسية لـخادم Jenkins: تهانينا ، لقد تم تثبيت Jenkins بنجاح. الخلاصة في هذا المقال قد شرحنا آلية تثبيت Jenkins باستخدام الحزم المقدمة من المشروع، وبدء تشغيل الخادم، وفتح جدار الحماية، وإنشاء مستخدم مسؤول. في هذه المرحلة، يمكنك البدء في استكشاف Jenkins. عند الانتهاء من الاستكشاف، إذا قررت الاستمرار في استخدام Jenkins فاتبع الدليل التالي لحماية كلمات المرور الخاصة بك وأيضًا معلومات النظام أو المنتج الحساسة التي ستكون إرسالها بين جهازك والخادم بنص عادي. ترجمة –وبتصرف– للمقال How To Install Jenkins on Ubuntu 18.04 لصاحبته Melissa Anderson and Kathleen Juell
  5. نظام التحكم بالإصدارات Gitإن Git هو نظام تحكم بالإصدارات موزَّع (distributed) ومفتوح المصدر مطوَّر من لينوس تورفالدس لدعم تطوير نواة لينُكس؛ حيث يكون كل مجلد في Git عبارة عن مستودع مع تأريخ كامل وإمكانيات لتتبع الإصدارات، وليس متعمِدًا على الوصول على الشبكة أو على خادوم مركزي. التثبيتيمكن تثبيت نظام التحكم بالإصدارات git باستخدام الأمر الآتي: sudo apt-get install gitالضبطيجب لكل مستخدم git أن يعرِّف نفسه أولًا إلى git، وذلك بتنفيذ الأمرّين الآتيين: git config --global user.email "you@example.com" git config --global user.name "Your Name"الاستخدام الأساسيما سبق يكفي لاستخدام git في طريقة موزعة وآمنة، حيث يُفترَض أنَّ المستخدمين يستطيعون الوصول إلى الخادوم عبر SSH؛ حيث يمكن إنشاء مستودع جديد على الخادوم بالأمر: git init --bare /path/to/repositoryملاحظة: الأمر السابق يُنشِئ مستودعًا «فارغًا» (bare)، أي أنه ليس بالإمكان استخدامه للتعديل على الملفات مباشرةً. إذا أردت الحصول على نسخة من محتويات المستودع على الخادوم، فاحذف الخيار ‎--bare. يمكن لأي عميل يملك وصولًا عبر SSH إلى الخادوم أن ينسخ المستودع بالأمر: git clone username@hostname:/path/to/repositoryبعد نسخ الملفات إلى جهاز العميل، يمكنه تعديلها ثم إيداعها ومشاركتها بالأوامر: cd /path/to/repository # edit some files git commit -a # Commit all changes to the local version of the repository git push origin master # Push changes to the server's version of the repositoryتثبيت خادوم gitoliteعلى الرغم من أنّ ما سبق كافٍ لإنشاء ونسخ وتعديل المستودعات، لكن المستخدمين الذين يريدون تثبيت git على خادوم سيريدون عمومًا إنجاز المهام في git كنظام إدارة التحكم بالأكواد المصدرية تقليدي؛ وعند وجود عدِّة مستخدمين وامتيازات وصول لهم، فالحل الأمثل هو تثبيت gitolite كما يلي: sudo apt-get install gitoliteضبط Gitoliteضبط خادوم Gitolite مختلف قليلًا عن معظم الخواديم في الأنظمة الشبيهة بِيونكس؛ فبدلًا من ملفات الضبط التقليدية في ‎/etc/‎، فإن gitolite يُخزِّن الضبط في مستودع git؛ أول خطوة لضبط تثبيت جديد هي السماح بالوصول إلى مستودع الضبط. أولًا، علينا إنشاء مستخدم لأجل gitolite لكي نصل إليه عبره: sudo adduser --system --shell /bin/bash --group --disabled-password --home /home/git gitسنترك الآن gitolite لكي يعرف عن مفتاح SSH العمومي لمدير المستودع؛ هنا نفترض أن المستخدم الحالي هو مدير المستودع؛ إذا لم تضبط مفتاح SSH بعد، فراجع الدرس الخاص بخادوم OpenSSH لمزيدٍ من التفاصيل: cp ~/.ssh/id_rsa.pub /tmp/$(whoami).pubلنبدِّل إلى المستخدم git ونستورد مفتاح المدير إلى gitolite: sudo su - git gl-setup /tmp/*.pubسيسمح Gitolite لك بعمل تغيرات مبدئية لضبطه أثناء عملية الإعداد؛ يمكنك الآن نسخ وتعديل مستودع ضبط gitolite من المستخدم المدير (المستخدم الذي استوردت مفتاح SSH العمومي الخاص به)؛ عُد إلى ذاك المستخدم، ثم انسخ مستودع الضبط: exit git clone git@$IP_ADDRESS:gitolite-admin.git cd gitolite-adminالمجلد gitolite-admin فيه مجلدين فرعيين، المجلد «conf» و «keydir»؛ ملفات الضبط موجودة في مجلد conf، ويحتوي مجلد keydir على مفاتيح SSH العمومية للمستخدم. إدارة مستخدمي ومستودعات gitoliteإضافة مستخدمين جدد إلى gitolite هي عملية سهلة: احصل على مفتاح SSH العمومي لهم ثم أضفه إلى مجلد keydir بالاسم USERNAME.pub، لاحظ أن أسماء مستخدمي gitolite لا تطابق بالضرورة أسماء مستخدمي النظام، حيث تُستخدَم أسمائهم في ملف ضبط gitolite فقط، وذلك لإدارة التحكم بالوصول؛ وبشكل مشابه، يمكن حذف المستخدمين بحذف ملف المفتاح العمومي الخاص بهم؛ ولا تنسَ أن تودع التغييرات وتدفعها إلى خادوم git بعد كل تعديل: git commit -a git push origin masterتُدار المستودعات بتعديل الملف conf/gitolite.conf؛ الشكل العام له هو قيود مفصولة بفراغات تُحدِّد ببساطة قائمةً بالمستودعات ثم بعض قواعد الوصول؛ ما يلي هو المثال الافتراضي لهذا الملف: repo gitolite-admin RW+ = admin R = alice repo project1 RW+ = alice RW = bob R = deniseاستخدام خادومكلاستخدام الخادوم المُنشَأ حديثًا، يجب أن يستورد مدير gitolite مفاتيح المستخدمين العمومية إلى مستودع ضبط gitolite، ثم يمكنهم الوصول إلى أي مستودع لهم حق الوصول إليه عبر الأمر الآتي: git clone git@$SERVER_IP:$PROJECT_NAME.gitأو إضافة مشروع في الخادوم عن بعد: git remote add gitolite git@$SERVER_IP:$PROJECT_NAME.gitترجمة -وبتصرف- للمقال Ubuntu Server Guide: Git.
  6. Postfix هو وكيل نقل البريد مفتوح المصدر (MTA) الذي يمكن استخدامه لتوجيه وتسليم البريد الإلكتروني على نظام Linux، وتشير التقديرات إلى أن حوالي 25 ٪ من خوادم البريد العام على الإنترنت تعمل على تشغيل Postfix. في هذا المقال، سنعلمك كيفية تثبيت Postfix وتشغيله بسرعة على خادم يعمل بنظام تشغيل أوبنتو 18.04. المتطلبات الأساسية من أجل تطبيق هذا المقال، يجب أن يكون لديك حق الوصول كمستخدم غير جذري (non-root) يملك صلاحيات sudo، للتعرف على كيفية إعداد ذلك يمكنك اتباع دليل الإعداد الأولي لخادم اوبنتو18.04 لإنشاء المستخدم. لإعداد Postfix بشكل صحيح، ستحتاج إلى اسم نطاق (Domain Name) مؤهل بالكامل يتم توجيهه إلى خادم اوبنتو 18.04، يمكنك العثور على مساعدة في إعداد اسم النطاق (Domain Name) الخاص بك باستخدام DigitalOcean باتباع هذا المقال، إذا كنت تخطط لقبول البريد، فستحتاج إلى التأكد من أن لديك سجل MX يشير إلى خادم البريد الخاص بك. لأغراض هذا المقال التعليمي، سنفترض أنك تقوم بإعداد الحاسوب المضيف له FQDN الخاص بـ mail.example.com. الخطوة الأولى: تثبيت Postfix يوجد Postfix في متجر أوبنتو الافتراضي، لذلك تثبيته بسيط. ابدأ أولًا تحديث ذاكرة التخزين المؤقت لحزمة apt الخاصة بك ثم قم بتثبيت البرنامج، سنقوم بتمرير DEBIAN_PRIORITY=low كمتغير في أمر التثبيت الخاص بنا للرد على بعض المتطلبات الإضافية: $ sudo apt update $ sudo DEBIAN_PRIORITY=low apt install postfix استخدم المعلومات التالية لملء المطلوب بشكل صحيح للبيئة الخاصة بك: النوع العام من إعدادات البريد (General type of mail configuration): سنختار موقع إنترنت لأن هذا يتناسب مع احتياجات البنية الأساسية لدينا. اسم نظام البريد (System mail name): هذا هو المجال الأساسي للمستخدم من أجل إنشاء عنوان بريد إلكتروني صحيح عند تقديم جزء من عنوان الحساب العنوان الحساب فقط على سبيل المثال، اسم hostname هو mail.example.com لكن ربما نرغب في تعيين اسم بريد النظام إلى example.com يتم إعطاؤه اسم المستخدم user1، سيستخدم Postfix العنوان user1@example.com. مستلما البريد root و postmaster‏ (Root and postmaster mail recipient): هما عبارة عن حسابات Linux يقومان بإعادة ارسال عنوان البريد إلى root@ و postmaster@، استخدم حسابك الأساسي لهذا الغرض في مثالنا هو sammy. مستقبلات أخرى لقبول البريد (Other destinations to accept mail for): وهذا يعرف بمستقبلات البريد التي تقبل Postfix instance، إذا كنت بحاجة لإضافة أي نطاقات أخرى سيكون هذا الخادم مسؤولاً عن تلقيها، فأضف تلك النطاقات هنا وإلا سيطبق الإعداد الافتراضي. فرض تحديثات متزامنة على قائمة انتظار البريد؟ (Force synchronous updates on mail queue?‎): نظرًا لأنك تستخدم على الأرجح ملفات النظام ، فقم برد ب "لا" هنا. الشبكات المحلية (Local networks): هذه قائمة من الشبكات التي تم إعدادها بخادم البريد الخاص بك من أجل ترحيل الرسائل، بمعظم الحالات سيعمل الإعداد الافتراضي، ولكن إذا اخترت تعديله ، فتأكد من أن يكون مقيدًا للغاية فيما يتعلق بنطاق الشبكة. تحديد الحد الأعلى لحجم صندوق البريد الوارد (Mailbox size limit): يستخدم هذا الحد للحد من حجم الرسائل الواردة و يتم تعطيل أي قيود على حجم البريد بضبطه على 0. الحرف المضاف للعنوان المحلي (Local address extension character): هذا الحرف يستخدم للفصل بين الجزء العادي من العنوان و الجزء المضاف (يستخدم لإنشاء أسماء مستعارة ديناميكية). برتوكولات الانترنت الواجب استخدامها (Internet protocols to use): اختر اذا ما كنت تريد تقييد اصدار IP الذي سيدعمه Postfix، سنختار كل IP لاغراضنا هنا. هذه هي الإعدادات التي سنستخدمها في هذا الدليل: General type of mail configuration?: Internet Site System mail name: example.com (not mail.example.com) Root and postmaster mail recipient: sammy Other destinations to accept mail for: $myhostname, example.com, mail.example.com, localhost.example.com, localhost Force synchronous updates on mail queue?: No Local networks: 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 Mailbox size limit: 0 Local address extension character: + Internet protocols to use: all من أجل اعادة ضبط الاعدادات السابقة بأي وقت يمكنك ذلك بتنفيذ الأمر التالي: $ sudo dpkg-reconfigure postfix سيتم ملء الطلبات السابقة بالردود السابقة بشكل تلقائي. عند الانتهاء ، يمكننا الآن إجراء المزيد من التهيئة لإعداد نظامنا بالطريقة التي نرغب بها. الخطوة الثانية: تحسين إعدادات Postfix بعد ذلك، يمكننا ضبط بعض الإعدادات التي لم تطلبها منا الحزمة. بدايةً، يمكننا ضبط صندوق البريد؛سوف نستخدم تنسيق Maildi الذي يفصل الرسائل إلى ملفات فردية يتم نقلها بين المجلدات بناءً على إجراء المستخدم أما الخيار الآخر فهو تنسيق mbox (الذي لن نغطيه هنا) الذي يخزن جميع الرسائل في ملف واحد. سنقوم بتعيين المتغير home_mailbox إلى القيمة Maildir/‎ أي ننشئ مجلدًا داخل المجلد الرئيسي للمستخدم إن استخدام الامر Postconf سيقوم بضبط الإعدادات اكتب الامر التالي لإعداد home/mailbox: $ sudo postconf -e 'home_mailbox= Maildir/' بعد ذلك، يمكنك تعيين موقع الجدول virtual_alias_maps الذي يحتوي حسابات البريد الإلكتروني المرتبطة بحسابات نظام Linux، سننشئ هذا الجدول في etc/postfix/virtual/ سنستخدم الأمر postconf مرة اخرى: $ sudo postconf -e 'virtual_alias_maps= hash:/etc/postfix/virtual' الخطوة الثالثة: خريطة عناوين البريد لحسابات Linux الآن سنقوم باعادة إعداد ملف جدول الخرائط الإفتراضي، افتح الملف في محرر النصوص الخاص بك: $sudo nano /etc/postfix/virtual يستخدم الاسم المستعار في جدول خريطة الافتراضي تنسيقًا بسيطًا على اليسار إذ يمكنك عرض أي عناوين ترغب في قبول بريدها الإلكتروني افصل بينها وبين اسم مستخدم Linux الذي ترغب في تسليم البريد إليه بمسافة بيضاء ثم أدخل مستخدم Linux. على سبيل المثال إذا كنت ترغب بقبول البريد الإلكتروني contact@example.com والبريد admin@example.com وترغب في تسليم رسائل البريد الإلكتروني هذه إلى المستخدم sammy، فيمكنك إعداد الملف ‎/etc/postfix/virtual كما يلي: contact@example.com sammy admin@example.com sammy بعد تعيين جميع العناوين على حسابات الخادم المناسبة، احفظ وأغلق الملف. يمكننا تطبيق وتفعيل السابق بتنفيذ الأمر: $ sudo postmap /etc/postfix/virtual أعد تشغيل عملية Postfix للتأكد من تطبيق جميع التغييرات: $sudo systemctl restart postfix أصبح خادم Postfix الآن مثبت وجاهز؛ سنقوم بإعداد عميل يمكنه التعامل مع البريد الذي يعالجه Postfix. الخطوة الرابعة: ضبط جدار الحماية إذا كنت تقوم بتشغيل جدار حماية UFW باعدادت الأولية التي تم تهيئة الخادم عليها سوف يتعين علينا السماح باستثناء Postfix. يمكنك السماح بالاتصالات بالخدمة بتنفيذ الأمر التالي: $ sudo ufw allow Postfix الآن خادم Postfix مثبت وجاهز سنقوم بإعداد عميل يمكنه التعامل مع البريد الذي يعالجه Postfix. الخطوة الخامسة: إعداد البيئة لربطها مع موقع البريد قبل أن نثبت العميل يجب أن نتأكد من صحة متغير بيئة MAIL الخاص بنا معدة بشكل صحيح، سيقوم العميل بفحص هذا المتغير لمعرفة مكان الذي أبحث فيه عن بريد المستخدم. من أجل تعيين المتغير بغض النظر عن كيفية وصولك إلى حسابك (من خلال ssh ، su ، su - ، sudo ، إلخ) ، نحتاج إلى تعيين المتغير في عدة مواقع مختلفة؛ سنقوم بإضافته إلى داخل ملفetc/bash.bashrc/و ملفetc/profile.d/للتأكد من أن كل مستخدم لديه هذا الإعداد. من أجل إضافة المتغير إلى هذه الملفات نفذ الأمر التالي: $echo 'export MAIL=~/Maildir' | sudo tee -a /etc/bash.bashrc | sudo tee -a /etc/profile.d/mail.sh لقراءة المتغير في جلستك الحالية يمكنك تنفيذ على الملف etc/profile.d/mail.sh/: $ source /etc/profile.d/mail.sh الخطوة السادسة: تثبيت وإعداد بريد العميل للتفاعل مع البريد الذي يتم تسليمه؛ سنقوم بتثبيت حزمةs-nailوهو البديل عن عميل BSD xmailالغني بالميزات ويمكنه التعامل مع تنسيق Maildir بشكل صحيح، وغالبًا ما يكون متوافقًا مع الإصدارات السابقة، يحتوي إصدار GNU للبريد على بعض القيود مثل حفظ بريد القراءة دائمًا بتنسيق mbox بغض النظر عن التنسيق المصدر. لتنزيل حزمة s-nail نستخدم الأمر: $ sudo apt install s-nail من أجل ضبط بعض الإعدادات افتح الملف etc/s-nail.rc/ باستخدام محرر النصوص الخاص بك: $ sudo nano /etc/s-nail.rc أضف الخيارات التالية في أسفل الملف ‎/etc/s-nail.rc: . . . set emptystart set folder=Maildir set record=+sent سيتيح هذا للعميل فتحه حتى مع البريد الوارد الفارغ؛ سيقوم أيضًا بتعيين المجلد Maildir داخل المجلد الداخلي ثم سيستخدم لإنشاء ملف mbox الذي تم ارساله ويخزن البريد المرسل. احفظ وأغلق الملف عند الانتهاء. الخطوة السابعة: تهيئة Maildir واختبار العميل الآن، يمكننا اختبار العميل من الخارج: تهيئة بنية المجلد أسهل طريقة لإنشاء Maildir في مجلدنا الرئيسي هي إرسال بريد إلكتروني إلى أنفسنا يمكننا القيام بذلك باستخدام الأمر s-nail نظرًا لأن الملف المرسل لن يكون متاحًا إلا بعد إنشاء Maildir، سنقوم بتعطيل الكتابة لهذا البريد الإلكتروني الأولي باستخدام الخيار Snorecord-. أرسل رسالة بريد إلكتروني عن طريق تمرير الجملة String إلى الأمر s-nail وحدد مستخدم Linux المستلم للرسالة: $ echo 'init' | s-nail -s 'init' -Snorecord sammy سيكون الرد ربما كتالي: Can't canonicalize "/home/sammy/Maildir" سيظهره هذا الأمر بشكل طبيعي عند ارسال الرسالة أول مرة و يمكننا التحقق من إنشاء المجلد من خلال البحث عن مجلد Maildir/~: $ ls -R ~/Maildir ستشاهد ما يحتوي عليه المجلد وقد تم إنشاء ملف جديد فيه رسالة جديدة في المجلد Maildir/new/~: /home/sammy/Maildir/: cur new tmp /home/sammy/Maildir/cur: /home/sammy/Maildir/new: 1463177269.Vfd01I40e4dM691221.mail.example.com /home/sammy/Maildir/tmp: يبدو أن البريد تم تسليمه. إدارة البريد مع العميل استخدم العميل من أجل التحقق من بريدك: $ s-nail ستجد الرسالة التالية تنتظرك: s-nail version v14.8.6. Type ? for help. "/home/sammy/Maildir": 1 message 1 new >N 1 sammy@example.com Wed Dec 31 19:00 14/369 init اضغط على زر Enter لعرض رسالتك التالية: [-- Message 1 -- 14 lines, 369 bytes --]: From sammy@example.com Wed Dec 31 19:00:00 1969 Date: Fri, 13 May 2016 18:07:49 -0400 To: sammy@example.com Subject: init Message-Id: \&lt;20160513220749.A278F228D9@mail.example.com\&gt; From: sammy@example.com init يمكنك العودة إلى قائمة الرسائل الخاصة بك بكتابة الرمز h ثم Enter: ? h نظرًا لأن هذه الرسالة ليست مفيدة للغاية يمكننا حذفها باستخدام الرمز d ثم Enter : ? d للعودة إلى شاشة الأوامر استخدم الرمز q ثم ENTER: ? q إرسال البريد مع العميل يمكنك اختيار إرسال رسالة عبر كتابة الرسالة بمحرر النصوص : $ nano ~/test_message داخل الملف ‎~/test_message اكتب النص الذي تود ارساله بالبريد: Hello, This is a test. Please confirm receipt! بإمكاننا باستخدام الأمر cat توجيه الرسالة باستخدام s-nail سيؤدي ذلك إلى إرسال الرسالة كمستخدم Linux الافتراضي، يمكنك ضبط الحقل "From" باستخدام الراية r- إذا كنت تريد تعديل هذه القيمة إلى شيء آخر: $ cat ~/test_message | s-nail -s 'Test email subject line' -r from_field_account user@email.com الخيارات بالأمر السابق تعني: s-: موضوع البريد الإلكتروني r-: حقل اختياري لتغيير الحقل "From" في البريد الإلكتروني بشكل افتراضي هو مستخدم Linux الذي قمت بتسجيل الدخول به سيتم استخدامه لملء هذا الحقل، يسمح لك الخيار r- باعادة تعيينه. user@email.com: الحساب المرسل اليه البريد الإلكتروني قم بتغييره ليكون حسابًا صحيحًا لك حق الوصول إليه. يمكنك عرض رسائلك المرسلة داخل عميل s-nail الخاص بك اعد تشغيل العميل التفاعلي مرة أخرى بكتابة الأمر التالي: $ s-nail بإمكانك عرض الرسائل المرسلة عبر الأمر التالي : ? file +sent يمكنك إدارة البريد المرسل باستخدام نفس الأوامر التي تستخدمها للبريد الوارد. الخلاصة يجب أن يكون لديك الآن القدرة على إعداد Postfix على خادم أوبنتو 18.04 إن إدارة خوادم البريد الإلكتروني مهمة صعبة على مسؤولين النظام ولكن مع هذا الإعداد يجب أن يكون لديك وظيفة البريد الإلكتروني MTA الأساسية لتبدأ. ترجمة -وبتصرف- للمقال How To Install and Configure Postfix on Ubuntu 18.04 لصاحبيه Justin Ellingwood و Hanif Jetha
  7. ASP.NET Core هي إطار عمل مفتوح المصدر وعالي الأداء لإنشاء تطبيقات ويب حديثة، ومن المفترض أن يكون النسخة الأفضل من إطار العمل ASP.NET لمايكروسوفت. تمَّ إصداره عام 2016، ويمكن تشغيله على العديد من أنظمة التشغيل مثل لينكس وmacOS، مما يتيح للمطورين استهداف نظام تشغيل معين للتطوير اعتمادًا على متطلبات التصميم. يستطيع المطور باستخدام ASP.NET Core بناء أي نوع من تطبيقات الويب أو الخدمات بغض النظر عن التعقيد والحجم. يمكن للمطورين أيضًا استخدام صفحات Razor لإنشاء تصميم يركز على الصفحة يعمل أعلى النمط التقليدي MVC (اختصارًا للعبارة Model-View-Controller). يوفر ASP.NET Core المرونة للتكامل مع أي إطار عمل للواجهة الأمامية للتعامل مع العمليات المنطقية من طرف العميل أو استخدام خدمة ويب. مثلًا، بإمكانك بناء واجهة برمجية RESTful مع ASP.NET Core واستخدامها ببساطة مع أطر عمل جافاسكربت مثل Angular، React و Vue.js. ستعدّ في هذا الدرس تطبيق ASP.NET Core وتنشره ليكون جاهزًا للإطلاق مع خادم MySQL على أوبنتو 18.04 باستخدام Nginx. ستنشر تطبيق ASP.NET Core تجريبي مماثل للتطبيق من توثيق مايكروسوفت والمُستضاف على GitHub. بمجرد أن يتم النشر، سيسمح لك التطبيق التجريبي بإنشاء قائمة أفلام وتخزينها في قاعدة البيانات. ستكون قادرًا على إنشاء، وقراءة، وتحديث، وحذف سجلات من قاعدة البيانات. يمكنك بدلًا من ذلك استخدام هذا الدرس لتنشر تطبيق ASP.NET Core خاص بك؛ من الممكن أن تحتاج إلى تنفيذ خطواتٍ إضافيةٍ تتضمن إنشاء ملف تهجير (migration) جديد إلى قاعدة البيانات الخاصة بك. المتطلبات الأساسية ستحتاج لما يلي لاتباع هذا الدرس: خادم أوبنتو 18.04 تم ضبطه باستخدام دليل التهيئة الأولية لخادم أوبنتو 18.04، متضمنًا مستخدمًا عاديًا مع وصول sudo وجدار حماية. خادم Nginx مثبَّت باتباع الخطوات كيفية تثبيت Nginx على أوبنتو 18.04. خادم ويب Nginx آمن. بإمكانك اتباع درس كيف تؤمّن خادم Nginx بشهادة Let's Encrypt في أوبنتو للقيام بذلك. ضبط سجلَّي الـ DNS لخادمك. يمكنك اتّباع هذه المقدمة إلى DigitalOcean DNS للتفاصيل حول كيفية إضافتها. سجل A مع إشارة اسم النطاق الخاص بك your-domain إلى عنوان IP العام للخادم. سجل A مع إشارة اسم النطاق الخاص بك مسبوقًا بـ www www.your-domain. إلى عنوان IP العام للخادم. نظام إدارة قواعد البيانات MySQL مثبَّت باتباع خطوات كيف تثبّت الإصدار الأخير من MySQL على أوبنتو 18.0. الخطوة 1: تثبيت مُشِّغل NET Core. الآني مُشِّغل NET Core. الآني (أي NET Core runtime.) مطلوب لتشغيل تطبيق NET Core.، لذا يجب البدء بتثبيته على جهازك. تحتاج أولًا لتسجيل مفتاح مايكروسوفت ومستودع المنتج. بعد ذلك ستثبّت الاعتماديات (dependencies) المطلوبة. أولًا، سجّل الدخول كمستخدم مُنشأ حديثًا، وتأكّد من أنَّك في المجلد الجذر: $ cd ~ ثمّ نفّذ الأمر التالي لتسجيل مفتاح مايكروسوفت ومستودع المنتج: $ wget -q https://packages.microsoft.com/config/ubuntu/18.04/packages-microsoft-prod.deb استخدم dpkg مع الراية i- لتثبيت الملف المحدد: $ sudo dpkg -i packages-microsoft-prod.deb لتسهيل تثبيت الحزم الأخرى الضرورية لتطبيقك، ستثبّت مستودع universe باستخدام الأمر التالي: $ sudo add-apt-repository universe ثمّ ثبّت حزمة apt-transport لتسمح باستخدام المستودعات التي يتم الوصول إليها عبر بروتوكول HTTP الآمن: $ sudo apt install apt-transport-https نفِّذ الأمر التالي لتنزيل قائمة الحزم من المستودعات وتحديثها للحصول على معلومات حول أحدث إصدارات الحزم واعتمادياتها: $ sudo apt update أخيرًا، يمكنك تثبيت SDK لمشغّل NET. الآني عبر الأمر: $ sudo apt install dotnet-sdk-2.2 ستُعرض تفاصيل ما سيجري تنزيله ويُطلب تأكيد ذلك عبر الضغط على Y أي yes للمتابعة. لقد انتهيت الآن من تثبيت SDK لمشغّل NET Core. الآني على الخادم، وأنت جاهز تقريبًا لتنزيل التطبيق التجريبي من Github لضبط إعدادات النشر. لكن أولًا يجب إنشاء قاعدة بيانات التطبيق. الخطوة 2: إنشاء مستخدم MySQL وقاعدة بيانات ستنشئ في هذا الجزء مستخدم على خادم MySQL، وقاعدة بيانات للتطبيق، وتمنح جميع الصلاحيات الضرورية للمستخدم الجديد ليتصل بقاعدة البيانات من تطبيقك. تحتاج لتبدأ إلى الوصول لـMySQL العميل باستخدام حساب MySQL الجذر كما هو موضح هنا: $ mysql -u root -p سيُطلب منك إدخال كلمة سر الحساب الجذر الذي تمّ إعداده ضمن درس المتطلبات الأساسية. ثم أنشئ قاعدة بيانات MySQL للتطبيق باستخدام الأمر: mysql> CREATE DATABASE MovieAppDb; ستشاهد الخرج التالي في سطر الأوامر: Output Query OK, 1 row affected (0.03 sec) لقد أنشأت الآن قاعدة البيانات بنجاح، بعد ذلك ستُنشئ مستخدم MySQL جديد، وتربطه بقاعدة البيانات التي أُنشئت حديثًا، وتمنحه جميع الصلاحيات. نفّذ الأمر التالي لتُنشئ مستخدم MySQL وكلمة مرور. تذكّر أن تغيّر اسم المستخدم وكلمة المرور ليصبحوا أكثر أمانًا: mysql> CREATE USER 'movie-admin'@'localhost' IDENTIFIED BY 'password'; ستشاهد الخرج التالي: Output Query OK, 0 rows affected (0.02 sec) يحتاج مستخدم MySQL إلى الإذن المناسب للوصول إلى قاعدة بيانات أو تنفيذ إجراء محدد عليها، حاليًا لا يملك المستخدم movie-admin الإذن المناسب على قاعدة بيانات التطبيق. سنغيّر ذلك بتنفيذ الأمر التالي لمنح حق الوصول للمستخدم movie-admin إلى قاعدة البيانات MovieAppDb: mysql> GRANT ALL PRIVILEGES ON MovieAppDb.* TO 'movie-admin'@'localhost'; ستشاهد الخرج التالي: Output Query OK, 0 rows affected (0.01 sec) يمكنك الآن إعادة تحميل جداول الصلاحيات بتشغيل الأمر التالي لتطبيق التغييرات التي قمت بها باستخدام عبارة التدفق: mysql> FLUSH PRIVILEGES; ستشاهد الخرج التالي: Output Query OK, 0 rows affected (0.00 sec) لقد أنشأت مستخدم جديد ومنحه الصلاحيات. لتختبر فيما إذا تمّ الأمر بشكلٍ صحيحٍ، أغلق MySQL العميل: mysql> quit; ثمّ سجّل الدخول مجددًا باستخدام بيانات الاعتماد لمستخدم MySQL الذي أنشأته وأدخل كلمة المرور المناسبة عندما تُطلب منك: $ mysql -u movie-admin -p للتأكد من أن المستخدم movie-admin يمكنه الوصول إلى قاعدة البيانات المُنشأة، تحقق باستخدام الأمر: mysql> SHOW DATABASES; الآن ستشاهد جدول MovieAppDb ضمن قائمة الخرج: Output +--------------------+ | Database | +--------------------+ | MovieAppDb | | information_schema | +--------------------+ 2 rows in set (0.01 sec) الآن، أغلق MySQL العميل: mysql> quit; لقد أنشأت قاعدة بيانات، ومستخدم MySQL جديد للتطبيق التجريبي، ومنحت المستخدم الجديد الصلاحيات الصحيحة للوصول إلى قاعدة البيانات. في الجزء التالي، ستبدأ بضبط التطبيق التجريبي. الخطوة 3: ضبط التطبيق التجريبي وبيانات اعتماد قاعدة البيانات كما ذُكر سابقًا، ستنشر تطبيق ASP.NET Core موجود. تم بناء هذا التطبيق لإنشاء قائمة أفلام باستخدام نمط التصميم (Model-View-Controller) لضمان وجود الهيكل المناسب والفصل بين الاهتمامات. لإنشاء أو إضافة فيلم جديد إلى القائمة، سيملأ المستخدم حقول النموذج بالتفاصيل المناسبة ويضغط على زر إنشاء لإرسال التفاصيل إلى المتحكم (controller). عند ذلك يستقبل المتحكم طلب POST HTTP مع التفاصيل المرسلة وتبقى البيانات في قاعدة البيانات من خلال النموذج (model). ستستخدم Git لسحب (pull) الشيفرة المصدرية لهذا التطبيق التجريبي من GitHub وحفظه في مجلد جديد. يمكنك أيضًا تحميل تطبيق بديل إذا كنت ستنشر تطبيقًا مختلفًا. للبدء، أنشئ مجلدًا جديدًا باسم movie-app من الطرفية (terminal) باستخدام الأمر التالي: $ sudo mkdir -p /var/www/movie-app سيكون هذا المجلد بمثابة المجلد الجذر لتطبيقك. بعد ذلك، عدّل مالك ومجموعة المجلد للسماح لحساب المستخدم العادي بالعمل على ملفات المشروع: $ sudo chown sammy:sammy /var/www/movie-app استبدل sammy باسم المستخدم العادي الذي يملك صلاحيات sudo. يمكنك الآن الانتقال إلى المجلد الأب ونسخ (clone) التطبيق من Github: $ cd /var/www $ git clone https://github.com/do-community/movie-app-list.git movie-app ستشاهد الخرج التالي: Output Cloning into 'movie-app'… remote: Enumerating objects: 91, done. remote: Counting objects: 100% (91/91), done. remote: Compressing objects: 100% (73/73), done. remote: Total 91 (delta 13), reused 91 (delta 13), pack-reused 0 Unpacking objects: 100% (91/91), done. لقد نسخت التطبيق التجريبي بنجاح من GitHub، لذا ستكون الخطوة التالية هي إنشاء اتصال ناجح بقاعدة بيانات التطبيق. ستقوم بذلك عن طريق تعديل خاصية ConnectionStrings ضمن ملف appsettings.json وإضافة تفاصيل قاعدة البيانات. غيّر المجلد ضمن التطبيق: $ cd movie-app ثم افتح الملف للتعديل: $ sudo nano appsettings.json أضف بيانات اعتماد قاعدة البيانات في ملف appsettings.json: { "Logging": { "LogLevel": { "Default": "Warning" } }, "AllowedHosts": "*", "ConnectionStrings": { "MovieContext": "Server=localhost;User Id=movie-admin;Password=password;Database=MovieAppDb" } } بوضع هذه البيانات بطريقةٍ صحيحة فقد أنشأت اتصالًا ناجحًا بقاعدة البيانات. الآن اضغط CTRL+X لحفظ تغييرات الملف واضغط Y للتأكيد. ثم اضغط ENTER لإغلاق الصفحة. تستخدم تطبيقات ASP.NET Core مكتبة NET. قياسية تسمّى Entity Framework (EF) Core لإدارة التفاعل مع قاعدة البيانات. Entity Framework Core هي إصدار خفيف عابر للمنصات (cross-platform) من التقنية الشائعة للوصول إلى بيانات Entity Framework. إنّها تقنية ربط الكائنات بالعلاقات (ORM) التي تتيح لمطوري NET. العمل مع قاعدة البيانات باستخدام أي مزود قاعدة بيانات، مثل MySQL. يمكنك الآن تحديث قاعدة بياناتك مع الجداول من التطبيق التجريبي المنسوخ. نفّذ الأمر التالي لهذا الغرض: $ dotnet ef database update سيحدّث هذا الأمر قاعدة البيانات ويُنشئ المخططات المناسبة. الآن، لتبني المشروع وكلّ اعتمادياته، نفّذ الأمر التالي: $ dotnet build ستشاهد خرجًا مشابهًا للتالي: Output Microsoft (R) Build Engine version 16.1.76+g14b0a930a7 for .NET Core Copyright (C) Microsoft Corporation. All rights reserved. Restore completed in 95.09 ms for /var/www/movie-app/MvcMovie.csproj. MvcMovie -> /var/www/movie-app/bin/Debug/netcoreapp2.2/MvcMovie.dll MvcMovie -> /var/www/movie-app/bin/Debug/netcoreapp2.2/MvcMovie.Views.dll Build succeeded. 0 Warning(s) 0 Error(s) Time Elapsed 00:00:01.91 سيؤدي هذا إلى بناء المشروع وتثبيت أيّة اعتماديات خارجية (third-party dependencies) مذكورة في ملف project.assets.json، ولكن لن يكون التطبيق جاهزًا للنشر بعد. نفّذ الأمر التالي ليصبح التطبيق جاهزًا للنشر: $ dotnet publish ستشاهد التالي: Output Microsoft (R) Build Engine version 16.1.76+g14b0a930a7 for .NET Core Copyright (C) Microsoft Corporation. All rights reserved. Restore completed in 89.62 ms for /var/www/movie-app/MvcMovie.csproj. MvcMovie -> /var/www/movie-app/bin/Debug/netcoreapp2.2/MvcMovie.dll MvcMovie -> /var/www/movie-app/bin/Debug/netcoreapp2.2/MvcMovie.Views.dll MvcMovie -> /var/www/movie-app/bin/Debug/netcoreapp2.2/publish/ هذا سيُحزّم التطبيق ويترجمه، ويقرأ اعتمادياته، وينشر مجموعة الملفات الناتجة في مجلد للنشر، ويُنتج ملف dll. عابر للمنصات يستخدم مشغّل NET Core. الآني المثبّت لتشغيل التطبيق. بتثبيت الاعتماديات، وإنشاء اتصال بقاعدة البيانات، وتحديث قاعدة البيانات بالجداول الضرورية، ونشرها للإنتاج، تكون قد أكملت ضبط التطبيق التجريبي. في الخطوة التالية ستضبط إعدادات خادم الويب لجعل التطبيق متاحًا وآمنًا على نطاقك. الخطوة 4: ضبط إعدادات خادم الويب الآن وبعد اتّباع درس كيف تؤمّن خادم Nginx بشهادة Let's Encrypt ستحصل على كتلة الخادم لنطاقك في ‎/etc/nginx/sites-available/your_domain مع توجيه server_name الذي تمّ تعيينه بالفعل بشكلٍ مناسب. في هذه الخطوة ستعدّل كتلة الخادم هذه لتقوم بضبط Nginx كوكيل (proxy) عكسي لتطبيقك. الوكيل العكسي هو خادم يقع أمام خوادم الويب ويعيد توجيه كل طلب من مستعرض الويب إلى خوادم الويب هذه. إنّه يستقبل كل الطلبات من الشبكة ويعيد توجيهها إلى خادم ويب مختلف. في حالة تطبيق ASP.NET Core، يعدّ خادم الويب Kestrel هو الخادم المفضّل المضمّن افتراضيًا، وهذا ممتاز لتقديم المحتوى الديناميكي من تطبيق ASP.NET Core لكونه يوفر أداءً أفضل لمعالجة الطلبات وقد صُمم لجعل ASP.NET أسرع قدر الإمكان. ومع ذلك لا يعد Kestrel خادم ويب كامل المواصفات لأنه لا يمكنه إدارة الأمان وتقديم الملفات الثابتة، ولهذا يُستحسن دائمًا تشغيله خلف خادم ويب. للبدء، تأكد من أنّك داخل المجلد الجذر للخادم: $ cd ~ افتح كتلة الخادم للتعديل بهذا الأمر: $ sudo nano /etc/nginx/sites-available/your_domain كما هو مفصّل في الخطوة 4 من درس كيف تؤمّن خادم Nginx بشهادة Let's Encrypt، إذا اخترت الخيار 2، فإنَّ برنامج Certbot سيضبط تلقائيًا كتلة الخادم هذه لإعادة توجيه حركة مرور HTTP إلى HTTPS مع بعض التعديلات فقط. تابع الإعدادات بضبط أول كتلتين في الملف لتصل إلى ما يلي في ملف ‎/etc/nginx/sites-available/your-domain: server { server_name your-domain www.your-domain; location / { proxy_pass http://localhost:5000; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection keep-alive; proxy_set_header Host $host; proxy_cache_bypass $http_upgrade; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } listen [::]:443 ssl ipv6only=on; # managed by Certbot listen 443 ssl; # managed by Certbot ssl_certificate /etc/letsencrypt/live/your-domain/fullchain.pem; # managed by Certbot ssl_certificate_key /etc/letsencrypt/live/your-domain/privkey.pem; # managed by Certbot include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot } … هذه الإعدادات في كتلة الخادم ستطلب من خادم Nginx التنصّت على المنفذ 443، الذي هو المنفذ القياسي للمواقع التي تستخدم SSL. بالإضافة إلى ذلك سيقبل Nginx حركة المرور العامة على المنفذ 443 ويعيد توجيه كل طلب مطابق إلى خادم Kestrel المدمج http://localhost:5000. أخيرًا، بعد كتلة الخادم التي عدلتها في الملف، تأكّد من أنّ كتلة الخادم الثانية في الملف ‎/etc/nginx/sites-available/your-domain تبدو كالتالي: … server { if ($host = www.your-domain) { return 301 https://$host$request_uri; } # managed by Certbot if ($host = your-domain) { return 301 https://$host$request_uri; } # managed by Certbot listen 80; listen [::]:80; server_name your-domain www.your-domain; return 404; # managed by Certbot } ستعيد كتلة الخادم توجيه كل الطلبات إلى https://your-domain وhttps://www.your-domain لوصول HTTPS آمن. بعد ذلك، دع Nginx يعكس التغييرات التي قمت بها على كتلة الخادم بتنفيذ الأمر: $ sudo nginx -s reload بعد إكمال إعداد خادم Nginx، تمّ ضبط الخادم بالكامل لإعادة توجيه جميع طلبات HTTPS الموجهة إلى https://your-domain على تطبيق ASP.NET Core الذي يعمل على الخادم Kestrel إلى http://localhost:5000. ولكن لم يتم ضبط Nginx ليدير إجراء الخادم Kestrel. ستستخدم وظائف systemd لمعالجة هذا والتأكّد من أنّ عملية Kestrel تعمل في الخلفية. ستسمح لك ملفات Systemd بأن تدير إجراءًا من خلال توفير وظائف البدء، والإيقاف، وإعادة التشغيل، والدخول، حالما تنشئ إجراء عمل يدعى وحدة. انتقل ضمن مجلد systemd: $ cd /etc/systemd/systems أنشئ ملفًا جديدًا للتعديل: $ sudo nano movie.service وأضف المحتوى التالي له: [Unit] Description=Movie app [Service] WorkingDirectory=/var/www/movie-app ExecStart=/usr/bin/dotnet /var/www/movie-app/bin/Debug/netcoreapp2.2/publish/MvcMovie.dll Restart=always RestartSec=10 SyslogIdentifier=movie User=sammy Environment=ASPNETCORE_ENVIRONMENT=Production Environment=DOTNET_PRINT_TELEMETRY_MESSAGE=false [Install] WantedBy=multi-user.target يحدد ملف الإعداد موقع مجلد المشروع مع WorkingDirectory وأمر التنفيذ في بداية العملية في ExecStart. بالإضافة إلى ذلك، لقد اعتدت على استخدام توجيه RestartSec لوصف متى سيتم إعادة تشغيل خدمة systemd إذا تعطلت خدمة مشغّل NET. الآني. الآن، احفظ الملف وفعّل خدمة movie المنشأة حديثًا مع الأمر: $ sudo systemctl enable movie.service بعد ذلك، تابع لتشغيل الخدمة والتحقق من أنّها تعمل عند التشغيل: $ sudo systemctl start movie.service ثمّ تفحّص حالتها: $ sudo systemctl status movie.service ستشاهد الخرج التالي: Output movie.service - Movie app Loaded: loaded (/etc/systemd/system/movie.service; enabled; vendor preset: enabled) Active: active (running) since Sun 2019-06-23 04:51:28 UTC; 11s ago Main PID: 6038 (dotnet) Tasks: 16 (limit: 1152) CGroup: /system.slice/movie.service └─6038 /usr/bin/dotnet /var/www/movie-app/bin/Debug/netcoreapp2.2/publish/MvcMovie.dll يعطيك هذا الخرج نظرةً عامةً عن الحالة الراهنة لخدمة movie.service المنشأة لتحافظ على التطبيق شغّالًا. تشير إلى أنّ الخدمة شغّالة وفعّالة حاليًا. انتقل إلى https://your-domain من متصفحك لتشغيل التطبيق واختباره. ستشاهد الصفحة الرئيسية للتطبيق التجريبي- تطبيق قائمة الأفلام. مع الخادم الوكيل العكسي وKestrel الذي تتم إدارته باستخدام systemd، تم ضبط تطبيق الويب بالكامل ويمكن الوصول إليه من المتصفح. خاتمة نشرت في هذا الدرس تطبيق ASP.NET Core على خادم أوبنتو. وقمت بتثبيت خادم MySQL واستخدمته لاستمرار البيانات وإدارتها، واستخدمت خادم الويب Nginx كوكيل عكسي لخدمة تطبيقك. بعد هذا الدرس، إذا كنت مهتمًا ببناء تطبيق ويب تفاعلي باستخدام #C بدلًا من جافاسكربت، يمكنك تجربة إطار العمل Blazor لواجهة المستخدم للويب من مايكروسوفت. إنّه واجهة المستخدم للويب تعتمد على المكونات ومقادة بالأحداث لتحقيق المنطق من جهة العميل في تطبيق ASP.NET Core. إذا كنت ترغب بنشر تطبيقك، ستحتاج إلى أخذ الإجراءات الأخرى بالحسبان لنشر تطبيقك. الشيفرة المصدرية الكاملة لهذا التطبيق التجريبي تجدها هنا على GitHub. ترجمة -وبتصرف- للمقال How To Deploy an ASP.NET Core Application with MySQL Server Using Nginx on Ubuntu 18.04 لصاحبه Oluyemi Olususi
  8. أصبحت لغة Go -التي هي لغة برمجية عاميّة الغرض- واحدةً من لغات البرمجة الأكثر شعبيةً لتطوير الواجهة الخلفية. بالتركيز على البساطة، فإنَّ مصممي لغة Go ابتكروا لغةً سهلة التعلّم وأسرع من العديد من اللغات الأخرى لتطبيقات الويب، مستفيدين من الميزات الفعّالة مثل قدرتها على التعامل مع عدة طلبات في وقت واحد بسبب تزامنها. لهذا السبب، سيكون نشر تطبيق ويب بلغة Go مفيدًا للعديد من مطوري الواجهة الخلفية. Nginx هو أحد أشهر خوادم الويب في العالم نظرًا لاستخدامه الخفيف للموارد وموثوقيته في حال وجود حمل زائد. تعتمد العديد من المواقع الضخمة والأكثر زيارةً على Nginx لتقدّم محتواها. في النشر، غالبًا ما يُستخدم Nginx موازن حمل(load balancer) أو وكيل عكسي (reverse proxy) لزيادة الأمان وجعل التطبيق أكثر قوة. بالتزامن مع لغة Go لتطوير الواجهة الخلفية في الويب، يمكن لخادم Nginx تقديم تطبيق ويب سريع وقوي. ستتعلم في هذا الدرس كيفية بناء تطبيق ويب Hello World بلغة Go وننشره على خادم أوبنتو 18.04 مستخدمين Nginx كخادم عكسي. المتطلبات الأساسية لمتابعة هذا الدرس، ستحتاج إلى ما يلي: خادم أوبنتو 18.04 تم ضبطه باتباع التهيئة الأولية لخادم أوبنتو 18.04، متضمنًا مستخدمًا عاديًا بصلاحيات sudo وجدار حماية. يجب أن تكون لغة Go مثبّتة على حاسوبك. خادم Nginx مثبّت باتّباع الدرس كيف تثبّت خادم Nginx على أوبنتو 18.04. لا تتبع الخطوة 5 - إعداد كتل الخادم؛ ستنشئ كتلة خادم Nginx لاحقًا في هذا الدرس. اسم نطاق يشير إلى خادمك. سنستخدم your_domain في هذا الدرس. هذا ضروري للحصول على شهادة SSL لموقعك، حتى يمكنك أن تقدّم تطبيقك بأمان مع تشفير TLS. بالإضافة إلى ذلك، لتحقيق نشر بدرجة الإنتاج لتطبيق الويب Go، من المهم أن تحافظ على خادمك آمنًا بتثبيت شهادة TLS/SSL. أرشح لك هذه الخطوة بشدة. لتؤمّن تطبيق الويب Go، اتّبع كيف تؤمّن خادم Nginx بشهادة Let's Encrypt على أوبنتو بعد الخطوة 3 من هذا الدرس لتحصل على شهادة TLS/SSL مجانية. الخطوة 1: بناء تطبيق ويب بلغة البرمجة Go في هذه الخطوة، ستبني نموذج تطبيق ويب بلغة Go يعرض عبارة Hello World على نطاقك your_domain ويقوم بتحيّة المستخدم على الرابط your_domain/greet/. إذا كنت تريد تعلّم المزيد من أساسيات البرمجة في Go، تفحّص مقالتنا كيف تكتب برنامجك الأول بلغة Go. بدايةً، أنشئ مجلد جديد في مجلد GOPATH ليتضمن الملف المصدري. يمكنك تسمية المجلد بأي اسم تريده، ولكن في هذا الدرس سنستخدم اسم go-web: $ mkdir $GOPATH/go-web باتّباع بنية الملف المقترحة في درس فهم، تنصيب وتهيئة بيئة عمل لغة البرمجة Go، سيعطي هذا مجلدك المسار ‎~/go/go-web: بعد ذلك، نفّذ التعليمة التالية لتغيّر المجلد إلى مجلدك الذي أنشأته حديثًا في GOPATH: $ cd $GOPATH/go-web استخدم محرر النصوص nano أو المحرر المفضل لك لإنشاء ملف باسم main.go، والذي سيتضمن الشيفرة المصدرية لتطبيقك الويب: $ nano main.go لإنشاء وظيفة التطبيق Hello World، أضف شيفرة Go التالية إلى ملف main.go المنشأ حديثًا: package main import ( "fmt" "net/http" ) func main() { http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Hello World") }) http.HandleFunc("/greet/", func(w http.ResponseWriter, r *http.Request) { name := r.URL.Path[len("/greet/"):] fmt.Fprintf(w, "Hello %s\n", name) }) http.ListenAndServe(":9990", nil) } لنتعرّف الآن على ما سيفعله جزء الشيفرة السابق، بدءًا من السطر الأول. كتبت أولًا نقطة الدخول إلى تطبيقك: package main … تخبر تعليمة package main مُصرِّف Go أن يصرّف هذا الملف على أنّه برنامجٌ تنفيذي بدلًا من أن يكون مكتبة مشتركة (shared library). ثمّ لديك تعليمات import: … import ( "fmt" "net/http" ) … يستورد هذا الجزء الوحدات الضرورية لعمل هذه الشيفرة، والتي تشمل حزمة fmt القياسية وحزمة net/http لخادم الويب الخاص بك. يُنشئ الجزء التالي مسارك الأول في الدالة main والتي هي نقطة الدخول لأي تطبيق Go: … func main () { http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Hello World") }) … } … أنشئ المسار الأب / ضمن الدالة func main، التي ستعيد النص Hello World عندما تُطلب. كما هو موضح في الجزء التالي فإنّ المسار الثاني يقبل معاملًا في الرابط (URL parameter)، في هذه الحالة اسمًا، لعرضه مصحوبًا بالتحية. … func main () { … http.HandleFunc("/greet/", func(w http.ResponseWriter, r *http.Request) { name := r.URL.Path[len("/greet/"):] fmt.Fprintf(w, "Hello %s\n", name) }) … } … يستخدم هذا URL.Path الخاص بلغة Go لتخزين القيمة مباشرةً بعد /greet/ وتمريرها كاسم من معامل الرابط. أخيرًا، هيّئ الخادم: … func main () { … http.ListenAndServe(":9990", nil) } يشغّل الجزء السابق الخادم ويعرض تطبيقك عبر المنفذ 9990 باستخدام خادم http المدمج بلغة Go. احفظ الملف وأغلق المحرر النصي بمجرد الانتهاء من فحص الشيفرة في main.go. بعد ذلك، ابنِ الملف الثنائي القابل للتنفيذ لتطبيقك باستخدام الأمر: $ go build main.go التعليمة السابقة ستصرِّف الملف main.go لإنتاج ملف قابل للتنفيذ باسم main. لقد أنشأت نموذج تطبيق ويب بلغة Go. بعد ذلك، ستنشئ ملف وحدة systemd ليبقى تطبيقك شغّالًا في الخلفية حتى عندما لا تصل إلى خادمك. الخطوة 2: إنشاء ملف وحدة Systemd في هذه الخطوة، ستنشئ ملف وحدة systemd ليبقى تطبيقك شغّالًا في الخلفية حتى عندما يسجّل المستخدم خروجه من الخادم. سيجعل هذا تطبيقك ثابتًا، مما يجعلك أقرب بخطوة للنشر على مستوى الإنتاج. بدايةً، أنشئ ملفًا جديدًا في مجلد ‎/lib/systemd/system باسم goweb.service باستخدام محرر النصوص nano أو محرر النصوص المفضّل لك: $ sudo nano /lib/systemd/system/goweb.service لضبط معاملات الخدمة، أضف الجزء التالي في الملف. [Unit] Description=goweb [Service] Type=simple Restart=always RestartSec=5s ExecStart=/home/user/go/go-web/main [Install] WantedBy=multi-user.target يحدّد المتغير ExecStart=/home/user/go/go-web/main أنَّ نقطة الدخول لهذه الخدمة عبر الملف main القابل للتنفيذ الموجود في المجلد ‎/home/user/go/go-web، إذ user هو اسم المستخدم لحساب المستخدم العادي الذي يملك صلاحيات sudo على الخادم. Restart=always تضمن أنَّ systemd سيحاول دائمًا أن يعيد تشغيل البرنامج إذا توقف. في السطر التالي، RestartSec=5s يضبط وقت انتظار لخمس ثوانٍ بين محاولات إعادة التشغيل. يحدِّد WantedBy=multi-user.target في أي حالة سيفعّل الخادم الخدمة. احفظ وأغلق الملف. بعد أن كتبت ملف وحدة الخدمة، شغّل خدمة الويب Go باستخدام الأمر: $ sudo service goweb start للتأكّد فيما إذا كانت الخدمة شغّالة، استخدم الأمر التالي: $ sudo service goweb status ستستقبل الخرج التالي: Output ● goweb.service - goweb Loaded: loaded (/lib/systemd/system/goweb.service; disabled; vendor preset: enabled) Active: active (running) since Wed 2019-07-17 23:28:57 UTC; 6s ago Main PID: 1891 (main) Tasks: 4 (limit: 1152) CGroup: /system.slice/goweb.service └─1891 /home/user/go/go-web/main لتتعلم المزيد عن العمل مع ملف وحدة systemd، ألقِ نظرة على فهم وحدات وملفات وحدة Systemd. الآن بعد أن أصبح لديك تطبيقًا شغّالًا، يمكنك ضبط الوكيل العكسي Nginx. الخطوة 3: ضبط وكيل عكسي مع Nginx ستنشئ في هذه الخطوة كتلة خادم Nginx وستضبط الوكيل العكسي Nginx لتعرض تطبيقك على الإنترنت. أولًا، غيّر مجلد العمل الخاص بك إلى مجلد sites-available على الخادم Nginx: $ cd /etc/nginx/sites-available أنشئ ملفًا جديدًا باسم النطاق الذي تريد عرض تطبيقك عليه. سيستخدم هذا الدرس الملف your_domain: $ sudo nano your_domain أضف الأسطر التالية إلى الملف لوضع الإعدادات لـ your_domain: server { server_name your_domain www.your_domain; location / { proxy_pass http://localhost:9990; } } كتلة الخادم Nginx تستخدم proxy_pass لتقديم تطبيق الويب Go على عنوان IP لخادمك المشار إليه على أنّه مضيف محلي localhost لتشغيله على المنفذ 9990 . يشير server_name إلى اسم النطاق المعيّن لعنوان IP الخاص بك، في هذه الحالة your_domain وwww.your_domain. بعد ذلك، أنشئ رابطًا رمزيًا لإعدادات Nginx هذه في مجلد sites-enabled بتشغيل الأمر التالي: $ sudo ln -s /etc/nginx/sites-available/your_domain /etc/nginx/sites-enabled/your_domain الرابط الرمزي هو اختصار لملف في موقع آخر. يشير الاختصار المُنشأ حديثًا إلى الملف الأصلي للتكيّف مع التحديثات عند إجراء التعديلات عليه. يتطلب Nginx نسخة من الإعدادات في كلا المجلدين. بعدها، أعد تحميل إعدادات Nginx بتشغيل تعليمة إعادة التحميل: $ sudo nginx -s reload لتتأكد أن نشرك يعمل، قم بزيارة http://your_domain في متصفحك، إذ ستتم تحيتك بسلسلة نصية Hello World. ملاحظة: كما ذُكر في قسم المتطلبات الأساسية، يُنصح في هذه النقطة أن يتم تفعيل SSL/TLS على خادمك. سيضمن ذلك تشفير جميع الاتصالات بين التطبيق وزوّاره، وهو أمر مهم بشكلٍ خاص إذا طلب التطبيق معلومات حساسة مثل تسجيل الدخول أو كلمة المرور. اتّبع الآن درس كيف تؤمّن خادم Nginx بشهادة Let's Encrypt على أوبنتو لتحصل على شهادة SSL مجانية لخادم Nginx على أوبنتو 18.04. بعد أن تحصل على شهادات SSL/TLS خاصة بك، عُد وأكمل هذا الدرس. ضبطت الآن الوكيل العكسي Nginx لتعرض تطبيقك على اسم النطاق الخاص بك، وقمت بتأمين تطبيق الويب Go مع SSL/TLS. في الخطوة التالية، ستختبر تطبيقك عبر اتصالٍ آمن. الخطوة 4: اختبار التطبيق في هذه الخطوة، ستختبر تطبيقك عبر اتصالٍ آمن لتتأكد من أنَّ كل شيء يعمل. افتح متصفح الويب المفضل لك، وقم بزيارة https://your_domain: ستستقبل رسالة Hello World بسيطة. استقبال هذه الرسالة عند استخدام https://‎ في الرابط يشير إلى أنَّ التطبيق يُعرض عبر اتصالٍ آمن. بعد ذلك، حاول زيارة المسار الثاني https://your_domain/greet/your-name مستبدلًا بالعبارة your-name أيّ اسم آخر تريد أن يلقي عليه تطبيقك التحيّة: سيعيد التطبيق تحيّة بسيطة مع your-name، الذي يعتمد على المعامل الممرّر للرابط. حالما تستقبل هذه النتائج، تكون قد نشرت تطبيق ويب Go بنجاح. خاتمة في هذا الدرس، أنشأت تطبيق ويب بسيط بلغة Go مستخدمًا مكاتبها القياسية، وقمت بضبط وكيل عكسي مستخدمًا Nginx، واستخدمت شهادة SSL على نطاقك لتأمين تطبيقك. لتتعلّم المزيد حول Go، تفحّص توثيقها الرسمي. بإمكانك أيضًا أن تلقي نظرة على قسم لغة GO لتتعلم المزيد حول البرمجة بهذه اللغة الفعالة. ترجمة -وبتصرف- للمقال How To Deploy a Go Web Application Using Nginx on Ubuntu 18.04 لصاحبه Michael Okoh
  9. 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
  10. عندما تُنشئ خادم أوبونتو 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
  11. 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.
  12. 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.
  13. 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.
  14. 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.
  15. عند إنشاءك خادم أوبونتو 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.
  16. حاوية لينكس (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.
  17. نشرح طريقة تثبيت Monit على نظام أوبنتو. وسنشرح كمثال كيفية إعداد Monit لمراقبة وإعادة تشغيل Nginx في حال توقفه. قسم DevOps في أكاديمية حسوب غني بالمقالات المفيدة للتعامل مع الخوادم.
  18. نشرح طريقة تثبيت وإعداد خادم Nginx على توزيعة أوبنتو، وسنستعمله لتخديم صفحات HTML الخاصة بنا. لتثبيت خادم أباتشي راجع فيديو تثبيت وضبط خادم Apache في أكاديمية حسوب. قسم خوادم الويب في أكاديمية حسوب غني بالمقالات المفيدة للتعامل معها.
  19. ستغطّي هذه السّلسلة عمليّة نشر تطبيق PHP بسيط باستخدام Ansible، الهدف النّهائي سيكون الحصول على خادوم ويب جديد يُخدِّم تطبيق PHP بسيط بدون أي اتصال عبر SSH أو تشغيل يدوي للأوامر على الخادوم الهدف، سنغطي في هذا القسم من الدرس تثبيت Ansible وإعداد البيئة بشكل عام. سنستخدم إطار عمل Laravel كمثال عن تطبيق PHP ولكن يُمكِن تعديل هذه التعليمات بسهولة لتدعم أطر عمل وتطبيقات أخرى في حال كانت متواجدة لديك. المتطلبات الأساسيةسنستخدم Ansible لتثبيت وإعداد Nginx، PHP، وخدمات أخرى على خادوم Ubuntu 14.04 ، يعتمد هذا الدّرس على معرفتك الأساسية بـ Ansible لذا إن كنت جديدًا عليها فبإمكانك قراءة درس Ansible الأساسي أولًا. ستحتاج لمتابعة هذا الدّرس إلى: خادوم Ubuntu 14.04 بأي حجم والذي سنستخدمه لإعداد ونشر تطبيق PHP الخاص بنا عليه، ستتم الإشارة إلى عنوان IP هذا الجهاز بـ your_server_ip خلال هذا الدّرس.خادوم Ubuntu 14.04 والذي سنستخدمه من أجل Ansible، وهو الخادوم الذي سنبقى في وضعية تسجيل دخول عليه في كامل هذا الدّرس.إعداد مستخدم غير جذري مع صلاحيّات sudo لكل خادوم.مفاتيح SSH من أجل خادوم Ansible لتصريح تسجيل الدخول على خادوم نشر PHP، ويُمكِن إعدادها باتّباع هذه السلسلة وتطبيقها على خادوم Ansible الخاص بنا.الخطوة الأولى – تثبيت Ansibleيُمكِن إنجاز هذه الخطوة بسهولة عن طريق تثبيت PPA (أرشيف الحِزَم الشخصي Personal Package Archive) وتثبيت حزمة Ansible باستخدام apt. نُضيف أوّلًا PPA باستخدام الأمر apt-add-repository: sudo apt-add-repository ppa:ansible/ansibleوبعد انتهائه نقوم بتحديث ذاكرة التخزين المؤقّت cache لـ apt: sudo apt-get update نقوم بتثبيت Ansible أخيرًا: sudo apt-get install ansibleحالما يتم تثبيت Ansible نقوم بإنشاء دليل جديد للعمل بداخله وضبط الإعدادات الأساسيّة، تستخدم Ansible افتراضيًّا ملف مضيفين hosts موجود في المسار etc/ansible/hosts/، وهو يحتوي كافّة الخواديم التي يُديرها، وبينما يكون هذا الملف مناسبًا لبعض حالات الاستخدام فهو عام global، وهو ما لا نريده هنا. سنقوم من أجل هذا الدّرس بإنشاء ملف مضيفين محلّي local واستخدامه بدلًا من الملف السابق، نستطيع فعل هذا عن طريق إنشاء ملف إعدادات Ansible جديد بداخل دليل العمل لدينا، والذي بإمكاننا استخدامه لإخبار Ansible بأن تبحث عن ملف المضيفين داخل نفس الدليل. نُنشِئ مُجلّدًا جديدًا (سنستخدمه لبقيّة هذا الدّرس): mkdir ~/ansible-php ننتقل إلى داخل المُجلّد الجديد: cd ~/ansible-php/نُنشِئ ملفًّا جديدًا يُدعى ansible.cfg ونفتحه من أجل تحريره باستخدام nano أو أي مُحرِّر نصوص تفضله: nano ansible.cfgنضيف خيار الإعدادات hostfile مع القيمة hosts في المجموعة [defaults] عن طريق نسخ ما يلي إلى الملف ansible.cfg: ansible.cfg [defaults] hostfile = hostsنحفظ الملف ansible.cfg ونغلقه، نقوم بعدها بإنشاء الملف hosts والذي يحتوي على عنوان IP لخادوم PHP حيث سيتم نشر تطبيقنا. nano hostsننسخ ما يلي لإضافة قسم من أجل php مع وضع عنوان IP الخاص بخادومك بدلًا من your_server_ip ووضع اسم المستخدم غير الجذري الذي قمت بإنشائه في المتطلبات الأساسيّة على خادوم PHP بدلًا من sammy: hosts [php] your_server_ip ansible_ssh_user=sammy نحفظ ونغلق الملف hosts، فلنقم بإجراء تحقّق أبسط للتأكد من قدرة Ansible على الاتصال بالمضيف كما هو متوقّع عن طريق استدعاء الوحدة ping على المجموعة php الجديدة: ansible php -m pingربّما تحصل على تحقّق من استيثاق مُضيف SSH اعتمادًا على كونك قد سجلّت الدخول إلى هذا المُضيف من قبل، ينبغي أن تعود ping باستجابة ناجحة تبدو كما يلي: Output 111.111.111.111 | success >> { "changed": false, "ping": "pong" تمّ الآن تثبيت وإعداد Ansible بنجاح، نستطيع الانتقال إلى إعداد خادوم الويب لدينا. الخطوة الثانية – تثبيت الحزم المطلوبةسنقوم في هذه الخطوة بتثبيت بعض حِزَم النظام المطلوبة باستخدام Ansible و apt، سنثبت تحديدًا git، nginx، sqlite3، mcrypt، وبعض حِزَم php5-*. نحتاج قبل إضافة الوحدة apt لتثبيت الحِزَم التي نريدها إلى إنشاء playbook بسيط (وهو عبارة عن قواعد تُحدِّد إعدادات Ansible)، سنبني على هذا الـ playbook مع تقدّمنا في هذا الدّرس، نقوم بإنشاء playbook جديد يُدعى php.yml: nano php.yml نلصق الإعدادات التالية، يُحدِّد أول سطرين مجموعة المضيفين التي نرغب باستخدامها (php) وتتحقّق من أنّها تنفّذ الأوامر باستخدام sudo افتراضيًّا، تُضيف باقي الأسطر وحدة بالحِزَم التي نحتاجها، تستطيع تخصيصها من أجل تطبيقاتك الخاصّة أو استخدام الإعدادات التالية إن كنت تتبع مثال تطبيق Laravel: --- - hosts: php sudo: yes tasks: - name: install packages apt: name={{ item }} update_cache=yes state=latest with_items: - git - mcrypt - nginx - php5-cli - php5-curl - php5-fpm - php5-intl - php5-json - php5-mcrypt - php5-sqlite - sqlite3نحفظ الملف php.yml، ونقوم أخيرًا بتشغيل ansible-playbook لتثبيت الحِزَم على الخادوم، يجب ألّا ننسى استخدام الخيار --ask-sudo-pass إن كان يتطلّب مستخدم sudo على خادوم PHP كلمة سر: ansible-playbook php.yml --ask-sudo-passالخطوة الثالثة – تعديل ملفات إعدادات النظامسنقوم في هذا القسم بتعديل بعض ملفّات إعدادات النظام على خادوم PHP، أهم خيار إعدادات يُمكِن تغييره (بغض النظر عن ملفّات Nginx، والتي سيتم تغطيتها في خطوة لاحقة) هو الخيار cgi.fix_pathinfo في php5-fpm، لأنّ القيمة الافتراضيّة له تُشكِّل خطرًا أمنيًّا. سنوضّح أوّلًا جميع الأقسام التي سنضيفها إلى هذا الملف، ونضمّن بعدها كامل الملف php.yml من أجلك لكي تقوم بنسخه ولصقه. يُمكِن استخدام الوحدة lineinfile للتأكّد من أنّ قيمة الإعدادات ضمن الملف مطابقة تمامًا لما نتوقعه، يُمكِن عمل هذا باستخدام تعبير نمطي regular expression عام بحيث تتمكّن Ansible من فهم معظم الصيغ التي من المحتمل أن يكون فيها المُعامِل، سنحتاج أيضًا لإعادة تشغيل php5-fpm وnginx لضمان تطبيق التغييرات، لذا نحتاج إلى إضافة مُداوِلَين handlers اثنين أيضًا في قسم جديد للمداولات handlers، تكون المداولات مثاليّة لهذا لأنّه يتم إطلاقها فقط عند تغيير المهمّة، ويتم أيضًا تشغيلها في نهاية الـ playbook، لذا يُمكن لمهام متعدّدة استدعاء نفس المُداوِل وسيعمل فقط مرّة واحدة. يبدو القسم الذي يُنفِّذ ما سبق كما يلي: name: ensure php5-fpm cgi.fix_pathinfo=0 lineinfile: dest=/etc/php5/fpm/php.ini regexp='^(.*)cgi.fix_pathinfo=' line=cgi.fix_pathinfo=0 notify: - restart php5-fpm - restart nginx handlers: - name: restart php5-fpm service: name=php5-fpm state=restarted - name: restart nginx service: name=nginx state=restartedملاحظة: خطأ برمجي bug في إصدار Ansible 1.9.1 يوجد خطا برمجي في إصدار Ansible 1.9.1 يمنع php5-fpm من إعادة تشغيلها مع الوحدة service، وقد استخدمنا هذا في مُداولاتنا. وحتى يتم إصدار إصلاح له نستطيع الالتفاف على هذه المشكلة عن طريق تغيير المُداوِل restart php5-fpm من استخدام الأمر service إلى استخدام الأمر shell كما يلي: - name: restart php5-fpm shell: service php5-fpm restartسيتجاوز هذا المشكلة ويعيد تشغيل php5-fpm بشكل صحيح. نحتاج بعد ذلك أيضًا إلى التأكّد من تمكين الوحدة php5-mcrypt، يُمكن فعل هذا عن طريق تنفيذ script يُدعى php5enmod باستخدام صدفة المهام shell task والتحقّق من وجود الملف 20-mcrypt.ini في مكانه عند تمكينه، لاحظ أنّنا نخبر Ansible أنّ المهمّة تقوم بإنشاء ملف مُحدَّد، فإن كان هذا الملف موجودًا فلن يتم تشغيل المهمّة: name: enable php5 mcrypt module shell: php5enmod mcrypt args: creates: /etc/php5/cli/conf.d/20-mcrypt.iniنفتح الآن الملف php.yml لتحريره مرّة أخرى: nano php.ymlنضيف المهام والمداولات السابقة بحيث يتطابق الملف مع التالي: --- - hosts: php sudo: yes tasks: - name: install packages apt: name={{ item }} update_cache=yes state=latest with_items: - git - mcrypt - nginx - php5-cli - php5-curl - php5-fpm - php5-intl - php5-json - php5-mcrypt - php5-sqlite - sqlite3 - name: ensure php5-fpm cgi.fix_pathinfo=0 lineinfile: dest=/etc/php5/fpm/php.ini regexp='^(.*)cgi.fix_pathinfo=' line=cgi.fix_pathinfo=0 notify: - restart php5-fpm - restart nginx - name: enable php5 mcrypt module shell: php5enmod mcrypt args: creates: /etc/php5/cli/conf.d/20-mcrypt.ini handlers: - name: restart php5-fpm service: name=php5-fpm state=restarted - name: restart nginx service: name=nginx state=restarted نقوم أخيرًا بتشغيل playbook: ansible-playbook php.yml --ask-sudo-pass يمتلك الآن الخادوم كافّة الحِزَم المطلوبة مُثبّتة عليه ومجموعة الإعدادات الأساسيّة جاهزة للانطلاق. الخاتمةتحدثنا في القسم الأول من هذا الدّرس عن طريقة تثبيت Ansible وإعداد البيئة بشكل عام من أجل التحضير لعمليّة نشر تطبيق PHP بسيط باستخدام Ansible، وسنكمل في القسم الثاني الحصول على Laravel وإعداده وإعداد خادوم Nginx لتخديم تطبيق PHP. ترجمة -وبتصرّف- لـ How To Deploy a Basic PHP Application Using Ansible on Ubuntu 14.04 لصاحبه Stephen Rees-Carter.
  20. إن UFW، أو Uncomplicated Firewall (الجدار الناري غير المعقَّد)، هو واجهة للجدار الناري iptables الذي يجنح لتبسيط عملية ضبط جدار ناري؛ وعلى الرغم من أنَّ iptables هو أداةٌ قويةٌ ومرنة، لكن قد يكون من الصعب على المبتدئين أن يتعلموا استخدامه ليضبطوا جدارًا ناريًا ضبطًا سليمًا. إذا كنت تطمح إلى أن تبدأ بتأمين شبكتك، ولكنك لست متأكدًا من أيّ أداةٍ ستختار، فربما يكون UFW هو الخيار المناسب لك. سيريك هذا الدرس كيفية ضبط جدارٍ ناريٍ في أوبنتو 14.04 بوساطة UFW. المتطلبات المسبقةقبل أن تبدأ في تطبيق هذا الدرس، يجب أن تملك حسابَ مستخدمٍ ليس جذرًا لكنه يستطيع الحصول على امتيازات الجذر عبر الأمر sudo. يمكنك تعلم كيف يتم ذلك عبر تطبيق الخطوات من 1 إلى 3 على الأقل في درس الإعداد الابتدائي لخادوم أوبنتو 14.04. يكون UFW مُثبَّتًا افتراضيًا في أوبنتو؛ إذا ألغي تثبيته لسببٍ ما، فيمكنك إعادة تثبيته باستخدام الأمر: sudo apt-get install ufw استخدام IPv6 مع UFWإذا كان IPv6 مفعّلًا على خادومك، فتأكد أن UFW مضبوطٌ لدعم IPv6 كي تستطيع إدارة قواعد الجدار الناري الخاصة بعناوين IPv6 بالإضافة إلى IPv4؛ ولفعل ذلك، عدِّل ضبط UFW بمحررك النصي المفضّل؛ سنستخدم nano هنا: sudo nano /etc/default/ufw تأكد من أن قيمة «IPV6» مساويةٌ للقيمة «yes»؛ إذ يجب أن يبدو الملف كما يلي: /etc/default/ufw excerpt … IPV6=yes … احفظ واخرج، اضغط Ctrl-X للخروج من الملف، ثم Y لحفظ التعديلات التي أجريتها، ثم اضغط Enter لتأكيد اسم الملف. عندما يفعَّل UFW، فسيُضبَط لكتابة قواعد جدار ناري لعناوين IPv4 و IPv6. كُتِبَ هذا الدرس مع أخذ IPv4 بعين الاعتبار، لكنه قابل للتطبيق على IPv6 طالما كنت مفعِّلًا إياه. التحقق من حالة وقواعد UFWفي أي وقتٍ تريد، تستطيع التحقق من حالة UFW باستخدام هذا الأمر: sudo ufw status verbose افتراضيًا، يكون UFW معطّلًا لذلك سيظهر عندك شيءٌ شبيهٌ بما يلي: Status: inactive إذا كان UFW مفعّلًا، فسيخبرك الناتج ذلك، وسيُظهِر أيّة قواعد قد ضُبِطَت؛ على سبيل المثال، إذا ضُبِطَ الجدار الناري للسماح بالاتصالات من أيّ مكانٍ إلى SSH (المنفذ 22)، فسيكون الناتج شيئًا شبيهًا بما يلي: Status: active Logging: on (low) Default: deny (incoming), allow (outgoing), disabled (routed) New profiles: skip To Action From -- ------ ---- 22/tcp ALLOW IN Anywhereيمكنك استخدام الأمر status في أي وقتٍ إذا أردت أن تعرف كيف ضَبَطَ UFW الجدارَ الناري. قبل تفعيل UFW، ربما تريد أن تتأكد أن جدارك الناري مضبوطٌ للسماح لك بالاتصال عبر SSH. لنبدأ بضبط السياسات الافتراضية (default policies). ضبط السياسات الافتراضيةإذا كنت قد بدأت لتوِّك مع جدارك الناري، فإن أولى القواعد التي عليك تعريفها هي السياسات الافتراضية؛ تتحكم هذه القواعد بطريقة معالجة البيانات الشبكية التي لم تُطابَق بدقّة مع أيّة قواعد أخرى؛ افتراضيًا، UFW مضبوطٌ لمنع جميع الاتصالات الواردة والسماح لكل الاتصالات الصادرة. هذا يعني أن أي شخصٍ يحاول أن يصل إلى خادومك السحابي لن يستطيع الاتصال، بينما يستطيع أيُ تطبيقٍ على خادومك أن يصل إلى «العالم الخارجي». لنرجع الضبط الافتراضي لقواعد UFW لكي نتأكد أنك تستطيع الإكمال مع هذا الدرس؛ استخدم الأمرين الآتيين لإعادة ضبط القيم الافتراضية المُستخدَمة من UFW: sudo ufw default deny incoming sudo ufw default allow outgoing وكما توقّعتَ، يعيد الأمران السابقان ضبط UFW إلى القيم الافتراضية بمنع الاتصالات الواردة والسماح للاتصالات الصادرة؛ قد تكون هذه القيم الافتراضية كافيةً للحواسيب الشخصية لكن تحتاج الخواديم إلى الرد على الطلبيات (requests) القادمة من المستخدمين الخارجيين؛ سنلقي نظرةً على ذلك لاحقًا. السماح لاتصالات SSHإذا فعّلنا جدار UFW الآن، فسيحجب جميع الاتصالات الواردة؛ هذا يعني أننا سنحتاج إلى إنشاء قواعد تسمح (وبدقّة) للاتصالات الشرعيّة (مثل اتصالات SSH أو HTTP) إذا أردنا أن يجيب خادومنا إلى ذاك النوع من الطلبيات؛ إذا كنت تستخدم خادومًا سحابيًا، فربما تريد السماح لاتصالات SSH الواردة كي تستطيع الاتصال وإدارة خادومك عن بُعد. لضبط خادومك للسماح باتصالات SSH، فاستخدم أمر UFW الآتي: sudo ufw allow ssh ينُشِئ الأمر السابق قواعد جدار ناري تسمح لجميع الاتصالات على المنفذ 22، الذي هو المنفذ الذي يستمع إليه «عفريت» (daemon)‏‏ ‏SSH؛ يعلم UFW ما هو «ssh» (بالإضافة إلى عدد كبير من أسماء الخدمات الأخرى) ولذلك لأنه مذكورٌ كخدمةٍ تَستخدمُ المنفذ 22 في ملف ‎/etc/services. نستطيع كتابة قاعدة مكافئة للقاعدة السابقة بتحديد المنفذ بدلًا من اسم الخدمة؛ على سبيل المثال، سيعمل هذا الأمر عمل الأمر السابق تمامًا: sudo ufw allow 22 إذا ضبطتَ عفريت SSH ليستخدم منفذًا آخر، فربما عليك تحديد المنفذ الملائم؛ على سبيل المثال، إذا كان يستمع خادم SSH إلى المنفذ 2222، فيمكنك استخدام الأمر الآتي للسماح للاتصالات على ذاك المنفذ: sudo ufw allow 2222 الآن، وبعد أن ضبطتَ جدارك الناري للسماح لاتصالات SSH القادمة، فعلينا تفعيله. تفعيل UFWاستخدم الأمر الآتي لتفعيل UFW: sudo ufw enable سيظهر لك تحذيرٌ يقول: «قد يقطع هذا الأمر اتصالات SSH الموجودة»؛ لكننا قد ضبطنا مسبقًا قاعدةً تسمح لاتصالات SSH، لذلك لا بأس من الإكمال، أجب بكتابة y. قد فعَّلتَ الجدار الناري الآن، تستطيع تنفيذ الأمر: sudo ufw status verbose لمعرفة القواعد المضبوطة. السماح لبقية الاتصالاتعليك الآن السماح لبقية الاتصالات التي يجب على خادومك الإجابة عليها؛ الاتصالات التي ستَسمح لها تتعلق باحتياجاتك. ولحسن الحظ، لقد تعلمت كيف تكتب قواعدًا تسمح للاتصالات بناءً على اسم الخدمة أو المنفذ (حيث فعلنا ذلك لخدمة SSH على المنفذ 22)؛ سنريك عدّة أمثلة لخدماتٍ شائعةٍ جدًا ربما تريد أن تسمح لها في جدارك الناري. إذا كانت لديك أيّة خدمات أخرى تريد السماح لاتصالاتها الواردة، فاتّبِع تلك الصيغة. خدمة HTTP – المنفذ 80يمكن السماح لاتصالات HTTP التي تستخدمها خوادم الويب غير المشفَّرة (unencrypted) بالأمر الآتي: sudo ufw allow http أو إذا كنت تفضِّل استخدام رقم المنفذ (80)، فنفِّذ هذا الأمر: sudo ufw allow 80 خدمة HTTPS – المنفذ 443يمكن السماح لاتصالات HTTPS التي تستخدمها خوادم الويب المشفَّرة (encrypted) بالأمر الآتي: sudo ufw allow https أو إذا كنت تفضِّل استخدام رقم المنفذ (443)، فنفِّذ هذا الأمر: sudo ufw allow 443 خدمة FTP – المنفذ 21يمكن السماح لاتصالات FTP التي تُستخدَم لنقل الملفات دون تشفير (والتي لا يجدر بك استخدامها على أيّة حال) بالأمر الآتي: sudo ufw allow ftp أو إذا كنت تفضِّل استخدام رقم المنفذ (21)، فنفِّذ هذا الأمر: sudo ufw allow 21/tcp السماح لمجالات منافذ معيّنةيمكنك تحديد مجالات منافذ عبر UFW؛ حيث تَستخدِم بعض التطبيقات عدِّة منافذ، بدلًا من منفذٍ واحد. على سبيل المثال، للسماح لاتصالات X11، التي تستخدم المنافذ 6000-6007، فاستخدم هذين الأمرين: sudo ufw allow 6000:6007/tcp sudo ufw allow 6000:6007/udp عند تحديد مجالات للمنافذ مع UFW، فيجب عليك تحديد البروتوكول (tcp أو udp) الذي تُطبَّق عليه القاعدة؛ لم نذكر ذلك من قبل لأنه عدم تحديد البروتوكول يسمح ببساطة بالاتصالات لكلي البروتوكولَين، وهذا مقبولٌ في أغلبية الحالات. السماح لعناوين IP محددةعند العمل مع UFW، تستطيع تحديد عناوين IP؛ على سبيل المثال، إذا أردت السماح للاتصالات من عنوان IP محدد، مثل عنوان IP للعمل أو المنزل الذي هو 15.15.15.51، فعليك استخدام الكلمة «from» ثم عنوان IP: sudo ufw allow from 15.15.15.51 تستطيع تحديد منفذ معيّن يُسمَح لعنوان IP بالاتصال إليه عبر كتابة «to any port» متبوعةً برقم المنفذ؛ على سبيل المثال، إذا أردت السماح لعنوان 15.15.15.51 بالاتصال إلى المنفذ 22 (SSH)، فاستخدم هذا الأمر: sudo ufw allow from 15.15.15.51 to any port 22 السماح للشبكات الفرعيةإذا أردت السماح لشبكة فرعية من عناوين IP، فيمكنك استخدام «ترميز CIDR»‏ (CIDR notation) لتحديد شبكة فرعية؛ فعلى سبيل المثال، إذا أردت السماح لجميع عناوين IP التي تتراوح بين 15.15.15.1 إلى 15.15.15.254 فيمكنك استخدام هذا الأمر: sudo ufw allow from 15.15.15.0/24وبشكلٍ مشابه، تستطيع أيضًا تحديد منفذ يُسمَح للشبكة الفرعية 15.15.15.0/24 بالاتصال إليه؛ سنستخدم أيضًا المنفذ 22 (SSH) كمثال: sudo ufw allow from 15.15.15.0/24 to any port 22 السماح بالاتصالات إلى بطاقة شبكية محددةإذا أردت إنشاء قاعدة جدار ناري تُطبَّق فقط على بطاقةٍ شبكيّةٍ محددة، فيمكنك فعل ذلك عبر كتابة «allow in on» متبوعةً باسم البطاقة الشبكيّة. ربما تريد أن تبحث عن بطاقاتك الشبكيّة قبل الإكمال؛ استخدم هذا الأمر لفعل ذلك: ip addr الناتج: … 2: eth0: حجب الاتصالاتإذا لم تعدِّل السياسة الافتراضية للاتصالات الواردة، فإن UFW مضبوطٌ ليحجب كل الاتصالات الواردة؛ عمومًا، هذا يُبسِّط عملية إنشاء سياسة جدار ناري آمنة وذلك بتطلّب إنشاء قواعد تحدد بدقة المنافذ وعناوين IP التي يسمح لها «بالعبور»؛ لكن في بعض الأحيان، تريد أن تحجب اتصالاتٍ معينة بناءً على عنوان IP المصدري أو الشبكة الفرعية، ربما لأنك تعلم أن خادومك يتعرض للهجوم من هناك. وأيضًا لو حوّلت سياسة التعامل الافتراضية مع الاتصالات الواردة إلى «السماح» (والذي ليس مستحسنًا لصالح الأمان)، فعليك إنشاء قيود «حجب» لأي خدمة أو عناوين IP لا تريد السماح بمرور الاتصالات إليها. يمكنك استخدام الأوامر المشروحة آنفًا لكتابة قيود الحجب، لكن مع استبدال «deny» بالكلمة «allow». على سبيل المثال، لحجب اتصالات HTTP، فعليك استخدام الأمر: sudo ufw deny http أو إذا أردت حجب جميع الاتصالات من 15.15.15.51 فيمكنك استخدام هذا الأمر: sudo ufw deny from 15.15.15.51 إذا أردت مساعدةً في كتابة قواعد الحجب، فانظر إلى قواعد السماح السابقة وعدِّلها بما يلائمها. لنلقِ الآن نظرةً على طريقة حذف القواعد. حذف القواعدمعرفة كيفية حذف قواعد الجدار الناري بنفس أهمية معرفة كيفية إنشائها؛ هنالك طريقتان لتحديد أيّة قواعد لتحذف: عبر رقم القاعدة أو عبر القاعدة نفسها (بشكلٍ شبيه لطريقة تحديد القاعدة عندما أُنشِئت). سنبدأ بطريقة الحذف عبر رقم القاعدة لأنها أسهل، مقارنةً بكتابة القواعد نفسها، خصوصًا إن كنتَ حديث العهد بالتعامل مع UFW. عبر رقم القاعدةإذا كنت تستخدم رقم القاعدة لحذف قواعد الجدار الناري، فإن أول شيء تريد فعله هو الحصول على قائمة بقواعد جدارك الناري؛ يملك أمر UFW status خيارًا لعرض الأرقام بجوار قواعدها، كما هو مبيّن هنا: sudo ufw status numbered الناتج: Status: active To Action From -- ------ ---- [ 1] 22 ALLOW IN 15.15.15.0/24 [ 2] 80 ALLOW IN Anywhereإذا قررت أنك تريد حذف القاعدة 2، التي تسمح بالاتصالات إلى المنفذ 80 (HTTP)، فيمكنك ذلك عبر تمرير رقمها إلى أمر UFW delete كما يلي: sudo ufw delete 2 ما سبق سيُظهِر محثًا (prompt) ليطلب موافقتك، ثم سيحذف القاعدة 2 التي تسمح باتصالات HTTP. الحظ أنك إن كنت قد فعَّلت IPv6، فعليك أن تحذف قاعدة IPv6 المناظرة لها. عبر القاعدة نفسهاالبديل عن تحديد رقم القاعدة هو تحديد القاعدة نفسها؛ على سبيل المثال، إذا أردت حذف قاعدة «allow http»، فيمكنك كتابة الأمر كما يلي: sudo ufw delete allow http يمكنك أيضًا تحديد القاعدة مستعملًا «allow 80»، بدلًا من اسم الخدمة: sudo ufw delete allow 80 ستَحذُف هذه الطريقة قواعد IPv4 و IPv6 إن كانت موجودةً. كيفية تعطيل UFW (خطوة اختيارية)إذا قررت أنّك لا تريد استعمال UFW لأي سببٍ كان، فيمكنك تعطيله عبر هذا الأمر: sudo ufw disable ستُعطَّل أيّة قواعد أنشَأتها باستخدام UFW، يمكنك بأي وقتٍ تنفيذ: sudo ufw enable إذا احتجت لتفعيله لاحقًا. إعادة ضبط قواعد UFW (خطوة اختيارية)إذا كانت لديك قواعد UFW مضبوطة، لكنك قررت أن تبدأ من الصفر، فيمكنك استخدام الأمر reset: sudo ufw reset سيُعطِِّل الأمر السابق UFW ويحذف أيّة قواعد عرَّفتَها سابقًا. أبقِ في بالك أن السياسات الافتراضية لن يُعاد ضبطها إلى إعداداتها الافتراضية إذا كنت قد عدَّلتها. الخلاصةيجب أن يكون قد ضُبِطَ جدارك الناري للسماح (على الأقل) لاتصالات SSH؛ تأكد أن تسمح لأيّة اتصالات واردة أخرى لخادومك بينما تقيّد أيّة اتصالات غير ضرورية، كي يكون خادومك آمنًا ويعمل عملًا صحيحًا. ترجمة -وبتصرّف- للمقال How To Set Up a Firewall with UFW on Ubuntu 14.04 لصاحبه Mitchell Anicas.
  21. 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
  22. نحن نبني أغلب أعمالنا على خوادم مبنية على 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
  23. تزداد شعبية 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.
  24. بروتوكول نقل الملفات 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
  25. من المهم جدًا الحفاظ على دقة وقت النظام، سواءً فعلنا ذلك للحرص على دقة ترتيب السجلات (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
×
×
  • أضف...