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

نشر تطبيق PHP باستخدام Ansible - إعداد مفاتيح SSH والجدار الناري


kinan mawed

هذا الدّرس هو جزء من سلسلة دروس حول نشر تطبيقات PHP باستخدام Ansible على Ubuntu، تحدّثنا في الجزئين السّابقين عن تثبيت Ansible وإعداده ومن ثم عن إعداد Laravel وNginx.

ansible-php-3.thumb.png.89754a43917115f9

سنغطّي في هذا الدّرس إعداد مفاتيح SSH لتدعم أدوات نشر وتوزيع الشيفرة، وإعداد الجدار الناري للنظام، هدفنا في النهاية هو الحصول على خادوم يعمل عليه تطبيق PHP بشكل كامل مع الإعدادات المذكورة آنفًا.

المتطلبات الأساسية

يبدأ هذا الدّرس مباشرة من حيث انتهى الجزء السّابق من هذه السلسلة، ونحتاج كافّة الملفّات والإعدادات التي تم الحصول عليها في ذلك الجزء، إن لم تقم بإكمال أول قسمين من هذه السلسلة فنرجو أن تفعل ذلك قبل متابعة هذا الدّرس.

الخطوة الأولى – تبديل مستودع التطبيق

سنقوم في هذه الخطوة بتحديث مستودع Git إلى مثال عن مستودع مُخصَّص قليلًا.

بما أنّ تثبيت Laravel الافتراضي لا يتطلّب الميّزات المتقدمة التي سنقوم بإعدادها في هذا الدّرس فسنقوم بتبديل المستودع الموجود حاليًّا إلى مثال عن مستودع مع إضافة شيفرة للتنقيح debugging code فقط من أجل أن نظهر متى يعمل كل شيء، يُوجد المستودع الذي سنستخدمه على الرابط https://github.com/do-community/do-ansible-adv-php.

نقوم بتغيير الدليل إلى ansible-php:

cd ~/ansible-php/

نفتح playbook الموجودة حاليًّا من أجل تحريرها:

nano php.yml

نقوم بإيجاد وتحديث المهمّة “Clone git repository” بحيث تبدو كما يلي:

                    Updated Ansible task

- name: Clone git repository
  git: >
    dest=/var/www/laravel
    repo=https://github.com/do-community/do-ansible-adv-php
    update=yes
    version=example
  sudo: yes
  sudo_user: www-data
  register: cloned

نحفظ ونشغل الـ playbook:

ansible-playbook php.yml --ask-sudo-pass

وبعد أن يتم تشغيلها نزور خادومنا في متصفح الويب لدينا (على الرابط http://your_server-ip بعد وضع عنوان خادومك)، ينبغي أن نشاهد رسالة تقول لم يتم العثور على التعريف "could not find driver".

يعني هذا أنّنا نجحنا في استبدال المستودع الافتراضي بمثال مستودعنا، ولكن لا يستطيع التطبيق الاتصال بقاعدة البيانات، وهو ما نتوقع مشاهدته هنا، وسنقوم بتثبيت وإعداد قاعدة البيانات لاحقًا في هذا الدّرس.

الخطوة الثانية – إعداد مفاتيح SSH من أجل النشر

سنقوم في هذه الخطوة بإعداد مفاتيح SSH والتي يُمكن استخدامها من أجل نشر شيفرة التطبيق.

ومع أنّ Ansible رائعة من أجل المحافظة على الإعدادات وإعداد الخواديم والتطبيقات، فيتم عادةً استخدام أدوات مثل Envoy و Rocketeer من أجل دفع تغييرات الشيفرة إلى الخادوم وتنفيذ أوامر التطبيق عن بُعد، تتطلّب أغلب هذه الأدوات اتصال SSH يتمكن من النفاذ إلى تثبيت التطبيق بشكل مباشر، يعني هذا في حالتنا أنّنا نحتاج إلى إعداد مفاتيح SSH من أجل المستخدم www-data.

سنحتاج إلى ملف مفتاح عام من أجل المستخدم الذي نرغب بدفع الشيفرة منه، يُوجد هذا الملف بشكل نموذج في المسار ssh/id_rsa.pub./~، ننسخ هذا الملف إلى الدليل ansible-php:

cp ~/.ssh/id_rsa.pub ~/ansible-php/deploykey.pub

بإمكاننا استخدام الوحدة authorized_key لـ Ansible من أجل تثبيت مفتاحنا العام داخل var/www/.ssh/authorized_keys/ والذي سيسمح لأدوات النشر بالاتصال والنفاذ إلى تطبيقنا، تحتاج الإعدادات فقط إلى معرفة مكان المفتاح، باستخدام lookup، وإلى معرفة المستخدم الذي سيتم تثبيت المفتاح لأجله (www-data في حالتنا).

                    New Ansible task

- name: Copy public key into /var/www
  authorized_key: user=www-data key="{{ lookup('file', 'deploykey.pub') }}"

نحتاج أيضًا لإعداد صدفة shell المستخدم www-data كي نستطيع فعليًّا تسجيل الدخول، وإلّا سيسمح SSH بالاتصال ولكن لن يتم عرض صدفة shell للمستخدم، يُمكن عمل هذا باستخدام الوحدة user وتعيين الصدفة إلى /bin/bash (أو الصدفة المفضلة لديك):

                    New Ansible task

- name: Set www-data user shell
  user: name=www-data shell=/bin/bash

نفتح الآن الـ playbook لتحريرها من أجل إضافة المهام الجديدة:

nano php.yml

نضيف المهام السابقة إلى الـ playbook التي تُدعى php.yml، يجب أن تبدو نهاية الملف متطابقة مع التالي:

                    Updated php.yml

. . .

  - name: Configure nginx
    template: src=nginx.conf dest=/etc/nginx/sites-available/default
    notify:
      - restart php5-fpm
      - restart nginx

  - name: Copy public key into /var/www
    authorized_key: user=www-data key="{{ lookup('file', 'deploykey.pub') }}"

  - name: Set www-data user shell
    user: name=www-data shell=/bin/bash

  handlers:

. . .

نقوم بحفظ وتشغيل الـ playbook:

ansible-playbook php.yml --ask-sudo-pass

عندما تنتهي Ansible من ذلك ينبغي أن نكون قادرين على الدخول باستخدام SSH عن طريق المستخدم www-data:

ssh www-data@your_server_ip

إن استطعنا تسجيل الدخول بنجاح فهي تعمل بشكل صحيح، بإمكاننا الآن تسجيل الخروج عن طريق إدخال logout أو ضغط CTRL+D.

لن نحتاج إلى استخدام هذا الاتصال في أي خطوات لاحقة، ولكن يبقى مفيدًا إن قمنا بإعداد أدوات أخرى، كما أشرنا سابقًا، أو من أجل التنقيح العام general debugging وصيانة التطبيق كما هو مطلوب.

الخطوة الثالثة – إعداد الجدار الناري

سنقوم في هذه الخطوة بإعداد الجدار الناري على الخادوم للسماح فقط بالاتصالات من أجل HTTP وSSH.

يأتي Ubuntu مع جدار ناري يُدعى UFW (الجدار الناري غير المعقد Uncomplicated Firewall) مُثبَّت عليه بشكل افتراضي، وتدعمه Ansible بالوحدة ufw، يمتلك عدد من الميزات القوية وتمّ تصميمه ليكون بسيطًا قدر الإمكان وهو ملائم بشكل مثالي لخواديم الويب المحتواة ذاتيًّا والتي تحتاج فقط إلى عدة منافذ مفتوحة، نرغب في حالتنا بأن يكون المنفذ 80 (من أجل HTTP) والمنفذ 22 (من أجل SSH) مفتوحًا، وربّما قد تريد المنفذ 443 مفتوحًا من أجل HTTPS.

تمتلك الوحدة ufw عددًا من الخيارات المختلفة تقوم بتنفيذ مهام مختلفة، وهذه المهام التي نريد تنفيذها هي:

  • تمكين UFW ورفض كامل حركة مرور البيانات traffic القادمة افتراضيًّا.
  • فتح منفذ SSH ولكن مع تحديده لمنع هجمات القوة القاسية brute force attacks.
  • فتح منفذ HTTP.

يُمكِن فعل هذا باستخدام المهام التالية على الترتيب:

                New Ansible tasks

- name: Enable UFW
  ufw: direction=incoming policy=deny state=enabled

- name: UFW limit SSH
  ufw: rule=limit port=ssh

- name: UFW open HTTP
  ufw: rule=allow port=http
</code>

نفتح الملف php.yml من أجل تحريره:

nano php.yml

نضيف المهام السابقة إلى الـ playbook، ينبغي أن تتطابق نهاية الملف مع التالي:

                    Updated php.yml

. . .

  - name: Copy public key into /var/www
    authorized_key: user=www-data key="{{ lookup('file', 'deploykey.pub') }}"

  - name: Set www-data user shell
    user: name=www-data shell=/bin/bash

  - name: Enable UFW
    ufw: direction=incoming policy=deny state=enabled

  - name: UFW limit SSH
    ufw: rule=limit port=ssh

  - name: UFW open HTTP
    ufw: rule=allow port=http

  handlers:

. . .

نقوم بحفظ وتشغيل الـ playbook:

ansible-playbook php.yml --ask-sudo-pass

بعد أن يتم هذا بنجاح يجب أن نكون قادرين على الاتصال عبر SSH (باستخدام Ansible) أو HTTP إلى خادومنا، ستكون المنافذ الأخرى مقفلة الآن.

نستطيع التحقّق من حالة UFW في أي وقت عن طريق تنفيذ هذا الأمر:

ansible php --sudo --ask-sudo-pass -m shell -a "ufw status verbose"

وبتقسيم أمر Ansible السابق من أجل فهمه نجد:

  • ansible: تقوم بتنفيذ مهمّة Ansible خام بدون playbook.
  • php: تقوم بتنفيذ المهمّة على المضيفين في هذه المجموعة.
  • --sudo: تنفّذ الأمر كـ sudo.
  • --ask-sudo-pass: تقوم بالحث prompt من أجل كلمة سر sudo.
  • -m shell: تقوم بتشغيل وحدة الصدفة shell.
  • -a "ufw status verbose“: الخيارات التي يجب تمريرها إلى الوحدة، وبما أنّها أمر shell نقوم بتمرير الأمر الخام raw (أي ufw status verbose) مباشرة بدون أي خيارات key=value.

يجب أن يُعيد شيئًا مشابهًا لهذا:

                    UFW status output

your_server_ip | success | rc=0 >>
Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), disabled (routed)
New profiles: skip

To                         Action      From
--                         ------      ----
22                         LIMIT IN    Anywhere
80                         ALLOW IN    Anywhere
22 (v6)                    LIMIT IN    Anywhere (v6)
80 (v6)                    ALLOW IN    Anywhere (v6)

ترجمة -وبتصرّف- لـ How To Deploy an Advanced PHP Application Using Ansible on Ubuntu 14.04 لصاحبه Stephen Rees-Carter.


تفاعل الأعضاء

أفضل التعليقات

لا توجد أية تعليقات بعد



انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أضف تعليق

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • أضف...