<?xml version="1.0"?>
<rss version="2.0"><channel><title>DevOps: Linux &#x644;&#x64A;&#x646;&#x643;&#x633;</title><link>https://academy.hsoub.com/devops/linux/page/5/?d=4</link><description>DevOps: Linux &#x644;&#x64A;&#x646;&#x643;&#x633;</description><language>ar</language><item><title>&#x627;&#x644;&#x62A;&#x647;&#x64A;&#x626;&#x629; &#x627;&#x644;&#x623;&#x648;&#x644;&#x64A;&#x629; &#x644;&#x62E;&#x627;&#x62F;&#x645; &#x623;&#x648;&#x628;&#x648;&#x646;&#x62A;&#x648; 18.04</title><link>https://academy.hsoub.com/devops/linux/%D8%A7%D9%84%D8%AA%D9%87%D9%8A%D8%A6%D8%A9-%D8%A7%D9%84%D8%A3%D9%88%D9%84%D9%8A%D8%A9-%D9%84%D8%AE%D8%A7%D8%AF%D9%85-%D8%A3%D9%88%D8%A8%D9%88%D9%86%D8%AA%D9%88-1804-r431/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2019_07/5d3da0ce01ed0_.jpg.0cb063735621c2076bc4574cfb2469c4.jpg" /></p>

<p>
	عند إنشاءك خادم أوبونتو 18.04 للمرة الأولى، يجب عليك اتخاذ بعض الخطوات كجزء من الإعدادات الأولية. سيزيد ذلك من أمان وسهولة استخدام الخادم، ويمنحك أساسًا قويًا لإجراءات لاحقة.
</p>

<p>
	<strong>ملاحظة:</strong> يشرح المقال أدناه الخطوات التي نوصي بها لإكمال تهيئة خادم أوبنتو 18.04 يدويا. اتباع هذه الاعدادات اليدوية سيساعدك في تعلم بعض المهارات الأساسية لإدارة الخادم وكتمرين لفهم الإجراءات التي تحدث في الخادم بصورة عامة. إن كنت تريد تهيئة الخادم وبدء استخدامة بسرعة، <a href="https://www.digitalocean.com/community/tutorials/automating-initial-server-setup-with-ubuntu-18-04" rel="external nofollow">يمكنك استخدام نصنا البرمجي لتهيئة الخادم الأولي</a> والذي ينفذ خطوات التهيئة تلقائيا.
</p>

<p>
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="30850" href="https://academy.hsoub.com/uploads/monthly_2019_07/5d3da0dc49439_.jpg.9c6f88baad1501197dc69c30698da46e.jpg" rel=""><img alt="التهيئة الأولية.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="30850" data-unique="osjd3gyo2" src="https://academy.hsoub.com/uploads/monthly_2019_07/5d3da0dc5f9fb_.thumb.jpg.88160b40b9bdbb5e873e71688ab4b297.jpg"></a>
</p>

<h2 id="-1-root-">
	خطوة 1 - تسجيل الدخول كمستخدم مسؤول (root)
</h2>

<p>
	تحتاج لمعرفة عنوان بروتوكول الإنترنت العام (<strong>public IP</strong>) للخادم الخاص بك لتسجيل الدخول. تحتاج أيضا إلى كلمة المرور، أو المفتاح السري لمستخدم مسؤول (ما يسمى ب <strong>root</strong> users) إن كنت قد ثبتت مفتاح <abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">SSH</abbr> للمصادقة. إن لم تكن قد سجلت الدخول إلى الخادم الخاص بك، فيمكنك اتباع المقال <a href="https://www.digitalocean.com/docs/droplets/how-to/connect-with-ssh/" rel="external nofollow">حول كيفية الاتصال ب Droplet باستخدام <abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">SSH</abbr></a>.
</p>

<p>
	قم بتسجيل الدخول إلى الخادم كمستخدم مسؤول <strong>root</strong> إن كنت غير متصلا حتى الآن باستخدام الأمر التالي. استبدل النص المظلل بعنوان بروتوكول الإنترنت العام للخادم الخاص بك.
</p>

<pre class="ipsCode" id="ips_uid_9485_7">
$ <abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">ssh</abbr> root@<span style="color: red">your_server_ip</span>
</pre>

<p>
	في حال ظهور تحذير عن موثوقية المضيف قم بقبوله. إن كنت تقوم بالدخول باستخدام إثبات الهوية؛ قم بتقديم كلمة المرور. أما إن كنت تستخدم مفتاح <abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">SSH</abbr> المحمي بعبارة مرور (passphrase)، سيُطلب منك إدخال عبارة المرور في بداية كل جلسة. قد يُطلب منك أيضا تغيير كلمة المرور للمستخدم المسؤول <strong>root</strong> في أول مرة تقوم بالتسجيل بها.
</p>

<h3 id="-root">
	عن المستخدم root
</h3>

<p>
	المستخدم المسؤول <strong>root</strong> في بيئة لينكس هو المتحكم والذي يمتلك صلاحيات عديدة. ونظرا لهذه الصلاحيات فلا ينصح باستخدامه دائمًا وذلك لتجنب القيام بتغييرات عن طريق الخطأ.
</p>

<p>
	الخطوة التالية هي إعداد مستخدم بديل بصلاحيات أقل للعمل اليومي. كما سنشرح كيفية إضافة صلاحيات في أي وقت تحتاج إليها.
</p>

<h2 id="-2-">
	خطوة 2 - إنشاء مستخدم جديد
</h2>

<p>
	بعد تسجيل دخولك كمستخدم مسؤول <strong>root</strong>، فأنت جاهز لإضافة حساب مستخدم جديد لاستخدامه من الآن فصاعدا.
</p>

<p>
	الأمر التالي يقوم بإنشاء مستخدم بالاسم <strong>sammy</strong>، يمكنك تسمية المستخدم بأي اسم تريده.
</p>

<pre class="ipsCode">
 <span class="hljs-meta"># adduser sammy</span>
</pre>

<p>
	ستُعرض عليك بعض الاسئلة بدأَ بكلمة مرور للحساب الجديد.
</p>

<p>
	يجب أن تقوم بإدخال كلمة مرور قوية. ومن ثم تعبئة باقي المعلومات والتي تعتبر اختيارية ويمكنك تجاوزها بالضغط على زر ENTER.
</p>

<h2 id="-3-">
	خطوة 3 - منح صلاحيات إدارية
</h2>

<p>
	يمتلك الحساب الذي قمنا بإنشائه صلاحيات اعتيادية. لكن قد نحتاج في بعض الأحيان إلى صلاحيات إدارية.
</p>

<p>
	لتجنب الخروج من هذا المستخدم والدخول إلى المستخدم المسؤول <strong>root</strong> بكثرة؛ يمكننا إعداد ما يسمى بصلاحيات المستخدم الأعلى أو صلاحيات مسؤول <strong>root</strong> لحساب المستخدم العادي، مما يتيح للمستخدم العادي تنفيذ الأوامر التي تحتاج إلى صلاحيات إدارية عن طريق استخدام الكلمة "<code>sudo</code>" قبل كل أمر.
</p>

<p>
	لإضافة هذه الصلاحيات للمستخدم الجديد، نحتاج لإضافة هذا المستخدم إلى مجموعة <strong>sudo</strong>. يمكن للمستخدمين ضمن مجموعة <strong>sudo</strong> في اوبنتو 18.14 استخدام الأمر <code>sudo</code>.
</p>

<p>
	نفِّذ الأمر التالي لإضافة المستخدم الجديد إلى مجموعة <strong>sudo</strong>، يجب أن تكون متصلا بالخادم باستخدام حساب مسؤول <strong>root</strong> (استخدم اسم المستخدم الذي أنشأته مسبقا).
</p>

<pre class="ipsCode">
<span class="hljs-meta"># usermod -aG sudo sammy</span>
</pre>

<p>
	الآن يمكنك الدخول باستخدام الحساب الجديد وتنفيذ الأوامر ذات الصلاحيات العليا عن طريق كتابة "<code>sudo</code>" قبل هذه الأوامر.
</p>

<h2 id="-4-">
	خطوة 4 - إعداد جدار حماية رئيسي
</h2>

<p>
	يمكن لخادم أوبونتو 18.04 استخدام جدار الحماية Uncomplicated Firewall) UFW) -جدار الحماية في نظام لينكس- للتأكد من عدم الاتصال سوى بخدمات معينة. يمكن إعداد جدار حماية رئيسي بسهولة باستخدام تطبيق UFW.
</p>

<p>
	ملاحظة: إن كان الخادم الخاص بك يعمل على DigitalOcean؛ فيمكنك استخدام <a href="https://www.digitalocean.com/community/tutorials/an-introduction-to-digitalocean-cloud-firewalls" rel="external nofollow" title="DigitalOcean Cloud Firewalls ">DigitalOcean Cloud Firewalls</a> بدلا من تطبيق UFW وذلك يعد اختياريا. يستحسن استخدام جدار حماية واحد فقط لتجنب أي تعارضات والتي قد تكون صعبة التصحيح.
</p>

<p>
	يمكن لمختلف التطبيقات تسجيل ملفات التعريف الخاصة بها مع UFW أثناء تثبيتها. تسمح هذه الملفات لتطبيق UFW بإدارة هذه التطبيقات وفقا لاسم التطبيق. لدى خدمة OpenSSH (Open Secure Shell) -أداة الاتصال الأولى لتسجيل الدخول عن بُعد باستخدام بروتوكول <abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">SSH</abbr>- التي تتيح لنا الاتصال بالخادم ملف تعريف مسجل لدى UFW.
</p>

<p>
	لرؤية ذلك نستخدم الأمر:
</p>

<pre class="ipsCode">
 # ufw <span class="hljs-keyword">app</span> <span class="hljs-keyword">list</span>
</pre>

<p>
	المخرجات:
</p>

<pre class="ipsCode">
Available <span class="hljs-string">applications:</span>

  OpenSSH
</pre>

<p>
	يجب التأكد من أن جدار الحماية يسمح لاتصالات <abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">SSH</abbr> حتى نتمكن من تسجيل الدخول مرة أخرى. يمكن القيام بذلك باستخدام الأمر:
</p>

<pre class="ipsCode">
 <span class="hljs-meta"># ufw allow OpenSSH</span>
</pre>

<p>
	ثم يمكننا تفعيل جدار الحماية:
</p>

<pre class="ipsCode">
 <span class="hljs-meta"># ufw enable</span>
</pre>

<p>
	قم بإدخال الحرف "<code>y</code>" وقم بالضغط على "<code>ENTER</code>" للمتابعة، للتأكد من أن اتصالات <abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">SSH</abbr> ما زالت تعمل نفذ الأمر:
</p>

<pre class="ipsCode">
  <span class="hljs-meta"># ufw status</span>
</pre>

<p>
	المخرجات
</p>

<pre class="ipsCode">
<span class="hljs-attribute">Status</span>: active

<span class="lisp">To                         Action      From
--                         ------      ----
OpenSSH                    ALLOW       Anywhere
OpenSSH (<span class="hljs-name">v6</span>)               ALLOW       Anywhere (<span class="hljs-name">v6</span>)</span>
</pre>

<p>
	في حال قمت بإعداد خدمات إضافية، قم بتعديل إعدادات جدار الحماية للسماح باتصالات هذه الخدمات؛ كون جدار الحماية يقوم بمنع الاتصالات عدا اتصالات <abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">SSH</abbr>. يمكنك اتباع <a href="https://academy.hsoub.com/devops/security/firewalls/%D8%A3%D8%B3%D8%A7%D8%B3%D9%8A%D8%A7%D8%AA-ufw-%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D9%88%D8%A3%D9%88%D8%A7%D9%85%D8%B1-%D8%B4%D8%A7%D8%A6%D8%B9%D8%A9-%D9%84%D9%84%D8%AC%D8%AF%D8%A7%D8%B1-%D8%A7%D9%84%D9%86%D8%A7%D8%B1%D9%8A-r121/" rel="" title="هذا المقال">هذا المقال</a> لتعلم بعض عمليات UFW الشهيرة.
</p>

<h2 id="-5-">
	خطوة 5 - السماح بالوصول الخارجي للمستخدم الجديد
</h2>

<p>
	بما أنه أصبح لدينا مستخدم جديد للاستخدام اليومي، سنحتاج للتأكد من أنه يمكننا الدخول إلى هذا المستخدم عبر <abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">SSH</abbr>.
</p>

<p>
	ملاحظة: للتأكد من ذلك، يمكنك الدخول إلى المستخدم الجديد باستخدام كلمة المرور واستخدام <code>sudo</code>. يستحسن البقاء متصلا باسم المستخدم المسؤول <strong>root</strong>. بهذه الطريقة يمكنك تصحيح أي مشاكل وإضافة أي تعديلات تحتاجها. إن تستخدم واجهتك أي مشكلة في الاتصال بالمستخدم المسؤول <strong>root</strong> باستخدام <abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">SSH</abbr> وكنت تستخدم DigitalOcean Droplet <a href="https://www.digitalocean.com/community/tutorials/how-to-use-the-digitalocean-console-to-access-your-droplet" rel="external nofollow">فيمكنك الدخول إلى Droplet باستخدام شاشة أوامر DigitalOcean</a>.
</p>

<p>
	عملية إعداد وصول <abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">SSH</abbr> لمستخدم الجديد تعتمد على ما إن كان حساب المستخدم المسؤول <strong>root</strong> يستخدم كلمة مرور أو مفتاح <abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">SSH</abbr> للمصادقة.
</p>

<h3 id="-root-">
	في حال كان المستخدم <strong>root</strong> يستخدم المصادقة بكلمة المرور
</h3>

<p>
	إن كنت مسجلا دخولك إلى حساب المستخدم المسؤول <strong>root</strong> باستخدام كلمة مرور، فإن عملية المصادقة باستخدام كلمة المرور مفعلة ل <abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">SSH</abbr>. مما يمكنك من إضافة <abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">SSH</abbr> لحساب المستخدم الجديد عن طريق تنفيذ الأمر التالي مستخدما اسم المستخدم الذي انشأته سابقا:
</p>

<pre class="ipsCode">
 <span class="hljs-variable">$ </span><abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">ssh</abbr> sammy<span class="hljs-variable">@your_server_ip</span>
</pre>

<p>
	بعد إدخال كلمة المرور الخاصة بالمستخدم الجديد؛ ستكون مسجلًا إلى النظام بالحساب الجديد ويمكنك تنفيذ الأوامر الإدارية من خلاله عن طريق إضافة<code>sudo</code>قبل الأمر:
</p>

<pre class="ipsCode">
 <span class="hljs-variable">$ </span>sudo command_to_run
</pre>

<p>
	سيطلب منك النظام إدخال كلمة المرور الخاصة بالمستخدم الحالي لأول مرة من كل جلسة ومن ثم في بعض الأوقات فقط.
</p>

<p>
	لتعزيز أمان الخادم الخاص بك، <strong>يستحسن أن تقوم بإعداد مفاتيح <abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">SSH</abbr> بدلا من استخدام كلمة المرور للمصادقة</strong>. يمكنك اتباع هذا المقال عن <a href="https://www.digitalocean.com/community/tutorials/how-to-set-up-ssh-keys-on-ubuntu-1804" rel="external nofollow">كيفية إعداد مفاتيح <abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">SSH</abbr> على أوبنتو 18.04</a> لتتعرف على طريقة إعداد المصادقة المعتمده على المفاتيح السرية.
</p>

<h3 id="-root-ssh">
	في حال كان المستخدم المسؤول <strong>root</strong> يستخدم المصادقة بمفتاح <abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">SSH</abbr>
</h3>

<p>
	في حال كنت مسجلا الى حساب المسؤول <strong>root</strong> باستخدام مفاتيح <abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">SSH</abbr>، فإن المصادقة باستخدام كلمة المرور ل <abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">SSH</abbr> معطلة. للدخول إلى حساب المستخدم الجديد بنجاح، تحتاج لإضافة نسخة من المفتاح العام المحلي إلى الملف "<code>‎~/.<abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">ssh</abbr>/authorized_keys</code>".
</p>

<p>
	يمكنك أيضا نسخ الملف "<code>‎~/.<abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">ssh</abbr>/authorized_keys</code>" - والذي يحتوي على المفتاح العام الخاص بك- من حساب المسؤول <strong>root</strong> إلى الحساب الجديد باستخدام الجلسة الحالية.
</p>

<p>
	لنسخ الملف بطريقة سهلة وبالملكية والصلاحيات الصحيحة؛ نستخدم الأمر "<code>rsync</code>". سيقوم هذا الأمر بنسخ مجلد "<code>‎.<abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">ssh</abbr></code>" للمستخدم المسؤول <strong>root</strong> ،يحافظ على الصلاحيات ويقوم بتعديل ملكية الملفات في مرة واحدة. تأكد من وضع اسم المستخدم الجديد الذي أنشأته مسبقا.
</p>

<p>
	<strong>ملاحظة</strong> يتعامل الأمر "<code>rsync</code>" مع المجلدات التي تنتهي بشرطة مائلة "/" بطريقة مختلفة عن المجلدات التي لا تنتهي بشرطة مائلة. تأكد من أن أسماء المجلدات (<code>‎~/.<abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">ssh</abbr></code>) لا تنتهي بشرطة مائلة عند استخدام هذا الأمر"<code>‎~/.<abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">ssh</abbr>/‎</code>".
</p>

<p>
	في حال أضفت شرطة مائلة في نهاية اسم المجلد عن طريق الخطأ في هذا الأمر، فسيقوم بنسخ محتويات المجلد من حساب المستخدم المسؤول <strong>root</strong> إلى المجلد الرئيسي لمستخدم "<code>sudo</code>" بدلا من نسخ الهيكل كاملا للمجلد "<code>‎~/.<abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">ssh</abbr></code>". وهكذا تكون الملفات في المكان الخاطئ ولن يتمكن <abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">SSH</abbr> من العثور عليها واستخدامها.
</p>

<pre class="ipsCode">
 <span class="hljs-comment">#</span> <span class="hljs-comment">rsync</span> <span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-comment">archive</span> <span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-comment">chown=sammy:sammy</span> <span class="hljs-comment">~/</span><span class="hljs-string">.</span><span class="hljs-comment"><abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">ssh</abbr></span> <span class="hljs-comment">/home/sammy</span>
</pre>

<p>
	الآن يمكنك استخدام <abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">SSH</abbr> مع المستخدم الجديد عن طريق الأمر التالي في شاشة الأوامر:
</p>

<pre class="ipsCode">
 <span class="hljs-variable">$ </span><abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">ssh</abbr> sammy<span class="hljs-variable">@your_server_ip</span>
</pre>

<p>
	يجب أن تقوم بالدخول إلى المستخدم الجديد بدون استخدام كلمة مرور. تذكر، لتنفيذ أمر باستخدام صلاحيات إدارية استخدم "<code>sudo</code>" قبل الأمر:
</p>

<pre class="ipsCode">
 <span class="hljs-variable">$ </span>sudo command_to_run
</pre>

<h2 id="-">
	ماذا بعد؟
</h2>

<p>
	الآن أصبح لديك إعدادات قوية للخادم الخاص بك. يمكنك تثبيت اي برنامج تحتاجه. اطلع على قسم <a href="https://academy.hsoub.com/devops/linux/" rel="">لينكس</a> في الأكاديمية لقراءة دليل آخر أو تعلم تثبيت برامج أخرى.
</p>

<p>
	ترجمة -وبتصرف- للمقال <a href="https://www.digitalocean.com/community/tutorials/initial-server-setup-with-ubuntu-18-04" rel="external nofollow">Initial Server Setup with Ubuntu 18.04</a> لصاحبه الكاتب Justin Ellingwood.
</p>
]]></description><guid isPermaLink="false">431</guid><pubDate>Sun, 28 Jul 2019 14:00:02 +0000</pubDate></item><item><title>&#x643;&#x64A;&#x641;&#x64A;&#x629; &#x627;&#x633;&#x62A;&#x636;&#x627;&#x641;&#x629; &#x639;&#x62F;&#x629; &#x645;&#x648;&#x627;&#x642;&#x639; &#x645;&#x639; Nginx &#x648; HAProxy &#x628;&#x627;&#x633;&#x62A;&#x639;&#x645;&#x627;&#x644; LXD &#x639;&#x644;&#x649; Ubuntu 16.04</title><link>https://academy.hsoub.com/devops/linux/%D9%83%D9%8A%D9%81%D9%8A%D8%A9-%D8%A7%D8%B3%D8%AA%D8%B6%D8%A7%D9%81%D8%A9-%D8%B9%D8%AF%D8%A9-%D9%85%D9%88%D8%A7%D9%82%D8%B9-%D9%85%D8%B9-nginx-%D9%88-haproxy-%D8%A8%D8%A7%D8%B3%D8%AA%D8%B9%D9%85%D8%A7%D9%84-lxd-%D8%B9%D9%84%D9%89-ubuntu-1604-r430/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2019_07/5d34627db1aa1_.jpg.d7bda75b65b6bb762e54b736f99d3416.jpg" /></p>

<p>
	حاوية لينكس (Linux container) هي تجميع لمجموعة من عمليات تكون منفصلة عن باقي النظام عبر استعمال الخصائص الأمنية لنواة لينكس مثل مجالات الأسماء (Namespaces) ومجموعات المراقبة (Control groups). وهي بنية مُشابهة للأجهزة الوهميّة (Virtual Machines)، إلا أنها أكثر خفّة، بحيث أنك لن تحتاج إلى تشغيل نواة إضافية أو محاكاة العتاد، ما يعني أنه بالإمكان إنشاء حاويات متعددة على نفس الخادوم. ويُمكنك باستعمال حاويات لينكس تشغيل وحدات متعددة لأنظمة تشغيل بأكملها، كلّها محجوزة بنفس الخادوم. أو تحزيم تطبيقاتك الخاصة والملفات التابعة لها في حاوية خاصة دون التأثير على باقي مكونات النظام.
</p>

<p>
	على سبيل المثال تخيّل أنك تملك خادوما وتريد تجهيز عدد من الخدمات، بما فيها المواقع اﻹلكترونية لعملائك. في النظام التقليدي، كل موقع إلكتروني سيكون عبارة عن مضيف وهمي (virtual host) من نفس خادوم Nginx أو Apache، لكن مع حاويات لينكس، كل موقع إلكتروني يتم إعداده في حاويته الخاصة مع خادوم ويب خاصّ به. ﻹنشاء وتسيير هذه الحاويات يمكن استعمال LXD الذي يوفر خدمة مراقبة الأجهزة الافتراضية hypervisor لتسيير دورة حياة الحاويات بأكملها. سنقوم في هذا الدرس بتنصيب موقعين إلكترونيين مبنيين على Nginx في نفس الخادوم. كل منهما محجوز في حاويته الخاصة، ثم سنقوم بتنصيب HAProxy ليعمل على شكل وسيط عكسي (reverse proxy) على حاوية ثالثة، ثم سنقوم بتوجيه الزوار إلى حاوية HAProxy لجعل كلا الموقعين قابلين للولوج من خلال شبكة الإنترنت.
</p>

<h2 id="-">
	المتطلّبات
</h2>

<p>
	لإتمام المطلوب نحتاج إلى ما يلي:
</p>

<ul>
<li>
		<p>
			خادوم Ubuntu 16.04 معد بإتباع الخطوات المتواجدة في <a href="https://academy.hsoub.com/devops/servers/%D8%A7%D9%84%D8%A5%D8%B9%D8%AF%D8%A7%D8%AF-%D8%A7%D9%84%D8%A7%D8%A8%D8%AA%D8%AF%D8%A7%D8%A6%D9%8A-%D9%84%D8%AE%D8%A7%D8%AF%D9%88%D9%85-%D8%A3%D9%88%D8%A8%D9%86%D8%AA%D9%88-1404-r4/" rel="">هذا الدّرس</a> ومستخدم إداري بامتيازات sudo غير المستخدم الجذر وجدار ناري.
		</p>
	</li>
	<li>
		<p>
			اسما نطاق مؤهلان بالكامل (FQDNs)، مع كل سجل DNS <code>A</code> موجه نحو عنوان IP الخاصّ بالخادوم، لتحقيق ذلك يمكن إتباع <a href="https://www.digitalocean.com/community/tutorials/how-to-set-up-a-host-name-with-digitalocean" rel="external nofollow">هذا الدرس</a>.
		</p>
	</li>
</ul>
<p>
	اختياريا، قم بإضافة 20 GB من تخزين الكتل (Block storage) عن طريق إتباع <a href="https://www.digitalocean.com/community/tutorial_series/getting-started-with-digitalocean-block-storage" rel="external nofollow">هذا الدرس</a> الذي يُمكن استعماله لتخزين جميع البيانات المتعلقة بالحاويات.
</p>

<h2 id="-lxd">
	الخطوة الأولى - إضافة المستخدم إلى مجموعة LXD
</h2>

<p>
	نسجل الدخول إلى الخادوم عن طريق حساب المستخدم غير الجذر الذي سيُستعمل لتأدية جميع مهام تسيير الحاوية، وليُنجِز ذلك يجب إضافة هذا الحساب إلى مجموعة <code>lxd</code> عن طريق الأمر التّالي:
</p>

<pre class="ipsCode">
<span class="hljs-comment">sudo</span> <span class="hljs-comment">usermod</span> <span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-comment">append</span> <span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-comment">groups</span> <span class="hljs-comment">lxd</span> <span class="hljs-comment">sammy</span>
</pre>

<p>
	أبدل <code>sammy</code> باسم المستخدم الخاصّ بك. نقوم بتسجيل الخروج من الخادوم ثم تسجيل الدخول إليه لتحديث جلسة SHH بعضوية المجموعة الجديدة، بعد ذلك، يمكن البدء بإعداد LXD.
</p>

<h2 id="-lxd">
	الخطوة الثانية - إعداد LXD
</h2>

<p>
	يحتاج LXD إلى إعدادات معينة ليعمل بالشكل المطلوب قبل استعماله، نوع التخزين على مستوى الواجهة الخلفية هو أهم إعداد يجب علينا تحديده، لتخزين الحاويات، التخزين المقترح لـLXD هو استعمال ملف من نوع ZFS مُخزّن إما داخل ملف مخصص مسبقا أو عن طريق استعمال تخزين الكتل. لدعم ملفات ZFS في LXD، سنقوم بتنصيب حزمة <code>zfsutils-linux</code>:
</p>

<pre class="ipsCode">
sudo apt-<span class="hljs-built_in">get</span> <span class="hljs-keyword">update</span>
sudo apt-<span class="hljs-built_in">get</span> install zfsutils-linux
</pre>

<p>
	بعد ذلك سنكون مستعدين لتهيئة LXD، أثناء التهيئة سيُطلَبُ منك تخصيص تفاصيل تخزين ZFS على مستوى النظام الخلفي. هناك طريقتان لذلك اعتمادا على إذا ما كنا سنستعمل ملفا معدا مسبقا أو تخزين الكتل، بعد تحديد آلية التخزين سنقوم بإعداد اختيارات تواصل الحاويات الخاصة بنا. لكن قبل ذلك، سنتعرّف على خياري تهيئة التّخزين.
</p>

<h3 id="-">
	الخيار الأول - استعمال ملف مخصص مسبقا
</h3>

<p>
	اتبع الخطوات التالية لإعداد LXD لاستعمال ملف مخصص مسبقا لتخزين الحاويات. أولا نفّذ اﻷمر التالي لبدأ عملية تهيئة LXD:
</p>

<pre class="ipsCode">
<span class="hljs-attribute">sudo lxd init</span>
</pre>

<p>
	سيُطلب منا اﻹدلاء بمجموعة من المعلومات كما يظهر في النتائج التالية، سنقوم باختيار الاختيارات الافتراضية بما في ذلك حجم الملف المقترح والمسمى جهاز الحلقة (loop device).
</p>

<p>
	المُخرجات:
</p>

<pre class="ipsCode">
Name of the storage backend to <span class="hljs-keyword">use</span> (dir <span class="hljs-keyword">or</span> zfs) [<span class="hljs-keyword">default</span>=zfs]: zfs
<span class="hljs-keyword">Create</span> a <span class="hljs-keyword">new</span> ZFS pool (yes/<span class="hljs-keyword">no</span>) [<span class="hljs-keyword">default</span>=yes]? yes
<span class="hljs-keyword">Name</span> <span class="hljs-keyword">of</span> the <span class="hljs-keyword">new</span> ZFS pool [<span class="hljs-keyword">default</span>=lxd]: lxd
Would you <span class="hljs-keyword">like</span> <span class="hljs-keyword">to</span> <span class="hljs-keyword">use</span> an existing <span class="hljs-keyword">block</span> device (yes/<span class="hljs-keyword">no</span>) [<span class="hljs-keyword">default</span>=<span class="hljs-keyword">no</span>]? <span class="hljs-keyword">no</span>
<span class="hljs-keyword">Size</span> <span class="hljs-keyword">in</span> GB <span class="hljs-keyword">of</span> the <span class="hljs-keyword">new</span> <span class="hljs-keyword">loop</span> device (<span class="hljs-number">1</span>GB <span class="hljs-keyword">minimum</span>) [<span class="hljs-keyword">default</span>=<span class="hljs-number">15</span>]: <span class="hljs-number">15</span>
Would you <span class="hljs-keyword">like</span> LXD <span class="hljs-keyword">to</span> be available <span class="hljs-keyword">over</span> the network (yes/<span class="hljs-keyword">no</span>) [<span class="hljs-keyword">default</span>=<span class="hljs-keyword">no</span>]? <span class="hljs-keyword">no</span>
<span class="hljs-keyword">Do</span> you want <span class="hljs-keyword">to</span> configure the LXD bridge (yes/<span class="hljs-keyword">no</span>) [<span class="hljs-keyword">default</span>=yes]? yes
<span class="hljs-keyword">Warning</span>: Stopping lxd.service, but it can still be activated <span class="hljs-keyword">by</span>:
  lxd.socket
LXD has been successfully configured.
</pre>

<p>
	يتم حساب الحجم المقترح تلقائيا بناء على المساحة المتاحة في الخادوم. بعد إعداد الجهاز، سنقوم بضبط إعدادات التشبيك، لكن قبل ذلك، لنتعرّف على الخيار الثاني.
</p>

<h3 id="-">
	الخيار الثاني - استعمال تخزين الكتل
</h3>

<p>
	إذا كنت تريد استعمال تخزين الكتل، ستحتاج إلى البحث عن الجهاز الذي يُشير نحو حجم تخزين الكتل (block storage volume) الذي تمّ إنشاؤه لتخصيصه في إعدادات LXD، سنذهب إلى تبويبة Volumes في <a href="https://cloud.digitalocean.com/" rel="external nofollow">لوحة التحكم الخاصّة بـDigitalOcean</a>. ثم نقوم بتحديد مكان للمساحة ثم النقر على النافذة المنبثقة More، ثم انقر على Config instructions.
</p>

<p>
	نقوم بتحديد مكان الجهاز عن طريق النّظر إلى مُخرج أمر تشكيل الحجم، ابحث بشكل خاص عن المسار المخصّص في أمر <code>sudo mkfs.ext4 -F</code>.
</p>

<p>
	تمثل الوثيقة التالية مثالا على هذا الحجم:
</p>

<p>
	<img class="ipsImage ipsImage_thumbnailed" data-fileid="30761" data-unique="ipawrutl4" src="https://academy.hsoub.com/uploads/monthly_2019_07/1.png.fd8c28a6e4b759b66231be9fe18b7d0f.png" alt="1.png"></p>

<p>
	الذي يهمنا هو الجزء المسطر بالأحمر.
</p>

<p>
	في هذه الحالة اسم الحجم هو:
</p>

<pre class="ipsCode">
/dev/disk/<span class="hljs-keyword">by</span>-<span class="hljs-built_in">id</span>/scsi<span class="hljs-number">-0</span>D0_Volume_volume-fra1<span class="hljs-number">-01</span>
</pre>

<p>
	يمكن لهذا الاسم أن يختلف في حالتك. بعد تعريف الحجم سنعود إلى الطرفية وسننفّذ الأمر التالي لبدء عملية تهيئة LXD:
</p>

<pre class="ipsCode">
<span class="hljs-attribute">sudo lxd init</span>
</pre>

<p>
	سوف تُطرَح علينا مجموعة من اﻷسئلة، أجب عليها بالأجوبة المُوضّحة أسفله:
</p>

<pre class="ipsCode">
Name <span class="hljs-keyword">of</span> the storage backend <span class="hljs-keyword">to</span> use (dir <span class="hljs-keyword">or</span> zfs) [<span class="hljs-keyword">default</span>=zfs]: zfs
Create a <span class="hljs-keyword">new</span> ZFS pool (<span class="hljs-literal">yes</span>/<span class="hljs-literal">no</span>) [<span class="hljs-keyword">default</span>=<span class="hljs-literal">yes</span>]? <span class="hljs-literal">yes</span>
Name <span class="hljs-keyword">of</span> the <span class="hljs-keyword">new</span> ZFS pool [<span class="hljs-keyword">default</span>=lxd]: lxd
</pre>

<p>
	إذا طُلب منك استخدام جهاز كتل جاهز آنفا فاختَر نعم (<code>yes</code>)، مع اﻹدلاء بمساره.
</p>

<pre class="ipsCode">
Would you like to <span class="hljs-keyword">use</span> an existing <span class="hljs-keyword">block</span> device (yes/<span class="hljs-keyword">no</span>) [<span class="hljs-keyword">default</span>=<span class="hljs-keyword">no</span>]? yes
<span class="hljs-keyword">Path</span> <span class="hljs-keyword">to</span> the existing <span class="hljs-keyword">block</span> device: /dev/disk/<span class="hljs-keyword">by</span>-<span class="hljs-keyword">id</span>/scsi<span class="hljs-number">-0</span>DO_Volume_volume-fra1<span class="hljs-number">-01</span>
</pre>

<p>
	ثم اختر القيم الافتراضية لباقي اﻷسئلة.
</p>

<pre class="ipsCode">
Would you like LXD <span class="hljs-keyword">to</span> be available over the network (<span class="hljs-literal">yes</span>/<span class="hljs-literal">no</span>) [<span class="hljs-keyword">default</span>=<span class="hljs-literal">no</span>]? <span class="hljs-literal">no</span>
Do you want <span class="hljs-keyword">to</span> configure the LXD bridge (<span class="hljs-literal">yes</span>/<span class="hljs-literal">no</span>) [<span class="hljs-keyword">default</span>=<span class="hljs-literal">yes</span>]? <span class="hljs-literal">yes</span>
Warning: Stopping lxd.service, but <span class="hljs-literal">it</span> can still be activated by:
  lxd.socket
LXD has been successfully configured.
</pre>

<p>
	بعد انتهاء العملية، سنقوم بإعداد الشبكة.
</p>

<h3 id="-networking-">
	إعداد التشبيك (Networking)
</h3>

<p>
	ستُظهِر لنا عمليّة التّهيئة مجموعة من شاشات التّعليمات كما هو موضّح في الصورة أسفله، ستمكّننا هذه التّعليمات من إعداد جسر التشبيك للحاويات حتى تتمكن من الحصول على عناوين IP خاصّة بها، وتتمكن من التواصل بينها والاتصال بشبكة الأنترنت.
</p>

<p>
	<img class="ipsImage ipsImage_thumbnailed" data-fileid="30762" data-unique="opznsgysw" src="https://academy.hsoub.com/uploads/monthly_2019_07/2.png.4abea66cc0e2fd1ec66b054440728289.png" alt="2.png"></p>

<p>
	قم باستعمال جميع القيم الافتراضية باستثناء تشبيك IPv6، قم باختيار الخيار <code>No</code> في هذه الحالة. إذ لن نستعمله في هذا الدرس.
</p>

<p>
	بعد الانتهاء من إعداد التّشبيك، ستكون جاهزا لإنشاء الحاويات.
</p>

<h2 id="-">
	الخطوة الثّالثة - إنشاء الحاويات
</h2>

<p>
	قمنا بإعداد LXD بنجاح، إذ قمنا بتخصيص موقع للتخزين على مستوى الواجهة الخلفية وقمنا بإعداد التشبيك الافتراضي ﻷي حاويات منشأة حديثا.
</p>

<p>
	ما يعني بأنّنا جاهزون ﻹنشاء وتسيير بعض الحاويات، وذلك باستعمال الأمر <code>lxc</code>. أول أمر سنُجرّبه هو الأمر <code>lxc list</code>، والذي يُعطينا لائحة الحاويات المُنصّبة المتوفرة:
</p>

<pre class="ipsCode">
lxc <span class="hljs-built_in">list</span>
</pre>

<p>
	المُخرجات:
</p>

<pre class="ipsCode">
Generating a client certificate. This may take a minute...
<span class="hljs-keyword">If</span> this is your <span class="hljs-built_in">first</span> <span class="hljs-built_in">time</span> <span class="hljs-built_in">using</span> LXD, you should also run: sudo lxd init
To start your <span class="hljs-built_in">first</span> container, <span class="hljs-built_in">try</span>: lxc launch ubuntu:<span class="hljs-number">16.04</span>

+------+-------+------+------+------+-----------+
| <span class="hljs-type">NAME</span> | <span class="hljs-type">STATE</span> | <span class="hljs-type">IPV4</span> | <span class="hljs-type">IPV6</span> | <span class="hljs-type">TYPE</span> | <span class="hljs-type">SNAPSHOTS</span> |
<span class="hljs-type">+------+-------+------+------+------+-----------+</span>
</pre>

<p>
	ولأنها المرة اﻷولى التي يتواصل فيها أمر <code>lxc</code> مع مراقب الأجهزة الافتراضية (Hypervisor) الخاص بـLXD،فإن المخرج يخبرنا بأن اﻷمر قام بإنشاء شهادة عميل تلقائيا وذلك للتواصل اﻵمن مع <code>LXD</code>. بعد ذلك، يخبرنا بمعلومات حول كيفيّة إطلاق الحاويات، ثمّ يعرِض لائحة فارغة من الحاويات ﻷننا لم ننشئ أيا منها بعد. لنَقُم بإنشاء ثلاثة حاويات، واحدة لكل خادوم ويب والثالثة للوسيط العكسي، دور هذا اﻷخير هو توجيه الاتصالات الواردة من اﻷنترنت نحو الخادوم المناسب داخل الحاوية.
</p>

<p>
	نقوم باستعمال أمر <code>lxc launch</code> لإنشاء وتشغيل حاوية (ubuntu:x) Ubuntu 16.04 باسم <code>web1</code>. الحرف <code>x</code> في <code>ubuntu:x</code> هو اختصار لكلمة <code>Xenial</code> الاسم الرمزي لـUbuntu 16.04، أمّا <code>ubuntu:</code> فهو مُعرّف المجلد المضبوط مسبقا الخاص بصور LXD.
</p>

<p>
	<strong>ملاحظة:</strong> يمكنك الوصول إلى اللائحة الكاملة لصور Ubuntu المتاحة عن طريق الأمر <code>lxc image list ubuntu:</code>، ولتوزيعات أخرى استعمل اﻷمر <code>lxc image list images:</code>.
</p>

<p>
	نفّذ الأوامر التالية لإنشاء الحاويات:
</p>

<pre class="ipsCode">
lxc <span class="hljs-built_in">launch</span> ubuntu:x web1
lxc <span class="hljs-built_in">launch</span> ubuntu:x web2
lxc <span class="hljs-built_in">launch</span> ubuntu:x haproxy
</pre>

<p>
	وبما أنها المرة اﻷولى التي ننشئُ فيها الحاويات، فسيقوم اﻷمر اﻷول بتنزيل صور الحاويات من اﻷنترنت وسيخزنها محليا، ستُنشَئُ الحاويّتان المتبقيّتان بشكل أسرع.
</p>

<p>
	لاحظ بيانات المخرج جرّاء إنشاء الحاوية <code>web1</code>:
</p>

<pre class="ipsCode">
Creating web1
Retrieving <span class="hljs-built_in">image</span>: <span class="hljs-number">100</span>%
Starting web1
</pre>

<p>
	بعد أن قمنا بإنشاء ثلاثة حاويات فارغة سنقوم باستعمال الأمر <code>lxc list</code> ﻹظهار المعلومات حولها:
</p>

<pre class="ipsCode">
lxc <span class="hljs-built_in">list</span>
</pre>

<p>
	يُظهِر المخرج جدولا باسم الحاوية وحالتها الحالية، عنوان IP الخاص بها، نوعها وما إذا تم أخد أية لقطات (snapshots) لها:
</p>

<pre class="ipsCode">
<span class="hljs-code">+---------+</span>---------<span class="hljs-code">+-----------------------+</span>------<span class="hljs-code">+------------+</span>-----------+
<span class="hljs-section">|  NAME   |  STATE  |         IPV4          | IPV6 |    TYPE    | SNAPSHOTS |
+---------+---------+-----------------------+------+------------+-----------+</span>
<span class="hljs-section">| haproxy | RUNNING | 10.10.10.10 (eth0)    |      | PERSISTENT | 0         |
+---------+---------+-----------------------+------+------------+-----------+</span>
<span class="hljs-section">| web1    | RUNNING | 10.10.10.100 (eth0)   |      | PERSISTENT | 0         |
+---------+---------+-----------------------+------+------------+-----------+</span>
<span class="hljs-section">| web2    | RUNNING | 10.10.10.200 (eth0)   |      | PERSISTENT | 0         |
+---------+---------+-----------------------+------+------------+-----------+</span>
</pre>

<p>
	سَجِّل أسماء الحاويات وعناوين IPv4 الخاصة بها لأننا سنحتاجها لإعداد الخدمات.
</p>

<h2 id="-nginx">
	الخطوة الرابعة - إعداد حاويات Nginx
</h2>

<p>
	لنقم بالاتصال مع الحاوية <code>web1</code> وإعداد الخادوم اﻷول، وللقيام بذلك نستعمل الأمر <code>lxc exec</code> الذي يأخذ اسم الحاوية والأوامر التي تريد تنفيذها.
</p>

<p>
	استعمل اﻷمر التالي للاتصال بالحاوية:
</p>

<pre class="ipsCode">
<span class="hljs-comment">lxc</span> <span class="hljs-comment">exec</span> <span class="hljs-comment">web1</span> <span class="hljs-literal">-</span><span class="hljs-literal">-</span> <span class="hljs-comment">sudo</span> <span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-comment">login</span> <span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-comment">user</span> <span class="hljs-comment">ubuntu</span>
</pre>

<p>
	يَدُلّ المقطع <code>--</code> على أنّ العوامل التي ستُمرَّرُ للأمر <code>lxc</code> ستنتهي وسيتم تمرير باقي السطر على شكل أوامر للتنفيذ داخل الحاوية، اﻷمر الذي سيُمرَّرُ في هذه الحالة هو <code>sudo --login --user ubuntu</code> والذي يوفر صدفة ولوج (login shell) للحساب <code>ubuntu</code> المعد مسبقا داخل الحاويّة. <strong>ملاحظة:</strong> إذا كنت تريد الاتصال بالحاوية بصلاحيات حساب الجذر، فقم باستعمال اﻷمر <code>lxc exec web1 -- /bin/bash</code> عوضا عمّا سبق. فور الدخول إلى الحاويّة، سيظهر لنا محثّ الصدفة على الشكل التالي:
</p>

<pre class="ipsCode">
ubuntu<span class="hljs-variable">@web1</span><span class="hljs-symbol">:~</span>$
</pre>

<p>
	المُستخدم <code>ubuntu</code> هذا معد مسبقا بصلاحيات sudo داخل الحاوية ويستطيع إصدار أوامر <code>sudo</code> دون الحاجة إلى اﻹدلاء بكلمة المرور. هذه الصدفة محدودة داخل حدود الحاوية. أي أنّ أيّ أمر نُشغله داخل هذه الصدفة يبقى داخل الحاوية ولا يخرج إلى الخادوم المُضيف. لِنحدّث لائحة حزم Ubuntu داخل الحاوية ولنُنصِّب Nginx:
</p>

<pre class="ipsCode">
sudo apt-<span class="hljs-built_in">get</span> <span class="hljs-keyword">update</span>
sudo apt-<span class="hljs-built_in">get</span> install nginx
</pre>

<p>
	لنعدل صفحة الويب الافتراضية لهذا الموقع ولنُضِف نصّا يوضح أن هذا الموقع مستضاف على الحاوية <code>web1</code>. افتح الملف <code>/var/www/html/index.nginx-debian.html</code>:
</p>

<pre class="ipsCode">

sudo nano /var/www/html/index<span class="hljs-selector-class">.nginx-debian</span><span class="hljs-selector-class">.html</span>
</pre>

<p>
	قم بالتعديلات التالية للملف:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_6449_6" style="">
<span class="dec">&lt;!DOCTYPE html&gt;</span><span class="pln">
</span><span class="tag">&lt;html&gt;</span><span class="pln">
</span><span class="tag">&lt;head&gt;</span><span class="pln">
</span><span class="tag">&lt;title&gt;</span><span class="pln">Welcome to nginx on LXD container web1!</span><span class="tag">&lt;/title&gt;</span><span class="pln">
</span><span class="tag">&lt;style&gt;</span><span class="pln">
    body </span><span class="pun">{</span><span class="pln">
        width</span><span class="pun">:</span><span class="pln"> </span><span class="lit">35em</span><span class="pun">;</span><span class="pln">
        margin</span><span class="pun">:</span><span class="pln"> </span><span class="lit">0</span><span class="pln"> </span><span class="kwd">auto</span><span class="pun">;</span><span class="pln">
        font</span><span class="pun">-</span><span class="pln">family</span><span class="pun">:</span><span class="pln"> </span><span class="typ">Tahoma</span><span class="pun">,</span><span class="pln"> </span><span class="typ">Verdana</span><span class="pun">,</span><span class="pln"> </span><span class="typ">Arial</span><span class="pun">,</span><span class="pln"> sans</span><span class="pun">-</span><span class="pln">serif</span><span class="pun">;</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">
</span><span class="tag">&lt;/style&gt;</span><span class="pln">
</span><span class="tag">&lt;/head&gt;</span><span class="pln">
</span><span class="tag">&lt;body&gt;</span><span class="pln">
</span><span class="tag">&lt;h1&gt;</span><span class="pln">Welcome to nginx on LXD container web1!</span><span class="tag">&lt;/h1&gt;</span><span class="pln">
</span><span class="tag">&lt;p&gt;</span><span class="pln">If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</span><span class="tag">&lt;/p&gt;</span><span class="pln">
...</span></pre>

<p>
	قمنا بتعديل الملف في مكانين العنوان <code>&lt;title&gt;</code> والوسم <code>&lt;h1&gt;</code> وذلك بإضافة المقطع <code>on LXD container web1</code>.
</p>

<p>
	أغلق المحرر بعد الحفظ. واﻵن، سجّل الخروج من الحاوية لنَعودَ إلى الخادوم المُضيف:
</p>

<pre class="ipsCode">
<span class="hljs-built_in">logout</span>
</pre>

<p>
	سنُكرر نفس اﻷمر بالنسبة لحاويّة <code>web2</code>، نسجل الدخول نُنصّب Nginx ثمّ نعدّل الملفّ <code>/var/www/html/index.nginx-debian.html</code> لذِكرِ <code>web2</code>، ثم نخرج من الحاويّة <code>web2</code>. لنستعمل <code>curl</code> للتأكد من أن الخواديم داخل الحاويات تعمل بشكل جيد. نحتاج إلى عناوين IP الخاصّة بالحاويات، والتي حصلنا عليها سابقا.
</p>

<pre class="ipsCode">
curl <span class="hljs-string">http:</span><span class="hljs-comment">//10.10.10.100/</span>
</pre>

<p>
	يجب على المُخرج أن يكون كما يلي:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_6449_8" style="">
<span class="dec">&lt;!DOCTYPE html&gt;</span><span class="pln">
</span><span class="tag">&lt;html&gt;</span><span class="pln">
</span><span class="tag">&lt;head&gt;</span><span class="pln">
</span><span class="tag">&lt;title&gt;</span><span class="pln">Welcome to nginx on LXD container web1!</span><span class="tag">&lt;/title&gt;</span><span class="pln">
</span><span class="tag">&lt;style&gt;</span><span class="pln">
    body </span><span class="pun">{</span><span class="pln">
        width</span><span class="pun">:</span><span class="pln"> </span><span class="lit">35em</span><span class="pun">;</span><span class="pln">
        margin</span><span class="pun">:</span><span class="pln"> </span><span class="lit">0</span><span class="pln"> </span><span class="kwd">auto</span><span class="pun">;</span><span class="pln">
        font</span><span class="pun">-</span><span class="pln">family</span><span class="pun">:</span><span class="pln"> </span><span class="typ">Tahoma</span><span class="pun">,</span><span class="pln"> </span><span class="typ">Verdana</span><span class="pun">,</span><span class="pln"> </span><span class="typ">Arial</span><span class="pun">,</span><span class="pln"> sans</span><span class="pun">-</span><span class="pln">serif</span><span class="pun">;</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">
</span><span class="tag">&lt;/style&gt;</span><span class="pln">
</span><span class="tag">&lt;/head&gt;</span><span class="pln">
</span><span class="tag">&lt;body&gt;</span><span class="pln">
</span><span class="tag">&lt;h1&gt;</span><span class="pln">Welcome to nginx on LXD container web1!</span><span class="tag">&lt;/h1&gt;</span><span class="pln">
</span><span class="tag">&lt;p&gt;</span><span class="pln">If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</span><span class="tag">&lt;/p&gt;</span><span class="pln">
...</span></pre>

<p>
	تفقّد الحاوية الثانية كذلك باستعمال الأمر <code>curl</code> وعنوان IP الخاصّ بها للتّأكد من أنّها قد ضُبطت بالشكل الصحيح، يمكن المرور إلى ضبط HAProxy بعد ذلك.
</p>

<h2 id="-haproxy">
	الخطوة الخامسة - إعداد حاوية HAProxy
</h2>

<p>
	سنقوم بإعداد حاوية HAProxy لتعمل كوسيط أمام هاتين الحاويتين. ولمزيد من المعلومات حول طريقة عمل HAProxy يمكنك الرجوع إلى <a href="https://academy.hsoub.com/devops/servers/%D9%85%D9%82%D8%AF%D9%91%D9%85%D8%A9-%D8%A5%D9%84%D9%89-haproxy-%D9%88%D9%85%D8%A8%D8%A7%D8%AF%D8%A6-%D9%85%D9%88%D8%A7%D8%B2%D9%86%D8%A9-%D8%A7%D9%84%D8%AD%D9%85%D9%84-load-balancing-r41/" rel="">هذا الدرس</a>.
</p>

<p>
	سنقوم بتوجيه حركة المرور نحو كل حاوية بناءا على اسم النطاق الذي نستعمله، سوف نستعمل اسم النطاق <code>example.com</code> في مثال الإعدادات الموالي، وهو نطاق خاص للتوثيقات التعليمية مثل هذا الدرس، سنقوم بإنشاء أول موقع إلكتروني متاح على اسمي النطاق <code>example.com</code> و <code>www.example.com</code>. الموقع اﻹلكتروني الثاني سيكون على اسم النّطاق <code>www2.example.com</code>. أبدِل أسماء النطاقات الخاصة بك مكان هذه اﻷسماء.
</p>

<p>
	سجل الدخول إلى حاوية <code>haproxy</code>:
</p>

<pre class="ipsCode">
<span class="hljs-comment">lxc</span> <span class="hljs-comment">exec</span> <span class="hljs-comment">haproxy</span> <span class="hljs-literal">-</span><span class="hljs-literal">-</span> <span class="hljs-comment">sudo</span> <span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-comment">login</span> <span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-comment">user</span> <span class="hljs-comment">ubuntu</span>
</pre>

<p>
	حدّث لائحة الحزم ونصِّب HAProxy:
</p>

<pre class="ipsCode">
sudo apt-<span class="hljs-built_in">get</span> <span class="hljs-keyword">update</span>
sudo apt-<span class="hljs-built_in">get</span> install haproxy
</pre>

<p>
	بعد انتهاء التنصيب سننتقل إلى إعداد HAProxy. ملف إعدادات HAProxy مُتواجد في المسار <code>‎/etc/haproxy/haproxy.cfg</code>. افتح هذا الملف بواسطة محرر النصوص المُفضّل لديك:
</p>

<pre class="ipsCode">
sudo nano <span class="hljs-regexp">/etc/</span>haproxy<span class="hljs-regexp">/haproxy.cfg</span>
</pre>

<p>
	أولا سنقوم ببعض التعديلات في قسم <code>defaults</code>. سنقوم بإضافة خيار <code>forwardfor</code> لكي نحتفظ بعنوان IP المصدري لعميل الويب، وسنضيف الخيار <code>http-server-close</code>، والذي سيقوم بتمكين إعادة استخدام الجلسة (session reuse) وتخفيض زمن الوصول (Latency).
</p>

<pre class="ipsCode">
global
...
defaults
    <span class="hljs-built_in">log</span> global
    mode    http
    <span class="hljs-keyword">option</span>  httplog
    <span class="hljs-keyword">option</span>  dontlognull
    <span class="hljs-keyword">option</span>   forwardfor
    <span class="hljs-keyword">option</span>   http-<span class="hljs-built_in">server</span>-close
    timeout connect <span class="hljs-number">5000</span>
    timeout client  <span class="hljs-number">50000</span>
    timeout <span class="hljs-built_in">server</span>  <span class="hljs-number">50000</span>
...
</pre>

<p>
	سنقوم بعد ذلك بإعداد الواجهة اﻷمامية للإشارة نحو حاويتي الواجهة الخلفية الخاصة بنا. أضف قسم <code>frontend</code> تحت اسم <code>www_frontend</code> كما يلي:
</p>

<pre class="ipsCode">
frontend www_frontend
    <span class="hljs-built_in">bind</span> *:80     <span class="hljs-comment"># Bind to port 80 (www) on the container</span>

    <span class="hljs-comment"># It matches if the HTTP Host: field mentions any of the hostnames (after the '-i').</span>
    acl host_web1 hdr(host) -i example.com www.example.com
    acl host_web2 hdr(host) -i web2.example.com

    <span class="hljs-comment"># Redirect the connection to the proper server cluster, depending on the match.</span>
    use_backend web1_cluster <span class="hljs-keyword">if</span> host_web1
    use_backend web2_cluster <span class="hljs-keyword">if</span> host_web2
</pre>

<p>
	توافق أوامر <code>acl</code> أسماء مُضيفات خواديم الويب ثم تقوم بإعادة توجيه الطلب إلى قسم <code>backend</code> المناسب. ثم نعرف قسمي <code>backend</code> جديدين واحد لكل خادوم ويب، ثم نقوم بتسميتهما <code>web1_cluster</code> و<code>web2_cluster</code> تباعا.
</p>

<p>
	أضف الشفرة التالية للملف لتعريف الواجهات الخلفية:
</p>

<pre class="ipsCode">
<span class="hljs-string">backend </span><span class="hljs-string">web1_cluster
</span>    <span class="hljs-string">balance </span><span class="hljs-string">leastconn
</span>    <span class="hljs-comment"># We set the X-Client-IP HTTP header. This is useful if we want the web server to know the real client IP.</span>
    <span class="hljs-string">http-request </span><span class="hljs-built_in">set-header</span> <span class="hljs-string">X-Client-</span><span class="hljs-string">IP </span>%[<span class="hljs-string">src]</span>
    <span class="hljs-comment"># This backend, named here "web1", directs to container "web1.lxd" (hostname).</span>
    <span class="hljs-string">server </span><span class="hljs-string">web1 </span><span class="hljs-string">web1.</span><span class="hljs-string">lxd:80 </span><span class="hljs-string">check
</span>
<span class="hljs-string">backend </span><span class="hljs-string">web2_cluster
</span>    <span class="hljs-string">balance </span><span class="hljs-string">leastconn
</span>    <span class="hljs-string">http-request </span><span class="hljs-built_in">set-header</span> <span class="hljs-string">X-Client-</span><span class="hljs-string">IP </span>%[<span class="hljs-string">src]</span>
    <span class="hljs-string">server </span><span class="hljs-string">web2 </span><span class="hljs-string">web2.</span><span class="hljs-string">lxd:80 </span><span class="hljs-string">check</span>
</pre>

<p>
	يحدّد خيار <code>balance</code> استراتيجية موازنة الحمل (load-balancing). في هذه الحالة، نُفضّل اقل عدد من الاتصالات. خيار <code>http-request</code> يضبط ترويسة HTTP (HTTP header) مع عنوان IP الخاصّ بعميل الويب الحقيقي، إذا لم نحدد هذه الترويسة فإن خادوم الويب سيسجل عنوان HAProxy IP على انه العنوان المصدري لجميع الاتصالات مما سيصعب تحليل أماكن و أصول حركة المرور. يُخصّص خيار <code>server</code> اسما كيفيا (arbitrary name) للخادوم <code>web1</code> متبوعا باسم المُضيف ومنفذ الخادوم. يُزوّد LXD الحاويات بخادوم DNS، وذلك لكي يُشير <code>web1.lxd</code> إلى عنوان IP التّابع للحاوية <code>web1</code>. الحاويات اﻷخرى لها أسماء مُضيفات خاصة بها مثل <code>web2.lxd</code> و<code>haproxy.lxd</code>.
</p>

<p>
	يدفع المُعامل <code>check</code> HAProxy إلى أداء فحوصات السلامة (Health checks) على الخادوم للتأكد من توفره.
</p>

<p>
	لاختبار صحة اﻹعدادات، نفّذ اﻷمر التالي:
</p>

<pre class="ipsCode">
<span class="hljs-regexp">/usr/</span>sbin<span class="hljs-regexp">/haproxy -f /</span>etc<span class="hljs-regexp">/haproxy/</span>haproxy.cfg -c
</pre>

<p>
	ينبغي على المخرج أن يكون كما يلي:
</p>

<pre class="ipsCode">
<span class="hljs-keyword">Configuration</span> <span class="hljs-keyword">file</span> <span class="hljs-keyword">is</span> valid
</pre>

<p>
	لِنُعد تحميل Haproxy لكي يقرأ اﻹعدادات الجديدة:
</p>

<pre class="ipsCode">
<span class="hljs-attribute">sudo systemctl reload haproxy</span>
</pre>

<p>
	والآن سجل الخروج من الحاوية للعودة إلى المُضيف:
</p>

<pre class="ipsCode">
<span class="hljs-built_in">logout</span>
</pre>

<p>
	قمنا بتجهيز Haproxy ليتصرف على شكل وسيط عكسي يوجّه أي اتصال يتلقاه عبر المنفذ رقم <code>80</code> نحو الخادوم الملائِم داخل كلا الحاويتين. لنتحقق من أن <code>haproxy</code> يستطيع فعلا تحويل الطلبات نحو الحاوية الصحيحة. ولذلك نستعمل اﻷمر التّالي:
</p>

<pre class="ipsCode">
curl --verbose --<span class="hljs-selector-tag">header</span> <span class="hljs-string">'Host: web2.example.com'</span> http:<span class="hljs-comment">//10.10.10.10</span>
</pre>

<p>
	يُرسل الأمر أعلاه طلبا لـHAProxy ويضبط ترويسة HTTP باسم <code>host</code> والتي سيستعملها HAProxy لتوجيه الاتصال نحو الخادوم الملائم.
</p>

<p>
	يجب على المخرج أن يكون كالتالي:
</p>

<pre class="ipsCode">
...
&gt; GET / HTTP/<span class="hljs-number">1.1</span>
&gt; Hos<span class="hljs-variable">t:</span> web2.example.<span class="hljs-keyword">com</span>
&gt; User-Agen<span class="hljs-variable">t:</span> curl/<span class="hljs-number">7.47</span>.<span class="hljs-number">0</span>
&gt; Accep<span class="hljs-variable">t:</span> */*
&gt; 
...
&lt; 
&lt;!DOCTYPE html&gt;
<span class="hljs-symbol">&lt;html&gt;</span>
<span class="hljs-symbol">&lt;head&gt;</span>
<span class="hljs-symbol">&lt;title&gt;</span>Welcome <span class="hljs-keyword">to</span> nginx <span class="hljs-keyword">on</span> LXD container web2!&lt;/title&gt;
<span class="hljs-symbol">&lt;style&gt;</span>
...
</pre>

<p>
	تمكن Hproxy من فهم الطلب وتوجيهه نحو الحاوية <code>web2</code> بنجاح. ومنه فإن الخادوم قدم لنا الصّفحة الرّئيسيّة الافتراضيّة التي قمنا بتعديلها سابقا وأظهر النص <code>on LXD container web2</code>.
</p>

<p>
	لنقم الآن بتوجيه الطلبات الخارجية إلى HAProxy حتى يتمكن بقية العالم من الولوج إلى مواقعنا الإلكترونية.
</p>

<h2 id="-haproxy">
	الخطوة السادسة - توجيه الاتصالات الواردة نحو حاوية HAProxy
</h2>

<p>
	القطعة اﻷخيرة من اﻷحجية هي توصيل الوسيط العكسي مع شبكة اﻷنترنت. نحتاج إلي ضبط الخادوم لتوجيه أي اتصال وارد إليه من اﻷنترنت عبر المنفذ 80 نحو حاوية HAProxy.
</p>

<p>
	نُصِّبَ HAProxy في حاوية خاصّة به، وبالتالي، فإنه غير قابل للولوج من اﻷنترنت افتراضيا ولحل هذه المشكلة، سنقوم بإنشاء قاعدة <code>iptables</code> لتوجيه الاتصالات. يحتاج اﻷمر <code>iptables</code> إلى عنواني IP، عنوان الخادوم العمومي (<code>your_server_ip</code>) وعنوان IP الخاصّ بالحاويّة <code>haproxy</code> (أي <code>your_haproxy_ip</code> أسفله)، والذي نحصل عليه من خلال اﻷمر <code>lxc list</code>.
</p>

<p>
	نفّذ هذا اﻷمر ﻹنشاء القاعدة:
</p>

<pre class="ipsCode">
sudo iptables -t nat -I PREROUTING -<span class="hljs-selector-tag">i</span> eth0 -<span class="hljs-selector-tag">p</span> TCP -d your_server_ip/<span class="hljs-number">32</span> --dport <span class="hljs-number">80</span> -j DNAT --to-destination your_haproxy_ip:<span class="hljs-number">80</span>
</pre>

<p>
	وهذا شرح لتفاصيل هذا اﻷمر:
</p>

<ul>
<li>
		المقطع <code>-t nat</code> يعني بأننا نستعمل الجدول <code>nat</code>.
	</li>
	<li>
		المقطع <code>-I PREROUTING</code> يعني أننا نضيف القاعدة إلى سلسلة التوجيه المسبَق (PREROUTING).
	</li>
	<li>
		المقطع <code>-i eth0</code> يعني أن الواجهة <code>eth0</code> هي التي ستُستَعمَل، وهي الواجهة العمومية الافتراضية على الخواديم.
	</li>
	<li>
		المقطع <code>-p TCP</code> يعني أننا نستعمل بروتوكول TCP.
	</li>
	<li>
		المقطع <code>-d your_server_ip/32</code> يحدد عنوان IP الهدف للقاعدة.
	</li>
	<li>
		المقطع <code>--dport 80</code> يُحدّد رقم المنفذ الهدف.
	</li>
	<li>
		المقطع <code>-j DNAT</code> يعني أننا نريد أن نؤدي قفزة نحو الهدف NAT (DNAT).
	</li>
	<li>
		المقطع <code>--to-destination your_haproxy_ip:80</code> يدلّ على أننا نريد من الطلب الذهاب إلى عنوان IP الخاصّ بالحاوية من طريق HAProxy.
	</li>
</ul>
<p>
	للمزيد من المعلومات حول IPTables، تفقّد الدّرس <a href="https://academy.hsoub.com/devops/security/firewalls/%D9%85%D8%A7-%D9%87%D9%88-%D8%A7%D9%84%D8%AC%D8%AF%D8%A7%D8%B1-%D8%A7%D9%84%D9%86%D8%A7%D8%B1%D9%8A-%D9%88%D9%83%D9%8A%D9%81-%D9%8A%D8%B9%D9%85%D9%84%D8%9F-r114/" rel="">ما هو الجدار الناري وكيف يعمل؟ </a> والدّرس <a href="https://academy.hsoub.com/devops/security/firewalls/%D8%A3%D8%B3%D8%A7%D8%B3%D9%8A%D8%A7%D8%AA-iptables-%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D9%88%D8%A3%D9%88%D8%A7%D9%85%D8%B1-%D8%B4%D8%A7%D8%A6%D8%B9%D8%A9-%D9%84%D9%84%D8%AC%D8%AF%D8%A7%D8%B1-%D8%A7%D9%84%D9%86%D8%A7%D8%B1%D9%8A-r119/" rel="">أساسيات IPTables - قواعد وأوامر شائعة للجدار الناري </a>.
</p>

<p>
	أخيرا لحفظ أمر <code>iptables</code> لكي يُعاد تطبيقُه بعد إعادة التشغيل نقوم بتنصيب حزمة <code>iptables-persistent</code>:
</p>

<pre class="ipsCode">
sudo apt-<span class="hljs-keyword">get</span> install iptables-persistent
</pre>

<p>
	أثناء تنصيب الحزم سيطلب منك حفظ قواعد <code>iptables</code> الحاليّة. وافق واحفظ جميع قواعد <code>iptables</code> الحاليّة.
</p>

<p>
	إذا قمت بإعداد اسمي نطاق FQDN، فسيمكنك أن تتصل بكل من الموقعين باستعمال متصفحك. لذا جرب ذلك.
</p>

<p>
	للتحقق من أن الخادومين يمكن الولوج لهما عن طريق اﻷنترنت، ادخل إلى كل منهما باستعمال حاسوبك المحلي عن طريق أمر <code>curl</code> بالشكل التالي:
</p>

<pre class="ipsCode">
<span class="hljs-string">curl </span><span class="hljs-built_in">--verbose</span> <span class="hljs-built_in">--header</span> <span class="hljs-string">'Host: example.com'</span> <span class="hljs-string">'http://your_server_ip'</span>
<span class="hljs-string">curl </span><span class="hljs-built_in">--verbose</span> <span class="hljs-built_in">--header</span> <span class="hljs-string">'Host: web2.example.com'</span> <span class="hljs-string">'http://your_server_ip'</span>
</pre>

<p>
	هذه اﻷوامر تقوم باتصالات HTTP مع عنوان IP العمومي الخاصّ بالخادوم وتضيف حقل ترويسة HTTP مع خيار <code>--header</code> والذي سيستعمله HAProxy لتنفيذ الطلب كما فعلنا في الخطوة الخامسة.
</p>

<p>
	هذا هو المخرج بالنسبة لأمر <code>curl</code> الأول:
</p>

<pre class="ipsCode">
*   Trying your_server_ip...
* Connected <span class="hljs-keyword">to</span> your_server_ip (your_server_ip) port <span class="hljs-number">80</span> (#<span class="hljs-number">0</span>)
&gt; GET / HTTP/<span class="hljs-number">1.1</span>
&gt; Hos<span class="hljs-variable">t:</span> example.<span class="hljs-keyword">com</span>
&gt; User-Agen<span class="hljs-variable">t:</span> curl/<span class="hljs-number">7.47</span>.<span class="hljs-number">0</span>
&gt; Accep<span class="hljs-variable">t:</span> */*
&gt; 
&lt; HTTP/<span class="hljs-number">1.1</span> <span class="hljs-number">200</span> OK
&lt; Server: nginx/<span class="hljs-number">1.10</span>.<span class="hljs-number">0</span> (Ubuntu)
...
&lt;!DOCTYPE html&gt;
<span class="hljs-symbol">&lt;html&gt;</span>
<span class="hljs-symbol">&lt;head&gt;</span>
<span class="hljs-symbol">&lt;title&gt;</span>Welcome <span class="hljs-keyword">to</span> nginx <span class="hljs-keyword">on</span> LXD container web1!&lt;/title&gt;
<span class="hljs-symbol">&lt;style&gt;</span>
    body {
...
</pre>

<p>
	وهذا هو مٌخرج الأمر الثّاني:
</p>

<pre class="ipsCode">
*   Trying your_server_ip...
* Connected <span class="hljs-keyword">to</span> your_server_ip (your_server_ip) port <span class="hljs-number">80</span> (#<span class="hljs-number">0</span>)
&gt; GET / HTTP/<span class="hljs-number">1.1</span>
&gt; Hos<span class="hljs-variable">t:</span> web2.example.<span class="hljs-keyword">com</span>
&gt; User-Agen<span class="hljs-variable">t:</span> curl/<span class="hljs-number">7.47</span>.<span class="hljs-number">0</span>
&gt; Accep<span class="hljs-variable">t:</span> */*
&gt; 
&lt; HTTP/<span class="hljs-number">1.1</span> <span class="hljs-number">200</span> OK
&lt; Server: nginx/<span class="hljs-number">1.10</span>.<span class="hljs-number">0</span> (Ubuntu)
...
&lt;!DOCTYPE html&gt;
<span class="hljs-symbol">&lt;html&gt;</span>
<span class="hljs-symbol">&lt;head&gt;</span>
<span class="hljs-symbol">&lt;title&gt;</span>Welcome <span class="hljs-keyword">to</span> nginx <span class="hljs-keyword">on</span> LXD container web2!&lt;/title&gt;
<span class="hljs-symbol">&lt;style&gt;</span>
    body {
...
</pre>

<p>
	تم إظهار الموقع الصحيح في كلتا الحالتين.
</p>

<h2 id="-">
	خاتمة
</h2>

<p>
	قمت الآن بضبط موقعي ويب كل منهما داخل حاويته الخاصة مع HAProxy كموجه للمرور، يمكنك تكرار نفس العملية ﻹعداد مواقع ويب أخرى كل داخل حاويته الخاصة، يمكن كذلك إضافة MySQL في حاوية جديدة وتنصيب نظام إدارة محتوى مثل Wordpress لتسيير كل موقع ويب على حدة.
</p>

<p>
	يمكنك كذلك استعمال هذه العملية لدعم نُسخِِ أقدم من برمجية معينة، على سبيل المثال، إن كان نظام إدارة محتوى يتطلب برمجية قديمة مثل PHP5 فبإمكانك تنصيب Ubuntu 14.04 على حاوية (<code>lxc launch ubuntu:t</code>) عوضا عن محاولة تخفيض إصدارات مدير الحزم المتوفرة على Ubuntu 16.04.
</p>

<p>
	يوفر LXD القدرة على أخذ لقطات للحالة الكاملة للحاويات، ما يجعل إنشاء النسخ الاحتياطية وإرجاع الحاويات إلى الوراء في وقت لاحق أمرا سهلا. إضافة إلى ما سبق فتنصيب LXD على خادومين مختلفين يمكّن من الربط بينهما وتهجير الحاويات بين الخواديم عبر الإنترنت.
</p>

<p>
	ترجمة -بتصرّف- للمقال <a href="https://www.digitalocean.com/community/tutorials/how-to-host-multiple-web-sites-with-nginx-and-haproxy-using-lxd-on-ubuntu-16-04" rel="external nofollow">How to Host Multiple Web Sites with Nginx and HAProxy Using LXD on Ubuntu 16.04 </a> لصاحبه Simos Xenitellis.
</p>
]]></description><guid isPermaLink="false">430</guid><pubDate>Sun, 21 Jul 2019 13:07:19 +0000</pubDate></item><item><title>&#x643;&#x64A;&#x641;&#x64A;&#x629; &#x627;&#x633;&#x62A;&#x62E;&#x62F;&#x627;&#x645; ProxySQL &#x643;&#x645;&#x648;&#x627;&#x632;&#x646; &#x62A;&#x62D;&#x645;&#x64A;&#x644; &#x644;&#x62E;&#x627;&#x62F;&#x645; MySQL &#x639;&#x644;&#x649; &#x646;&#x638;&#x627;&#x645; &#x627;&#x644;&#x62A;&#x634;&#x63A;&#x64A;&#x644; &#x623;&#x648;&#x628;&#x646;&#x62A;&#x648; 16.04</title><link>https://academy.hsoub.com/devops/linux/%D9%83%D9%8A%D9%81%D9%8A%D8%A9-%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-proxysql-%D9%83%D9%85%D9%88%D8%A7%D8%B2%D9%86-%D8%AA%D8%AD%D9%85%D9%8A%D9%84-%D9%84%D8%AE%D8%A7%D8%AF%D9%85-mysql-%D8%B9%D9%84%D9%89-%D9%86%D8%B8%D8%A7%D9%85-%D8%A7%D9%84%D8%AA%D8%B4%D8%BA%D9%8A%D9%84-%D8%A3%D9%88%D8%A8%D9%86%D8%AA%D9%88-1604-r429/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2020_09/thumbnail.png.bf997301f6048a0e31534157f7489cb0.png" /></p>

<p>
	<a href="http://www.proxysql.com/" rel="external nofollow">ProxySQL</a> هو عبارة عن خادم وكيل (proxy server) مفتوح المصدر لخادم <a href="https://academy.hsoub.com/devops/servers/databases/mysql/" rel="">قاعدة البيانات MySQL</a>، أي أنه يعمل كوسيط بين خادم قاعدة البيانات MySQL والتطبيقات التي تتعامل مع <a href="https://academy.hsoub.com/devops/servers/databases" rel="">قاعدة البيانات</a> هذه. حيث يقوم الخادم الوكيل بتحسين الأداء، وذلك عن طريق توزيع النقل بين خوادم قاعدة البيانات مشتركة. كما يحسّن من عملية توفّر قاعدة البيانات، وذلك من خلال الانتقال الآلي إلى خادم أخر متاح عند فشل أحد خوادم قاعدة البيانات.
</p>

<p>
	سيتم في هذه المقالة شرح طريقة تنصيب الخادم الوكيل ProxySQL <a href="https://academy.hsoub.com/devops/servers/%D9%85%D8%A7-%D8%A7%D9%84%D9%85%D9%82%D8%B5%D9%88%D8%AF-%D8%A8%D8%AA%D9%88%D8%B2%D9%8A%D8%B9-%D8%A7%D9%84%D8%AD%D9%90%D9%85%D9%84-load-balancing-r319/" rel="">كموازن تحميل</a> (load balancer، توزيع الحمل) لعدة خوادم بيانات MySQL مع تمكين الانتقال الآلي إلى الخوادم المتاحة عند فشل أحدها. حيث سيتم استخدام مجموعة التناسخ المتماثل Group Replication ذات العُقد الرئيسية المتعددة multi-primary مكونة من ثلاث خوادم MySQL، غير أنه يمكن تطبيق الشرح الوارد في هذه المقالة على أي عدد من الخوادم.
</p>

<p>
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="30704" href="https://academy.hsoub.com/uploads/monthly_2019_07/5d2edab0cd714_proxySQL.jpg.01c8e8c7feeb9dce019cd24fd4bc0442.jpg" rel=""><img alt="كيفية استخدام proxySQL كموازن تحميل.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="30704" data-unique="u7875bdi6" src="https://academy.hsoub.com/uploads/monthly_2019_07/5d2edab0e2de4_proxySQL.thumb.jpg.bb3108429c586db0ade8f0dfb8a3791b.jpg"></a>
</p>

<h2>
	المتطلبات
</h2>

<p>
	قبل البدء يجب أن يتوفر ما يلي:
</p>

<ul>
<li>
		خادم أوبنتو 16.04 يتضمن على حساب مستخدم عادي (غير جزر) بصلاحيات <code>sudo</code> وجدار حماية.
	</li>
	<li>
		ثلاث خوادم بيانات MySQL مهيّأة للعمل كمجموعة تناسخ متماثل، والتي يمكن إعدادها اعتمادًا على <a href="https://www.digitalocean.com/community/tutorials/how-to-configure-mysql-group-replication-on-ubuntu-16-04" rel="external nofollow">هذه المقالة</a>، الفقرة multi-primary.
	</li>
</ul>
<h2>
	الخطوة الأولى- تنصيب ProxySQL
</h2>

<p>
	قام مطورو ProxySQL بتوفير حزم أوبنتو رسمية لكل إصدارات ProxySQL، وذلك على صفحتهم في موقع <a href="https://github.com/sysown/proxysql/releases" rel="external nofollow">GitHub</a>، لذا سنقوم بتحميل أخر إصدار ProxySQL من هذه الصفحة، حيث تتضمن هذه الصفحة على <a href="https://github.com/sysown/proxysql/releases" rel="external nofollow">لائحة بجميع إصدارات ProxySQL</a>، وكل إصدار تَمّت تسميته وفق الصيغة <code>proxysql_version-distribution.deb</code>، إذ <code>version</code> هي عبارة عن رقم إصدار حزمة ProxySQL مثل 1.4.4، و <code>distribution</code> هي عبارة عن توزيعة لينكس المخصصة لها هذه الحزمة مثل ubuntu16_amd64.
</p>

<p>
	سنقوم الآن بتحميل أخر إصدار من حزمة ProxySQL (1.4.4 هو آخر إصدار لحظة كتابة هذه المقالة) إلى المسار <code>‎/tmp</code>، وذلك بتنفيذ الأوامر التالية في موجه أوامر لينكس:
</p>

<pre class="ipsCode">
<span class="hljs-variable">$ </span>cd /tmp
<span class="hljs-variable">$ </span> curl -OL <span class="hljs-symbol">https:</span>/<span class="hljs-regexp">/github.com/sysown</span><span class="hljs-regexp">/proxysql/releases</span><span class="hljs-regexp">/download/v</span>1.<span class="hljs-number">4.4</span>/
proxysql_1.<span class="hljs-number">4.4</span>-ubuntu16_amd64.deb
</pre>

<p>
	ثم نقوم بعد انتهاء عملية التحميل، بتنصيب هذه الحزمة باستخدام أداة إدارة حزم <a href="https://academy.hsoub.com/devops/linux/%D8%A3%D8%B3%D8%A7%D8%B3%D9%8A%D8%A7%D8%AA-%D8%A5%D8%AF%D8%A7%D8%B1%D8%A9-%D8%A7%D9%84%D8%AD%D8%B2%D9%85-apt-%D8%8Cyum-%D8%8Cdnf-%D8%8Cpkg-r231/" rel=""><code>‎.deb</code></a> البرمجية <code>dpkg</code>، وذلك بتنفيذ الأوامر التالية في موجه أوامر لينكس:
</p>

<pre class="ipsCode">
$ sudo dpkg -<span class="hljs-selector-tag">i</span> proxysql_*
</pre>

<p>
	حيث استُخدمت الراية <code>‎-i</code> للدلالة على رغبتنا بتنصيب الحزمة من ملف محدد. ثم نقوم بعد انتهاء عملية التنصيب بحذف ملف الحزمة المُحمّل لعدم الحاجة إليه بعد الآن، وذلك بتنفيذ الأمر التالي:
</p>

<pre class="ipsCode">
<span class="hljs-variable">$ </span>rm proxysql<span class="hljs-number">_</span>*
</pre>

<p>
	نحتاج الآن لتطبيق عميل لقاعدة البيانات MySQL ليتصل مع نسخة ProxySQL المُنصّبة، ذلك لأن ProxySQL يستخدم واجهة تخاطب متوافقة مع MySQL من أجل مهام الإدارة. لذا سنستخدم موجه أوامر MySQL، والذي هو جزء من الحزمة mysql-client المتوفرة على مخازن حزم أوبنتو. لكن قبل البدء بتنصيب هذه الحزمة يجب أن نحدّث مستودع الحزم لضمان تحميل وتنصيب آخر إصدار من هذه الحزمة، وذلك بتنفيذ الأمر التالي:
</p>

<pre class="ipsCode">
$ sudo apt-<span class="hljs-built_in">get</span> <span class="hljs-keyword">update</span>
</pre>

<p>
	ثم نقوم بتنصيب الحزمة mysql-client، وذلك بتنفيذ الأمر التالي:
</p>

<pre class="ipsCode">
$ sudo apt-get <span class="hljs-keyword">install</span> mysql-<span class="hljs-keyword">client</span>
</pre>

<p>
	أصبح لدينا الآن جميع متطلبات تشغيل ProxySQL، غير أن هذه الخدمة لا تُشَّغل آليًا بعد التنصيب، لذا يتوجب علينا تشغيلها يدويًا وذلك بتنفيذ الأمر التالي:
</p>

<pre class="ipsCode">
$ sudo systemctl <span class="hljs-literal">start</span> proxysql
</pre>

<p>
	سيعمل ProxySQL الآن بإعداداته الافتراضية، والتي يمكن عرضها بتنفيذ الأمر التالي:
</p>

<pre class="ipsCode">
<span class="hljs-variable">$ </span>systemctl status proxysql
</pre>

<p>
	فنحصل على الخرج التالي في نافذة موجه الأوامر:
</p>

<pre class="ipsCode">
● proxysql.service - <span class="hljs-symbol">LSB:</span> High Performance Advanced Proxy <span class="hljs-keyword">for</span> MySQL
   <span class="hljs-symbol">Loaded:</span> loaded (<span class="hljs-regexp">/etc/init</span>.d/proxysql; bad; vendor <span class="hljs-symbol">preset:</span> enabled)
   <span class="hljs-symbol">Active:</span> active (running) since Thu <span class="hljs-number">2017</span>-<span class="hljs-number">12</span>-<span class="hljs-number">21</span> <span class="hljs-number">19</span>:<span class="hljs-number">19</span>:<span class="hljs-number">20</span> UTC; <span class="hljs-number">5</span>s ago
     <span class="hljs-symbol">Docs:</span> <span class="hljs-symbol">man:</span>systemd-sysv-generator(<span class="hljs-number">8</span>)
  <span class="hljs-symbol">Process:</span> <span class="hljs-number">12350</span> ExecStart=<span class="hljs-regexp">/etc/init</span>.d/proxysql start (code=exited، status=<span class="hljs-number">0</span>/SUCCESS)
    <span class="hljs-symbol">Tasks:</span> <span class="hljs-number">23</span>
   <span class="hljs-symbol">Memory:</span> <span class="hljs-number">30.9</span>M
      <span class="hljs-symbol">CPU:</span> <span class="hljs-number">86</span>ms
   <span class="hljs-symbol">CGroup:</span> /system.slice/proxysql.service
           ├─<span class="hljs-number">12355</span> proxysql -c /etc/proxysql.cnf -D /var/<span class="hljs-class"><span class="hljs-keyword">lib</span>/<span class="hljs-title">proxysql</span></span>
           └─<span class="hljs-number">12356</span> proxysql -c /etc/proxysql.cnf -D /var/<span class="hljs-class"><span class="hljs-keyword">lib</span>/<span class="hljs-title">proxysql</span></span>
</pre>

<p>
	حيث تدلّ العبارة <code>active (running)</code> على أن ProxySQL مُنصَّب وفي حالة عمل.
</p>

<p>
	في الخطوة التالية سنقوم بزيادة الأمان، وذلك بإعداد كلمة السر المستخدمة للدخول إلى الواجهة التخاطبية لإدارة ProxySQL.
</p>

<h2>
	الخطوة الثانية- إعداد كلمة سر مدير ProxySQL
</h2>

<p>
	يستخدم ProxySQL في أول مرة يتم تشغيله فيها بعد التنصيب ملف الإعدادات القادم مع الحزمة، وذلك من أجل التهيئة الابتدائية لجميع إعداداته بالقيم الافتراضية، إذ يقوم ProxySQL بعد عملية التهيئة هذه بحفظ هذه الإعدادات في قاعدة البيانات، والتي يمكن إدارتها وتعديلها عن طريق موجه أوامر MySQL. لذا يجب عند إعداد كلمة سر مدير ProxySQL الاتصال بقاعدة البيانات الخاصة بالإعدادات لتعديل الإعدادات الموافقة.
</p>

<p>
	لإعداد كلمة السر سنقوم في البداية بالدخول إلى الواجهة التخاطبية لإدارة ProxySQL، وذلك بتنفيذ الأمر التالي:
</p>

<pre class="ipsCode">
$ mysql -u admin -p -h <span class="hljs-number">127.0</span><span class="hljs-number">.0</span><span class="hljs-number">.1</span> -P <span class="hljs-number">6032</span> --prompt='ProxySQLAdmin&gt; '
</pre>

<ul>
<li>
		<code>‎-u</code>: يُستخدم هذا العلَم لتحديد اسم المستخدم الذي يريد القيام بالمهام الإدارية مثل تغيير الإعدادات، وبما أنه لم يتم بعد إضافة أي مستخدم، لذا تم استخدام اسم المستخدم الافتراضي <code>admin</code>.
	</li>
	<li>
		<code>‎-h</code>: يُستخدم هذا العلَم لتحديد المضيف المُراد الاتصال به، وبما أننا نريد الاتصال بالواجهة التخاطبية لإدارة ProxySQL المحلي لذا استخدمنا المضيف المحلي <code>127.0.0.1</code>.
	</li>
	<li>
		<code>‎-P</code>: يُستخدم هذا العلَم لتحديد منفذ الاتصال بالواجهة التخاطبية لإدارة ProxySQL، حيث تَستخدم هذه الواجهة التخاطبية المنفذ 6032.
	</li>
	<li>
		<code>‎--prompt</code>: وهو علَم اختياري لتغيير الموجِّه الافتراضي <code>mysql&gt;‎</code>، حيث قمنا هنا بتغييره إلى <code>ProxySQLAdmin&gt;‎</code> لتوضيح أننا اتصلنا بالواجهة التخاطبية لإدارة ProxySQL، وذلك لتجنب الالتباس لاحقًا عند الاتصال أيضًا بخوادم قاعدة البيانات MySQL.
	</li>
</ul>
<p>
	عند تنفيذ الأمر السابق سيطلب منا موجه الأوامر إدخال كلمة سر الدخول إلى الواجهة التخاطبية لإدارة ProxySQL، وبما أننا لم نقم بإعدادها بعد، لذا سنُدخل كلمة السر الافتراضية <code>admin</code>.
</p>

<p>
	عند نجاح عملية الدخول إلى الواجهة التخاطبية لإدارة ProxySQL، يتغيّر موجه أوامر النظام إلى الموجه <code>ProxySQLAdmin&gt;‎</code> الخاص بالواجهة التخاطبية لإدارة ProxySQL كما يلي:
</p>

<pre class="ipsCode">
ProxySQL administration console prompt

Welcome to the MySQ<span class="hljs-class">L monitor.  Commands end with ;</span><span class="hljs-built_in"> or </span>\g.
Your MySQL connection id is 2
Server version: 5.5.30 (ProxySQL Admin Module)

Copyright (c) 2000، 2017، Oracle<span class="hljs-built_in"> and/or </span>its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation<span class="hljs-built_in"> and/or </span>its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;'<span class="hljs-built_in"> or </span>'\h' for help. Type '\c' to clear the current input statement.

ProxySQLAdmin&gt;
</pre>

<p>
	ثم نقوم بتغيير كلمة السر مدير ProxySQL، وذلك بتنفيذ الأمر التالي في موجه أوامر الواجهة التخاطبية لإدارة ProxySQL:
</p>

<pre class="ipsCode">
ProxySQLAdmin&gt; UPDATE global<span class="hljs-number">_</span>variables SET <span class="hljs-keyword">variable</span><span class="hljs-number">_</span><span class="hljs-keyword">value</span>=<span class="hljs-string">'admin:password'</span> 
WHERE <span class="hljs-keyword">variable</span><span class="hljs-number">_n</span>ame=<span class="hljs-string">'admin-admin_credentials'</span>;

Output
Query OK، <span class="hljs-number">1</span> row affected (<span class="hljs-number">0.0</span><span class="hljs-number">0</span> sec)
</pre>

<p>
	حيث تمّ استخدام الأمر <code>UPDATE</code> من أجل تغيير كلمة السر <code>password</code> للحساب الإداري <code>admin</code> الموجودة في المتغير <code>admin-admin_credentials</code> ضمن قاعدة البيانات <code>global_variables</code>.
</p>

<p>
	طبعًا يجب استبدال <code>password</code> في الأمر السابق بكلمة سر قوية قبل تنفيذه.
</p>

<p>
	لا تدخل عملية تغيير كلمة السر حيِّز التنفيذ مباشرة، وذلك نتيجة بنية نظام الإعدادات الخاص بالخادم ProxySQL، والذي يتكون من ثلاث طبقات منفصلة هي:
</p>

<ul>
<li>
		طبقة الذاكرة MEMORY: وهي عبارة عن قواعد بيانات الإعدادات المُحمّلة في الذاكرة والتي يتم التفاعل معها والتعديل عليها مباشرة من خلال موجه أوامر الواجهة التخاطبية لإدارة ProxySQL.
	</li>
	<li>
		طبقة وقت التشغيل RUNTIME: يَستعمل ProxySQL هذه الطبقة لتفعيل الإعدادات المعدَّلة ودخولها حيز التنفيذ مباشرة.
	</li>
	<li>
		 طبقة القرص DISK: وهي عبارة عن قاعدة بيانات محفوظة على القرص الصلب والتي يتم فيها حفظ الإعدادات، حيث تُحمَّل هذه الإعدادات في طبقة الذاكرة عند إقلاع النظام، وبالتالي تضيع أي تعديلات تم إجرائها على هذه الإعدادات في طبقة وقت التشغيل، وذلك أثناء إعادة تشغيل النظام إن لم يتم حفظها في طبقة القرص.
	</li>
</ul>
<p>
	أي أن التعديلات التي قمنا بإجرائها على كلمة السر مازالت في طبقة الذاكرة، ولتدخل حيز التنفيذ يجب نقلها إلى طبقة وقت التشغيل، وذلك بتنفيذ الأمر التالي موجه أوامر الواجهة التخاطبية لإدارة ProxySQL:
</p>

<pre class="ipsCode">
ProxySQLAdmin&gt; LOAD ADMIN <span class="hljs-keyword">VARIABLES</span> TO <span class="hljs-comment">RUNTIME</span>;
</pre>

<p>
	ثم يجب القيام بحفظها في طبقة القرص كي نحافظ عليها بشكل دائم، وذلك بتنفيذ الأمر التالي موجه أوامر الواجهة التخاطبية لإدارة ProxySQL:
</p>

<pre class="ipsCode">
ProxySQLAdmin&gt; SAVE ADMIN <span class="hljs-keyword">VARIABLES</span> TO <span class="hljs-comment">DISK</span>;
</pre>

<p>
	حيث استُخدم الأمر <code>ADMIN</code> من أجل التعامل مع المتغيرات المتعلقة فقط بموجه أوامر الواجهة التخاطبية لإدارة ProxySQL.
</p>

<p>
	هذا ويستخدم ProxySQL أوامر مشابهة للتي يستخدمها خادم MySQL، في التعامل مع الأقسام الأخرى من الإعدادات، والتي سيتم استخدامها لاحقًا في هذه المقالة.
</p>

<p>
	الآن وبعد أن تم تنصيب ProxySQL وإعداد كلمة سر مدير النظام، سنقوم بإعداد ثلاث عُقد MySQL ليتمكن ProxySQL من مراقبتها.
</p>

<h2>
	الخطوة الثالثة- إعداد المراقبة في MySQL
</h2>

<p>
	يجب أن يكون ProxySQL قادرًا على الاتصال بعُقد MySQL ليتمكن من تقدير حالتها، ولتنفيذ ذلك يجب أن يكون قادرًا على الاتصال بكل خادم عن طريق مستخدم مخصص. لذا سنقوم بإعداد المستخدم الضروري في عُقد MySQL وتنصيب وظائف SQL إضافية، والتي تسمح لخادم ProxySQL بالاستعلام عن حالة مجموعة التناسخ المتماثل.
</p>

<p>
	وبما أن مجموعة التناسخ المتماثل قد تم إعدادها مسبقًا، لذا يجب أن تُطبَّق الخطوات التالية على عضو وحيد من المجموعة.
</p>

<p>
	نفتح نافذة موجه أوامر نظام لينكس ثانية، ثم نسجل الدخول إلى الخادم الذي يحوي أحد عُقد MySQL، وذلك بتنفيذ الأمر التالي:
</p>

<pre class="ipsCode">
<span class="hljs-variable">$ </span><abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">ssh</abbr> sammy<span class="hljs-variable">@your_mysql_server_ip_1</span>
</pre>

<p>
	ثم نحمل ملف SQL الذي يحتوي على بعض الوظائف الضرورية لدعم عمل مجموعة التناسخ المتماثل الخاصة بالخادم الوكيل ProxySQL، وذلك بتنفيذ الأمر التالي في موجه الأوامر:
</p>

<pre class="ipsCode">
$ curl -OL <span class="hljs-string">https:</span><span class="hljs-comment">//gist.github.com/lefred</span>
<span class="hljs-regexp">/77ddbde301c72535381ae7af9f968322/</span>raw
<span class="hljs-regexp">/5e40b03333a3c148b78aa348fd2cd5b5dbb36e4d/</span>addition_to_sys.sql
</pre>

<p>
	<strong>ملاحظة</strong>: إن هذه الملف مُوفَّر من قبل مطوري ProxySQL غير أنه موجود ضمن مخزن GitHub شخصي، مما يعني أنه قد يُحذف أو يصبح قديمًا. لكنه قد يُضاف في المستقبل لمخزن ProxySQL الرسمي على شكل ملف له إصدار. ولمزيد من المعلومات حول هذا الملف يمكن قراءة المقال التالي: <a href="http://lefred.be/content/mysql-group-replication-native-support-in-proxysql/" rel="external nofollow">native ProxySQL support for MySQL group replication</a>.
</p>

<p>
	يمكن رؤية محتويات هذا الملف بتنفيذ الأمر التالي:
</p>

<pre class="ipsCode">
$ <span class="hljs-keyword">less</span> addition_to_sys.sql
</pre>

<p>
	ثم نقوم بتنفيذ الأمر التالي على الملف، حيث سيطلب منا موجه أوامر MySQL إدخال كلمة السر المستخدم الجذر root:
</p>

<pre class="ipsCode">
$ mysql -u root -<span class="hljs-selector-tag">p</span> &lt; addition_to_sys.sql
</pre>

<p>
	في حال نجاح عملية تنفيذ الأمر السابق، فإنه لن يظهر أي خرج في نافذة موجه الأوامر. وتصبح جميع عُقد MySQL قادرة على تأمين الوظائف الضرورية لتمكين قدرة ProxySQL على معرفة حالة مجموعة التناسخ المتماثل.
</p>

<p>
	والآن نحتاج لإنشاء مستخدم مخصص ليستخدمه ProxySQL في مراقبة سلامة نسخ البيانات. لكن علينا في البداية الدخول إلى موجه أوامر MySQL والذي سيطلب منا مرة أخرى إدخال كلمة سر المستخدم الجزر root:
</p>

<pre class="ipsCode">
<span class="hljs-variable">$ </span>mysql -u root -p
</pre>

<p>
	نقوم الآن بإنشاء المستخدم المخصص والذي سنسميه <code>monitor</code>، وذلك بتنفيذ الأمر التالي في موجه أوامر MySQL بعد استبدال كلمة السر <code>monitorpassword</code> بأخرى قوية:
</p>

<pre class="ipsCode">
(member1)mysql&gt; <span class="hljs-keyword">CREATE</span> USER <span class="hljs-string">'monitor'</span>@<span class="hljs-string">'%'</span> IDENTIFIED <span class="hljs-keyword">BY</span> <span class="hljs-string">'monitorpassword'</span>;
</pre>

<p>
	ثم نقوم بمنح هذا المستخدم صلاحية الاستعلام عن حالة خوادم MySQL، وذلك بتنفيذ الأمر:
</p>

<pre class="ipsCode">
(member1)mysql&gt; GRANT <span class="hljs-keyword">SELECT</span> <span class="hljs-keyword">on</span> sys.* <span class="hljs-keyword">to</span> <span class="hljs-string">'monitor'</span>@<span class="hljs-string">'%'</span>;
</pre>

<p>
	وأخيرًا نُطبِّق التعديلات لتصبح سارية المفعول، وذلك بتنفيذ الأمر التالي:
</p>

<pre class="ipsCode">
(<span class="hljs-name">member1</span>)mysql&gt; FLUSH PRIVILEGES<span class="hljs-comment">;</span>
</pre>

<p>
	وبما أننا نعمل ضمن مجموعة التناسخ المتماثل، فإن إضافة مستخدم مخصص لمراقبة حالة أحد عُقد المجموعة، سيُطبَّق على جميع العُقد الأخرى في المجموعة.
</p>

<p>
	سيتم في الخطوة التالية تزويد ProxySQL بمعلومات المستخدم المخصص للمراقبة، ليتمكن ProxySQL من الدخول إلى عُقد MySQL.
</p>

<h2>
	الخطوة الرابعة- إعداد المراقبة في ProxySQL
</h2>

<p>
	سنقوم بإعداد ProxySQL ليستخدم مستخدم جديد أثناء مراقبة عُقد MySQL، وذلك عن طريق تحديث قيمة المتغيّر الموافق. وذلك بشكل مشابه لطريقة إعداد كلمة سر مدير ProxySQL في الخطوة الثانية.
</p>

<p>
	ننتقل إلى موجه أوامر الواجهة التخاطبية لإدارة ProxySQL، ثم نحدّث قيمة المتغير <code>mysql-monitor_username</code> بقيم حساب المستخدم المخصص لمراقبة عُقد MySQL، وذلك بتنفيذ الأمر:
</p>

<pre class="ipsCode">
ProxySQLAdmin&gt; UPDATE global<span class="hljs-number">_</span>variables SET <span class="hljs-keyword">variable</span><span class="hljs-number">_</span><span class="hljs-keyword">value</span>=<span class="hljs-string">'monitor'</span> 
WHERE <span class="hljs-keyword">variable</span><span class="hljs-number">_n</span>ame=<span class="hljs-string">'mysql-moniter_username'</span>;
</pre>

<p>
	ولكي يأخذ هذا التحديث حيّز التنفيذ، يجب تطبيقه على طبقة وقت التشغيل ثم حفظه في طبقة القرص، وذلك بتنفيذ الأوامر التالية في موجه أوامر الواجهة التخاطبية لإدارة ProxySQL:
</p>

<pre class="ipsCode">
ProxySQLAdmin&gt; LOAD MYSQL <span class="hljs-keyword">VARIABLES</span> TO <span class="hljs-comment">RUNTIME</span>;
ProxySQLAdmin&gt; SAVE MYSQL <span class="hljs-keyword">VARIABLES</span> TO <span class="hljs-comment">DISK</span>;
</pre>

<p>
	حيث استخدمنا الأمر <code>MYSQL</code> بدل <code>ADMIN</code> عند تحديث قيمة المتغير، لأننا نتعامل هنا مع متغيرات إعداد MySQL.
</p>

<p>
	وهكذا تم إعداد ProxySQL بحساب المستخدم المراقب، وسيتم في الخطوة التالية إضافة عُقد MySQL إلى ProxySQL.
</p>

<h2>
	الخطوة الخامسة- إضافة عُقد MySQL إلى ProxySQL
</h2>

<p>
	لجعل ProxySQL مدركاً لعُقد MySQL، يجب إخباره بطريقة توزُّع هذه العُقد في المجموعات المضيفة، والتي هي عبارة عن مجموعة محددة من العُقد. وتعرَّف كل مجموعة مضيفة برقم موجب مثل 1 أو 2. حيث تُستخدم المجموعات المضيفة من أجل توجيه استعلامات SQL المختلفة إلى مجموعات مختلفة من المضيفات عند قيام ProxySQL بتوجيه الاستعلامات.
</p>

<p>
	يتم في إعدادات التناسخ الثابتة تعيين المجموعات المضيفة بشكل اعتباطي، غير أن مجموعة التناسخ المتماثل الخاصة بالخادم ProxySQL تقوم آليًا بتقسيم جميع العُقد الموجودة فيها إلى أربع مجموعات مضيفة وذلك حسب حالتها كما يلي:
</p>

<ul>
<li>
		مجموعة عُقد الكتابة: وهي عبارة عن مجموعة عُقد MySQL التي تقبل الاستعلامات الخاصة بتغيير البيانات. حيث يراعي ProxySQL المحافظة على العدد الأعظمي المعرَّف من العقد الرئيسية في هذه المجموعة.
	</li>
	<li>
		مجموعة عُقد الكتابة الاحتياطية: وهي كذلك الأمر مجموعة عُقد MySQL التي تقبل الاستعلامات الخاصة بتغيير البيانات، غير أنه لا يتم تعيينها كعقد كتابة إلا في حال فشل أحد عُقد مجموعة الكتابة. حيث يضع ProxySQL في هذه المجموعة العُقد الرئيسة المتبقية عند تجاوز عدد العُقد الرئيسية العدد الأعظمي المطلوب في مجموعة الكتابة.
	</li>
	<li>
		مجموعة عُقد القراءة: وهي مجموعة العُقد التي لا تقبل الاستعلامات الخاصة بتغيير البيانات، ويتم استخدمها فقط لقراءة البيانات. ولا يضع ProxySQL إلا العُقد الثانوية في هذه المجموعة.
	</li>
	<li>
		مجموعة العُقد المفصولة: وتتضمن هذه المجموعة على العُقد الرديئة من حيث الاتصال ونقل البيانات.
	</li>
</ul>
<p>
	إن المعرِّف الرقمي لكل مجموعة مضيفة لا يتم تحديده آليًا، لذا يجب إخبار ProxySQL بالمعرِّف الرقمي الذي سيتم استخدامه لكل مجموعة. سنستخدم في حالتنا هنا المعرِّف 1 لمجموعة العُقد المفصولة، و المعرِّف 2 لمجموعة عُقد الكتابة، والمعرِّف 3 لمجموعة عُقد القراءة، والمعرِّف 4 لمجموعة عُقد الكتابة الاحتياطية. ولتطبيق هذه المعرّفات، سنقوم بإنشاء صف بهذه المتغيرات (المجموعات المضيفة) وقيمها الموافقة (المعرّفات الرقمية) في جدول الإعدادات <code>mysql_group_replication_hostgroups</code>، وذلك بتنفيذ الأمر التالي في موجه أوامر الواجهة التخاطبية لإدارة ProxySQL:
</p>

<pre class="ipsCode">
ProxySQLAdmin&gt; 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 (<span class="hljs-number">2</span>، <span class="hljs-number">4</span>، <span class="hljs-number">3</span>، <span class="hljs-number">1</span>، <span class="hljs-number">1</span>، <span class="hljs-number">3</span>، <span class="hljs-number">1</span>، <span class="hljs-number">100</span>);
</pre>

<p>
	تم في الأمر السابق إعداد متغيرات إضافية ضمن صف هي:
</p>

<ul>
<li>
		<code>active</code>: وهو المتغيّر الخاص بتمكين ProxySQL من مراقبة المجموعات المضيفة، حيث تم إسناده بالقيمة 1 (تمكين).
	</li>
	<li>
		<code>max_writers</code>: وهو المتغير الخاص بتحديد العدد الأعظمي من عُقد الكتابة، حيث تم إسناده بالقيمة 3 كون مجموعة التناسخ المتماثل الخاصة بنا من النوع multi-primary، أي قمنا بتعيين جميع العُقد الثلاثة كعُقد كتابة.
	</li>
	<li>
		<code>writer_is_also_reader</code>: يُستخدم لتفعيل القراءة في عُقد الكتابة. حيث تم إسناده بالقيمة 1 وذلك لإعلام ProxySQL باستخدام جميع عُقد القراءة كعُقد كتابة أيضًا.
	</li>
	<li>
		<code>max_transactions_behind</code>: يُستخدم لتحديد العدد الأعظمي من محاولات الاتصال قبل تصنيف العُقدة كعُقدة مفصولة.
	</li>
</ul>
<p>
	<strong>ملاحظة</strong>: بما أننا نستخدم في مثالنا هنا مجموعة التناسخ المتماثل ذات العُقد الرئيسية المتعددة والتي تستطيع جميع عُقدها الكتابة إلى قاعدة البيانات، لذا سوف نوازن تحميل جميع استعلامات SQL عبر مجموعة عُقد الكتابة. أما في الأنواع الأخرى من مجموعات التناسخ المتماثل، يقوم التقسيم بين عُقد الكتابة (الرئيسية) وعُقد القراءة (الثانوية)، بتوجيه استعلامات القراءة إلى مجوعات مضيفة مختلفة عن المجموعات المضيفة الخاصة باستعلامات الكتابة، غير أن ProxySQL لا يقوم بمعملية التوجيه هذه آليًا، لذا يجب في هذه الحالة إعداد توجيه الاستعلامات باستخدام القواعد.
</p>

<p>
	بما أن ProxySQL يعلم الآن طريقة توَّزع عُقد MySQL ضمن المجموعات المضيفة، لذا أصبح بمقدورنا الآن إضافة خوادم MySQL الموافقة لهذه العُقد إلى قائمة الخوادم المرتبطة بالخادم الوكيل ProxySQL. وذلك من خلال إدخال <code>INSERT</code> عنوان IP واسم المجموعة المضيفة الأولية لكل خادم إلى الجدول <code>mysql_servers</code>، والمتضمّن على لائحة بخوادم MySQL التي يستطيع ProxySQL التفاعل معها. وذلك بتنفيذ الأوامر التالية في موجه أوامر الواجهة التخاطبية لإدارة ProxySQL بعد استبدال عناوين IP الخوادم بالقيمة الحقيقية:
</p>

<pre class="ipsCode">
ProxySQLAdmin&gt; INSERT INTO mysql_servers(hostgroup_id، hostname، port) VALUES (<span class="hljs-number">2</span>، '<span class="hljs-number">203.0</span><span class="hljs-number">.113</span><span class="hljs-number">.1</span>'، <span class="hljs-number">3306</span>);
ProxySQLAdmin&gt; INSERT INTO mysql_servers(hostgroup_id، hostname، port) VALUES (<span class="hljs-number">2</span>، '<span class="hljs-number">203.0</span><span class="hljs-number">.113</span><span class="hljs-number">.2</span>'، <span class="hljs-number">3306</span>);
ProxySQLAdmin&gt; INSERT INTO mysql_servers(hostgroup_id، hostname، port) VALUES (<span class="hljs-number">2</span>، '<span class="hljs-number">203.0</span><span class="hljs-number">.113</span><span class="hljs-number">.3</span>'، <span class="hljs-number">3306</span>);
</pre>

<p>
	حيث أُسنِدت القيمة 2 للمعامل <code>hostgroup_id</code> لجعل جميع هذه الخوادم عُقد كتابة، كما تمّ تعيين المنفذ 3306 لجميع خوادم MySQL. ولكي يأخذ هذا التحديث حيّز التنفيذ، يجب تطبيقه على طبقة وقت التشغيل ثم حفظه في طبقة القرص، وذلك بتنفيذ الأوامر التالية في موجه أوامر الواجهة التخاطبية لإدارة ProxySQL:
</p>

<pre class="ipsCode">
ProxySQLAdmin&gt; LOAD MYSQL <span class="hljs-keyword">VARIABLES</span> TO <span class="hljs-comment">RUNTIME</span>;
ProxySQLAdmin&gt; SAVE MYSQL <span class="hljs-keyword">VARIABLES</span> TO <span class="hljs-comment">DISK</span>;
</pre>

<p>
	سيقوم ProxySQL الآن بتوزيع عُقد MySQL الخاصة بنا ضمن المجموعات المضيفة كما هو محدد. وللتأكد من ذلك سنقوم بالاستعلام <code>SELECT</code> عن الجدول <code>runtim330e_mysql_servers</code> والذي يعرض الحالة الآنية لقائمة خوادم MySQL المرتبطة بالخادم ProxySQL، وذلك بتنفيذ الأمر التالي:
</p>

<pre class="ipsCode">
ProxySQLAdmin&gt; LOAD MYSQL VARIABLES TO RUNTIME;

<span class="hljs-section">Output
+--------------+-------------+--------+</span>
<span class="hljs-section">| hostgroup_id | hostname    | status |
+--------------+-------------+--------+</span>
| 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 |
<span class="hljs-section">| 3            | 203.0.113.3 | ONLINE |
+--------------+-------------+--------+</span>
6 rows in set (0.01 sec)
</pre>

<p>
	نلاحظ من الجدول أنه تم عرض جميع الخوادم في كل من المجموعة المضيفة ذات المعرِّف 2 والمجموعة المضيفة ذات المعرِّف 3، وهذا يدلّ على أن جميع الخوادم هي عُقد كتابة وقراءة في نفس الوقت. كما نلاحظ أن جميع الخوادم بحالة <code>ONLINE</code> أي أنها جميعها بحالة عمل.
</p>

<p>
	لكن قبل أن نتمكن من استعمالها، يجب علينا إعداد متطلبات ولوج المستخدم إلى قاعدة البيانات MySQL في كل عُقدة.
</p>

<h2>
	الخطوة السادسة- إنشاء مستخدمي قاعدة البيانات MySQL
</h2>

<p>
	يلعب ProxySQL دور موازن تحميل، حيث يقوم المستخدمون بالاتصال بالخادم ProxySQL والذي يقوم بدوره بتمرير هذا الاتصال إلى عُقدة MySQL المختارة. هذا ويتصل ProxySQL بكل عُقدة عن طريق متطلبات الولوج التي استخدمها المستخدم للدخول إلى ProxySQL.
</p>

<p>
	لنتمكن من الولوج إلى قواعد البيانات الكائنة في عُقد مجموعة التناسخ، نحتاج لإنشاء حساب مستخدم بنفس متطلبات الولوج الخاصة بالخادم ProxySQL ومنح هذا المستخدم الصلاحيات الضرورية. كما هو الحال في الخطوة الثالثة، يجب أن تُطبّق الخطوات التالية على عضو وحيد من مجموعة التناسخ المتماثل، حيث يمكننا اختيار أي عضو نريد.
</p>

<p>
	ننتقل إلى موجه أوامر MySQL، ثم نُنشئ مستخدم جديد اسمه <code>playgrounduser</code> وكلمة سره <code>playgrounduser</code>، وذلك بتنفيذ الأمر التالي:
</p>

<pre class="ipsCode">
(member1)mysql&gt; <span class="hljs-keyword">CREATE</span> USER <span class="hljs-string">'playgrounduser'</span>@<span class="hljs-string">'%'</span> IDENTIFIED <span class="hljs-keyword">BY</span> <span class="hljs-string">'playgroundpassword'</span>;
</pre>

<p>
	ثم نمنح هذا المستخدم صلاحيات الولوج الكاملة إلى قاعدة البيانات <code>playground</code>، وذلك بتنفيذ الأمر التالي في موجه أوامر MySQL:
</p>

<pre class="ipsCode">
(member1)mysql&gt; GRANT <span class="hljs-literal">ALL</span> PRIVILEGES <span class="hljs-keyword">on</span> playground.* <span class="hljs-keyword">to</span> <span class="hljs-string">'playgrounduser'</span>@<span class="hljs-string">'%'</span>;
</pre>

<p>
	ثم نُطبِّق التعديلات، وننهي موجه أوامر MySQL كما يلي:
</p>

<pre class="ipsCode">
(<span class="hljs-name">member1</span>)mysql&gt; FLUSH PRIVILEGES<span class="hljs-comment">;</span>
(<span class="hljs-name">member1</span>)mysql&gt; EXIT<span class="hljs-comment">;</span>
</pre>

<p>
	للتأكّد من أنه تم إنشاء المستخدم بشكل صحيح، سنقوم باختبار قدرته على الولوج إلى قاعدة البيانات الكائنة في عُقدة MySQL بواسطة متطلبات الولوج التي تم إعدادها، وذلك بإعادة فتح موجه أوامر لينكس والدخول إلى موجه أوامر MySQL بحساب المستخدم الذي تم إنشائه، حيث سيطلب موجه الأوامر إدخال كلمة السر الخاصة بهذا المستخدم:
</p>

<pre class="ipsCode">
<span class="hljs-variable">$ </span>mysql -u playgrounduser -p
</pre>

<p>
	وبعد نجاح الدخول إلى موجه أوامر MySQL بحساب المستخدم <code>playgrounduser</code>، ننفذ استعلام تجريبي على قاعدة البيانات playground، وذلك كما يلي:
</p>

<pre class="ipsCode">
(member1)mysql&gt; SHOW TABLES FROM playground;

<span class="hljs-section">Output
+----------------------+</span>
<span class="hljs-section">| Tables_in_playground |
+----------------------+</span>
<span class="hljs-section">| equipment            |
+----------------------+</span>
1 row in set (0.00 sec)
</pre>

<p>
	فنلاحظ ظهور لائحة الجداول الموجودة في قاعدة البيانات، حيث تحوي على الجدول <code>equipment</code> الذي تم إنشائه سابقًا، مما يدل على أنه تم إنشاء المستخدم بشكل صحيح على عُقد MySQL.
</p>

<p>
	نستطيع الآن إنهاء موجه أوامر MySQL بتنفيذ الأمر <code>EXIT</code>، لكننا سنُبقي عليه متصلًا بالخادم لاستخدامه لاحقًا في تنفيذ اختبارات الخطوة الأخيرة.
</p>

<p>
	نحتاج الآن لإنشاء مستخدم موافق في خادم ProxySQL.
</p>

<h2>
	الخطوة السابعة- إنشاء مستخدم ProxySQL
</h2>

<p>
	إن آخر خطوة في الإعدادات هو سماح الاتصال بالخادم ProxySQL باستخدام حساب المستخدم <code>playgrounduser</code>، ومرور هذا الاتصال عبره إلى عُقد MySQL.
</p>

<p>
	لتحقيق ذلك نحتاج لإعداد المتغيرات الموجودة في الجدول <code>mysql_users</code> والتي تحتفظ بمعلومات حساب المستخدم. وذلك بإدخال اسم المستخدم (في حالتنا <code>playgrounduser</code>) وكلمة مروره ومعرِّف المجموعة المضيفة الافتراضية (في حالتنا المعرّف 2 الموافق لمجموعة الكتابة) في قاعدة بيانات الإعدادات، من خلال موجه أوامر الواجهة التخاطبية لإدارة ProxySQL:
</p>

<pre class="ipsCode">
ProxySQLAdmin&gt; INSERT INTO mysql_users(<span class="hljs-name">username</span>، password، default_hostgroup) VALUES ('playgrounduser'، 'playgroundpassword'، <span class="hljs-number">2</span>)<span class="hljs-comment">;</span>
</pre>

<p>
	ولكي يأخذ هذا التحديث حيّز التنفيذ، يجب تطبيقه على طبقة وقت التشغيل ثم حفظه في طبقة القرص، وذلك بتنفيذ الأوامر التالية في موجه أوامر الواجهة التخاطبية لإدارة ProxySQL:
</p>

<pre class="ipsCode">
ProxySQLAdmin&gt; LOAD MYSQL <span class="hljs-keyword">VARIABLES</span> TO <span class="hljs-comment">RUNTIME</span>;
ProxySQLAdmin&gt; SAVE MYSQL <span class="hljs-keyword">VARIABLES</span> TO <span class="hljs-comment">DISK</span>;
</pre>

<p>
	للتأكد من أننا قادرين على الاتصال بقاعدة بيانات عُقد MySQL باستخدام حساب المستخدم الذي تم إنشاؤه، سنقوم بفتح نافذة موجه أوامر لينكس أخرى ثم نتصل بخادم ProxySQL باستخدام قناة الاتصال <abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">SSH</abbr>، مع إبقاء موجه أوامر الواجهة التخاطبية لإدارة ProxySQL لأننا سنحتاجه لاحقًا.
</p>

<pre class="ipsCode">
<span class="hljs-variable">$ </span><abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">ssh</abbr> sammy<span class="hljs-variable">@your_proxysql_server_ip_1</span>
</pre>

<p>
	يتنصّت ProxySQL على المنفذ 6033 للاتصالات القادمة من العملاء، لذا سنحاول الاتصال بقاعدة البيانات الحقيقية (ليس بالواجهة الإدارية) باستخدام اسم المستخدم <code>playgrounduser</code> وكلمة مروره<code>playgroundpassword</code> (التي سيطلبها موجه الأوامر) والمنفذ 6033:
</p>

<pre class="ipsCode">
$ mysql -u playgrounduser -p -h <span class="hljs-number">127.0</span><span class="hljs-number">.0</span><span class="hljs-number">.1</span> -P <span class="hljs-number">6033</span> --prompt='ProxySQLClient&gt; '
</pre>

<p>
	حيث تم استبدال الموجه الافتراضي بالموجه <code>ProxySQLClient&gt;‎</code> وذلك من أجل تمييزه عن موجه الواجهة التخاطبية لإدارة ProxySQL، كونه سنستخدم كلاهما في الإعدادات النهائية.
</p>

<p>
	وعند نجاح عملية الاتصال سيظهر موجه الأوامر <code>ProxySQLClient&gt;‎</code> للدلالة على أن الخادم ProxySQL قد قبل حساب المستخدم <code>playgrounduser</code>:
</p>

<pre class="ipsCode">
ProxySQL client prompt
Welcome to the MySQ<span class="hljs-class">L monitor.  Commands end with ;</span><span class="hljs-built_in"> or </span>\g.
Your MySQL connection id is 31
Server version: 5.5.30 (ProxySQL)

Copyright (c) 2000، 2017، Oracle<span class="hljs-built_in"> and/or </span>its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation<span class="hljs-built_in"> and/or </span>its
affiliates. Other names may be trademarks of their respective owners.

Type 'help;'<span class="hljs-built_in"> or </span>'\h' for help.Type '\c' to clear the current input statement.

ProxySQLClient&gt;
</pre>

<p>
	سنقوم بتنفيذ تعبير برمجي بسيط للتأكد من أن الخادم ProxySQL سيتصل بأحد عُقد MySQL، حيث يقوم هذا التعبير البرمجي بالاستعلام في قاعدة البيانات عن اسم المضيف الذي يعمل عليه الخادم، وتكون نتيجة تنفيذ هذا التعبير عبارة عن خرج وحيد يتضمن على اسم مضيف الخادم:
</p>

<pre class="ipsCode">
ProxySQLClient&gt; SELECT @@hostname;
<span class="hljs-section">Output
+------------+</span>
<span class="hljs-section">| @@hostname |
+------------+</span>
<span class="hljs-section">| member1    |
+------------+</span>
1 row in set (0.00 sec)
</pre>

<p>
	سيتم بناء على إعداداتنا توجيه الاستعلام من قبل الخادم ProxySQL إلى واحد من عُقد MySQL الثلاث المُسندة للمجموعة المضيفة الخاصة بالكتابة. وتكون نتيجة الاستعلام <code>member1</code> والذي هو أحد مضيفات عُقد MySQL.
</p>

<p>
	وهكذا تم الانتهاء من الإعدادات التي تسمح بعمل ProxySQL كموازن تحميل للاتصالات بين عُقد MySQL.
</p>

<p>
	سنقوم في الخطوة الثامنة والأخيرة بالتحقق من قدرة ProxySQL على تنفيذ التعابير البرمجية الخاصة بالقراءة والكتابة في قاعدة البيانات حتى في حال فشل أحد العُقد.
</p>

<h2>
	الخطوة الثامنة- التحقق من إعدادات ProxySQL
</h2>

<p>
	لقد تحققنا سابقًا من أن الاتصال يعمل بشكل سليم بين ProxySQL وعُقد MySQL، لذا ستكون الاختبارات الأخيرة للتأكُّد من أن أذونات قاعدة البيانات تسمح بتنفيذ التعابير البرمجية الخاصة بالقراءة والكتابة القادمة من الخادم ProxySQL، والتأكُّد من أن هذه التعابير قابلة للتنفيذ حتى في حال فشل بعض عُقد المجموعة.
</p>

<p>
	سنقوم بتنفيذ تعبير القراءة <code>SELECT</code> في موجه أوامر عميل ProxySQL للتحقق من قدرتنا على قراءة البيانات من قاعدة البيانات <code>playground</code>، وذلك كما يلي:
</p>

<pre class="ipsCode">
ProxySQLClient&gt; SELECT * FROM playground.equipment;
<span class="hljs-section">Output
+----+--------+-------+--------+</span>
<span class="hljs-section">| id | type   | quant | color  |
+----+--------+-------+--------+</span>
|  3 | slide  |     2 | blue   |
| 10 | swing  |    10 | yellow |
<span class="hljs-section">| 17 | seesaw |     3 | green  |
+----+--------+-------+--------+</span>
3 rows in set (0.00 sec)
</pre>

<p>
	نلاحظ أن خرج تنفيذ التعبير السابق عبارة عن جدول <code>equipment</code> يحوي على ثلاث مكونات، والذي تم إنشاؤه سابقاً في قاعدة البيانات <code>playground</code>، وهذا يدل على نجاح عملية القراءة من قاعدة بيانات MySQL عن طريق الخادم ProxySQL.
</p>

<p>
	والآن سنحاول الكتابة في قاعدة البيانات، وذلك بتنفيذ تعبير الكتابة <code>INSERT</code> لكتابة بيانات جديدة في الجدول <code>equipment</code> الموجود ضمن قاعدة البيانات <code>playground</code>، وذلك كما يلي:
</p>

<pre class="ipsCode" id="ips_uid_4196_10">
ProxySQLClient&gt; INSERT INTO playground.equipment (type، quant، color) VALUES ("drill"، 5، "red");

</pre>

<p>
	وللتحقق من أنه تم كتابة البيانات السابقة في قاعدة البيانات playground، نعيد تنفيذ تعبير القراءة SELECT السابق كما يلي:
</p>

<pre class="ipsCode" id="ips_uid_4196_12">
ProxySQLClient&gt; 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)</pre>

<p>
	نلاحظ من الخرج ظهور مكون جديد في الجدول <code>equipment</code> الموجود في قاعدة البيانات، وهذا يدل على نجاح عملية الكتابة في قاعدة بيانات MySQL عن طريق الخادم ProxySQL.
</p>

<p>
	وهكذا تأكّدنا من قدرة الخادم ProxySQL على استخدام قاعدة البيانات بشكل كامل، لكن ماذا يحصل في حال فشل أحد خوادم MySQL.
</p>

<p>
	سنقوم الآن بمحاكاة فشل أحد خوادم MySQL، وذلك بإيقاف عملية <code>mysql</code> من موجه أوامر أحد خوادم MySQL كما يلي:
</p>

<pre class="ipsCode">
$ systemctl <span class="hljs-built_in">stop</span> mysql
</pre>

<p>
	بعد توقف أحد خوادم MySQL، سنحاول ثانيةً الاستعلام عن البيانات الموجودة في الجدول equipment من موجه أوامر عميل ProxySQL كما يلي:
</p>

<pre class="ipsCode">
ProxySQLClient&gt; <span class="hljs-keyword">SELECT</span> * <span class="hljs-keyword">FROM</span> playground.equipment;
</pre>

<p>
	فنلاحظ أن الخرج لم يتغير، وهذا يدل على أن ProxySQL لاحظ فشل أحد عُقد MySQL، وقام بالانتقال إلى عُقدة أخرى سليمة لتنفيذ عملية الاستعلام عن البيانات الموجودة في قاعدة بيانات MySQL.
</p>

<p>
	هذا ويمكننا التحقق من ذلك عن طريق الاستعلام عن الجدول <code>runtime_mysql_servers</code> من موجه أوامر الواجهة التخاطبية لإدارة ProxySQL، كما ورد في الخطوة الخامسة:
</p>

<pre class="ipsCode">
ProxySQLAdmin&gt; SELECT hostgroup<span class="hljs-emphasis">_id، hostname، status FROM runtime_</span>mysql<span class="hljs-emphasis">_servers;

</span><span class="hljs-section">Output
+--------------+-------------+---------+</span>
<span class="hljs-section">| hostgroup_id | hostname    | status  |
+--------------+-------------+---------+</span>
| 1            | 203.0.113.1 | SHUNNED |
| 2            | 203.0.113.2 | ONLINE  |
| 2            | 203.0.113.3 | ONLINE  |
| 3            | 203.0.113.2 | ONLINE  |
<span class="hljs-section">| 3            | 203.0.113.3 | ONLINE  |
+--------------+-------------+---------+</span>
6 rows in set (0.01 sec)
</pre>

<p>
	نلاحظ من الخرج أن عُقدة MySQL التي قمنا بإيقافها قد أصبحت <code>SHUNNED</code>، وهذا يعني أنها غير قابلة للوصول مؤقتًا، لذا سيتم توزيع كل النقل بين العُقدتين المتبقيتين بحالة عمل.
</p>

<p>
	سيقوم ProxySQL بمراقبة حالة العُقدة المتوقفة عن العمل بشكل مستمر، ويعيدها للحالة <code>online</code> في حال عادت للعمل، أو يعتبرها مفصولة <code>offline</code> في حال تجاوزت زمن الانتظار المحدد في الخطوة الخامسة (في المتغير <code>max_transactions_behind</code>).
</p>

<p>
	سنقوم الآن باختبار مراقبة ProxySQL لحالة عُقد MySQL، وذلك بإعادة تشغيل خادم MySQL المتوقّف، وبالتالي إعادة العُقدة المتوقّفة إلى العمل ثانيةً:
</p>

<pre class="ipsCode">
$ systemctl <span class="hljs-literal">start</span> mysql
</pre>

<p>
	ثم ننتظر قليلًا ونعيد الاستعلام عن الجدول <code>runtime_mysql_servers</code> من موجه أوامر الواجهة التخاطبية لإدارة ProxySQL:
</p>

<pre class="ipsCode">
ProxySQLAdmin&gt; SELECT hostgroup<span class="hljs-emphasis">_id، hostname، status FROM runtime_</span>mysql<span class="hljs-emphasis">_servers;

</span><span class="hljs-section">Output
+--------------+-------------+--------+</span>
<span class="hljs-section">| hostgroup_id | hostname    | status |
+--------------+-------------+--------+</span>
| 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 |
<span class="hljs-section">| 3            | 203.0.113.3 | ONLINE |
+--------------+-------------+--------+</span>
6 rows in set (0.01 sec)
</pre>

<p>
	نلاحظ من الخرج أن ProxySQL لاحظ فورًا عودة العُقدة للعمل، وقام بإعادة حالتها إلى <code>ONLINE</code>. يمكنك إعادة هذا الاختبار على عُقدة أخرى (أو اثنين منها)، والتحقق من أن وجود عُقدة واحدة على الأقل بحالة عمل، كافي لاستخدام قاعدة البيانات بحرية في عمليتي القراءة والكتابة.
</p>

<h2>
	ملخص
</h2>

<p>
	تم في هذه المقالة شرح طريقة إعداد الخادم الوكيل ProxySQL لموازنة تحميل استعلامات SQL عبر العديد من عُقد MySQL القادرة على الكتابة ضمن بنية مجموعة التناسخ المتماثل ذات العُقد الرئيسية المتعددة. حيث يساعد هذا النوع من الإعدادات على تحسين أداء قواعد البيانات الكثيرة الاستخدام، عن طريق توزيع الحمل عبر العديد من الخوادم، كما توفر قابلية الانتقال الآلي إلى الخوادم المتاحة عند فشل أحدها.
</p>

<p>
	لم يتم في هذه المقالة تغطية إلاّ البنية القائمة على عُقدة واحدة كمثال. إلا أن إمكانيات ProxySQL الجبارة في الحفاظ على الاستعلامات والتوجيه وتحليل الأداء تعمل كذلك الأمر على الكثير من البنى الأخرى. يمكنك الاضطلاع على المزيد حول ميزات ProxySQL وطريقة استخدامه في حل العديد من مشاكل إدارة قواعد البيانات في <a href="http://proxysql.com/blog/" rel="external nofollow">مدونة ProxySQL الرسمية</a>.
</p>

<p>
	ترجمة المقال بتصرف للمقال <a href="https://www.digitalocean.com/community/tutorials/how-to-use-proxysql-as-a-load-balancer-for-mysql-on-ubuntu-16-04" rel="external nofollow">How to Use ProxySQL as a Load Balancer for MySQL on Ubuntu 16.04</a> لصاحبته Mateusz Papiernik
</p>
]]></description><guid isPermaLink="false">429</guid><pubDate>Sun, 21 Jul 2019 13:00:00 +0000</pubDate></item><item><title>&#x643;&#x64A;&#x641; &#x62A;&#x631;&#x627;&#x642;&#x628; &#x623;&#x645;&#x646; &#x627;&#x644;&#x646;&#x638;&#x627;&#x645; &#x627;&#x644;&#x62E;&#x627;&#x635; &#x628;&#x643; &#x628;&#x627;&#x633;&#x62A;&#x639;&#x645;&#x627;&#x644; osquery &#x639;&#x644;&#x649; Ubuntu 16.04</title><link>https://academy.hsoub.com/devops/linux/%D9%83%D9%8A%D9%81-%D8%AA%D8%B1%D8%A7%D9%82%D8%A8-%D8%A3%D9%85%D9%86-%D8%A7%D9%84%D9%86%D8%B8%D8%A7%D9%85-%D8%A7%D9%84%D8%AE%D8%A7%D8%B5-%D8%A8%D9%83-%D8%A8%D8%A7%D8%B3%D8%AA%D8%B9%D9%85%D8%A7%D9%84-osquery-%D8%B9%D9%84%D9%89-ubuntu-1604-r428/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2020_09/thumbnail.png.a85fed885deddd745e762483c88c8420.png" /></p>

<p>
	إنَّ osquery عبارة عن أداة أمنية مفتوحة المصدر دورها تحويل نظام تشغيل بأكمله إلى قاعدة بيانات ضخمة، مع جداول يُمكنك استعلامها باستعمال جمل مُشابهة لجمل SQL. يُمكنك بهذه الاستعلامات مراقبة صلاحيّة الملفات، الاطلاع على حالة وإعدادات الجدار الناري، القيام بتدقيقات أمنية على الخادوم الهدف وغير ذلك.
</p>

<p>
	التطبيق عابر للمنصّات مع دعم للنسخ الجديدة من macOS، Windows 10، CentOS وUbuntu. تُوصف رسميا بأنّها "إطار عمل يحتوي على مجموعة من الأدوات المبنية على SQL لمراقبة نظام التّشغيل والحصول على الإحصائيات" وقد كانت بداية الإطار من شركة Facebook.
</p>

<p>
	يُمكنك باستخدام osquery تنفيذ أوامر مثل <code>select * from logged_in_users ;‎</code> على الخادوم الخاصّ بك لتحصل على نتيجة مُشابهة لما يلي:
</p>

<pre class="ipsCode">
+-----------+----------+-------+------------------+------------+------+
|<span class="hljs-string"> type      </span>|<span class="hljs-string"> user     </span>|<span class="hljs-string"> tty   </span>|<span class="hljs-string"> host             </span>|<span class="hljs-string"> time       </span>|<span class="hljs-string"> pid  </span>|
+-----------+----------+-------+------------------+------------+------+
|<span class="hljs-string"> login     </span>|<span class="hljs-string"> LOGIN    </span>|<span class="hljs-string"> ttyS0 </span>|<span class="hljs-string">                  </span>|<span class="hljs-string"> 1483580429 </span>|<span class="hljs-string"> 1546 </span>|
|<span class="hljs-string"> login     </span>|<span class="hljs-string"> LOGIN    </span>|<span class="hljs-string"> tty1  </span>|<span class="hljs-string">                  </span>|<span class="hljs-string"> 1483580429 </span>|<span class="hljs-string"> 1549 </span>|
|<span class="hljs-string"> user      </span>|<span class="hljs-string"> root     </span>|<span class="hljs-string"> pts/0 </span>|<span class="hljs-string"> 24.27.68.82      </span>|<span class="hljs-string"> 1483580584 </span>|<span class="hljs-string"> 1752 </span>|
|<span class="hljs-string"> user      </span>|<span class="hljs-string"> sammy    </span>|<span class="hljs-string"> pts/1 </span>|<span class="hljs-string"> 11.11.11.11      </span>|<span class="hljs-string"> 1483580770 </span>|<span class="hljs-string"> 4057 </span>|
|<span class="hljs-string"> boot_time </span>|<span class="hljs-string"> reboot   </span>|<span class="hljs-string"> ~     </span>|<span class="hljs-string"> 4.4.0-57-generic </span>|<span class="hljs-string"> 1483580419 </span>|<span class="hljs-string"> 0    </span>|
|<span class="hljs-string"> runlevel  </span>|<span class="hljs-string"> runlevel </span>|<span class="hljs-string"> ~     </span>|<span class="hljs-string"> 4.4.0-57-generic </span>|<span class="hljs-string"> 1483580426 </span>|<span class="hljs-string"> 53   </span>|
+-----------+----------+-------+------------------+------------+------+
</pre>

<p>
	إن سرَّك ما سبق، فسيُعجبك استعمال osquery كأداة أمنية لمُراقبة النظام واستكشاف الوصول غير المُصرّح له على خادومك الخاصّ.
</p>

<p>
	يُوفّر تنصيب osquery ما يلي من المكونات:
</p>

<ul>
<li>
		<code>osqueryi</code>: صدفة osquery التفاعليّة، للقيام باستعلامات ظرفيّة.
	</li>
	<li>
		<code>osqueryd</code>: عفريت (daemon) لتوقيت وتشغيل الاستعلامات في الخلفيّة.
	</li>
	<li>
		<code>osqueryctl</code>: سكربت مُساعد لاختبار نشرِِ (deployment) أو إعدادِِ لـosquery. يُمكن أن يُستعمَل كذلك عوضا عن مُدير خدمات نظام التّشغيل لتشغيل/إيقاف/إعادة تشغيل <code>osqueryd</code>.
	</li>
</ul>
<p>
	أداتا <code>osqueryi</code> و <code>osqueryd</code> مُستقلّتان عن بعضهما. إذ لا يحتاجان إلى التواصل بينهما. ولا يتواصلان، ويُمكنك استعمال الواحدة دون الأخرى. معظم المعامِلات والخيارات المطلوبة لتشغيل كل واحدة هي نفسها بين الأداتين، ويُمكنك تشغيل <code>osqueryi</code> باستعمال ملفّ إعدادات <code>osqueryd</code> لتتمكّن من تشخيص البيئة دون الحاجة إلى انتقال دائم بين أسطر الأوامر.
</p>

<p>
	سنقوم في هذا الدّرس بما يلي:
</p>

<ul>
<li>
		تثبيت osquery
	</li>
	<li>
		<p>
			ضبط الأجزاء التي يحتاج إليها osquery في نظام التّشغيل (مثل Rsyslog)، وذلك لكي يعمل osquery بشكل صحيح.
		</p>
	</li>
	<li>
		<p>
			ضبط ملفّ إعدادات يُمكن أن يُستعمل من طرف كل من <code>osqueryi</code> و <code>osqueryd</code>.
		</p>
	</li>
	<li>
		العمل مع حِزمات (packs) osquery، وهي عبارة عن مجموعات من الاستعلامات المسبوقَةِ التّعريف يُمكنك إضافتها إلى المُؤقّت (schedule).
	</li>
	<li>
		تنفيذ استعلامات ظرفيّة باستعمال <code>osqueryi</code> للبحث عن مشاكل أمنيّة.
	</li>
	<li>
		تشغيل العفريت لكي يقوم بتنفيذ الاستعلامات آليّا.
	</li>
</ul>
<p>
	السّجلات المُولَّدة من طرف العفريت <code>osqueryd</code> مُراد بها أن تُنقَل إلى نقاط نهاية (endpoints) خارجيّة تحتاج إلى خبرات إضافيّة لضبطها واستعمالها بشكل صحيح. لن يُغطيّ هذا الدّرس هذا الإعداد، لكنّك ستتعلّم كيفيّة ضبط وتشغيل العفريت وحفظ النتائج محليّا.
</p>

<h2 id="-">
	المُتطلّبات
</h2>

<p>
	لمُتابعة هذا الدّرس، ستحتاج إلى ما يلي:
</p>

<ul>
<li>
		خادوم Ubuntu 16.04 معد بإتباع الخطوات المتواجدة في <a href="https://academy.hsoub.com/devops/servers/%D8%A7%D9%84%D8%A5%D8%B9%D8%AF%D8%A7%D8%AF-%D8%A7%D9%84%D8%A7%D8%A8%D8%AA%D8%AF%D8%A7%D8%A6%D9%8A-%D9%84%D8%AE%D8%A7%D8%AF%D9%88%D9%85-%D8%A3%D9%88%D8%A8%D9%86%D8%AA%D9%88-1404-r4/" rel="">هذا الدّرس</a> ومستخدم إداري بامتيازات sudo غير المستخدم الجذر وجدار ناري.
	</li>
</ul>
<p>
	يجب عليك كذلك أن تمتلك فهما بسيطا لأساسيّات SQL ومعرفة أوليّة حول <a href="https://academy.hsoub.com/devops/security/%D9%85%D9%82%D8%AF%D9%85%D8%A9-%D9%81%D9%8A-%D8%AA%D8%A3%D9%85%D9%8A%D9%86-%D8%AE%D8%A7%D8%AF%D9%88%D9%85-%D9%84%D9%8A%D9%86%D9%83%D8%B3-r51/" rel="">تأمين نظام لينكس </a>.
</p>

<h2 id="-osquery-">
	الخطوة الأولى: تثبيت osquery على الخادوم
</h2>

<p>
	يُمكنك تنصيب osquery عبر تجميعه من الشيفرة المصدرية، أو عبر استعمال مدير الحزم. وبما أنّ المستودع الرسمي لـUbuntu لا يحتوي على حزمة تنصيب، فسيتوجب عليك إضافة المستودع الرسمي لـosquery إلى النظام.
</p>

<p>
	أضف أولًا المفتاح العمومي للمُستودع:
</p>

<pre class="ipsCode">
sudo apt-key adv --keyserver keyserver<span class="hljs-selector-class">.ubuntu</span><span class="hljs-selector-class">.com</span> --recv-keys <span class="hljs-number">1484120</span>AC4E9F8A1A577AEEE97A80C63C9D8B80B
</pre>

<p>
	ثمّ أضف المُستودع:
</p>

<pre class="ipsCode">
sudo<span class="hljs-built_in"> add-apt-repository </span><span class="hljs-string">"deb [arch=amd64] https://osquery-packages.s3.amazonaws.com/xenial xenial main"</span>
</pre>

<p>
	حدّث قاعدة بيانات الحزم:
</p>

<pre class="ipsCode">
sudo apt-<span class="hljs-built_in">get</span> <span class="hljs-keyword">update</span>
</pre>

<p>
	وأخيرا، نصّب osquery:
</p>

<pre class="ipsCode">
sudo apt-<span class="hljs-keyword">get</span> install osquery
</pre>

<p>
	افتراضيّا، لا يُمكن اعتبار osquery مُفيدا للغاية، إذ لا يُعتبر تطبيقا يُمكنك تنصيبه والاستفادة من كامل مزاياه مُباشرة. سواء رغبت باستعمال الصدفة التفاعليّة (interactive shell) أو العفريت، سيتوجّب عليك تمرير بعض المُعاملات والخيارات، إما عبر سطر الأوامر أو عبر ملفّ إعدادات. لعرض المُعاملات والخيارات المتوفّرة للعفريت، اكتب ما يلي:
</p>

<pre class="ipsCode">
osqueryd <span class="hljs-comment">--help</span>
</pre>

<p>
	سيحتوي المُخرج على عشرات المعاملات لسطر الأوامر وخيارات الضّبط. ما يلي جزء من المُخرج عند تجربة الأمر في الخادوم التجريبي الذي استعمِل من أجل هذا المقال:
</p>

<pre class="ipsCode">
osquery 2.1.2, your OS as a high-performance relational database
Usage: osqueryd [OPTION]... 

osquery command line flags:

    -<span class="ruby">-flagfile PATH                           Line-delimited file of additional flags
</span>    -<span class="ruby">-config_check                            Check the format of an osquery config <span class="hljs-keyword">and</span> exit
</span>    -<span class="ruby">-config_dump                             Dump the contents of the configuration
</span>    -<span class="ruby">-config_path VALUE                       Path to JSON config file
</span>    -<span class="ruby">-config_plugin VALUE                     Config plugin name
</span>    -<span class="ruby">-config_tls_endpoint VALUE               <abbr title="Transport Layer Security | بروتوكول أمن طبقة النقل">TLS</abbr>/HTTPS endpoint <span class="hljs-keyword">for</span> config retrieval
</span>    -<span class="ruby">-config_tls_max_attempts VALUE           Number of attempts to <span class="hljs-keyword">retry</span> a <abbr title="Transport Layer Security | بروتوكول أمن طبقة النقل">TLS</abbr> config/enroll request
</span>    -<span class="ruby">-config_tls_refresh VALUE                Optional interval <span class="hljs-keyword">in</span> seconds to re-read configuration
</span>    -<span class="ruby">-daemonize                               Run as daemon (osqueryd only)
</span>
...

...

osquery configuration options (set by config or CLI flags):

    -<span class="ruby">-audit_allow_config                      Allow the audit publisher to change auditing configuration
</span>    -<span class="ruby">-audit_allow_sockets                     Allow the audit publisher to install socket-related rules
</span>    -<span class="ruby">-audit_persist                           Attempt to retain control of audit
</span>    -<span class="ruby">-aws_access_key_id VALUE                 AWS access key ID
</span>    -<span class="ruby">-aws_firehose_period VALUE               Seconds between flushing logs to Firehose (default <span class="hljs-number">10</span>)
</span>    -<span class="ruby">-aws_firehose_stream VALUE               Name of Firehose stream <span class="hljs-keyword">for</span> logging
</span>    -<span class="ruby">-aws_kinesis_period VALUE                Seconds between flushing logs to Kinesis (default <span class="hljs-number">10</span>)
</span>    -<span class="ruby">-aws_kinesis_random_partition_key        Enable random kinesis partition keys
</span>    -<span class="ruby">-aws_kinesis_stream VALUE                Name of Kinesis stream <span class="hljs-keyword">for</span> logging
</span>    -<span class="ruby">-aws_profile_name VALUE                  AWS profile <span class="hljs-keyword">for</span> authentication <span class="hljs-keyword">and</span> region configuration
</span>    -<span class="ruby">-aws_region VALUE                        AWS region</span>
</pre>

<p>
	للاطلاع على المعاملات الإضافيّة المُتوفرة للصدفة التفاعلية فقط، نفّذ ما يلي:
</p>

<pre class="ipsCode">
osqueryi <span class="hljs-comment">--help</span>
</pre>

<p>
	تشغيل <code>osqueryi</code> أسهل طريقة لعرض واستعلام جداول osquery المتوفرة افتراضيّا. على سبيل المثال، شغّل الصّدفة باستعمال الأمر التّالي:
</p>

<pre class="ipsCode">
osqueryi <span class="hljs-comment">--verbose</span>
</pre>

<p>
	سيضعك هذا في صدفة تفاعليّة، وستُلاحظ مُخرجا مُشابها لما يلي:
</p>

<pre class="ipsCode">
I0105 <span class="hljs-number">01</span>:<span class="hljs-number">52</span>:<span class="hljs-number">54.987584</span>  <span class="hljs-number">4761</span> init<span class="hljs-selector-class">.cpp</span>:<span class="hljs-number">364</span>] osquery initialized [version=<span class="hljs-number">2.1</span>.<span class="hljs-number">2</span>]
I0105 <span class="hljs-number">01</span>:<span class="hljs-number">52</span>:<span class="hljs-number">54.987808</span>  <span class="hljs-number">4761</span> extensions<span class="hljs-selector-class">.cpp</span>:<span class="hljs-number">351</span>] Could not autoload extensions: Failed reading: /etc/osquery/extensions<span class="hljs-selector-class">.load</span>
I0105 <span class="hljs-number">01</span>:<span class="hljs-number">52</span>:<span class="hljs-number">54.987944</span>  <span class="hljs-number">4761</span> extensions<span class="hljs-selector-class">.cpp</span>:<span class="hljs-number">364</span>] Could not autoload modules: Failed reading: /etc/osquery/modules<span class="hljs-selector-class">.load</span>
I0105 <span class="hljs-number">01</span>:<span class="hljs-number">52</span>:<span class="hljs-number">54.988209</span>  <span class="hljs-number">4761</span> init<span class="hljs-selector-class">.cpp</span>:<span class="hljs-number">606</span>] Error reading config: config file does not exist: /etc/osquery/osquery<span class="hljs-selector-class">.conf</span>
I0105 <span class="hljs-number">01</span>:<span class="hljs-number">52</span>:<span class="hljs-number">54.988334</span>  <span class="hljs-number">4761</span> events<span class="hljs-selector-class">.cpp</span>:<span class="hljs-number">886</span>] Error registering subscriber: socket_events: Subscriber disabled via configuration
I0105 <span class="hljs-number">01</span>:<span class="hljs-number">52</span>:<span class="hljs-number">54.993973</span>  <span class="hljs-number">4763</span> interface<span class="hljs-selector-class">.cpp</span>:<span class="hljs-number">307</span>] Extension manager service starting: /home/sammy/.osquery/shell<span class="hljs-selector-class">.em</span>
Using <span class="hljs-selector-tag">a</span> virtual database. Need help, type <span class="hljs-string">'.help'</span>
osquery&gt;
</pre>

<p>
	من رسائل المعلومات والأخطاء أعلاه، من الواضح بأنّ بعضا من أجزاء osquery لا تعمل كما يجب . بعض الاستعلامات مثل <code>select * from yara ;‎</code> لن تُرجع أي شيء، ما يعني بأنّ الجدول لا يحتوي على أية بيانات.
</p>

<p>
	بعض الاستعلامات الأخرى مثل <code>select time, severity, message from syslog ;‎</code> تُرجع رسالة كما يلي، ما يُوضّح بأنّنا بحاجة إلى بعض من العمل الإضافي:
</p>

<pre class="ipsCode">
<span class="hljs-selector-tag">W1202</span> <span class="hljs-selector-tag">15</span><span class="hljs-selector-pseudo">:44</span><span class="hljs-selector-pseudo">:48.600539</span>  <span class="hljs-selector-tag">1720</span> <span class="hljs-selector-tag">virtual_table</span><span class="hljs-selector-class">.cpp</span><span class="hljs-selector-pseudo">:492</span>] <span class="hljs-selector-tag">Table</span> <span class="hljs-selector-tag">syslog</span> <span class="hljs-selector-tag">is</span> <span class="hljs-selector-tag">event-based</span> <span class="hljs-selector-tag">but</span> <span class="hljs-selector-tag">events</span> <span class="hljs-selector-tag">are</span> <span class="hljs-selector-tag">disabled</span>
<span class="hljs-selector-tag">W1202</span> <span class="hljs-selector-tag">15</span><span class="hljs-selector-pseudo">:44</span><span class="hljs-selector-pseudo">:48.600587</span>  <span class="hljs-selector-tag">1720</span> <span class="hljs-selector-tag">virtual_table</span><span class="hljs-selector-class">.cpp</span><span class="hljs-selector-pseudo">:499</span>] <span class="hljs-selector-tag">Please</span> <span class="hljs-selector-tag">see</span> <span class="hljs-selector-tag">the</span> <span class="hljs-selector-tag">table</span> <span class="hljs-selector-tag">documentation</span>: <span class="hljs-selector-tag">https</span>:<span class="hljs-comment">//osquery.io/docs/#syslog</span>
</pre>

<p>
	سنقوم بتعديل إعدادات الخادوم الخاصّ بنا لحل هذه المُشكلة.
</p>

<p>
	اخرج من سطر أوامر osquery عبر كتابة ما يلي:
</p>

<pre class="ipsCode">
.<span class="hljs-keyword">exit</span>
</pre>

<p>
	سنقوم في الفقرة التّالية بتعديل الأجزاء من نظام التّشغيل التي يحتاج إليها osquery للعمل بشكل صحيح.
</p>

<h2 id="-osquery-">
	الخطوة الثّانيّة: السّماح لـosquery بالوصول إلى سجلّ النّظام
</h2>

<p>
	سنقوم في هذه الخطوة بتعديل تطبيق syslog الخاص بنظام التشغيل لتمكين osquery من الحصول على واستعلام سجّل النّظام. وفي Ubuntu 16.04، هذا يعني تعديل ملفّ إعدادات Rsyslog. والتعديل الوحيد الذي سيتوجب عليك القيام به هو إضافة بضعة أسطر من الشيفرة إلى ملفّ الإعدادات. كبداية، افتح الملفّ <code>‎/etc/rsyslog.conf</code>:
</p>

<pre class="ipsCode">
sudo nano <span class="hljs-regexp">/etc/</span>rsyslog.conf
</pre>

<p>
	نحتاج إلى إضافة بضعة أسطر من الإعدادات التي ستُحدِّدُ لـRsyslog الأنبوب (pipe) الذي تجِبُ الكتابة إليه، وأيّا من مُعطيات (parameters) syslog يجب كتابتها للأنبوب. افتراضيّا، الأنبوب هو <code>‎/var/osquery/syslog_pipe</code>. سيقوم osquery بعد ذلك بملء جدول <code>syslog</code> الخاصّ به من المعلومات المكتوبة لهذا الأنبوب.
</p>

<p>
	ألحِق ما يلي من الأسطر إلى نهاية الملفّ:
</p>

<pre class="ipsCode">
template(
  name=<span class="hljs-string">"OsqueryCsvFormat"</span>
  type=<span class="hljs-string">"string"</span>
  string=<span class="hljs-string">"%timestamp:::date-rfc3339,csv%,%hostname:::csv%,%syslogseverity:::csv%,%syslogfacility-text:::csv%,%syslogtag:::csv%,%msg:::csv%\n"</span>
)
*.* action(type=<span class="hljs-string">"ompipe"</span> Pipe=<span class="hljs-string">"/var/osquery/syslog_pipe"</span> template=<span class="hljs-string">"OsqueryCsvFormat"</span>)
</pre>

<p>
	احفظ وأغلق الملفّ. لتطبيق التغييرات، أعد تشغيل عفريت syslog:
</p>

<pre class="ipsCode">
<span class="hljs-attribute">sudo systemctl restart rsyslog</span>
</pre>

<p>
	لنُنشئ الآن ملفّ إعدادات يضبط بعض الخيارات الافتراضية ويُوقِّتُ بعض الاستعلامات.
</p>

<h2 id="-osquery">
	الخطوة الثّالثة: إنشاء ملفّ إعدادات osquery
</h2>

<p>
	إنشاء ملفّ إعدادات يُسهِّلُ من عمليّة تشغيل <code>osqueryi</code>.فعوضا عن تمرير عدد كبير من خيارات سطر الأوامر، يُمكن لـ<code>osqueryi</code> قراءة هذه الخيارات من ملفّ إعدادات مُتواجد في المسار <code>‎/etc/osquery/osquery.conf</code>. وبالطّبع، فملفّ الإعدادات سيكون مُتاحا للعفريت كذلك.
</p>

<p>
	يحتوي ملفّ الإعدادات على الاستعلامات التي تحتاج إلى تنفيذها حسب توقيت مُعيّن. لكنّ مُعظم الاستعلامات التي يُمكنك تشغيلها متوفّرة على شكل حزمات (packs). ملفّات الحزمات مُتوفرة في المُجلّد <code>‎/usr/share/osquery/packs</code>.
</p>

<p>
	لا يأتي osquery مُجهّزا بملفّ إعدادات مُسبق، لكنّ هناك نموذج ملفّ إعدادات يُمكنك نسخه إلى <code>/etc/osquery</code> وتعديله. لكنّ ملفّ الإعدادات هذا لا يحتوي على جميع الخيارات التي تحتاج إليها لتشغيله على توزيعة لينكس مثل Ubuntu، لذا سنقوم بإنشاء ملفّنا الخاصّ.
</p>

<p>
	هناك ثلاثة أقسام لملفّ الإعدادات:
</p>

<ul>
<li>
		قائمة بخيارات العفريت وإعدادات المزايا. يُمكن لهذه الإعدادات أن تُقرأ كذلك من طرف <code>osqueryi</code>.
	</li>
	<li>
		قائمة استعلامات موقوتة لتُشغَّل متى ما وَجَبَ ذلك.
	</li>
	<li>
		قائمة حزمات لتُستعمل للتعامل مع استعلامات موقوتة أكثر تحديدا.
	</li>
</ul>
<p>
	ما يلي قائمة من الخيارات التي سنستعملها في ملفّ الإعدادات الخاصّ بنا، ما يعنيه كلّ خيار، والقيم التي سنعيِّنها لهذه الخيارات. تكفي هذه القائمة من الخيارات لتشغيل كل من <code>osqueryi</code> و<code>osqueryd</code> على Ubuntu 16.04 وتوزيعات لينكس الأخرى.
</p>

<ul>
<li>
		<strong>config_plugin</strong>: من أين نُريد osquery أن يقرأ الإعدادات الخاصّة به. بما أنّ الإعدادات تُقرأ من ملفّ على القرص افتراضيّا، فستكون القيمة <code>filesystem</code>.
	</li>
	<li>
		<strong>logger_plugin</strong>: يُحدّد هذا الخيار مكان كتابة نتائج الاستعلامات الموقوتة. سنستعمل القيمة <code>filesystem</code> مُجدّدا.
	</li>
	<li>
		<strong>logger_path</strong>: هذا هو المسار الذي يُؤدّي إلى مُجلّد السّجلات الذي ستجد به ملفّات تحتوي على المعلومات، التنبيهات والأخطاء ونتائج الاستعلامات الموقوتة. القيمة الافتراضيّة هي <code>‎/var/log/osquery</code>.
	</li>
	<li>
		<strong>disable_logging</strong>: سنقوم بتفعيل التّسجيل عبر تحديد القيمة <code>false</code> لهذا الخيار.
	</li>
	<li>
		<strong>log_result_events</strong>: عبر تحديد القيمة <code>true</code> لهذا الخيار، سيُعبّر كل سطر من سجلات النّتائج عن تغيير في الحالة.
	</li>
	<li>
		<strong>schedule_splay_percent</strong>: في حالة تواجد عدد كبير من الاستعلامات الموقوتة في نفس المدة الزمنية، سيقوم هذا الخيار بتمديدها للحد من التأثيرات على أداء الخادوم. القيمة الافتراضيّة هي <code>10</code>، وهي نسبة مئويّة.
	</li>
	<li>
		<strong>pidfile</strong>: المكان الذي سيُكتب فيه مُعرِّف العمليّة (process id) الخاصّ بعفريت osquery. القيمة الافتراضيّة هي <code>‎/var/osquery/osquery.pidfile</code>.
	</li>
	<li>
		<strong>events_expiry</strong>: المُدة الزمنية بالثواني التي سيتم فيها الاحتفاظ بنتائج المُشترك في مخزن osquery. القيمة الافتراضية هي <code>3600</code>.
	</li>
	<li>
		<strong>database_path</strong>: مسار قاعدة بيانات osquery. سنستعمل القيمة الافتراضية <code>‎/var/osquery/osquery.db</code>.
	</li>
	<li>
		<strong>verbose</strong>: مع تفعيل التّسجيل، يُستعمل هذا الخيار لتفعيل أو تعطيل رسائل معلومات مُفصّلة. سنعيّن للخيار القيمة <code>false</code>.
	</li>
	<li>
		<strong>worker_threads</strong>: عدد السلاسل المُستعملة للتعامل مع الاستعلامات. سنترك القيمة الافتراضية <code>2</code>.
	</li>
	<li>
		<strong>enable_monitor</strong>: تفعيل أو تعطيل مراقِب المُؤقّت. سنقوم بتفعيله، أي القيمة <code>true</code>.
	</li>
	<li>
		<strong>disable_events</strong>: يُستعمل هذا الخيار لضبط نظام osquery الخاصّ بالنّشر والاشتراك. نحتاج إلى تفعيله، أي القيمة <code>false</code>.
	</li>
	<li>
		<strong>disable_audit</strong>: يُستعمل لتعطيل استقبال الأحداث (events) من النظام الفرعي المسؤول عن التّدقيق في نظام التّشغيل. نحتاج إلى تفعيله، لذا فالقيمة التي سنستعملها هي <code>false</code>.
	</li>
	<li>
		<strong>audit_allow_config</strong>: السّماح لناشر التّدقيق بتغيير إعدادات التّدقيق. القيمة الافتراضية هي <code>true</code>.
	</li>
	<li>
		<strong>audit_allow_sockets</strong>: يقوم هذا الخيار بالسماح لناشر التّدقيق بتنصيب قواعد مُتعلّقة بالمقابس (socket). القيمة هي <code>true</code>.
	</li>
	<li>
		<strong>host_identifier</strong>: يُستعمَلُ لتعريف المُضيف الذي يُشغّل osquery. عند جمع نتائج من عدّة خوادم، فمن المُفيد التّمكن من التّعرف على الخادوم الذي جاء منه التّسجيل. القيمة تكون إمّا <code>hostname</code> أو <code>uuid</code>. القيمة الافتراضية التي سنعتمد عليها هي <code>hostname</code>.
	</li>
	<li>
		<strong>enable_syslog</strong>: يجب أن تكون قيمة هذا الخيار <code>true</code> ليتمكّن osquery من الحصول على معلومات <code>syslog</code>.
	</li>
	<li>
		<strong>schedule_default_interval</strong>: عند عدم توفير مُدّة لاستعلام موقوت، استعمِل هذه القيمة. سنُعيّن لهذا الخيار القيمَة <code>3600</code> ثانيّة.
	</li>
</ul>
<p>
	سبق لك وأن تعرّفت على كيفيّة عرض جميع مُعاملات سطر الأوامر وخيارات الضّبط المتوفّرة لكل من <code>osqueryi</code> و <code>osqueryd</code>، لكنّ الخيارات أعلاه كافيّة لتشغيل osquery على هذا الخادوم. أنشئ وافتح ملفّ الإعدادات باستخدام الأمر التّالي:
</p>

<pre class="ipsCode">
sudo nano <span class="hljs-regexp">/etc/</span>osquery<span class="hljs-regexp">/osquery.conf</span>
</pre>

<p>
	يعتمد ملفّ الإعدادات على صيغة <a href="https://academy.hsoub.com/programming/javascript/%D8%AA%D8%B9%D9%84%D9%85-json-r604/" rel="">JSON</a>. انسخ ما يلي إلى الملفّ:
</p>

<pre class="ipsCode prettyprint lang-javascript prettyprinted" id="ips_uid_7656_8" style="">
<span class="pun">{</span><span class="pln">
  </span><span class="str">"options"</span><span class="pun">:</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    </span><span class="str">"config_plugin"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"filesystem"</span><span class="pun">,</span><span class="pln">
    </span><span class="str">"logger_plugin"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"filesystem"</span><span class="pun">,</span><span class="pln">
    </span><span class="str">"logger_path"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"/var/log/osquery"</span><span class="pun">,</span><span class="pln">
    </span><span class="str">"disable_logging"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"false"</span><span class="pun">,</span><span class="pln">
    </span><span class="str">"log_result_events"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"true"</span><span class="pun">,</span><span class="pln">
    </span><span class="str">"schedule_splay_percent"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"10"</span><span class="pun">,</span><span class="pln">
    </span><span class="str">"pidfile"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"/var/osquery/osquery.pidfile"</span><span class="pun">,</span><span class="pln">
    </span><span class="str">"events_expiry"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"3600"</span><span class="pun">,</span><span class="pln">
    </span><span class="str">"database_path"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"/var/osquery/osquery.db"</span><span class="pun">,</span><span class="pln">
    </span><span class="str">"verbose"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"false"</span><span class="pun">,</span><span class="pln">
    </span><span class="str">"worker_threads"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"2"</span><span class="pun">,</span><span class="pln">
    </span><span class="str">"enable_monitor"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"true"</span><span class="pun">,</span><span class="pln">
    </span><span class="str">"disable_events"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"false"</span><span class="pun">,</span><span class="pln">
    </span><span class="str">"disable_audit"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"false"</span><span class="pun">,</span><span class="pln">
    </span><span class="str">"audit_allow_config"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"true"</span><span class="pun">,</span><span class="pln">
    </span><span class="str">"host_identifier"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"hostname"</span><span class="pun">,</span><span class="pln">
    </span><span class="str">"enable_syslog"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"true"</span><span class="pun">,</span><span class="pln">
    </span><span class="str">"audit_allow_sockets"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"true"</span><span class="pun">,</span><span class="pln">
    </span><span class="str">"schedule_default_interval"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"3600"</span><span class="pln"> 
  </span><span class="pun">},</span></pre>

<p>
	القسم التّالي من ملفّ الإعدادات هو قسم التوقيت. يُعرَّف كل استعلام عبر مفتاح أو اسم يجب أن يكون فريدا في الملفّ، متبوعا بالاستعلام المُراد تنفيذه والمدّة الزمنية بالثواني. سنقوم بتوقيت استعلام لينظر إلى جدول <code>crontab</code> كلّ 300 ثانيّة. أضف ما يلي إلى ملفّ الإعدادات:
</p>

<pre class="ipsCode prettyprint lang-javascript prettyprinted" id="ips_uid_7656_10" style="">
<span class="pln">  </span><span class="str">"schedule"</span><span class="pun">:</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    </span><span class="str">"crontab"</span><span class="pun">:</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
      </span><span class="str">"query"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"SELECT * FROM crontab;"</span><span class="pun">,</span><span class="pln">
      </span><span class="str">"interval"</span><span class="pun">:</span><span class="pln"> </span><span class="lit">300</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">
  </span><span class="pun">},</span></pre>

<p>
	يُمكنك إضافة أي عدد من الاستعلامات تُريد، أبقِ فقط على الصّيغة الصحيحة لكي لا تحدث أخطاء في التدقيق. على سبيل المثال، لإضافة بضعة استعلامات أخرى، أضف ما يلي من الأسطر:
</p>

<pre class="ipsCode prettyprint lang-javascript prettyprinted" id="ips_uid_7656_12" style="">
<span class="pln">  </span><span class="str">"schedule"</span><span class="pun">:</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    </span><span class="str">"crontab"</span><span class="pun">:</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
      </span><span class="str">"query"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"SELECT * FROM crontab;"</span><span class="pun">,</span><span class="pln">
      </span><span class="str">"interval"</span><span class="pun">:</span><span class="pln"> </span><span class="lit">300</span><span class="pln">
    </span><span class="pun">},</span><span class="pln">
    </span><span class="str">"system_profile"</span><span class="pun">:</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
      </span><span class="str">"query"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"SELECT * FROM osquery_schedule;"</span><span class="pln">
    </span><span class="pun">},</span><span class="pln"> 
    </span><span class="str">"system_info"</span><span class="pun">:</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
      </span><span class="str">"query"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"SELECT hostname, cpu_brand, physical_memory FROM system_info;"</span><span class="pun">,</span><span class="pln">
      </span><span class="str">"interval"</span><span class="pun">:</span><span class="pln"> </span><span class="lit">3600</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">
  </span><span class="pun">},</span></pre>

<p>
	بعد الاستعلامات الموقوتة، يُمكنك إضافة استعلامات خاصّة تُدعى المُزخرفات (decorators)، وهي استعلامات تُضيف بيانات إلى بداية الاستعلامات الموقوتة الأخرى. الاستعلامات المُزخرفة التّالية ستقوم بإضافة المعرّف UUID الخاصّ بالمُضيف الذي يُشغّل osquery واسم المُستخدم في بداية كلّ استعلام موقوت.
</p>

<p>
	أضف ما يلي إلى نهاية الملفّ:
</p>

<pre class="ipsCode prettyprint lang-javascript prettyprinted" id="ips_uid_7656_14" style="">
<span class="pln">  </span><span class="str">"decorators"</span><span class="pun">:</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    </span><span class="str">"load"</span><span class="pun">:</span><span class="pln"> </span><span class="pun">[</span><span class="pln">
      </span><span class="str">"SELECT uuid AS host_uuid FROM system_info;"</span><span class="pun">,</span><span class="pln">
      </span><span class="str">"SELECT user AS username FROM logged_in_users ORDER BY time DESC LIMIT 1;"</span><span class="pln">
    </span><span class="pun">]</span><span class="pln">
  </span><span class="pun">},</span></pre>

<p>
	يُمكننا أخيرا توجيه osquery إلى قائمة من الحزمات التي تحتوي على استعلامات مُحدّدة. يوفّر osquery مجموعة افتراضيّة من الحزمات تجدها في المُجلّد <code>‎/usr/share/osquery/packs</code>. أحد هذه الحزمات مُخصّصة لنظام macOS وبقيّتها لأنظمة لينكس. يُمكنك استعمال الحزمات من مساراتها الافتراضية، ويُمكنك كذلك نسخها إلى المُجلّد <code>‎/etc/osquery</code>.
</p>

<p>
	أضف الأسطر التّالية إلى الملفّ لإنهاء الإعداد:
</p>

<pre class="ipsCode prettyprint lang-javascript prettyprinted" id="ips_uid_7656_16" style="">
<span class="pln">  </span><span class="str">"packs"</span><span class="pun">:</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
     </span><span class="str">"osquery-monitoring"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"/usr/share/osquery/packs/osquery-monitoring.conf"</span><span class="pun">,</span><span class="pln">
     </span><span class="str">"incident-response"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"/usr/share/osquery/packs/incident-response.conf"</span><span class="pun">,</span><span class="pln">
     </span><span class="str">"it-compliance"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"/usr/share/osquery/packs/it-compliance.conf"</span><span class="pun">,</span><span class="pln">
     </span><span class="str">"vuln-management"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"/usr/share/osquery/packs/vuln-management.conf"</span><span class="pln">
  </span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span></pre>

<p>
	لاحظ معقوفة الإغلاق <code>}</code>في الأخير، هذه المعقوفة تُوافق معقوفة الفتح في السطر الأول من بداية الملفّ.
</p>

<p>
	يجب على ملفّ الإعدادات الكامل أن يبدو كما يلي:
</p>

<pre class="ipsCode prettyprint lang-javascript prettyprinted" id="ips_uid_7656_18" style="">
<span class="pun">{</span><span class="pln">
  </span><span class="str">"options"</span><span class="pun">:</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    </span><span class="str">"config_plugin"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"filesystem"</span><span class="pun">,</span><span class="pln">
    </span><span class="str">"logger_plugin"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"filesystem"</span><span class="pun">,</span><span class="pln">
    </span><span class="str">"logger_path"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"/var/log/osquery"</span><span class="pun">,</span><span class="pln">
    </span><span class="str">"disable_logging"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"false"</span><span class="pun">,</span><span class="pln">
    </span><span class="str">"log_result_events"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"true"</span><span class="pun">,</span><span class="pln">
    </span><span class="str">"schedule_splay_percent"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"10"</span><span class="pun">,</span><span class="pln">
    </span><span class="str">"pidfile"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"/var/osquery/osquery.pidfile"</span><span class="pun">,</span><span class="pln">
    </span><span class="str">"events_expiry"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"3600"</span><span class="pun">,</span><span class="pln">
    </span><span class="str">"database_path"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"/var/osquery/osquery.db"</span><span class="pun">,</span><span class="pln">
    </span><span class="str">"verbose"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"false"</span><span class="pun">,</span><span class="pln">
    </span><span class="str">"worker_threads"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"2"</span><span class="pun">,</span><span class="pln">
    </span><span class="str">"enable_monitor"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"true"</span><span class="pun">,</span><span class="pln">
    </span><span class="str">"disable_events"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"false"</span><span class="pun">,</span><span class="pln">
    </span><span class="str">"disable_audit"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"false"</span><span class="pun">,</span><span class="pln">
    </span><span class="str">"audit_allow_config"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"true"</span><span class="pun">,</span><span class="pln">
    </span><span class="str">"host_identifier"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"hostname"</span><span class="pun">,</span><span class="pln">
    </span><span class="str">"enable_syslog"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"true"</span><span class="pun">,</span><span class="pln">
    </span><span class="str">"audit_allow_sockets"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"true"</span><span class="pun">,</span><span class="pln">
    </span><span class="str">"schedule_default_interval"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"3600"</span><span class="pln"> 
  </span><span class="pun">},</span><span class="pln">
  </span><span class="str">"schedule"</span><span class="pun">:</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    </span><span class="str">"crontab"</span><span class="pun">:</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
      </span><span class="str">"query"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"SELECT * FROM crontab;"</span><span class="pun">,</span><span class="pln">
      </span><span class="str">"interval"</span><span class="pun">:</span><span class="pln"> </span><span class="lit">300</span><span class="pln">
    </span><span class="pun">},</span><span class="pln">
    </span><span class="str">"system_profile"</span><span class="pun">:</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
      </span><span class="str">"query"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"SELECT * FROM osquery_schedule;"</span><span class="pln">
    </span><span class="pun">},</span><span class="pln"> 
    </span><span class="str">"system_info"</span><span class="pun">:</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
      </span><span class="str">"query"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"SELECT hostname, cpu_brand, physical_memory FROM system_info;"</span><span class="pun">,</span><span class="pln">
      </span><span class="str">"interval"</span><span class="pun">:</span><span class="pln"> </span><span class="lit">3600</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">
  </span><span class="pun">},</span><span class="pln">
  </span><span class="str">"decorators"</span><span class="pun">:</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    </span><span class="str">"load"</span><span class="pun">:</span><span class="pln"> </span><span class="pun">[</span><span class="pln">
      </span><span class="str">"SELECT uuid AS host_uuid FROM system_info;"</span><span class="pun">,</span><span class="pln">
      </span><span class="str">"SELECT user AS username FROM logged_in_users ORDER BY time DESC LIMIT 1;"</span><span class="pln">
    </span><span class="pun">]</span><span class="pln">
  </span><span class="pun">},</span><span class="pln">
  </span><span class="str">"packs"</span><span class="pun">:</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
     </span><span class="str">"osquery-monitoring"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"/usr/share/osquery/packs/osquery-monitoring.conf"</span><span class="pun">,</span><span class="pln">
     </span><span class="str">"incident-response"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"/usr/share/osquery/packs/incident-response.conf"</span><span class="pun">,</span><span class="pln">
     </span><span class="str">"it-compliance"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"/usr/share/osquery/packs/it-compliance.conf"</span><span class="pun">,</span><span class="pln">
     </span><span class="str">"vuln-management"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"/usr/share/osquery/packs/vuln-management.conf"</span><span class="pln">
  </span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span></pre>

<p>
	احفظ وأغلق الملفّ ثمّ تحقّق من الإعدادات باستعمال الأمر التّالي:
</p>

<pre class="ipsCode">
sudo osqueryctl <span class="hljs-built_in">config</span>-check
</pre>

<p>
	يجب على المُخرج أن يبدو كما يلي:
</p>

<pre class="ipsCode">
I0104 <span class="hljs-number">11</span>:<span class="hljs-number">11</span>:<span class="hljs-number">46.022858</span> <span class="hljs-number">24501</span> rocksdb.<span class="hljs-string">cpp:</span><span class="hljs-number">187</span>] Opening RocksDB <span class="hljs-string">handle:</span> <span class="hljs-regexp">/var/</span>osquery/osquery.db
</pre>

<p>
	إن حدث خطأ ما، فسيحتوي المُخرج على موقع الخطأ لكي تتمكّن من إصلاحه.
</p>

<p>
	بعد إعداد ملفّ إعدادات سليم، يُمكنك الآن الانتقال إلى إعداد حزمة osquery المطلوبة لمُراقبة صلاحيّة الملفّات.
</p>

<h2 id="-osquery-">
	الخطوة الرّابعة: إعداد حزمة osquery المطلوبة لمُراقبة صلاحيّة الملفّات
</h2>

<p>
	مُراقبة صلاحيّة وسلامة الملفات على خادومك من الأجزاء المهمّة في مُراقبة أمن النّظام. ويُوفّر لنا osquery حلّا جاهزا في هذه المسألة. الحزمات التي أضفناها في ملفّ الإعدادات في القسم السّابق عبارة عن حزمات جاهزة. سنقوم في هذا الجزء من الدرس بإضافة حزمة واحدة إضافيّة إلى القائمة، والتي ستحتوي على الاستعلام والتّعليمات التي سيتم استعمالها لمُراقبة صلاحية الملفّات. سنقوم بتسمية الملفّ <code>fim.conf</code>. أنشئ الملفّ وافتحه باستعمال مُحرّر النّصوص الخاصّ بك:
</p>

<pre class="ipsCode">
sudo nano <span class="hljs-regexp">/usr/</span>share<span class="hljs-regexp">/osquery/</span>packs<span class="hljs-regexp">/fim.conf</span>
</pre>

<p>
	سنقوم بإنشاء حزمة لمراقبة أحداث الملفّات في المُجلّدات <code>/home</code>، <code>/etc</code> و<code>‎/tmp</code> كلّ 300 ثانيّة. الضبط الكامل للحزمة متواجد أسفله، انسخه إلى الملفّ:
</p>

<pre class="ipsCode prettyprint lang-javascript prettyprinted" id="ips_uid_7656_20" style="">
<span class="pun">{</span><span class="pln">
  </span><span class="str">"queries"</span><span class="pun">:</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    </span><span class="str">"file_events"</span><span class="pun">:</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
      </span><span class="str">"query"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"select * from file_events;"</span><span class="pun">,</span><span class="pln">
      </span><span class="str">"removed"</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">false</span><span class="pun">,</span><span class="pln">
      </span><span class="str">"interval"</span><span class="pun">:</span><span class="pln"> </span><span class="lit">300</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">
  </span><span class="pun">},</span><span class="pln">
  </span><span class="str">"file_paths"</span><span class="pun">:</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    </span><span class="str">"homes"</span><span class="pun">:</span><span class="pln"> </span><span class="pun">[</span><span class="pln">
      </span><span class="str">"/root/.<abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">ssh</abbr>/%%"</span><span class="pun">,</span><span class="pln">
      </span><span class="str">"/home/%/.<abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">ssh</abbr>/%%"</span><span class="pln">
    </span><span class="pun">],</span><span class="pln">
      </span><span class="str">"etc"</span><span class="pun">:</span><span class="pln"> </span><span class="pun">[</span><span class="pln">
      </span><span class="str">"/etc/%%"</span><span class="pln">
    </span><span class="pun">],</span><span class="pln">
      </span><span class="str">"home"</span><span class="pun">:</span><span class="pln"> </span><span class="pun">[</span><span class="pln">
      </span><span class="str">"/home/%%"</span><span class="pln">
    </span><span class="pun">],</span><span class="pln">
      </span><span class="str">"tmp"</span><span class="pun">:</span><span class="pln"> </span><span class="pun">[</span><span class="pln">
      </span><span class="str">"/tmp/%%"</span><span class="pln">
    </span><span class="pun">]</span><span class="pln">
  </span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span></pre>

<p>
	احفظ وأغلق الملفّ.
</p>

<p>
	لجعل الملفّ الجديد وقواعده مُتوفّرة لـosquery، أضفه إلى قائمة الحزمات في نهاية الملفّ <code>‎/etc/osquery/osquery.conf</code>، افتح الملفّ للتّعديل:
</p>

<pre class="ipsCode">
sudo nano <span class="hljs-regexp">/etc/</span>osquery<span class="hljs-regexp">/osquery.conf</span>
</pre>

<p>
	بعدها عدّل قسم الحزمات لتشمل الملفّ الجديد (الصّف الأول ممّا يلي):
</p>

<pre class="ipsCode prettyprint lang-javascript prettyprinted" id="ips_uid_7656_22" style="">
<span class="pun">...</span><span class="pln">

</span><span class="str">"packs"</span><span class="pun">:</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
     </span><span class="str">"fim"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"/usr/share/osquery/packs/fim.conf"</span><span class="pun">,</span><span class="pln">
     </span><span class="str">"osquery-monitoring"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"/usr/share/osquery/packs/osquery-monitoring.conf"</span><span class="pun">,</span><span class="pln">
     </span><span class="str">"incident-response"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"/usr/share/osquery/packs/incident-response.conf"</span><span class="pun">,</span><span class="pln">
     </span><span class="str">"it-compliance"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"/usr/share/osquery/packs/it-compliance.conf"</span><span class="pun">,</span><span class="pln">
     </span><span class="str">"vuln-management"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"/usr/share/osquery/packs/vuln-management.conf"</span><span class="pln">
  </span><span class="pun">}</span></pre>

<p>
	احفظ وأغلق الملفّ. ولتتأكد من أنّنا لم نرتكب أي خطأ في تعديل الملفّ، تحقّق مُجدّدا:
</p>

<pre class="ipsCode">
sudo osqueryctl <span class="hljs-built_in">config</span>-check
</pre>

<p>
	لنبدأ الآن استعمال <code>osqueryi</code> لاستعلام النّظام.
</p>

<h2 id="-osqueryi-">
	الخطوة الخامسة: استعمال osqueryi لتنفيذ تدقيقات أمنية ظرفيّة
</h2>

<p>
	هناك العديد من الحالات التي يُفيد فيها osquery. سنقوم في هذا القسم بالقيام بمجموعة من التدقيقات الأمنية على النّظام باستعمال الصدفة التّفاعليّة <code>osqueryi</code>. وتذكّر بأنّنا لم نقم بتشغيل عفريت osquery بعد. وهذا من ميّزات osquery الجميلة، إذ تستطيع تنفيذ استعلامات باستعمال <code>osqueryi</code> حتى ولو لم يكن العفريت مُفعّلا، مع استعمال ملفّ الإعدادات الذي أعددناه لضبط البيئة أيضا.
</p>

<p>
	لتشغيل <code>osqueryi</code> مع ملفّ الإعدادات، نفّذ ما يلي:
</p>

<pre class="ipsCode">
<span class="hljs-comment">sudo</span> <span class="hljs-comment">osqueryi</span> <span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-comment">config_path</span> <span class="hljs-comment">/etc/osquery/osquery</span><span class="hljs-string">.</span><span class="hljs-comment">conf</span> <span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-comment">verbose</span>
</pre>

<p>
	<strong>مُلاحظة:</strong> تمرير خيار <code>‎--verbose</code> إلى أمر تشغيل كلّ من <code>osqueryi</code> و<code>osqueryd</code> من أفضل الممارسات لأنّه يُظهر أية أخطاء أو تنبيهات يُمكن لها أن تُساعدك على استكشاف وحل مشاكل osquery. ويُمكن تشغيل <code>osqueryi</code> دون صلاحيات المُدير، لكنّك ستحتاج إلى تنفيذ الأمر بصلاحيات الجذر إن كنت ترغب في استعمال ملفّ الإعدادات الخاصّ بالعفريت.
</p>

<p>
	لنبدأ بتنفيذ تدقيقات أمنية بسيطة أولا ثمّ ننتقل إلى مُستويات أعلى خطوة بخطوة. على سبيل المثال، لنطّلع على من قد سجّل دخوله إلى النّظام في الوقت الحالي غيركَ أنت؟ يُمكن ذلك عبر الاستعلام التّالي:
</p>

<pre class="ipsCode">
<span class="hljs-keyword">select</span> * <span class="hljs-keyword">from</span> logged_in_users ;
</pre>

<p>
	يجب على المُخرج أن يبدو كالتّالي:
</p>

<pre class="ipsCode">
+-----------+----------+-------+------------------+------------+------+
|<span class="hljs-string"> type      </span>|<span class="hljs-string"> user     </span>|<span class="hljs-string"> tty   </span>|<span class="hljs-string"> host             </span>|<span class="hljs-string"> time       </span>|<span class="hljs-string"> pid  </span>|
+-----------+----------+-------+------------------+------------+------+
|<span class="hljs-string"> boot_time </span>|<span class="hljs-string"> reboot   </span>|<span class="hljs-string"> ~     </span>|<span class="hljs-string"> 4.4.0-57-generic </span>|<span class="hljs-string"> 1483580419 </span>|<span class="hljs-string"> 0    </span>|
|<span class="hljs-string"> runlevel  </span>|<span class="hljs-string"> runlevel </span>|<span class="hljs-string"> ~     </span>|<span class="hljs-string"> 4.4.0-57-generic </span>|<span class="hljs-string"> 1483580426 </span>|<span class="hljs-string"> 53   </span>|
|<span class="hljs-string"> login     </span>|<span class="hljs-string"> LOGIN    </span>|<span class="hljs-string"> ttyS0 </span>|<span class="hljs-string">                  </span>|<span class="hljs-string"> 1483580429 </span>|<span class="hljs-string"> 1546 </span>|
|<span class="hljs-string"> login     </span>|<span class="hljs-string"> LOGIN    </span>|<span class="hljs-string"> tty1  </span>|<span class="hljs-string">                  </span>|<span class="hljs-string"> 1483580429 </span>|<span class="hljs-string"> 1549 </span>|
|<span class="hljs-string"> user      </span>|<span class="hljs-string"> root     </span>|<span class="hljs-string"> pts/0 </span>|<span class="hljs-string"> 11.11.11.11      </span>|<span class="hljs-string"> 1483580584 </span>|<span class="hljs-string"> 1752 </span>|
|<span class="hljs-string"> user      </span>|<span class="hljs-string"> sammy    </span>|<span class="hljs-string"> pts/1 </span>|<span class="hljs-string"> 11.11.11.11      </span>|<span class="hljs-string"> 1483580770 </span>|<span class="hljs-string"> 4057 </span>|
+-----------+----------+-------+------------------+------------+------+
</pre>

<p>
	في المُخرج أعلاه حسابا مُستخدمين حقيقين قد سجّلا دخولهما إلى الجهاز، وكلاهما من نفس عنوان IP. يجب على عنوان IP هذا أن يكون معروفا. إن لم يكن كذلك، فسيتوجب عليك البحث عن مصدر تسجيل الدخول المثير للشبهات.
</p>

<p>
	يُخبرنا الاستعلام السّابق من قد سجّل دخوله في الوقت الحاليّ، لكن ماذا عن تسجيلات الدخول السّابقة؟ يُمكنك معرفة ذلك عبر استعلام الجدول <code>last</code> كما يلي:
</p>

<pre class="ipsCode">
<span class="hljs-keyword">select</span> * <span class="hljs-keyword">from</span> <span class="hljs-keyword">last</span> ;
</pre>

<p>
	لا يُشير المُخرج إلى أي شيء غير اعتيادي، ما يعني بأنّه لم يُسجّل أي أحد غيرنا دخوله إلى الجهاز مُؤخّرا:
</p>

<pre class="ipsCode">
+----------+-------+------+------+------------+------------------+
|<span class="hljs-string"> username </span>|<span class="hljs-string"> tty   </span>|<span class="hljs-string"> pid  </span>|<span class="hljs-string"> type </span>|<span class="hljs-string"> time       </span>|<span class="hljs-string"> host             </span>|
+----------+-------+------+------+------------+------------------+
|<span class="hljs-string"> reboot   </span>|<span class="hljs-string"> ~     </span>|<span class="hljs-string"> 0    </span>|<span class="hljs-string"> 2    </span>|<span class="hljs-string"> 1483580419 </span>|<span class="hljs-string"> 4.4.0-57-generic </span>|
|<span class="hljs-string"> runlevel </span>|<span class="hljs-string"> ~     </span>|<span class="hljs-string"> 53   </span>|<span class="hljs-string"> 1    </span>|<span class="hljs-string"> 1483580426 </span>|<span class="hljs-string"> 4.4.0-57-generic </span>|
|<span class="hljs-string">          </span>|<span class="hljs-string"> ttyS0 </span>|<span class="hljs-string"> 1546 </span>|<span class="hljs-string"> 5    </span>|<span class="hljs-string"> 1483580429 </span>|<span class="hljs-string">                  </span>|
|<span class="hljs-string"> LOGIN    </span>|<span class="hljs-string"> ttyS0 </span>|<span class="hljs-string"> 1546 </span>|<span class="hljs-string"> 6    </span>|<span class="hljs-string"> 1483580429 </span>|<span class="hljs-string">                  </span>|
|<span class="hljs-string">          </span>|<span class="hljs-string"> tty1  </span>|<span class="hljs-string"> 1549 </span>|<span class="hljs-string"> 5    </span>|<span class="hljs-string"> 1483580429 </span>|<span class="hljs-string">                  </span>|
|<span class="hljs-string"> LOGIN    </span>|<span class="hljs-string"> tty1  </span>|<span class="hljs-string"> 1549 </span>|<span class="hljs-string"> 6    </span>|<span class="hljs-string"> 1483580429 </span>|<span class="hljs-string">                  </span>|
|<span class="hljs-string"> root     </span>|<span class="hljs-string"> pts/0 </span>|<span class="hljs-string"> 1752 </span>|<span class="hljs-string"> 7    </span>|<span class="hljs-string"> 1483580584 </span>|<span class="hljs-string"> 11.11.11.11      </span>|
|<span class="hljs-string"> sammy    </span>|<span class="hljs-string"> pts/1 </span>|<span class="hljs-string"> 4057 </span>|<span class="hljs-string"> 7    </span>|<span class="hljs-string"> 1483580770 </span>|<span class="hljs-string"> 11.11.11.11      </span>|
+----------+-------+------+------+------------+------------------+
</pre>

<p>
	هل تم ضبط وتفعيل الجدار النّاري؟ هل لا يزال الجدار النّاري قيد التّشغيل؟ إن كنت في شك من أمرك، فنفّذ الاستعلام التّالي:
</p>

<pre class="ipsCode">
<span class="hljs-keyword">select</span> * <span class="hljs-keyword">from</span> iptables ;
</pre>

<p>
	إن لم تحصل على أي مُخرج، فهذا يعني بأنّ جدار IPTables النّاري لم يُضبَط. إن كان الخادوم مُتصلا بالأنترنت فهذا ليس جيّدا، لذا من المُفضّل أن تُعدّ الجدار النّاري الخاصّ بك.
</p>

<p>
	يُمكنك تعديل الاستعلام السّابق وتنفيذه لترشيح أعمدة مُحدّدة كما يلي:
</p>

<pre class="ipsCode">
<span class="hljs-keyword">select</span> <span class="hljs-keyword">chain</span>, <span class="hljs-keyword">policy</span>, src_ip, dst_ip <span class="hljs-keyword">from</span> iptables ;
</pre>

<p>
	يجب على الاستعلام أن يمنحك مُخرجا مُشابها لما يلي. ابحث عن أي مصدر مُثير للشبهات وعناوين IP الوجهة (destination IP addresses) التي لم تقم بضبطها:
</p>

<pre class="ipsCode">
+---------+--------+---------+-----------+
| chain   | policy | src_ip  | dst_ip    |
+---------+--------+---------+-----------+
| INPUT   | ACCEPT | <span class="hljs-number">0.0</span><span class="hljs-number">.0</span><span class="hljs-number">.0</span> | <span class="hljs-number">0.0</span><span class="hljs-number">.0</span><span class="hljs-number">.0</span>   |
| INPUT   | ACCEPT | <span class="hljs-number">0.0</span><span class="hljs-number">.0</span><span class="hljs-number">.0</span> | <span class="hljs-number">127.0</span><span class="hljs-number">.0</span><span class="hljs-number">.0</span> |
| INPUT   | ACCEPT | <span class="hljs-number">0.0</span><span class="hljs-number">.0</span><span class="hljs-number">.0</span> | <span class="hljs-number">0.0</span><span class="hljs-number">.0</span><span class="hljs-number">.0</span>   |
| INPUT   | ACCEPT | <span class="hljs-number">0.0</span><span class="hljs-number">.0</span><span class="hljs-number">.0</span> | <span class="hljs-number">0.0</span><span class="hljs-number">.0</span><span class="hljs-number">.0</span>   |
| INPUT   | ACCEPT | <span class="hljs-number">0.0</span><span class="hljs-number">.0</span><span class="hljs-number">.0</span> | <span class="hljs-number">0.0</span><span class="hljs-number">.0</span><span class="hljs-number">.0</span>   |
| INPUT   | ACCEPT | <span class="hljs-number">0.0</span><span class="hljs-number">.0</span><span class="hljs-number">.0</span> | <span class="hljs-number">0.0</span><span class="hljs-number">.0</span><span class="hljs-number">.0</span>   |
| INPUT   | ACCEPT | <span class="hljs-number">0.0</span><span class="hljs-number">.0</span><span class="hljs-number">.0</span> | <span class="hljs-number">0.0</span><span class="hljs-number">.0</span><span class="hljs-number">.0</span>   |
| INPUT   | ACCEPT | <span class="hljs-number">0.0</span><span class="hljs-number">.0</span><span class="hljs-number">.0</span> | <span class="hljs-number">0.0</span><span class="hljs-number">.0</span><span class="hljs-number">.0</span>   |
| INPUT   | ACCEPT | <span class="hljs-number">0.0</span><span class="hljs-number">.0</span><span class="hljs-number">.0</span> | <span class="hljs-number">0.0</span><span class="hljs-number">.0</span><span class="hljs-number">.0</span>   |
| INPUT   | ACCEPT | <span class="hljs-number">0.0</span><span class="hljs-number">.0</span><span class="hljs-number">.0</span> | <span class="hljs-number">0.0</span><span class="hljs-number">.0</span><span class="hljs-number">.0</span>   |
| FORWARD | ACCEPT | <span class="hljs-number">0.0</span><span class="hljs-number">.0</span><span class="hljs-number">.0</span> | <span class="hljs-number">0.0</span><span class="hljs-number">.0</span><span class="hljs-number">.0</span>   |
| FORWARD | ACCEPT | <span class="hljs-number">0.0</span><span class="hljs-number">.0</span><span class="hljs-number">.0</span> | <span class="hljs-number">0.0</span><span class="hljs-number">.0</span><span class="hljs-number">.0</span>   |
| OUTPUT  | ACCEPT | <span class="hljs-number">0.0</span><span class="hljs-number">.0</span><span class="hljs-number">.0</span> | <span class="hljs-number">0.0</span><span class="hljs-number">.0</span><span class="hljs-number">.0</span>   |
| OUTPUT  | ACCEPT | <span class="hljs-number">0.0</span><span class="hljs-number">.0</span><span class="hljs-number">.0</span> | <span class="hljs-number">0.0</span><span class="hljs-number">.0</span><span class="hljs-number">.0</span>   |
+---------+--------+---------+-----------+
</pre>

<p>
	ما نوع العمليّات الموقوتة في crontab؟ هل قُمت بتوقيتها بنفسك؟ سيُساعدك الاستعلام التّالي على اكتشاف البرمجيات الخبيثة التي تمّ توقيتها لتعمل في فترات زمنية مُعيّنة:
</p>

<pre class="ipsCode">
<span class="hljs-keyword">select</span> command, <span class="hljs-keyword">path</span> <span class="hljs-keyword">from</span> crontab ;
</pre>

<p>
	يجب على المُخرج أن يكون على الشّكل التّالي. إن بدت أية أوامر مُثيرة للشبهات، فهذا يعني بأنّها تحتاج إلى تحقيق إضافي:
</p>

<pre class="ipsCode">
+----------------------------------------------------------------------------------------------------------------------------------------+--------------------------------+
|<span class="hljs-string"> command                                                                                                                                </span>|<span class="hljs-string"> path                           </span>|
+----------------------------------------------------------------------------------------------------------------------------------------+--------------------------------+
|<span class="hljs-string"> root cd / &amp;&amp; run-parts --report /etc/cron.hourly                                                                                       </span>|<span class="hljs-string"> /etc/crontab                   </span>|
|<span class="hljs-string"> root test -x /usr/sbin/anacron </span>||<span class="hljs-string"> ( cd / &amp;&amp; run-parts --report /etc/cron.daily )                                                       </span>|<span class="hljs-string"> /etc/crontab                   </span>|
|<span class="hljs-string"> root test -x /usr/sbin/anacron </span>||<span class="hljs-string"> ( cd / &amp;&amp; run-parts --report /etc/cron.weekly )                                                      </span>|<span class="hljs-string"> /etc/crontab                   </span>|
|<span class="hljs-string"> root test -x /usr/sbin/anacron </span>||<span class="hljs-string"> ( cd / &amp;&amp; run-parts --report /etc/cron.monthly )                                                     </span>|<span class="hljs-string"> /etc/crontab                   </span>|
|<span class="hljs-string"> root if [ -x /usr/share/mdadm/checkarray ] &amp;&amp; [ $(date +\%d) -le 7 ]; then /usr/share/mdadm/checkarray --cron --all --idle --quiet; fi </span>|<span class="hljs-string"> /etc/cron.d/mdadm              </span>|
|<span class="hljs-string"> root test -x /etc/cron.daily/popularity-contest &amp;&amp; /etc/cron.daily/popularity-contest --crond                                          </span>|<span class="hljs-string"> /etc/cron.d/popularity-contest </span>|
+----------------------------------------------------------------------------------------------------------------------------------------+--------------------------------+
</pre>

<p>
	هل هناك من ملفّات على النّظام مع خاصيّة <code>setuid</code> مُفعّلة؟ هناك بضعة من هذه الأنواع من الملفّات على أي خادوم يعمل بـUbuntu 16.04، لكن أي من هذه هي؟ وهل هناك من ملفات لا يجب عليها أن تتواجد في النظام؟ يُمكن لإجابات هذه الأسئلة أن تُساعدك على اكتشاف ثنائيّات بأبواب خلفيّة (backdoored binaries). نفّذ الاستعلام التّالي بين الفينة والأخرى وقارن النتائج مع نتائج أقدم لتتمكن من اكتشاف أية إضافات أو تغييرات غير مرغوب فيها:
</p>

<pre class="ipsCode">
<span class="hljs-keyword">select</span> * <span class="hljs-keyword">from</span> suid_bin ;
</pre>

<p>
	مقطع من المُخرج يبدو كما يلي:
</p>

<pre class="ipsCode">
+-------------------------------+----------+-----------+-------------+
|<span class="hljs-string"> path                          </span>|<span class="hljs-string"> username </span>|<span class="hljs-string"> groupname </span>|<span class="hljs-string"> permissions </span>|
+-------------------------------+----------+-----------+-------------+
|<span class="hljs-string"> /bin/ping6                    </span>|<span class="hljs-string"> root     </span>|<span class="hljs-string"> root      </span>|<span class="hljs-string"> S           </span>|
|<span class="hljs-string"> /bin/su                       </span>|<span class="hljs-string"> root     </span>|<span class="hljs-string"> root      </span>|<span class="hljs-string"> S           </span>|
|<span class="hljs-string"> /bin/mount                    </span>|<span class="hljs-string"> root     </span>|<span class="hljs-string"> root      </span>|<span class="hljs-string"> S           </span>|
|<span class="hljs-string"> /bin/umount                   </span>|<span class="hljs-string"> root     </span>|<span class="hljs-string"> root      </span>|<span class="hljs-string"> S           </span>|
|<span class="hljs-string"> /bin/fusermount               </span>|<span class="hljs-string"> root     </span>|<span class="hljs-string"> root      </span>|<span class="hljs-string"> S           </span>|
|<span class="hljs-string"> /bin/ntfs-3g                  </span>|<span class="hljs-string"> root     </span>|<span class="hljs-string"> root      </span>|<span class="hljs-string"> S           </span>|
|<span class="hljs-string"> /bin/ping                     </span>|<span class="hljs-string"> root     </span>|<span class="hljs-string"> root      </span>|<span class="hljs-string"> S           </span>|
|<span class="hljs-string"> /sbin/mount.ntfs-3g           </span>|<span class="hljs-string"> root     </span>|<span class="hljs-string"> root      </span>|<span class="hljs-string"> S           </span>|
|<span class="hljs-string"> /sbin/mount.ntfs              </span>|<span class="hljs-string"> root     </span>|<span class="hljs-string"> root      </span>|<span class="hljs-string"> S           </span>|
|<span class="hljs-string"> /sbin/unix_chkpwd             </span>|<span class="hljs-string"> root     </span>|<span class="hljs-string"> shadow    </span>|<span class="hljs-string"> G           </span>|
|<span class="hljs-string"> /sbin/pam_extrausers_chkpwd   </span>|<span class="hljs-string"> root     </span>|<span class="hljs-string"> shadow    </span>|<span class="hljs-string"> G           </span>|
|<span class="hljs-string"> /usr/bin/chage                </span>|<span class="hljs-string"> root     </span>|<span class="hljs-string"> shadow    </span>|<span class="hljs-string"> G           </span>|
|<span class="hljs-string"> /usr/bin/locate               </span>|<span class="hljs-string"> root     </span>|<span class="hljs-string"> mlocate   </span>|<span class="hljs-string"> G           </span>|
|<span class="hljs-string"> /usr/bin/chfn                 </span>|<span class="hljs-string"> root     </span>|<span class="hljs-string"> root      </span>|<span class="hljs-string"> S           </span>|
|<span class="hljs-string"> /usr/bin/chsh                 </span>|<span class="hljs-string"> root     </span>|<span class="hljs-string"> root      </span>|<span class="hljs-string"> S           </span>|
|<span class="hljs-string"> /usr/bin/newuidmap            </span>|<span class="hljs-string"> root     </span>|<span class="hljs-string"> root      </span>|<span class="hljs-string"> S           </span>|
|<span class="hljs-string"> /usr/bin/write                </span>|<span class="hljs-string"> root     </span>|<span class="hljs-string"> tty       </span>|<span class="hljs-string"> G           </span>|
|<span class="hljs-string"> /usr/bin/mlocate              </span>|<span class="hljs-string"> root     </span>|<span class="hljs-string"> mlocate   </span>|<span class="hljs-string"> G           </span>|
|<span class="hljs-string"> /usr/bin/at                   </span>|<span class="hljs-string"> daemon   </span>|<span class="hljs-string"> daemon    </span>|<span class="hljs-string"> SG          </span>|
|<span class="hljs-string"> /usr/bin/sg                   </span>|<span class="hljs-string"> root     </span>|<span class="hljs-string"> root      </span>|<span class="hljs-string"> S           </span>|
</pre>

<p>
	لعرض قائمة بوحدات النواة المُحمَّلة (loaded kernel modules)، نفّذ الاستعلام التّالي:
</p>

<pre class="ipsCode">
<span class="hljs-keyword">select</span> <span class="hljs-keyword">name</span>, used_by, <span class="hljs-keyword">status</span> <span class="hljs-keyword">from</span> kernel_modules <span class="hljs-keyword">where</span> <span class="hljs-keyword">status</span>=<span class="hljs-string">"Live"</span> ;
</pre>

<p>
	هذا استعلام آخر يجب تنفيذه بين الحين والآخر لمُقارنة مُخرجه مع نتائج أقدم للتحقق ممّا إذا كان هناك تغيير ما أو لا.
</p>

<p>
	عرض قائمة بجميع المنافذ المُنصتة (listening ports) من أحد الطرق الأخرى التي يُمكنك بها إيجاد أبواب خلفيّة على الخادوم. للقيام بذلك، نفّذ الأمر التّالي:
</p>

<pre class="ipsCode">
<span class="hljs-keyword">select</span> * <span class="hljs-keyword">from</span> listening_ports ;
</pre>

<p>
	يجب على المُخرج أن يكون كالتّالي على خادوم جديد مع <abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">SSH</abbr> وحدها تعمل على المنفذ <code>22</code>:
</p>

<pre class="ipsCode">
+-------+------+----------+--------+---------+
|<span class="hljs-string"> pid   </span>|<span class="hljs-string"> port </span>|<span class="hljs-string"> protocol </span>|<span class="hljs-string"> family </span>|<span class="hljs-string"> address </span>|
+-------+------+----------+--------+---------+
|<span class="hljs-string"> 1686  </span>|<span class="hljs-string"> 22   </span>|<span class="hljs-string"> 6        </span>|<span class="hljs-string"> 2      </span>|<span class="hljs-string"> 0.0.0.0 </span>|
|<span class="hljs-string"> 1686  </span>|<span class="hljs-string"> 22   </span>|<span class="hljs-string"> 6        </span>|<span class="hljs-string"> 10     </span>|<span class="hljs-string"> ::      </span>|
|<span class="hljs-string"> 25356 </span>|<span class="hljs-string"> 0    </span>|<span class="hljs-string"> 0        </span>|<span class="hljs-string"> 0      </span>|<span class="hljs-string">         </span>|
+-------+------+----------+--------+---------+
</pre>

<p>
	إن كان المُخرج يحتوي على منافذ تعلم بأنّ الخادوم يُنصت منها، فلا داعي للقلق، أمّا إن كانت هناك منافذ أخرى مفتوحة، فسيتوجّب عليك التّحقيق في ماهيّة هذه المنافذ.
</p>

<p>
	لعرض نشاطات الملفّات على الخادوم، نفّذ الاستعلام التّالي:
</p>

<pre class="ipsCode">
<span class="hljs-keyword">select</span> target_path, <span class="hljs-keyword">action</span>, uid <span class="hljs-keyword">from</span> file_events ;
</pre>

<p>
	يعرض المُخرج جميع نشاطات الملفات الحديثة على الخادوم، إضافة إلى مُعرّف المُستخدم المسؤول عن النّشاط:
</p>

<pre class="ipsCode">
+---------------------------+---------+------+
|<span class="hljs-string"> target_path               </span>|<span class="hljs-string"> action  </span>|<span class="hljs-string"> uid  </span>|
+---------------------------+---------+------+
|<span class="hljs-string"> /home/sammy/..bashrc.swp  </span>|<span class="hljs-string"> CREATED </span>|<span class="hljs-string"> 1000 </span>|
|<span class="hljs-string"> /home/sammy/..bashrc.swp  </span>|<span class="hljs-string"> UPDATED </span>|<span class="hljs-string"> 1000 </span>|
|<span class="hljs-string"> /home/sammy/..bashrc.swp  </span>|<span class="hljs-string"> UPDATED </span>|<span class="hljs-string"> 1000 </span>|
|<span class="hljs-string"> /home/sammy/.bashrc       </span>|<span class="hljs-string"> UPDATED </span>|<span class="hljs-string"> 1000 </span>|
|<span class="hljs-string"> /home/sammy/..bashrc.swp  </span>|<span class="hljs-string"> DELETED </span>|<span class="hljs-string"> 1000 </span>|
|<span class="hljs-string"> /home/sammy/..bashrc.swp  </span>|<span class="hljs-string"> CREATED </span>|<span class="hljs-string"> 1000 </span>|
|<span class="hljs-string"> /home/sammy/..bashrc.swp  </span>|<span class="hljs-string"> UPDATED </span>|<span class="hljs-string"> 1000 </span>|
|<span class="hljs-string"> /home/sammy/..bashrc.swp  </span>|<span class="hljs-string"> UPDATED </span>|<span class="hljs-string"> 1000 </span>|
|<span class="hljs-string"> /home/sammy/.bashrc       </span>|<span class="hljs-string"> UPDATED </span>|<span class="hljs-string"> 1000 </span>|
|<span class="hljs-string"> /home/sammy/.bashrc       </span>|<span class="hljs-string"> UPDATED </span>|<span class="hljs-string"> 1000 </span>|
|<span class="hljs-string"> /home/sammy/.bashrc       </span>|<span class="hljs-string"> UPDATED </span>|<span class="hljs-string"> 1000 </span>|
|<span class="hljs-string"> /home/sammy/..bashrc.swp  </span>|<span class="hljs-string"> DELETED </span>|<span class="hljs-string">      </span>|
|<span class="hljs-string"> /etc/test_file.txt        </span>|<span class="hljs-string"> DELETED </span>|<span class="hljs-string">      </span>|
|<span class="hljs-string"> /home/sammy/.bash_history </span>|<span class="hljs-string"> UPDATED </span>|<span class="hljs-string"> 1000 </span>|
|<span class="hljs-string"> /home/sammy/.bash_history </span>|<span class="hljs-string"> UPDATED </span>|<span class="hljs-string"> 1000 </span>|
|<span class="hljs-string"> /etc/secret_file.md       </span>|<span class="hljs-string"> CREATED </span>|<span class="hljs-string"> 0    </span>|
|<span class="hljs-string"> /etc/secret_file.md       </span>|<span class="hljs-string"> UPDATED </span>|<span class="hljs-string"> 0    </span>|
|<span class="hljs-string"> /etc/secret_file.md       </span>|<span class="hljs-string"> UPDATED </span>|<span class="hljs-string"> 0    </span>|
+---------------------------+---------+------+
</pre>

<p>
	هناك العديد من الاستعلامات مُشابهة لما سبق يُمكنك بها أن تحصل على فكرة حول مشاكل أمنية مُحتملة.
</p>

<p>
	إن لم تكن مُتأكدا من مُخطّط (schema) جدول ما، يُمكنك استعمال الأمر التّالي لمعرفة مُخطّط الجدول:
</p>

<pre class="ipsCode">
.schema <span class="hljs-built_in">name</span>-<span class="hljs-keyword">of</span>-table
</pre>

<p>
	مع إبدال <code>name-of-table</code> باسم الجدول. ويُمكنك كذلك عرض قائمة بالجداول المُتوفرة بالأمر:
</p>

<pre class="ipsCode">
<span class="hljs-title">.tables</span>
</pre>

<p>
	هناك العديد من الأمثلة الأخرى في الحزمات التي تأتي مع osquery، وقد صُمِّم العديد منها ليعمل بشكل دوري من طرف <code>osqueryd</code>. سنتعرّف في القسم التّالي على كيفيّة تشغيل العفريت لتنفيذ هذه الاستعلامات.
</p>

<p>
	##الخطوة السّادسة: تشغيل osqueryd يسمح العفريت <code>osqueryd</code> بتنفيذ الاستعلامات في فترات زمنيّة مُحدّدة. ما يشمل كلّا من الاستعلامات التي ضبطناها في الخطوة الرّابعة، الاستعلامات المتواجدة في الحزمات التي أعددناها في تلك الخطوة، وحزمة FIM التي أعددناها في الخطوة الخامسة كذلك. إن لم تطّلع على الحزمات بعد، فهذا وقت مُناسب لإلقاء نظرة على مُحتويات <code>‎/usr/share/osquery/packs</code>. تُكتَب النتائج المُولَّدة من طرف <code>osqueryd</code> إلى ملفّ باسم <code>osqueryd.results.log</code> في مُجلّد <code>‎/var/log/osquery</code>. هذا الملفّ غير موجود افتراضيّا. ولا يتم إنشاؤه إلا بعد تشغيل العفريت وبدء توليد النّتائج من طرفه.
</p>

<p>
	يُمكنك تشغيل <code>osqueryd</code> إما بأداة <code>systemctl</code> أو <code>osqueryctl</code>. كلاهما يؤدي نفس المُهمّة، لذا لا يهم أيّ واحد منهما تستعمل. سيتحقّق <code>osqueryd</code> من تواجد ملفّ إعدادات عند تشغيله، وسيُنبّهك إن لم يجد واحدا. سيبقى مُشتغلا دون ملفّ إعدادات، إلا أن ذلك لن يكون ذا فائدة تُذكر.
</p>

<p>
	وبما أنّه قد سبق وأن أعددنا ملفّ إعدادات، فكل ما تحتاج إليه هو تشغيل العفريت:
</p>

<pre class="ipsCode">
sudo systemctl <span class="hljs-literal">start</span> osqueryd
</pre>

<p>
	أو يُمكن كتابة ما يلي:
</p>

<pre class="ipsCode">
sudo osqueryctl <span class="hljs-literal">start</span>
</pre>

<p>
	بعد بضعة دقائق من تشغيل العفريت، من المُفترض أن يزداد حجم الملفّ <code>‎/var/log/osquery/osqueryd.results.log</code>. يُمكنك أن ترى ذلك بنفسك عبر تنفيذ الأمر التّالي مرارا وتكرارا:
</p>

<pre class="ipsCode">
<span class="hljs-keyword">ls</span> -lh /<span class="hljs-keyword">var</span>/<span class="hljs-keyword">log</span>/osquery/osqueryd.results.<span class="hljs-built_in">log</span>
</pre>

<p>
	ازدياد حجم الملفّ يدل على أن نتائج الاستعلامات الموقوتة تُكتَب على القرص. لا يمتلك osquery للأسف نظام تنبيهات مثل OSSEC، ما يعني بأنّك لن تستطيع رؤية نتائج الاستعلامات الموقوتة إلا عبر عرض ملفّ النتائج. ويُمكنك القيام بذلك عبر الأمر <code>tail</code> الذي سيقوم بعرض آخر 10 أسطر من الملفّ على الشّاشة بشكل مُستمر:
</p>

<pre class="ipsCode">
sudo tail <span class="hljs-params">-f</span> /<span class="hljs-built_in">var</span>/<span class="hljs-keyword">log</span>/osquery/osqueryd.results.<span class="hljs-keyword">log</span>
</pre>

<p>
	اضغط على <code>CTRL+C</code> لإيقاف العرض المُستمرّ للسّجل.
</p>

<p>
	قد ترغب على المدى البعيد بنقل نتائج الاستعلامات إلى منصّة تحليل خارجيّة يُمكنك العمل معها. بعض الخيارات مفتوحة المصدر تشمل كلّا من <a href="https://github.com/mwielgoszewski/doorman" rel="external nofollow">Doorman</a>، <a href="https://github.com/apfelwerk/Zentral/wiki" rel="external nofollow">Zentral</a> و <a href="https://www.elastic.co/products/elasticsearch" rel="external nofollow">ElasticSearch</a>.
</p>

<h2 id="-">
	ختاما
</h2>

<p>
	يعد osquery أداة قويّة مُفيدة لتشغيل استعلامات ظرفية وموقوتة باستعمال جمل SQL المألوفة. <code>osqueryi</code> هو المكون الذي يُمكّنك من تشغيل استعلامات سريعة، أما <code>osqueryd</code> فهو للاستعلامات الموقوتة. لتحليل نتائج الاستعلامات الموقوتة، سيتوجب عليك نقلها إلى منصّة خارجية لتحليل السّجلات. يُمكنك الحصول على المزيد من المعلومات حول osquery على <a href="https://osquery.io/" rel="external nofollow">osquery.io</a>.
</p>

<p>
	ترجمة -بتصرّف- للمقال <a href="https://www.digitalocean.com/community/tutorials/how-to-monitor-your-system-security-with-osquery-on-ubuntu-16-04" rel="external nofollow"> How To Monitor Your System Security with osquery on Ubuntu 16.04 </a> لصاحبه finid.
</p>
]]></description><guid isPermaLink="false">428</guid><pubDate>Wed, 10 Jul 2019 18:00:00 +0000</pubDate></item><item><title>&#x62F;&#x644;&#x64A;&#x644;&#x643; &#x625;&#x644;&#x649; ImageMagick: &#x62A;&#x63A;&#x64A;&#x64A;&#x631; &#x62D;&#x62C;&#x645; &#x627;&#x644;&#x635;&#x648;&#x631; &#x639;&#x628;&#x631; &#x633;&#x637;&#x631; &#x627;&#x644;&#x623;&#x648;&#x627;&#x645;&#x631;</title><link>https://academy.hsoub.com/devops/linux/%D8%AF%D9%84%D9%8A%D9%84%D9%83-%D8%A5%D9%84%D9%89-imagemagick-%D8%AA%D8%BA%D9%8A%D9%8A%D8%B1-%D8%AD%D8%AC%D9%85-%D8%A7%D9%84%D8%B5%D9%88%D8%B1-%D8%B9%D8%A8%D8%B1-%D8%B3%D8%B7%D8%B1-%D8%A7%D9%84%D8%A3%D9%88%D8%A7%D9%85%D8%B1-r424/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2019_05/5ced9a599fcbe_.jpg.278d1c767a43798bdedc5f814ff007f2.jpg" /></p>

<p>
	دعنا نفترض أنَّك تكتب سلسلة من البرامج التعليمية لـ Blender وأنك تستخدم PrintScreen لأخذ لقطات الشاشة. يمنحك هذا دليلًا مليئًا بالصور الضخمة غير المُحسَّنة للتحميل إلى صفحة ويب وعرضها. آخر شيء تريد القيام به هو تغيير حجمها يدويًا. انت محظوظ! باستخدام خيار تغيير الحجم <code>‎<strong>-resize</strong></code> يمكنك بسرعة وسهولة تغيير حجم هذه الصور إلى حجم يمكن التحكم فيه.
</p>

<p>
	<a class="ipsAttachLink ipsAttachLink_image" href="https://academy.hsoub.com/uploads/monthly_2019_05/5ced9a5fabeed_.jpg.78d70a0fdc994356404ab09e49f144ff.jpg" data-fileid="29648" rel=""><img class="ipsImage ipsImage_thumbnailed" data-fileid="29648" data-unique="lg983ojde" src="https://academy.hsoub.com/uploads/monthly_2019_05/5ced9a5fc2692_.thumb.jpg.20dea631942ff59f9488bc69a64a2ae9.jpg" alt="تغيير حجم الصور.jpg"></a>
</p>

<p>
	ضع كل الصور التي تريد توسيع نطاقها في مجلد وانتقل إلى موقع الدليل عبر سطر الأوامر. ثم أدخل الأمر التالي:
</p>

<pre class="ipsCode" id="ips_uid_4670_6">
mogrify -resize 960x528 *.png
</pre>

<p>
	يقوم هذا الأمر بتغيير حجم جميع ملفات png. في الدليل إلى حجم 960 بكسل في 528 بكسل. ربَّما الارتفاع ليس بنفس أهمية العرض. يمكنك ببساطة كتابة الأمر السابق على النحو التالي:
</p>

<pre class="ipsCode" id="ips_uid_4670_8">
mogrify -resize 960 *.png
</pre>

<p>
	سيؤدي هذا إلى تغيير حجم جميع صورك إلى 960 بكسل، وسيتمُّ تغيير الارتفاع وفقًا لذلك، محافظًا على نسبة العرض إلى الارتفاع. ربما لديك الطول والعرض الذي تريده، لكنك ترغب في الحفاظ على نسبة العرض إلى الارتفاع. يمكنك إدخال الأمر على النحو التالي:
</p>

<pre class="ipsCode" id="ips_uid_4670_10">
mogrify -resize 960x528! *.png
</pre>

<p>
	سيؤدِّي ذلك إلى توسيع نطاق صورك إلى 960 × 528 بكسل متى كان ذلك ممكناً، لكنَّه سيحافظ على نسبة العرض إلى الارتفاع لتلك الصور التي لن يتم تكبيرها إلى هذه الأبعاد بالضبط.
</p>

<p>
	ترجمة -وبتصرّف- للمقال <a href="https://dototot.com/imagemagick-tutorial-batch-resize-images-command-line/" rel="external nofollow">ImageMagick Tutorial: How To Batch Resize Images on the Command Line</a> لصاحبه Jared
</p>
]]></description><guid isPermaLink="false">424</guid><pubDate>Tue, 28 May 2019 20:33:50 +0000</pubDate></item><item><title>[&#x641;&#x64A;&#x62F;&#x64A;&#x648;] &#x627;&#x644;&#x623;&#x630;&#x648;&#x646;&#x627;&#x62A; &#x641;&#x64A; &#x646;&#x638;&#x627;&#x645; &#x644;&#x64A;&#x646;&#x643;&#x633;</title><link>https://academy.hsoub.com/devops/linux/%D9%81%D9%8A%D8%AF%D9%8A%D9%88-%D8%A7%D9%84%D8%A3%D8%B0%D9%88%D9%86%D8%A7%D8%AA-%D9%81%D9%8A-%D9%86%D8%B8%D8%A7%D9%85-%D9%84%D9%8A%D9%86%D9%83%D8%B3-r425/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2019_06/linux.png.c0419445d17270785fbe1d239562417f.png" /></p>

<p>
	<iframe allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen="" frameborder="0" height="400" src="https://www.youtube.com/embed/WYVSo7sUwYU" width="560"></iframe>
</p>

<p>
	نشرح في هذا الفيديو مفهوم المالك والأذونات على الملفات في نظام لينكس، وكيفية قراء الأذونات وتفاصيلها والأوامر اللازمة لإدارتها.
</p>

<ul>
<li>
		لعرض المستخدمين في النظام: <code>cat /etc/passwd</code>
	</li>
	<li>
		لعرض المجموعات في النظام: <code>cat /etc/group</code>
	</li>
	<li>
		لعرض الملفات مع كامل تفاصيلها: <code>ls -l</code>
	</li>
	<li>
		لتغيير ملكية أحد المجلدات أو الملفات: <code>chown -R USER:GROUP $FILE</code>
	</li>
	<li>
		لتغيير أدونات أحد المجلدات أو الملفات: <code>chmod -R +rwx $FILES</code>
	</li>
</ul>
<p>
	يمكنك الاطلاع على <a href="https://suar.me/PVeN" rel="external">الصورة الآتية</a> للاستزادة.
</p>

<p>
	<a href="https://academy.hsoub.com/devops/linux/" rel="">قسم لينكس</a> في أكاديمية حسوب غني بالمقالات المفيدة عن التعامل مع النظام.
</p>
]]></description><guid isPermaLink="false">425</guid><pubDate>Sat, 15 Jun 2019 12:09:06 +0000</pubDate></item><item><title>&#x62F;&#x644;&#x64A;&#x644;&#x643; &#x625;&#x644;&#x649; ImageMagick: &#x627;&#x642;&#x62A;&#x635;&#x627;&#x635; &#x627;&#x644;&#x635;&#x648;&#x631; &#x639;&#x628;&#x631; &#x633;&#x637;&#x631; &#x627;&#x644;&#x623;&#x648;&#x627;&#x645;&#x631;</title><link>https://academy.hsoub.com/devops/linux/%D8%AF%D9%84%D9%8A%D9%84%D9%83-%D8%A5%D9%84%D9%89-imagemagick-%D8%A7%D9%82%D8%AA%D8%B5%D8%A7%D8%B5-%D8%A7%D9%84%D8%B5%D9%88%D8%B1-%D8%B9%D8%A8%D8%B1-%D8%B3%D8%B7%D8%B1-%D8%A7%D9%84%D8%A3%D9%88%D8%A7%D9%85%D8%B1-r423/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2019_05/5ced953d24241_.jpg.bc517cacfab4771e4f5cd37d7f1f0847.jpg" /></p>

<p>
	دعنا نفترض أنك تكتب سلسلة من البرامج التعليمية على Blender وأنك تستخدم مفتاح PrintScreen لالتقاط لقطات الشاشة. إنَّ مفتاح PrintScreen رائع، لكنه يمسك بكل شيء. ربَّما لا تريد أن يظهر تطبيقك في كل صورة. وربما لا تريد تحرير عشرات الصور يدويًا. أنت محظوظ! لدى برنامج ImageMagick وسيلة سهلة لاستخدام وظيفة الاقتصاص للصور التي يمكنك تنفيذها بسرعة وسهولة من سطر الأوامر.
</p>

<p>
	إذا لم تكن قد قمت بالفعل بتثبيت البرنامج، فاحصل على ImageMagick بالطريقة السهلة:
</p>

<pre class="ipsCode">
sudo apt-<span class="hljs-keyword">get</span> install imagemagick
</pre>

<p>
	ضع كل الصور التي تريد اقتصاصها في مجلد وانتقل إليه عبر سطر الأوامر. في المثال الذي أستخدمه هنا، أرغب في قطع البيكسلات السفلية البالغ عددها 25 بكسل من سلسلة صور png. نفِّذْ الأمر التالي للقيام بذلك:
</p>

<pre class="ipsCode">
mogrify -<span class="hljs-keyword">format</span> png -<span class="hljs-keyword">gravity</span> south -chop <span class="hljs-number">0x25</span> *.png
</pre>

<p>
	الرايات التي استعملناها مع الأمر هي:
</p>

<ul>
<li>
		‎<strong><code>:-format png</code></strong> ينص الخيار بإخراج الملف بصيغة png.
	</li>
	<li>
		‎:<strong><code>-gravity south</code></strong> ينصُّ الخيار ببدء الاقتصاص من أسفل الصورة.
	</li>
	<li>
		‎:<strong><code>-chop 0x25</code></strong> ينصُّ الخيار بقصَّ 25 بكسلًا من الارتفاع.
	</li>
	<li>
		‎<strong><code>*.png</code></strong>: ينصُّ الخيار بتطبيق جميع ما سبق على أي ملف ذو اللاحقة <code>png.</code>
	</li>
</ul>
<p>
	أدناه ملفي الأصلي:
</p>

<p>
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="29647" href="https://academy.hsoub.com/uploads/monthly_2019_05/02Screenshot-from-2013-10-28-134349-1.jpg.27f910d0d42c0470f244da1d0ed7851f.jpg" rel=""><img alt="02Screenshot-from-2013-10-28-134349-1.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="29647" data-unique="kj0465jwd" src="https://academy.hsoub.com/uploads/monthly_2019_05/02Screenshot-from-2013-10-28-134349-1.thumb.jpg.2089cbe12e950ec2585988bde8520601.jpg"></a>
</p>

<p>
	والصورة المشذبة حديثا:
</p>

<p>
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="29646" href="https://academy.hsoub.com/uploads/monthly_2019_05/1_imageMagickCropTutorial-1-1-955x528.jpg.16c0dc1261b89a9faccaef882cf20f90.jpg" rel=""><img alt="1_imageMagickCropTutorial-1-1-955x528.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="29646" data-unique="wacdzmlp1" src="https://academy.hsoub.com/uploads/monthly_2019_05/1_imageMagickCropTutorial-1-1-955x528.thumb.jpg.74796c078531c398a1b8390965fd60f2.jpg"></a>
</p>

<p>
	ترجمة -وبتصرّف- للمقال <a href="https://dototot.com/imagemagick-tutorial-batch-crop-images-command-line/" rel="external nofollow">ImageMagick Tutorial: How To Batch Crop Images on the Command Line</a> لصاحبه Jared
</p>
]]></description><guid isPermaLink="false">423</guid><pubDate>Tue, 28 May 2019 20:16:28 +0000</pubDate></item><item><title>&#x62A;&#x62B;&#x628;&#x64A;&#x62A; Node.js &#x639;&#x644;&#x649; &#x646;&#x638;&#x627;&#x645; &#x623;&#x628;&#x648;&#x646;&#x62A;&#x648; 18.04</title><link>https://academy.hsoub.com/devops/linux/%D8%AA%D8%AB%D8%A8%D9%8A%D8%AA-nodejs-%D8%B9%D9%84%D9%89-%D9%86%D8%B8%D8%A7%D9%85-%D8%A3%D8%A8%D9%88%D9%86%D8%AA%D9%88-1804-r419/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2019_05/5ce5904df2006_node.js.jpg.a1c00c7e6af6e699d24e74e31d61ec02.jpg" /></p>

<p>
	تُعرّف <a href="https://wiki.hsoub.com/Node.js/" rel="external">Node.js</a> بأنّها منصّة <a href="https://wiki.hsoub.com/JavaScript" rel="external">JavaScript</a> للبرمجة عامّة الأغراض تسمح للمستخدمين ببناء تطبيقات شبكيّة بسرعة. تجعل Node.js عمليّة التّطوير أكثر اتّساقًا وتكاملًا وذلك بتسخير ميّزات JavaScript في كلٍّ من الواجهة الأماميّة (front end) والواجهة الخلفيّة (backend).
</p>

<p>
	سنعرض لك في هذا الدّليل كيفيّة البدء بمنصة Node.js على نظام خادم أبونتو 18.04.
</p>

<p>
	<a class="ipsAttachLink ipsAttachLink_image" href="https://academy.hsoub.com/uploads/monthly_2019_05/5ce590564854c_node.js.jpg.e91e183b7981b8d1b289d6bdd8d131e4.jpg" data-fileid="29599" rel=""><img class="ipsImage ipsImage_thumbnailed" data-fileid="29599" data-unique="l177qum13" src="https://academy.hsoub.com/uploads/monthly_2019_05/5ce5905669e9c_node.js.thumb.jpg.cfeded3a63ec93933d1465d108141dfd.jpg" alt="تثبيت node.js على أبنتو.jpg"></a>
</p>

<h2 id="-">
	المتطلبات
</h2>

<p>
	يفترض هذا الدّليل أنك تستخدم أبونتو 18.04. قبل أن تبدأ، يجب أن يتوفّر لديك على نظامك حساب مستخدم غير جذر (non-root) ذا امتيازات sudo. يمكنك تعلُّم كيفيّة القيام بهذا من خلال اتّباع خطوات <a href="https://www.digitalocean.com/community/tutorials/initial-server-setup-with-ubuntu-18-04" rel="external nofollow">دليل إعداد الخادم الابتدائي لنظام أبونتو 18.04</a>.
</p>

<h2 id="-distro-stable-">
	تثبيت إصدار التوزيعة المستقرة (Distro-Stable) في أبونتو
</h2>

<p>
	يتضمّن أبونتو 18.04 في مستودعاته الافتراضيّة إصدارًا من Node.js يُمكن استخدامه للحصول على تجربة مُتّسقة على عدّة أنظمة. حتى كتابة هذا الدّليل، فإن الإصدار المتوفّر في المستودعات هو 8.10.0. هذا الإصدار ليس الأحدث، لكنّه مُستقّرٌ وكافٍ لإجراء تجارب سريعةٍ مع اللغة.
</p>

<p>
	للحصول على هذا الإصدار، يمكنك استخدام مدير الحزمة <code>apt</code>. قم بتحديث فهرس الحزمة المحليّة لديك بكتابة الأمر التالي:
</p>

<pre class="ipsCode">
<span class="hljs-attribute">sudo apt update</span>
</pre>

<p>
	قم بتثبيت Node.js من المستودعات:
</p>

<pre class="ipsCode">
sudo apt <span class="hljs-keyword">install</span> nodejs
</pre>

<p>
	إذا لبّت الحزمة الموجودة في المستودعات حاجتك، فهذا كل ما تحتاج القيام به لإعداد Node.js. في معظم الحالات، قد ترغب في تثبيت مدير الحزم الخاصّ بالمنصة (Node.js package manager أو <code>npm</code>). يمكنك القيام بذلك بكتابة التّالي:
</p>

<pre class="ipsCode">
sudo apt <span class="hljs-keyword">install</span> npm
</pre>

<p>
	سيسمح ما سبق لك بتثبيت وحدات وحزم لاستخدامها مع Node.js.
</p>

<p>
	نظرًا لوجود تعارضٍ مع حزمة أخرى، يُدعى الملفّ التّنفيذيّ المُحمّل من مستودعات أبونتو <code>nodejs</code> بدلًا من <code>node</code>. تذكّر هذا الأمر جيدًا عند تشغيلك للبرمجيّة.
</p>

<p>
	للتّحقق من إصدار Node.js المُثبّت لديك بعد هذه الخطوات الأوليّة، قم بكتابة الأمر التّالي:
</p>

<pre class="ipsCode">
<span class="hljs-attribute">nodejs -v</span>
</pre>

<p>
	بعد أن تتأكد من إصدار Node.js المُثبّت لديك من مستودعات أبونتو، تستطيع حينها أن تقرر إذا ما كنت تريد العمل مع إصدارات مُغايرة، أرشفة حزم مختلفة أو مدير إصدار آخر. سنناقش هذه العناصر فيما يلي كما سنعرض سُبلًا أكثر مرونةً وحداثةً للتّثبيت.
</p>

<h2 id="-ppa">
	التّثبيت باستخدام أرشيف الحزم الشّخصي PPA
</h2>

<p>
	للحصول على إصداراتٍ أحدث من Node.js، يمكنك إضافة أرشيف الحزم الشّخصي المُدار من قبل NodeSource. يحتوي هذا الأرشيف على إصدارات أحدث مما هو موجود في مستودعات أبونتو الرّسميّة. كما سيسمح لك بالاختيار من باقة إصدارات أوسع تتراوح بين Node.js v8.x (المدعومة حتى نهاية العام الجاري)، الإصدار ذي الدّعم الطّويل الأمد الحالي Node.js v10.x، والإصدار الحالي Node.js v12.x.
</p>

<p>
	قم أوّلًا بتثبيت PPA لتستطيع الوصول إلى محتوياته. من الدّليل الرّئيسيّ لديك، استخدم <code>curl</code> لجلب البرنامج النّصي لتّثبيت الإصدار المُفضّل لديك، لا تنسَ استبدال <code>‎10.x</code> بالسّلسلة الخاصة بالإصدار الذي تريده إن لم يكن هو المطلوب:
</p>

<pre class="ipsCode">
<span class="hljs-keyword">cd</span> ~
curl -sL http<span class="hljs-variable">s:</span>//<span class="hljs-keyword">deb</span>.nodesource.<span class="hljs-keyword">com</span>/setup_10.<span class="hljs-keyword">x</span> -<span class="hljs-keyword">o</span> nodesource_setup.<span class="hljs-keyword">sh</span>
</pre>

<p>
	يمكنك فحص محتويات هذا البرنامج النّصّي من خلال فتحه باستخدام<code>nano</code> أو باستخدام محرّرك النّصّي المُفضّل:
</p>

<pre class="ipsCode">
<span class="hljs-selector-tag">nano</span> <span class="hljs-selector-tag">nodesource_setup</span><span class="hljs-selector-class">.sh</span>
</pre>

<p>
	قم بتنفيذ البرنامج النّصّي ضمن امتيازات <code>sudo</code>:
</p>

<pre class="ipsCode">
<span class="hljs-symbol">sudo</span> <span class="hljs-keyword">bash </span>nodesource_setup.sh
</pre>

<p>
	سيُضاف أرشيف الحزم الشخصي هذا إلى إعداداتك وستُحدّث خابية الحزم المحليّة لديك تلقائيًّا. بعد تنفيذ نص التثبيت من Nodesource، يمكنك تثبيت حزمة Node.js بنفس الطريقة المذكورة أعلاه:
</p>

<pre class="ipsCode">
sudo apt <span class="hljs-keyword">install</span> nodejs
</pre>

<p>
	للتّحقق من إصدار Node.js المُثبّت لديك بعد هذه الخطوات الأوليّة، قم بكتابة الأمر التّالي:
</p>

<pre class="ipsCode">
<span class="hljs-attribute">nodejs -v</span>
</pre>

<p>
	وسترى خرجًا مشابهًا للتّالي:
</p>

<pre class="ipsCode" id="ips_uid_9543_12">
v10.14.0
</pre>

<p>
	nvmتتضمّن حزمة <code>nodejs</code> الملف الثنائي <code>nodejs</code> بالإضافة إلى <code>npm</code>. لذلك، فلست بحاجةٍ لتثبيت <code>npm</code> على حدة.
</p>

<p>
	يستخدم <code>npm</code> ملف إعدادات في دليلك الرّئيسيّ لتعقّب التّحديثات. سيُنشَئ هذا الملف عند المرّة الأولى التي تقوم بها بتشغيل <code>npm</code>. قم بتنفيذ هذا الأمر للتّحقق أنّ <code>npm</code> مُثبّتة بالفعل وإنشاء ملف الإعدادت هذا:
</p>

<pre class="ipsCode">
<span class="hljs-built_in">npm</span> -v
</pre>

<p>
	وسترى خرجًا مشابهًا للتّالي:
</p>

<pre class="ipsCode" id="ips_uid_9543_6">
6.4.1
</pre>

<p>
	لكي يتسنّى لبعض حزم <code>npm</code> أن تعمل (تتطلّب تلك الحزم على سبيل المثال ترجمة الشّيفرة البرمجيّة من المصدر)، أنت بحاجةٍ لتثبيت حزمة <code>build-essential</code>:
</p>

<pre class="ipsCode">
sudo apt <span class="hljs-keyword">install</span> <span class="hljs-keyword">build</span>-essential
</pre>

<p>
	أصبح لديك الآن الأدوات الضّروريّة للعمل مع حزم <code>npm</code> التي تتطلّب ترجمة الشيفرة البرمجيّة من المصدر.
</p>

<h2 id="-nvm">
	التثبيت باستخدام NVM
</h2>

<p>
	كبديلٍ عن تثبيت Node.js باستخدام <code>apt</code>، يمكنك استخدام أداة <code>nvm</code>، هذه الأداة هي مدير إصدارات المنصة (Node.js Version Manager). عوضًا عن العمل على مستوى نظام التشغيل، تعمل <code>nvm</code> على مستوى مجلد مستقلٍّ داخل مجلدك الرّئيسيّ. هذا يعني أنّ بإمكانك تثبيت عدّة إصدارات قائمة بحدّ ذاتها من Node.js ضمن المجلد الرّئيسيّ دون التّأثير على النّظام بأكمله.
</p>

<p>
	يسمح لك ضبط بيئتك باستخدام <code>nvm</code> بالوصول إلى أحدث إصدارات Node.js وفي الوقت ذاته الإبقاء على الإصدارات السابقة وإدارتها بفعاليّة. إنّها وسيلة مختلفةٌ كليًّا عن <code>apt</code> كما أنّ إصدارات Node.js التي تديرها باستخدام <code>nvm</code> مميّزة عن تلك التي تديرها باستخدام <code>apt</code>.
</p>

<p>
	يمكنك استخدام <code>curl</code> لتنزيل البرنامج النّصي الخاص بتثبيت <code>nvm</code> من <a href="https://github.com/nvm-sh/nvm" rel="external nofollow">صفحة المشروع على GitHub</a>. لاحظ أنّ رقم الإصدار قد يختلف عمّا هو موجود في هذا الدّليل:
</p>

<pre class="ipsCode">
curl -sL http<span class="hljs-variable">s:</span>//raw.githubusercontent.<span class="hljs-keyword">com</span>/creationix/nvm/v0.<span class="hljs-number">33.11</span>/install.<span class="hljs-keyword">sh</span> -<span class="hljs-keyword">o</span> install_nvm.<span class="hljs-keyword">sh</span>
</pre>

<p>
	تفحّص البرنامج النّصي للتّثبيت باستخدام<code>nano</code>:
</p>

<pre class="ipsCode">
<span class="hljs-selector-tag">nano</span> <span class="hljs-selector-tag">install_nvm</span><span class="hljs-selector-class">.sh</span>
</pre>

<p>
	قم بتنفيذ البرنامج النّصي باستخدام <code>bash</code>:
</p>

<pre class="ipsCode">
<span class="hljs-keyword">bash </span>install_nvm.sh
</pre>

<p>
	سيثبِّت الأمر السّابق البرمجيّة في مجلد فرعيّ من المجلد الرئيسي ضمن الملف <code>‎~/.nvm</code> كما سيضيف الأسطر اللازمة إلى الملف <code>‎~/.profile</code> لاستخدام الملف المذكور.
</p>

<p>
	لتستطيع النّفاذ إلى قدرات <code>nvm</code> الوظيفيّة، ستحتاج إما لتسجيل الخروج ومن ثمّ تسجيل الدّخول مرة أخرى أو إعادة تحميل الملف <code>~/.profile</code> باستخدام الأمر <code>source</code> وذلك حتى تدرك الجلسة الحاليّة التّغييرات التي أحدثتها.
</p>

<pre class="ipsCode">
<span class="hljs-keyword">source</span> ~/.<span class="hljs-keyword">profile</span>
</pre>

<p>
	الآن بعد أن قمت بتثبيت <code>nvm</code>، يمكنك تثبيت إصدارات معزولةٍ من Node.js. للحصول على معلومات حول إصدارات Node.js المتوفّرة، نفذ الأمر التّالي:
</p>

<pre class="ipsCode">
<span class="hljs-attribute">nvm ls-remote</span>
</pre>

<p>
	سيظهر لك خرجٌ مشابهٌ لما يلي:
</p>

<pre class="ipsCode" id="ips_uid_9543_8">
...
        v10.15.3   (Latest LTS: Dubnium)
        v11.0.0
        v11.1.0
        v11.2.0
        v11.3.0
        v11.4.0
        v11.5.0
        v11.6.0
        v11.7.0
        v11.8.0
        v11.9.0
        v11.10.0
        v11.10.1
        v11.11.0
        v11.12.0
        v11.13.0
        v11.14.0
        v11.15.0
        v12.0.0
        v12.1.0
        v12.2.0
</pre>

<p>
	كما ترى، الإصدار ذو الدّعم الطّويل الأمد الحالي عند كتابة هذا الدّليل هو v10.15.3، يمكنك تثبيته من خلال الأمر التّالي:
</p>

<pre class="ipsCode">
<span class="hljs-selector-tag">nvm</span> <span class="hljs-selector-tag">install</span> 10<span class="hljs-selector-class">.15</span><span class="hljs-selector-class">.3</span>
</pre>

<p>
	عادة ما تُبدّل <code>nvm</code> لاستخدام الإصدار الأحدث. يمكنك أن تحدّد الإصدار الذي قمت بتحميله توًّا لتستخدمه <code>nvm</code> من خلال الأمر:
</p>

<pre class="ipsCode">
<span class="hljs-selector-tag">nvm</span> <span class="hljs-selector-tag">use</span> 10<span class="hljs-selector-class">.15</span><span class="hljs-selector-class">.3</span>
</pre>

<p>
	عندما تُثبّت Node.js باستخدام <code>nvm</code>، فإنّ الملف التنفيذي يحمل الاسم <code>node</code>. يمكنك معرفة الإصدار الذي تستخدمه الصّدفة (Shell) لديك من خلال الأمر التّالي:
</p>

<pre class="ipsCode">
<span class="hljs-keyword">node</span> <span class="hljs-title">-v</span>
</pre>

<p>
	وسيكون الخرج:
</p>

<pre class="ipsCode" id="ips_uid_9543_10">
v10.15.3
</pre>

<p>
	إذا كان لديك أكثر من إصدار Node.js، يمكنك معاينتها بكتابة الأمر:
</p>

<pre class="ipsCode">
<span class="hljs-attribute">nvm ls</span>
</pre>

<p>
	إذا رغبت بتحديد أحد هذه الإصدارات كافتراضيّ، نفذ الأمر التالي:
</p>

<pre class="ipsCode">
nvm alias <span class="hljs-section">default</span> <span class="hljs-number">10.15</span><span class="hljs-number">.3</span>
</pre>

<p>
	سيتم اختيار هذا الإصدار تلقائيًّا عند الشّروع في جلسةٍ جديدة. يمكنك أيضًا الإشارة إلى الإصدار باسم بديل (Alias) كما يلي:
</p>

<pre class="ipsCode">
nvm <span class="hljs-keyword">use</span> <span class="hljs-keyword">default</span>
</pre>

<p>
	يقوم كل إصدار من Node.js بتعقب حزمه ويتوفر لديه <code>npm</code> خاصّ لإدارة هذه الحزم.
</p>

<p>
	يمكنك استخدام <code>npm</code> لتثبيت حزم إلى دليل مشروع Node.js وهو <code>‎./node_modules</code>. استخدم الصّياغة التّالية لتثبيت الوحدة <code>express</code>:
</p>

<pre class="ipsCode">
npm <span class="hljs-keyword">install</span> express
</pre>

<p>
	إذا أردت تثبيت الوحدة على نحوٍ عموميٍّ (Global) لجعلها متاحةً للمشاريع الأخرى باستخدام الإصدار نفسه من Node.js، يمكنك إضافة الراية <code>‎-g</code>:
</p>

<pre class="ipsCode">
npm <span class="hljs-keyword">install</span> -g express
</pre>

<p>
	سيقوم الأمر السّابق بتثبيت الحزمة في:
</p>

<pre class="ipsCode">
~<span class="hljs-regexp">/.nvm/versions</span><span class="hljs-regexp">/node/node</span>_version/<span class="hljs-class"><span class="hljs-keyword">lib</span>/<span class="hljs-title">node_modules</span>/<span class="hljs-title">express</span></span>
</pre>

<p>
	سيسمح لك تثبيت الوحدة على نحوٍ عموميٍّ بتنفيذ أوامر من سطر الأوامر، لكن سيكون عليك ربط الحزمة في النّطاق الخاص بك لطلبها من داخل برنامج ما:
</p>

<pre class="ipsCode">
<span class="hljs-built_in">npm</span> link express
</pre>

<p>
	يمكنك الاطلاع على المزيد من الخيارات التي يوفرها <code>nvm</code> بكتابة الأمر التالي:
</p>

<pre class="ipsCode">
nvm <span class="hljs-built_in">help</span>
</pre>

<h2 id="-node-js">
	حذف منصة Node.js
</h2>

<p>
	يمكنك حذف Node.js باستخدام <code>apt</code> أو <code>apt</code> تبعًا للإصدار الذي تريد حذفه. لحذف إصدار التّوزيعة المستقرّة، عليك أن تستخدم الأداة <code>apt</code> على مستوى النّظام.
</p>

<p>
	لحذف إصدار التّوزيعة المستقرّة، استخدم الأمر الآتي:
</p>

<pre class="ipsCode">
sudo apt <span class="hljs-built_in">remove</span> nodejs
</pre>

<p>
	سيحذف هذا الأمرُ الحزمةَ ويحتفظ بملفات الإعدادات. قد تكون هذه الملفات ذات فائدة لك إذا ما رغبت بتثبيت الحزمة مرة أخرى بعد مرور الوقت. إن لم ترد الاحتفاظ بملف الإعدادات لاستخدامه لاحقًا، قم بتنفيذ الأمر التالي:
</p>

<pre class="ipsCode">
<span class="hljs-attribute">sudo apt purge nodejs</span>
</pre>

<p>
	سيقوم هذا الأمر بإلغاء تثبيت الحزمة وحذف ملفات الإعدادات المرافقة لها.
</p>

<p>
	كخطوة أخيرة، يمكنك حذف جميع الحزم غير المستخدمة والتي تم تثبيتها تلقائيًّا مع الحزم التي قمت بحذفها توًّا باستخدام الأمر التالي:
</p>

<pre class="ipsCode">
<span class="hljs-attribute">sudo apt autoremove</span>
</pre>

<p>
	لإلغاء تثبيت إصدار قمت بتفعليه باستخدام <code>nvm</code> ، تحقق أولًّا فيما إذا كان الإصدار المعنيّ هو الإصدار النشط حاليًّا:
</p>

<pre class="ipsCode">
<span class="hljs-attribute">nvm current</span>
</pre>

<p>
	إذا <strong>لم يكن</strong> الإصدار المستهدف هو الإصدار النّشط حاليًّا، نفذ الأمر التّالي:
</p>

<pre class="ipsCode">
<span class="hljs-attribute">nvm</span> uninstall node_version
</pre>

<p>
	سيقوم هذا الأمر بإلغاء تثبيت الإصدار المختار من Node.js.
</p>

<p>
	أمّا إذا <strong>كان</strong> الإصدار الذي ترغب بحذفه هو الإصدار النشط، عليك أولًا إلغاء تفعيل <code>nvm</code> لتمكين التّغييرات التي ستقوم بإجرائها:
</p>

<pre class="ipsCode">
<span class="hljs-attribute">nvm deactivate</span>
</pre>

<p>
	يمكنك الآن إلغاء تثبيت الإصدار الحالي باستخدام أمر <code>uninstall</code> المستخدم أعلاه والذي سيقوم بحذف جميع الملفات المرافقة للإصدار المعني من Node.js ما عدا الملفات المخبّأة والتي يمكن استخدامها لاحقًا لإعادة التّثبيت.
</p>

<h2 id="-">
	الخاتمة
</h2>

<p>
	هناك بالفعل العديد من الطّرق للبدء باستخدام Node.js على خادم أبونتو 18.04. عادةً ما تملي الظروف أيًّا من الطرق المذكورة أعلاه هي الأفضل. وفي حين أنّ استخدام الإصدار الموجود في مستودع أبونتو هو الخيار الأسهل، يُقدّم استخدام <code>nvm</code> خيارات ومرونةً أكثر.
</p>

<p>
	ترجمة -وبتصرف- للمقال <a href="https://www.digitalocean.com/community/tutorials/how-to-install-node-js-on-ubuntu-18-04" rel="external nofollow">How To Install Node.js on Ubuntu 18.04</a> لصاحبيه Brennen Bearnes و Kathleen Juell
</p>
]]></description><guid isPermaLink="false">419</guid><pubDate>Wed, 22 May 2019 18:09:37 +0000</pubDate></item><item><title>&#x62A;&#x62B;&#x628;&#x64A;&#x62A; &#x62C;&#x627;&#x641;&#x627; &#x639;&#x644;&#x649; &#x623;&#x628;&#x648;&#x646;&#x62A;&#x648; 18.04 &#x628;&#x627;&#x633;&#x62A;&#x62E;&#x62F;&#x627;&#x645; &#x627;&#x644;&#x623;&#x62F;&#x627;&#x629; apt</title><link>https://academy.hsoub.com/devops/linux/%D8%AA%D8%AB%D8%A8%D9%8A%D8%AA-%D8%AC%D8%A7%D9%81%D8%A7-%D8%B9%D9%84%D9%89-%D8%A3%D8%A8%D9%88%D9%86%D8%AA%D9%88-1804-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-%D8%A7%D9%84%D8%A3%D8%AF%D8%A7%D8%A9-apt-r418/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2020_09/5f50b3bb1e174_installjavaonlinux.png.9c8ffb683187cddb34b61f5980a9201d.png" /></p>

<p>
	نحتاج إلى كلٍّ من جافا (Java) وآلة جافا الوهميّة (Java Virtual Machine) لتشغيل العديد من البرمجيّات مثل <a href="http://tomcat.apache.org/" rel="external nofollow">Tomcat</a>، و <a href="https://www.eclipse.org/jetty/" rel="external nofollow">Jetty</a>، و <a href="https://javaee.github.io/glassfish/" rel="external nofollow">Glassfish</a>، و <a href="http://cassandra.apache.org/" rel="external nofollow">Cassandra</a>، و <a href="https://jenkins.io/" rel="external nofollow">Jenkins</a>.
</p>

<p>
	سنتعلم في هذا الدّليل كيفية تثبيت إصدارات مختلفة من (Java Runtime Environment (JRE و (Java Developer Kit (JDK باستخدام <code>apt</code>. سنثبِّت OpenJDK بالإضافة إلى الحزم الرّسميّة من موقع Oracle، سنختار بعدئذٍ الإصدار الذي تريد استخدامه لمشروعك. ستستطيع عند الانتهاء من استخدام JDK لتطوير البرمجيّات أو استخدام Java Runtime لتنفيذ البرمجيّات.
</p>

<p>
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="29601" href="https://academy.hsoub.com/uploads/monthly_2019_05/5ce6ded387504_.png.207970d5fa69f6a46cae88bf9671b93a.png" rel=""><img alt="تثبيت جافا.png" class="ipsImage ipsImage_thumbnailed" data-fileid="29601" data-unique="4f6eqqp3g" src="https://academy.hsoub.com/uploads/monthly_2019_05/5ce6ded4497ec_.thumb.png.7f7e52543f93b57f60c574a61fde89a0.png"></a>
</p>

<h2 id="-">
	المتطلبات
</h2>

<p>
	ستحتاج لمتابعة هذا الدّليل إلى:
</p>

<ul>
<li>
		خادم أبنتو 18.04 سبق إعداده باتّباع <a href="https://www.digitalocean.com/community/tutorials/initial-server-setup-with-ubuntu-18-04" rel="external nofollow">خطوات دليل إعداد الخادم الابتدائي</a>، وهذا يتضمّن سحاب مستخدم غير جذر (non-root) ذا امتيازات sudo وجدارًا ناريًّا.
	</li>
</ul>
<h2 id="-jre-jdk-">
	تثبيت JRE/JDK الافتراضيّة
</h2>

<p>
	الخيار الأسهل عند تثبيت جافا هو استخدام الإصدارات المُضمّنة مع أبنتو. يتضمّن أوبنتو 18.04 افتراضيًّا Open JDK والتي هي تنويعة مفتوحة المصدر من JRE و JDK.
</p>

<p>
	لتثبيت الإصدار 11 من OpenJDK، قُم أوّلًا بتحديث فهرس الحزمة:
</p>

<pre class="ipsCode" id="ips_uid_8776_6">
    sudo apt update
</pre>

<p>
	تحقّق بعد ذلك إذا ما كانت جافا مُثبّتةً بالفعل:
</p>

<pre class="ipsCode">
    java -<span class="hljs-built_in">version</span>
</pre>

<p>
	إذا لم تكن جافا مُثبّتةً، سترى الخرج التّالي:
</p>

<pre class="ipsCode">
Output
Command <span class="hljs-string">'java'</span> not found, <span class="hljs-keyword">but </span>can <span class="hljs-keyword">be </span><span class="hljs-keyword">installed </span>with:

apt <span class="hljs-keyword">install </span>default-<span class="hljs-keyword">jre
</span>apt <span class="hljs-keyword">install </span>openjdk-11-<span class="hljs-keyword">jre-headless
</span>apt <span class="hljs-keyword">install </span>openjdk-8-<span class="hljs-keyword">jre-headless
</span>apt <span class="hljs-keyword">install </span>openjdk-9-<span class="hljs-keyword">jre-headless</span>
</pre>

<p>
	نفّذ الأمر التّالي لتثبيت OpenJDK:
</p>

<pre class="ipsCode">
<span class="hljs-title">sudo</span> apt install <span class="hljs-keyword">default</span>-jre
</pre>

<p>
	سيُثبّت هذا الأمر بيئة التشغيل الآني لجافا (JRE اختصار للعبارة Java Runtime Environment) التي ستسمح لك بتشغيل جميع برمجيّات جافا تقريبًا.
</p>

<p>
	تحقّق من التّثبيت باستخدام:
</p>

<pre class="ipsCode">
java -<span class="hljs-built_in">version</span>
</pre>

<p>
	سترى الخرج التّالي:
</p>

<pre class="ipsCode">
Output
openjdk version <span class="hljs-string">"11.0.3"</span> <span class="hljs-number">2019</span><span class="hljs-number">-04</span><span class="hljs-number">-16</span>
OpenJDK Runtime Environment (build <span class="hljs-number">11.0</span><span class="hljs-number">.3</span>+<span class="hljs-number">7</span>-Ubuntu<span class="hljs-number">-1</span>ubuntu218<span class="hljs-number">.04</span><span class="hljs-number">.1</span>)
OpenJDK <span class="hljs-number">64</span>-Bit Server VM (build <span class="hljs-number">11.0</span><span class="hljs-number">.3</span>+<span class="hljs-number">7</span>-Ubuntu<span class="hljs-number">-1</span>ubuntu218<span class="hljs-number">.04</span><span class="hljs-number">.1</span>, mixed mode, sharing)
</pre>

<p>
	قد تحتاج إلى أدوات جافا التطويرية (JDK اختصار للعبارة Java Development Kit) إلى جانب JRE إذا أردت ترجمة وتشغيل بعض البرمجيّات المعتمدة على جافا. لتثبيت JDK، قم بتنفيذ الأمر التّالي:
</p>

<pre class="ipsCode">
<span class="hljs-title">sudo</span> apt install <span class="hljs-keyword">default</span>-jdk
</pre>

<p>
	سيثبت هذا الأمر JRE أيضًا.
</p>

<p>
	تحقّق من تثبيت JDK من خلال تفحّص إصدار مصرِّف جافا <code>javac</code>:
</p>

<pre class="ipsCode">
javac -<span class="hljs-built_in">version</span>
</pre>

<p>
	سترى الخرج التّالي:
</p>

<pre class="ipsCode" id="ips_uid_8776_9">
javac 11.0.3</pre>

<p>
	سنعمل الآن على تحديد الإصدار الذي نريد تثبيته من OpenJDK.
</p>

<h2 id="-openjdk">
	تثبيت إصدارات محددة من OpenJDK
</h2>

<p>
	بالإضافة إلى تثبيت حزمة OpenJDK الافتراضية، يمكنك أيضًا تثبيت إصدارات مختلفة من OpenJDK. ستتعلّم في هذا الدّليل تثبيت الإصدارين الحاليّ والسّابق من الإصدارات ذات الدّعم الطّويل الأمد.
</p>

<h3 id="-openjdk-8-">
	<strong>OpenJDK 8</strong>
</h3>

<p>
	جافا 8 هي إحدى الإصدارات ذات الدّعم الطّويل الأمد من Oracle. على الرّغم من انتهاء صيانتها العامّة منذ كانون الثّاني من هذا العام إلّا أن التّحديثات العامّة للإصدارات الشّخصيّة وإصدارات التّطوير مستمرّة حتى كانون الأوّل 2020. لتثبيت OpenJDK 8، قم بتنفيذ الأمر التّالي:
</p>

<pre class="ipsCode">
    sudo apt <span class="hljs-keyword">install</span> openjdk-<span class="hljs-number">8</span>-jdk
</pre>

<p>
	تحقّق من التّثبيت من خلال الأمر:
</p>

<pre class="ipsCode">
    java -<span class="hljs-built_in">version</span>
</pre>

<p>
	سيظهر لك الخرج التّالي:
</p>

<pre class="ipsCode">
Output
openjdk version <span class="hljs-string">"1.8.0_162"</span>
OpenJDK Runtime Environment (build <span class="hljs-number">1.8</span><span class="hljs-number">.0</span>_162<span class="hljs-number">-8</span>u162-b12<span class="hljs-number">-1</span>-b12)
OpenJDK <span class="hljs-number">64</span>-Bit Server VM (build <span class="hljs-number">25.162</span>-b12, mixed mode)
</pre>

<p>
	من المُمكن تثبيت JRE فقط من خلال تنفيذ الأمر <code>sudo apt install openjdk-8-jre</code>.
</p>

<h3 id="-openjdk-11-">
	<strong>OpenJDK 11</strong>
</h3>

<p>
	جافا 11 هي الإصدار الحاليّ ذي الدّعم الدّعم الطّويل الأمد ومن المُتوقّع أن يستمرّ دعمها حتّى العام 2022 .
</p>

<p>
	لتثبيت OpenJDK 11، قم بتنفيذ الأمر التّالي:
</p>

<pre class="ipsCode">
    sudo apt <span class="hljs-keyword">install</span> openjdk-<span class="hljs-number">11</span>-jdk
</pre>

<p>
	لتثبيت JRE فقط، استخدم الأمر التّالي:
</p>

<pre class="ipsCode">
    sudo apt <span class="hljs-keyword">install</span> openjdk-<span class="hljs-number">11</span>-jre
</pre>

<p>
	سنقوم الآن بتثبيت حزم JDK و JRE الرّسميّة من Oracle.
</p>

<h2 id="-oracle-jdk">
	تثبيت Oracle JDK
</h2>

<p>
	إذا أردت تثبيت Oracle JDK، الإصدار الرّسمي الذي توزعه Oracle، ستحتاج لإضافة مستودع حزمة جديد للإصدار الذي ترغب باستخدامه.
</p>

<p>
	لتثبيت جافا 8، قم أولًا بإضافة مستودع حزمته:
</p>

<pre class="ipsCode">
    sudo<span class="hljs-built_in"> add-apt-repository </span>ppa:webupd8team/java
</pre>

<p>
	عند إضافة المستودع، سترى رسالةً كهذه:
</p>

<pre class="ipsCode">
Output
Oracle Java (JDK) Installer (automatically downloads <span class="hljs-keyword">and</span> installs Oracle JDK8). There are no actuJava
 <span class="hljs-built_in">files</span> <span class="hljs-keyword">in</span> this PPA.

Important -&gt; Why Oracle Java <span class="hljs-number">7</span> And <span class="hljs-number">6</span> Installers No Longer Work: <span class="hljs-keyword">http</span>://www.webupd8.org/<span class="hljs-number">2017</span>/<span class="hljs-number">06</span>/why-oracl
e-java<span class="hljs-number">-7</span>-<span class="hljs-keyword">and</span><span class="hljs-number">-6</span>-installers-no.html

Update: Oracle Java <span class="hljs-number">9</span> has reached <span class="hljs-function"><span class="hljs-keyword">end</span> <span class="hljs-title">of</span> <span class="hljs-title">life</span>: <span class="hljs-title">http</span>://<span class="hljs-title">www</span>.<span class="hljs-title">oracle</span>.<span class="hljs-title">com</span>/<span class="hljs-title">technetwork</span>/<span class="hljs-title">java</span>/<span class="hljs-title">javase</span>/<span class="hljs-title">downloads</span>/<span class="hljs-title">j</span></span>
dk9-downloads<span class="hljs-number">-3848520.</span>html

The PPA supports Ubuntu <span class="hljs-number">18.04</span>, <span class="hljs-number">17.10</span>, <span class="hljs-number">16.04</span>, <span class="hljs-number">14.04</span> <span class="hljs-keyword">and</span> <span class="hljs-number">12.04</span>.

More info (<span class="hljs-keyword">and</span> Ubuntu installation instructions):
- <span class="hljs-keyword">for</span> Oracle Java <span class="hljs-number">8</span>: <span class="hljs-keyword">http</span>://www.webupd8.org/<span class="hljs-number">2012</span>/<span class="hljs-number">09</span>/install-oracle-java<span class="hljs-number">-8</span>-<span class="hljs-keyword">in</span>-ubuntu-via-ppa.html

Debian installation instructions:
- Oracle Java <span class="hljs-number">8</span>: <span class="hljs-keyword">http</span>://www.webupd8.org/<span class="hljs-number">2014</span>/<span class="hljs-number">03</span>/how-<span class="hljs-built_in">to</span>-install-oracle-java<span class="hljs-number">-8</span>-<span class="hljs-keyword">in</span>-debian.html

For Oracle Java <span class="hljs-number">10</span>, see <span class="hljs-keyword">a</span> different PPA: <span class="hljs-keyword">https</span>://www.linuxuprising.com/<span class="hljs-number">2018</span>/<span class="hljs-number">04</span>/install-oracle-java<span class="hljs-number">-10</span>-<span class="hljs-keyword">in</span>-ubuntu-<span class="hljs-keyword">or</span>.html

More info: <span class="hljs-keyword">https</span>://launchpad.net/~webupd8team/+archive/ubuntu/java
Press [ENTER] <span class="hljs-built_in">to</span> continue <span class="hljs-keyword">or</span> Ctrl-c <span class="hljs-built_in">to</span> <span class="hljs-built_in">cancel</span> adding <span class="hljs-keyword">it</span>.
</pre>

<p>
	اضغط <code>ENTER</code> للاستمرار ثمّ قُم بتحديث قائمة الحزم:
</p>

<pre class="ipsCode">
<span class="hljs-attribute">    sudo apt update</span>
</pre>

<p>
	حالما تُحدَّث القائمة، قُم بتثبيت جافا 8:
</p>

<pre class="ipsCode">
    sudo apt <span class="hljs-keyword">install</span> <span class="hljs-keyword">oracle</span>-java8-installer
</pre>

<p>
	سيُنزّل نظامك JDK من Oracle ويطلب منك قبول اتفاقيّة التّرخيص. قُم بالموافقة على الاتفاقيّة وسيبدأ تثبيت JDK.
</p>

<p>
	سننظر الآن إلى إمكانيّة اختيار إصدار جافا الذي ترغب باستخدامه.
</p>

<h2 id="-">
	إدارة جافا
</h2>

<p>
	قد يتوفّر لديك عدّة إصدارات جافا مُثبّتةٍ على خادمٍ واحد. يمكنك إعداد أيٍّ من هذه الإصدارات ليكون الافتراضي لديك أو استخدام سطر الأوامر من خلال الأمر<code>update-alternatives</code>:
</p>

<pre class="ipsCode">
    sudo <span class="hljs-keyword">update</span>-alternatives <span class="hljs-comment">--config java</span>
</pre>

<p>
	إذا ثبَّت جميع إصدارات جافا في هذا الدّليل، سيبدو الخرج لديك كالتّالي:
</p>

<pre class="ipsCode">
Output
There are <span class="hljs-number">3</span> choices <span class="hljs-keyword">for</span> the alternative java (providing /usr/bin/java).

  Selection    Path                                            Priority   Status
------------------------------------------------------------
* <span class="hljs-number">0</span>            /usr/<span class="hljs-class"><span class="hljs-keyword">lib</span>/<span class="hljs-title">jvm</span>/<span class="hljs-title">java</span>-11-<span class="hljs-title">openjdk</span>-<span class="hljs-title">amd64</span>/<span class="hljs-title">bin</span>/<span class="hljs-title">java</span>      1101      <span class="hljs-title">auto</span> <span class="hljs-title">mode</span></span>
  <span class="hljs-number">1</span>            /usr/<span class="hljs-class"><span class="hljs-keyword">lib</span>/<span class="hljs-title">jvm</span>/<span class="hljs-title">java</span>-11-<span class="hljs-title">openjdk</span>-<span class="hljs-title">amd64</span>/<span class="hljs-title">bin</span>/<span class="hljs-title">java</span>      1101      <span class="hljs-title">manual</span> <span class="hljs-title">mode</span></span>
  <span class="hljs-number">2</span>            /usr/<span class="hljs-class"><span class="hljs-keyword">lib</span>/<span class="hljs-title">jvm</span>/<span class="hljs-title">java</span>-8-<span class="hljs-title">openjdk</span>-<span class="hljs-title">amd64</span>/<span class="hljs-title">jre</span>/<span class="hljs-title">bin</span>/<span class="hljs-title">java</span>   1081      <span class="hljs-title">manual</span> <span class="hljs-title">mode</span></span>
  <span class="hljs-number">3</span>            /usr/<span class="hljs-class"><span class="hljs-keyword">lib</span>/<span class="hljs-title">jvm</span>/<span class="hljs-title">java</span>-8-<span class="hljs-title">oracle</span>/<span class="hljs-title">jre</span>/<span class="hljs-title">bin</span>/<span class="hljs-title">java</span>          1081      <span class="hljs-title">manual</span> <span class="hljs-title">mode</span></span>
</pre>

<p>
	اختر الرّقم الموافق لإصدار جافا الذي ترغب في استخدامه افتراضيّا، أو اضغط <code>ENTER</code> لترك الإعدادت على ما هي عليه.
</p>

<p>
	يمكنك القيام بهذا لأوامر جافا أخرى، مثل المترجم (<code>javac</code>):
</p>

<pre class="ipsCode">
    sudo <span class="hljs-keyword">update</span>-alternatives <span class="hljs-comment">--config javac</span>
</pre>

<p>
	نذكر على سبيل المثال لا الحصر من بعض الأوامر الأخرى التي يمكنك تنفيذ ما سبق عليها: <code>keytool</code>، <code>Javadoc</code> و <code>jarsigner</code>.
</p>

<h2 id="-java_home-">
	تعيين متغير البيئة <code>JAVA_HOME</code>
</h2>

<p>
	تستخدم العديد من البرامج المكتوبة باستخدام لغة جافا مُتغيّر البيئة <code>JAVA_HOME</code> لتحديد مسار تثبيت جافا.
</p>

<p>
	لتعيين مُتغيّر البيئة هذا، حدّد أولًا أين ثُبتّت جافا. استخدم الأمر <code>update-alternatives</code> كما يلي:
</p>

<pre class="ipsCode">
    sudo <span class="hljs-keyword">update</span>-alternatives <span class="hljs-comment">--config java</span>
</pre>

<p>
	سيعرض لك هذا الأمر جميع تثبيات جافا لديك مع مسار كلٍّ منها:
</p>

<pre class="ipsCode">
There are <span class="hljs-number">3</span> choices <span class="hljs-keyword">for</span> the alternative java (providing /usr/bin/java).

  Selection    Path                                            Priority   Status
------------------------------------------------------------
* <span class="hljs-number">0</span>            /usr/<span class="hljs-class"><span class="hljs-keyword">lib</span>/<span class="hljs-title">jvm</span>/<span class="hljs-title">java</span>-11-<span class="hljs-title">openjdk</span>-<span class="hljs-title">amd64</span>/<span class="hljs-title">bin</span>/<span class="hljs-title">java</span>      1101      <span class="hljs-title">auto</span> <span class="hljs-title">mode</span></span>
  <span class="hljs-number">1</span>            /usr/<span class="hljs-class"><span class="hljs-keyword">lib</span>/<span class="hljs-title">jvm</span>/<span class="hljs-title">java</span>-11-<span class="hljs-title">openjdk</span>-<span class="hljs-title">amd64</span>/<span class="hljs-title">bin</span>/<span class="hljs-title">java</span>      1101      <span class="hljs-title">manual</span> <span class="hljs-title">mode</span></span>
  <span class="hljs-number">2</span>            /usr/<span class="hljs-class"><span class="hljs-keyword">lib</span>/<span class="hljs-title">jvm</span>/<span class="hljs-title">java</span>-8-<span class="hljs-title">openjdk</span>-<span class="hljs-title">amd64</span>/<span class="hljs-title">jre</span>/<span class="hljs-title">bin</span>/<span class="hljs-title">java</span>   1081      <span class="hljs-title">manual</span> <span class="hljs-title">mode</span></span>
  <span class="hljs-number">3</span>            /usr/<span class="hljs-class"><span class="hljs-keyword">lib</span>/<span class="hljs-title">jvm</span>/<span class="hljs-title">java</span>-8-<span class="hljs-title">oracle</span>/<span class="hljs-title">jre</span>/<span class="hljs-title">bin</span>/<span class="hljs-title">java</span>          1081      <span class="hljs-title">manual</span> <span class="hljs-title">mode</span></span>

Press &lt;enter&gt; to keep the current choice[*], or <span class="hljs-keyword">type</span> selection <span class="hljs-symbol">number:</span>
</pre>

<p>
	في حالتنا هذه، فإنّ مسارات التّثبيت هي كالتّالي:
</p>

<ol>
<li>
		<p>
			OpenJDK 11 على المسار ‎<code>/usr/lib/jvm/java-11-openjdk-amd64/bin/java</code>.
		</p>
	</li>
	<li>
		<p>
			OpenJDK 8 على المسار ‎<code>/usr/lib/jvm/java-8-openjdk-amd64/jre/bin/java</code>.
		</p>
	</li>
	<li>
		<p>
			Oracle Java 8 على المسار ‎<code>/usr/lib/jvm/java-8-oracle/jre/bin/java</code>.
		</p>
	</li>
</ol>
<p>
	قُم بنسخ مسار الإصدار المفضّل لديك ثم افتح الملف ‎<code>/etc/environment</code> باستخدام <code>nano</code> أو محرّر النّصوص الذي تفضّله:
</p>

<pre class="ipsCode">
    sudo nano <span class="hljs-regexp">/etc/</span>environment
</pre>

<p>
	أَضِف السطر التّالي في نهاية هذا الملف وتأكّد من استبدال المسار الملّون بالمسار الذي قمت أنت بنسخه:
</p>

<pre class="ipsCode prettyprint lang-javascript prettyprinted" id="ips_uid_8776_16" style="">
<span class="pln">JAVA_HOME</span><span class="pun">=</span><span class="str">"/usr/lib/jvm/java-11-openjdk-amd64/bin/"</span></pre>

<p>
	سيضبط تعديل هذا الملف مسار <code>JAVA_HOME</code> لجميع المستخدمين على نظامك.
</p>

<p>
	احفظ تعديلاتك على الملف وأغلق المُحرّر.
</p>

<p>
	أعِد تحميل هذا الملف لتطبيق التعديلات على جلستك الحاليّة:
</p>

<pre class="ipsCode">
    <span class="hljs-keyword">source</span> <span class="hljs-regexp">/etc/</span>environment
</pre>

<p>
	تحقّق من تعيين مُتغيّر البيئة:
</p>

<pre class="ipsCode">
    <span class="hljs-built_in">echo</span> <span class="hljs-variable">$JAVA_HOME</span>
</pre>

<p>
	سترى المسار الذي قمت بتعيينه منذ قليل:
</p>

<pre class="ipsCode">
Output
/usr/<span class="hljs-class"><span class="hljs-keyword">lib</span>/<span class="hljs-title">jvm</span>/<span class="hljs-title">java</span>-11-<span class="hljs-title">openjdk</span>-<span class="hljs-title">amd64</span>/<span class="hljs-title">bin</span>/</span>
</pre>

<p>
	سيحتاج المستخدمون الآخرون إلى تنفيذ الأمر <code>source /etc/environment</code> أو تسجيل الخروج وإعادة تسجيل الدخول ليصبح هذا الضّبط نافذ المفعول.
</p>

<h2 id="-">
	خاتمة
</h2>

<p>
	قمتَ في هذا الدّليل بتثبيت عدة إصدارات من جافا وتعلّمت كيفيّة إدارة هذه الإصدارات. يمكنك الآن تثبيت برمجيات تعمل على Java مثل Tomcat، أو Jetty، أو  Glassfish، أو Cassandra، أو Jenkins.
</p>

<p>
	ترجمة -وبتصرف- للمقال <a href="https://www.digitalocean.com/community/tutorials/how-to-install-java-with-apt-on-ubuntu-18-04" rel="external nofollow">How To Install Java with <code>apt</code> on Ubuntu 18.04</a> لصاحبه Koen Vlaswinkel
</p>
]]></description><guid isPermaLink="false">418</guid><pubDate>Wed, 22 May 2019 13:03:00 +0000</pubDate></item><item><title>[&#x641;&#x64A;&#x62F;&#x64A;&#x648;] &#x625;&#x62F;&#x627;&#x631;&#x629; &#x627;&#x644;&#x645;&#x644;&#x641;&#x627;&#x62A; &#x641;&#x64A; &#x644;&#x64A;&#x646;&#x643;&#x633;</title><link>https://academy.hsoub.com/devops/linux/%D9%81%D9%8A%D8%AF%D9%8A%D9%88-%D8%A5%D8%AF%D8%A7%D8%B1%D8%A9-%D8%A7%D9%84%D9%85%D9%84%D9%81%D8%A7%D8%AA-%D9%81%D9%8A-%D9%84%D9%8A%D9%86%D9%83%D8%B3-r417/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2019_05/5ce069eb5b5d2_linux.png.608a07cf6fa202944894b26719bccf83.png" /></p>

<p>
	<iframe allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen="" frameborder="0" height="400" src="https://www.youtube.com/embed/yyhd0gmhJ7I" width="560"></iframe>
</p>

<p>
	نشرح في هذا الفيديو إدارة الملفات والمجلدات على نظام لينكس.
</p>

<p>
	الأوامر المشروحة في هذا الفيديو:
</p>

<ul>
<li>
		<code>pwd</code> لطباعة المجلد الحالي
	</li>
	<li>
		<code>cd</code> للتنقل بين المجلدات
	</li>
	<li>
		<code>ls</code> لعرض الملفات والمجلدات
	</li>
	<li>
		<code>touch</code> لإنشاء ملفات جديدة
	</li>
	<li>
		<code>mkdir</code> لإنشاء مجلدات جديدة
	</li>
	<li>
		<code>mv</code> لنقل الملفات والمجلدات
	</li>
	<li>
		<code>cp</code> لنسخ الملفات والمجلدات
	</li>
	<li>
		<code>rm</code> لحذف الملفات والمجلدات
	</li>
	<li>
		<code>ln</code> لإنشاء وصلات رمزية وصلبة
	</li>
</ul>
<p>
	قسم <a href="https://academy.hsoub.com/devops/linux/" rel="">لينكس</a> في أكاديمية حسوب غني بالمقالات المفيدة التي تشرح مختلف جوانب استعمال هذا النظام.
</p>
]]></description><guid isPermaLink="false">417</guid><pubDate>Sat, 18 May 2019 20:24:39 +0000</pubDate></item><item><title>&#x643;&#x64A;&#x641; &#x62A;&#x642;&#x635; &#x645;&#x642;&#x627;&#x637;&#x639; &#x627;&#x644;&#x641;&#x64A;&#x62F;&#x64A;&#x648; &#x628;&#x627;&#x633;&#x62A;&#x62E;&#x62F;&#x627;&#x645; AVConv &#x639;&#x644;&#x649; &#x633;&#x637;&#x631; &#x627;&#x644;&#x623;&#x648;&#x627;&#x645;&#x631;</title><link>https://academy.hsoub.com/devops/linux/%D9%83%D9%8A%D9%81-%D8%AA%D9%82%D8%B5-%D9%85%D9%82%D8%A7%D8%B7%D8%B9-%D8%A7%D9%84%D9%81%D9%8A%D8%AF%D9%8A%D9%88-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-avconv-%D8%B9%D9%84%D9%89-%D8%B3%D8%B7%D8%B1-%D8%A7%D9%84%D8%A3%D9%88%D8%A7%D9%85%D8%B1-r410/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2020_09/thumbnailpng.png.7123af42c300039655a913f6bc75bac4.png" /></p>

<p>
	فلنفترض أنّ لديك مقطع فيديو طويلًا تريد قطع جزء من وسطه دون أن تكلّف نفسك عناء استيراد المقطع إلى محرّر فيديو، وقطع أجزاء منه، ثم تصديره من جديد. هذه الطريقة مملّة، وعلاوةص على ذلك تغيّر ترميز (Transcoding) الفيديو لغير حاجة. توجد طريقة سهلة لقصّ مقاطع الفيديو من سطر الأوامر باستخدام برنامج avconv عن طريق تنفيذ الأمر التالي في سطر الأوامر:
</p>

<pre class="ipsCode" id="ips_uid_5784_8">
avconv -i [input file] -ss [start time] -t [duration] -codec copy [output file]
</pre>

<p>
	سنعطي مثالًا على كيفيّة تنفيذ الأمر أعلاه. فلنفترض أنّ لدينا مقطع فيديو يبدأ بـ 42 ثانية لا نرغب فيها.
</p>

<p>
	<img alt="01_41seconds.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="29270" data-unique="ddgqzqbaf" src="https://academy.hsoub.com/uploads/monthly_2019_04/01_41seconds.jpg.71abffa73a82850ea138db663d25df22.jpg"></p>

<p>
	نحتاج لتعيين المعامل <code>‎-ss</code> إلى القيمة <code>00:00:42</code>. يقبل هذا المعطى رمزًا زمنيًّا بصيغة "ثوان:دقائق:ساعات". يخبر المعامل البرنامج أنّنا نريد الإبقاء على محتوى الفيديو الموجود بعد 42 ثانية.
</p>

<p>
	ماذا لو كانت لدينا 12 ثانيّة أخرى غير مرغوب بها في آخر الفيديو؟. في هذه الحالة يمكننا استخدام المعامل <code>‎-t</code> لتحديد المدّة التي نريد الاحتفاظ بها من الفيديو. يوجد إشكال بسيط هنا، فقيمة المعامل <code>‎-t</code> هي مدّة زمنيّة وليست نقطة زمنيّة محدّدة، وهذه المدّة هي الطول الإجمالي للمقطع الناتج. يعني هذا أنّ ما كان يوجد عند النقطة الزمنيّة <code>00:00:42</code> سيصبح عند <code>00:00:00</code> في الملفّ الناتج عن القصّ. وبالتالي إنْ أردنا قصّ 12 ثانيّة من آخر الفيديو فسنحتاج لعمليّة حسابيّة بسيطة. توجد طريقة سهلة تتمثّل في طرح قيمة المعامل <code>‎-ss</code> من النقطة الزمنيّة التي تريد التوقّف عندها، واستخدام هذه القيمة في المعامل <code>‎-t</code>. إذا كنّا نريد التوقّف عند النقطة <code>00:04:08</code> فإنّ قيمة <code>‎-t</code> ستكون <code>00:03:26</code>.
</p>

<p>
	نحصُل في النهاية على الأمر التالي:
</p>

<pre class="ipsCode" id="ips_uid_5784_10">
avconv -i input.mkv -ss 00:00:42 -t 00:03:26 -codec copy output.mkv
</pre>

<p>
	لدينا الآن مقطع فيديو بطول 3 دقائق و26 ثانيّة.
</p>

<p>
	هذه هي طريقة قصّ الفيديو باستخدام avconv نظريّا. عمليًّا، قد تحتاج لتغيير بسيط. لسبب مّا لا يُنسَخ الصوت إلى الفيديو الناتج بطريقة جيّدة، لذا قد تحتاج لإعادة ترميز الصوت. إنْ واجهت هذه المشكلة فيمكنك التغلّب عليها بسهولة باستخدام الأمر التالي:
</p>

<pre class="ipsCode" id="ips_uid_5784_12">
avconv -i input.mkv -ss 00:00:42 -t 00:03:26 -c:v copy -c:a flac output.mkv
</pre>

<p>
	<img alt="02_alltrimmed.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="29271" data-unique="ez2buxwaw" src="https://academy.hsoub.com/uploads/monthly_2019_04/02_alltrimmed.jpg.8f8d242112ef0dd9b0903bdc6a127809.jpg"></p>

<p>
	يطلُب الأمرُ من البرنامج بنسخ ترميز الفيديو من المصدر، وفي نفس الأثناء إعادة ترميز الصوت إلى flac، الذي هو ترميز يضغط الصوت بدون فقد للمعلومات.
</p>

<p>
	ترجمة – بتصرّف – للمقال <a href="https://dototot.com/how-to-trim-videos-with-the-command-line-using-avconv/" rel="external nofollow">How to Trim Videos with the Command Line Using AVConv</a>.
</p>
]]></description><guid isPermaLink="false">410</guid><pubDate>Wed, 08 May 2019 13:00:00 +0000</pubDate></item><item><title>&#x643;&#x64A;&#x641; &#x62A;&#x646;&#x634;&#x626; &#x635;&#x648;&#x631;&#x64B;&#x627; &#x645;&#x62A;&#x62D;&#x631;&#x643;&#x629; &#x628;&#x635;&#x64A;&#x63A;&#x629; GIF &#x645;&#x646; &#x645;&#x62C;&#x645;&#x648;&#x639;&#x629; &#x635;&#x648;&#x631; PNG &#x628;&#x627;&#x633;&#x62A;&#x62E;&#x62F;&#x627;&#x645; ImageMagick &#x648;&#x633;&#x637;&#x631; &#x627;&#x644;&#x623;&#x648;&#x627;&#x645;&#x631;</title><link>https://academy.hsoub.com/devops/linux/%D9%83%D9%8A%D9%81-%D8%AA%D9%86%D8%B4%D8%A6-%D8%B5%D9%88%D8%B1%D9%8B%D8%A7-%D9%85%D8%AA%D8%AD%D8%B1%D9%83%D8%A9-%D8%A8%D8%B5%D9%8A%D8%BA%D8%A9-gif-%D9%85%D9%86-%D9%85%D8%AC%D9%85%D9%88%D8%B9%D8%A9-%D8%B5%D9%88%D8%B1-png-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-imagemagick-%D9%88%D8%B3%D8%B7%D8%B1-%D8%A7%D9%84%D8%A3%D9%88%D8%A7%D9%85%D8%B1-r409/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2020_09/thumbnail.png.6c9cf36e5a27f8cba102f6dbaa4e129c.png" /></p>

<p>
	يشرح هذا المقال كيفيّة إنشاء صور متحرّكة بصيغة GIF انطلاقًا من مجموعة صور بصيغة PNG عبر سطر الأوامر على لينكس (توزيعة أوبونتو).
</p>

<p>
	أدناه مثال على تجميع صور لإنشاء صورة متحرّكة تُستخدم لشدّ الانتباه.
</p>

<p>
	<img alt="01_shebang2.gif" class="ipsImage ipsImage_thumbnailed" data-fileid="29269" data-unique="b01slnkqx" src="https://academy.hsoub.com/uploads/monthly_2019_04/01_shebang2.gif.977f3df6195fcec17072257d1db1bb38.gif"></p>

<p>
	نبدأ أوّلًا بتثبيت الأداة ImageMagick التي سنستعملها خلال هذا الدرس:
</p>

<pre class="ipsCode" id="ips_uid_8934_6">
sudo apt install imagemagick
</pre>

<p>
	الخطوة التاليّة لتثبيت الأداة هي الانتقال إلى المجلّد الذي يحوي مجموعة الصوّر التي نريد استخدامها لإنشاء الصورة المتحرّكة. بالنسبة لهذا المثال فمسار المجلّد هو<code>Desktop/shebang</code> :
</p>

<pre class="ipsCode" id="ips_uid_8934_8">
cd Desktop/shebang
</pre>

<p>
	من السهل جدًّا استخدام ImageMagick وفهمُ آليّة عمله. يوفّر ImageMagick برنامجًا يُسمّى <code>convert</code>، هو الذي سنستخدمه لتحويل الصور. يمكن عبر الأمر التالي إظهار صفحة التوثيق الخاصّة بالبرنامج، والتي تشرح آليّة عمله:
</p>

<pre class="ipsCode" id="ips_uid_8934_10">
man convert
</pre>

<p>
	تُظهر صفحة التوثيق السطر التالي، والذي يوضح طريقة استخدام البرنامج:
</p>

<pre class="ipsCode" id="ips_uid_8934_12">
convert [input-option] input-file [output-option] output-file
</pre>

<p>
	نمرّر للبرنامج <code>convert</code> خيّارًا للإدخال، وملفًّا مُدخلًا، ونحدّد خيّارات عمليّة التحويل وأخيرًا اسم الملفّ الناتج عن عمليّة التحويل.
</p>

<p>
	نفّذ الأمر التالي في سطر الأوامر:
</p>

<pre class="ipsCode" id="ips_uid_8934_14">
convert -delay 2 -loop 0 *.png -scale 480x270 shebang.gif
</pre>

<p>
	فلنمرّ على الأمر أعلاه خطوة خطوة.
</p>

<p>
	الخيّار الأوّل هو <code>‎-delay</code>. يعيّن هذا الخيّار مدّة التوقّف بين إطارات الصورة المتحرّكة، بالأجزاء المئويّة من الثانيّة. أعطيناه هنا القيمة <code>2</code> (أي جزئيْن مئويّين من ثانيّة). نحدّد بعد ذلك عدد مرات تكرار التحريك عبر الخيّار <code>‎-loop</code>. نريد ألّا يتوقّف التحريك، لذا نعطي القيمة <code>0</code> للخيّار. إنْ أردنا تحريك الصورة لمرّة واحدة فقط، فستكون القيمة <code>1</code>، وإنْ أردنا تحريكها مرتين فالقيمة المناسبة هي <code>2</code>. نريد أن يكون مُدخَل البرنامج مجموعةً من الصوّر، لذا نستخدم حرف البدل <code>*</code> لإخبار برنامج <code>convert</code> أنّنا نريد استخدام جميع الصوّر الموجودة في مجلّد العمل التي تنتهي بـ<code>png</code>. لدينا صوّرPNG مُصدَّرة من برنامج Blender، وتبلغ أبعادها ‎1920 x 1080، وهو قيّاس كبير جدًّا ولا يناسب صوّر GIF المتحرّكة، فنحدّد أبعاد الملفّ الناتج عن التحويل عبر الخيّار <code>‎-scale</code> لتكون الأبعاد ‎.480×270 أخيرًا، ندخل اسم الملفّ الناتج وصيغته (<code>shebang.gif</code>).
</p>

<p>
	ترجمة – بتصرّف – للمقال <a href="https://dototot.com/how-to-create-animated-gifs-from-a-png-sequence-with-imagemagick-and-the-command-line/" rel="external nofollow">How To Create Animated GIFs from a PNG Sequence with ImageMagick and the Command Line</a>.
</p>
]]></description><guid isPermaLink="false">409</guid><pubDate>Wed, 01 May 2019 13:04:00 +0000</pubDate></item><item><title>[&#x641;&#x64A;&#x62F;&#x64A;&#x648;] &#x62C;&#x62F;&#x648;&#x644;&#x629; &#x627;&#x644;&#x645;&#x647;&#x627;&#x645; &#x639;&#x628;&#x631; cron</title><link>https://academy.hsoub.com/devops/linux/%D9%81%D9%8A%D8%AF%D9%8A%D9%88-%D8%AC%D8%AF%D9%88%D9%84%D8%A9-%D8%A7%D9%84%D9%85%D9%87%D8%A7%D9%85-%D8%B9%D8%A8%D8%B1-cron-r412/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2019_04/cron.png.caad9e5dd46a4e0bd44e41a0b42cce9f.png" /></p>

<p>
	<iframe allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen="" frameborder="0" height="400" width="560" src="https://www.youtube.com/embed/zcsGNNYkDgU"></iframe>
</p>

<p>
	نشرح في هذا الفيديو جدولة المهام باستخدام cron على أنظمة لينكس، مع ذكر عدّة أمثلة عملية عليه، وطريقة تعديل ملف crontab.
</p>

<p>
	قسم <a href="https://academy.hsoub.com/devops" rel="">DevOps</a> في أكاديمية حسوب غني بالمقالات المفيدة للتعامل مع الخوادم.
</p>
]]></description><guid isPermaLink="false">412</guid><pubDate>Tue, 30 Apr 2019 08:06:00 +0000</pubDate></item><item><title>&#x643;&#x64A;&#x641;&#x64A;&#x629; &#x62A;&#x647;&#x64A;&#x626;&#x629; &#x62A;&#x637;&#x628;&#x64A;&#x642; &#x627;&#x644;&#x645;&#x641;&#x643;&#x631;&#x629; Jupyter Notebook &#x644;&#x644;&#x639;&#x645;&#x644; &#x645;&#x639; &#x644;&#x63A;&#x629; &#x627;&#x644;&#x628;&#x631;&#x645;&#x62C;&#x629; Python 3</title><link>https://academy.hsoub.com/devops/linux/%D9%83%D9%8A%D9%81%D9%8A%D8%A9-%D8%AA%D9%87%D9%8A%D8%A6%D8%A9-%D8%AA%D8%B7%D8%A8%D9%8A%D9%82-%D8%A7%D9%84%D9%85%D9%81%D9%83%D8%B1%D8%A9-jupyter-notebook-%D9%84%D9%84%D8%B9%D9%85%D9%84-%D9%85%D8%B9-%D9%84%D8%BA%D8%A9-%D8%A7%D9%84%D8%A8%D8%B1%D9%85%D8%AC%D8%A9-python-3-r388/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2018_03/15.png.05045864866b54e4857f3d023cb15b0c.png" /></p>

<p>
	يؤمن تطبيق المفكرة Jupyter Notebook موجه أوامر تفاعلي شبيه بتطبيقات الويب، والذي يمكن استخدامه مع العديد من لغات البرمجة مثل Python و Julia و R و Haskell و Ruby، وذلك في التطبيقات الخاصة بالبيانات والإحصاء والذكاء الصناعي.<br>
	سيتم في هذه المقالة شرح طريقة تهيئة وإعداد تطبيق المفكرة Jupyter Notebook للعمل مع أكواد لغة البرمجة Python 3 محليًا أو من الخادم Ubuntu 16.04 server. إن تطبيق المفكرة Jupyter Notebook هو عبارة عن برنامج مفكرة يقوم بتوليد المستندات المتضمنة على الأكواد البرمجية والشروحات والصور والمخططات البيانية والمعادلات الرياضية، لاستخدامها في عرض وتطوير ومشاركة الأبحاث العلمية.
</p>

<h2 id="المتطلبات">
	المتطلبات
</h2>

<p>
	قبل البدء يجب توفر بيئة برمجية مهيّأة محليًا (على الحاسب الشخصي) أو على الخادم Ubuntu 16.04 مع امتلاك صلاحية مدير النظام (المستخدم الجذر root) أو استخدام الأمر <code>sudo</code> عند تنفيذ الأوامر في موجه أوامر لينكس.
</p>

<h2 id="الخطوة-الأولى--تنصيب-تطبيق-المفكرة-jupyter-notebook">
	الخطوة الأولى- تنصيب تطبيق المفكرة Jupyter Notebook
</h2>

<p>
	سيتم استخدام أداة إدارة الحزم <code>pip</code> لتنصيب تطبيق المفكرة Jupyter Notebook في بيئة Python البرمجية المُنشأة مسبقًا. لكن يجب في البداية الانتقال إلى المجلد<code>environment</code>s الخاص ببيئة Python البرمجية <code>my_env</code> المُنشأة مسبقًا وتفعيلها، وذلك بتنفيذ الأوامر التالية في موجه أوامر النظام:
</p>

<pre class="ipsCode" id="ips_uid_7048_7">
sammy@ubuntu:~$  cd ~/environments 
sammy@ubuntu:~/environments$  . my_env/bin/activate
(my_env) sammy@ubuntu:~/environments$</pre>

<p>
	ثم علينا التأكد من أن الأداة <code>pip</code> محدّثة لآخر إصدار وذلك بتنفيذ الأمر التالي:
</p>

<pre class="ipsCode" id="ips_uid_7048_7">
<code>(my_env) sammy@ubuntu:~/environments$ pip install --upgrade pip
</code></pre>

<p>
	ثم نقوم عن طريق الأداة <code>pip</code> بتنصيب تطبيق المفكرة Jupyter Notebook في البيئة البرمجية <code>my_env</code>، وذلك بتنفيذ الأمر التالي:
</p>

<pre class="ipsCode" id="ips_uid_7048_7">
<code>(my_env) sammy@ubuntu:~/environments$ pip install jupyter
</code></pre>

<p>
	وهكذا تم تنصيب تطبيق المفكرة Jupyter Notebook في البيئة البرمجية.<br>
	الخطوة التالية وهي اختيارية للذين يريدون الاتصال عبر قناة الاتصال <abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">SSH</abbr> بواجهة الويب التفاعلية لتطبيق المفكرة Jupyter Notebook المنصَّب على الخادم.
</p>

<h2 id="الخطوة-الثانية-اختيارية--الاتصال-بتطبيق-المفكرة-jupyter-notebook-المنصَّب-على-الخادم-عبر-قناة-الاتصال-ssh">
	الخطوة الثانية (اختيارية)- الاتصال بتطبيق المفكرة Jupyter Notebook المنصَّب على الخادم عبر قناة الاتصال <abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">SSH</abbr>
</h2>

<p>
	سيتم في هذه الخطوة شرح طريقة الاتصال بواجهة الويب التفاعلية لتطبيق المفكرة Jupyter Notebook المنصَّب مسبقًا على الخادم، وذلك عبر قناة الاتصال <abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">SSH</abbr>. حيث تؤمن قناة الاتصال <abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">SSH</abbr> اتصالاً آمنًا بتطبيق المفكرة Jupyter Notebook كونه يستخدم منفذ محدد في الخادم (مثل المنفذ <code>:8888</code> أو <code>:8889</code> الخ).<br>
	سيتم في الفقرتين التاليتين شرح طريقة إنشاء قناة الاتصال <abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">SSH</abbr>. الأولى من نظام التشغيل ماكنتوش أو لينكس، والثانية من نظام التشغيل ويندوز.
</p>

<h3 id="طريقة-إنشاء-قناة-الاتصال-ssh-من-نظام-التشغيل-ماكنتوش-أو-لينكس">
	طريقة إنشاء قناة الاتصال <abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">SSH</abbr> من نظام التشغيل ماكنتوش أو لينكس
</h3>

<p>
	سيتم في هذه الفقرة شرح طريقة إنشاء قناة اتصال <abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">SSH</abbr> من نظام التشغيل ماكنتوش أو لينكس، باستخدام الأمر <code><abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">ssh</abbr></code> مع مجموعة من المعاملات التي تؤمن نجاح عملية الاتصال.<br>
	يمكن إنشاء قناة اتصال <abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">SSH</abbr> جديدة بتنفيذ الأمر التالي في نافذة جديدة لموجه أوامر النظام:
</p>

<pre class="ipsCode" id="ips_uid_7048_7">
<code>$ <abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">ssh</abbr> -L 8888:localhost:8888 your_server_username@your_server_ip
</code></pre>

<p>
	حيث يستخدم الأمر <code><abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">ssh</abbr></code> من أجل فتح اتصال <abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">SSH</abbr>، في حين يستخدم العلم -L لتحديد المنفذ المعطى في المضيف المحلي (العميل) الذي سيتم توجيهه إلى المنفذ والمضيف البعيد (الخادم) المعطى، أي أن أي شيء سيعمل على المنفذ الثاني (مثلا <code>8888</code>) على الخادم، سيظهر على المنفذ الأول (مثلا <code>8888</code>) على العميل (الحاسب الشخصي). ويفضل تغيير رقم المنفذ <code>8888</code> إلى أي رقم آخر اختياري لتجنب وجود عملية أخرى تعمل على نفس المنفذ.<br>
	إن المُعامل <code>your_server_username</code> هو اسم المستخدم (مثلا <code>sammy</code>) الذي تم إنشاؤه مسبقًا على الخادم، والمُعامل <code>your_server_ip</code> هو عنوان IP للخادم (مثلا <code>203.0.113.0</code>). أي يصبح الأمر السابق بعد إدخال اسم المستخدم وعنوان IP للخادم كما يلي:
</p>

<pre class="ipsCode" id="ips_uid_7048_7">
<code>$ <abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">ssh</abbr> -L 8888:localhost:8888 sammy@203.0.113.0
</code></pre>

<p>
	وفي حال نجاح عملية الاتصال بالخادم وعدم حدوث أي خطأ، ينتقل موجه أوامر النظام إلى البيئة البرمجية المهيّأة مسبقًا على الخادم كما يلي:
</p>

<pre class="ipsCode" id="ips_uid_7048_7">
<code>(my_env) sammy@ubuntu:~/environments$
</code></pre>

<p>
	ثم نقوم بتشغيل تطبيق المفكرة Jupyter Notebook المنصَّب مسبقًا في بيئتنا البرمجية كما يلي:
</p>

<pre class="ipsCode" id="ips_uid_7048_7">
<code>(my_env) sammy@ubuntu:~/environments$ jupyter notebook
</code></pre>

<p>
	والآن أصبح بالإمكان التفاعل مع تطبيق المفكرة Jupyter Notebook من خلال واجهة الويب التفاعلية الخاصة به، وذلك بإدخال العنوان الالكتروني <code><a href="http://localhost:8888" ipsnoembed="false" rel="external nofollow">http://localhost:8888</a></code> في المتصفح، كما يجب إدخال السلسلة الرمزية token الخاصة بالتصديق عند طلبها من قبل المتصفح، أو كتابتها بعد العنوان في المتصفح.
</p>

<h3 id="طريقة-إنشاء-قناة-الاتصال-ssh-من-نظام-التشغيل-ويندوز-عن-طريق-putty">
	طريقة إنشاء قناة الاتصال <abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">SSH</abbr> من نظام التشغيل ويندوز عن طريق Putty
</h3>

<p>
	تستخدم الأداة Putty لإنشاء قناة اتصال <abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">SSH</abbr> في نظام التشغيل ويندوز، لذا يجب في البداية تنصيبها، وعند فتحها تظهر واجهة الأداة كما هو موضح بالشكل التالي:
</p>

<p style="text-align: center;">
	<img alt="a01.png" class="ipsImage ipsImage_thumbnailed" data-fileid="27265" data-unique="n0ss83vxd" src="https://academy.hsoub.com/uploads/monthly_2018_03/a01.png.1ee68cc52f172558b70f44099535ff74.png"></p>

<p>
	حيث يتم إدخال العنوان الإلكتروني URL للخادم أو عنوان IP ضمن حقل اسم المضيف Host Name، ثم الضغط على الخيار <abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">SSH</abbr> في أسفل النافذة اليسارية من واجهة الأداة، فتظهر قائمة منسدلة من الخيارات، نختار منها الخيار Tunnels فتظهر في النافذة اليمينية مجموعة من خيارات التحكم بقناة الاتصال <abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">SSH</abbr> كما هو موضح بالشكل التالي:
</p>

<p style="text-align: center;">
	<img alt="a02.png" class="ipsImage ipsImage_thumbnailed" data-fileid="27266" data-unique="xpkllssbq" src="https://academy.hsoub.com/uploads/monthly_2018_03/a02.png.e21aa67ed09ec24b871a9e9422f60090.png"></p>

<p>
	ثم نقوم بإدخال رقم منفذ الحاسب الشخصي المراد استخدامه لتطبيق المفكرة Jupyter Notebook (مثلًا <code>8888</code>)، ضمن حقل منفذ المصدر Source port، ويفضل أن يكون رقم هذا المنفذ أكبر من <code>8888</code> لضمان عدم وجود أي تطبيق أخر يعمل على هذا المنفذ. ثم ندخل العنوان <code>localhost:8888</code> في حقل الهدف Distination حيث <code>:8888</code> هو رقم المنفذ الذي يعمل عليه تطبيق المفكرة Jupyter Notebook في الخادم، ثم نضغط على زر الإضافة Add، فيظهر المنفذ في قائمة المنافذ الموجَّهة Forwarded ports. وأخيرًا نضغط على زر الفتح Open من أجل الاتصال بالخادم عن طريق قناة الاتصال <abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">SSH</abbr>، ثم ندخل العنوان <code>localhost:8888</code> (طبعًا يجب أن يكون رقم المنفذ موافقًا لرقم المنفذ الذي تم اختياره) في متصفح الويب من أجل الاتصال بتطبيق المفكرة Jupyter Notebook العامل على الخادم، كما يجب إدخال السلسلة الرمزية token الخاصة بالتصديق عند طلبها من قبل المتصفح، أو كتابتها بعد العنوان في المتصفح.
</p>

<h2 id="الخطوة-الثالثة--تشغيل-تطبيق-المفكرة-jupyter-notebook">
	الخطوة الثالثة- تشغيل تطبيق المفكرة Jupyter Notebook
</h2>

<p>
	بعد الانتهاء من تنصيب تطبيق المفكرة Jupyter Notebook، يصبح بالإمكان تشغيله من موجه أوامر النظام بتنفيذ الأمر التالي:
</p>

<pre class="ipsCode" id="ips_uid_7048_7">
<code>(my_env) sammy@ubuntu:~/environments$ jupyter notebook
</code></pre>

<p>
	فيُطبع في نافذة موجه الأوامر سجل معلومات تشغيل تطبيق المفكرة Jupyter Notebook كما يلي:
</p>

<pre class="ipsCode" id="ips_uid_7048_7">
<code>[I NotebookApp] Serving notebooks from local directory: /home/sammy
[I NotebookApp] 0 active kernels 
[I NotebookApp] The Jupyter Notebook is running at: http://localhost:8888/
[I NotebookApp] Use Control-C to stop this server and shut down all kernels (twice to skip confirmation).
...
</code></pre>

<p>
	حيث تتضمن هذه المعلومات على رقم المنفذ الذي يعمل عليه التطبيق، وعند تشغيل التطبيق لأول مرة سيكون رقم المنفذ <code>8888</code>.<br>
	يقوم المتصفح الافتراضي تلقائياً بفتح واجهة الويب التفاعلية الخاصة بتطبيق المفكرة Jupyter Notebook عند تشغيله على الحاسب الشخصي (ليس على الخادم)، وفي حال لم يتم ذلك أو تم إغلاق المتصفح، يمكن إعادة فتحه من جديد بإدخال عنوانه <code><a href="http://localhost:8888/" ipsnoembed="false" rel="external nofollow">http://localhost:8888/</a></code> الظاهر في سجل معلومات التطبيق في المتصفح.<br>
	يتم إنهاء تطبيق المفكرة Jupyter Notebook بالضغط على المفاتيح <code>CTRL</code> و <code>C</code> ثم ضغط المفتاح <code>y</code> (نعم) عند السؤال عن تأكيد عملية الإنهاء، ثم ضغط المفتاح <code>ENTER</code>، فتُطبع رسالة تأكيد عملية إنهاء التطبيق التالية في نافذة موجه الأوامر:
</p>

<pre class="ipsCode" id="ips_uid_7048_7">
<code>[C 12:32:23.792 NotebookApp] Shutdown confirmed
[I 12:32:23.794 NotebookApp] Shutting down kernels
</code></pre>

<h2 id="الخطوة-الرابعة--استخدام-تطبيق-المفكرة-jupyter-notebook">
	الخطوة الرابعة- استخدام تطبيق المفكرة Jupyter Notebook
</h2>

<p>
	سيتم في هذه الفقرة شرح أساسيات استخدام تطبيق المفكرة Jupyter Notebook، لكن يجب في البداية تشغيله إن لم يكن في حالة العمل، وذلك بتنفيذ الأمر التالي:
</p>

<pre class="ipsCode" id="ips_uid_7048_7">
<code>(my_env) sammy@ubuntu:~/environments$ jupyter notebook
</code></pre>

<p>
	نستطيع الآن الإتصال به والتفاعل معه من خلال واجهة الويب التفاعلية. يمتاز تطبيق المفكرة Jupyter Notebook بالقوة حيث يحتوي على الكثير من الميزات، لكن سيقتصر الشرح على بعض الميزات الأساسية التي تسمح بمباشرة العمل على هذا التطبيق.<br>
	يعرض تطبيق المفكرة Jupyter Notebook جميع الملفات والمجلدات الواقعة ضمن المسار الذي تم تشغيله منه، لذا يجب تشغيله دائمًا من مسار المشروع البرمجي الذي يتم العمل عليه.<br>
	يتم إنشاء ملف مفكرة Jupyter Notebook جديد بالضغط على خيار جديد New الموجود في الزاوية اليمينية العُلوية من واجهة الويب التفاعلية، فتظهر قائمة منسدلة نختار منها Python 3 كما هو موضح بالشكل التالي:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="27267" href="https://academy.hsoub.com/uploads/monthly_2018_03/a03.png.31398c27471b6df7979f9e8919378a01.png" rel=""><img alt="a03.png" class="ipsImage ipsImage_thumbnailed" data-fileid="27267" data-unique="v4uquhvul" src="https://academy.hsoub.com/uploads/monthly_2018_03/a03.thumb.png.6fcd1f8a734f41382987d4f8652ba687.png"></a>
</p>

<p>
	فيُفتح الملف الجديد المُنشأ ضمن واجهة الويب التفاعلية. نستطيع الآن كتابة وتنفيذ كود Python ضمن خليّة الكود البرمجي. كما يمكن تغيير هذه الخلية لتقبل لغة التوصيف Markdown، وذلك بالضغط على خيار الخلية Cell ثم خيار نوع الخلية Cell Type ثم خيار التوصيف Markdown من الشريط العلوي، فيصبح بالإمكان الآن استخدام هذه الخلية لكتابة الملاحظات وحتى تضمين المعادلات الرياضية المكتوبة بلغة <a href="https://www.latex-project.org/" rel="external nofollow">LaTeX</a> بعد وضعها بين الرمزين ($$)، فمثلا يمكن كتابة كود التوصيف التالي ضمن الخلية بعد تحويلها لخلية توصيف:
</p>

<pre class="ipsCode" id="ips_uid_7048_7">
<code># Simple Equation

Let us now implement the following equation:
$$ y = x^2$$

where $x = 2$
</code></pre>

<p>
	يتم تحويل هذا الكود إلى نص بضغط المفاتيح <code>CTRL</code> و <code>ENTER</code> فنحصل على النتيجة التالية:
</p>

<p style="text-align: center;">
	<img alt="a04.png" class="ipsImage ipsImage_thumbnailed" data-fileid="27268" data-unique="l97fusxx1" src="https://academy.hsoub.com/uploads/monthly_2018_03/a04.png.45209f510e0eda09f43efe12c20e4d7d.png"></p>

<p>
	وهكذا نلاحظ أنه يمكن استخدام خلايا التوصيف من أجل توثيق الكود البرمجي. سنقوم الآن بإنشاء معادلة رياضية بسيطة ونطبع نتيجة تنفيذها، وذلك بالضغط على الخلية العلوية ثم الضغط على المفاتيح <code>ALT</code> و <code>CTRL</code> من أجل إنشاء خلية جديدة تحتها ثم ندخل فيها الكود التالي:
</p>

<pre class="ipsCode" id="ips_uid_7048_7">
<code>x = 2
y = x**2

print(y)
</code></pre>

<p>
	ثم نقوم بتنفيذ الكود بضغط المفاتيح <code>CTRL</code> و <code>ENTER</code> فنحصل على النتيجة التالية:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="27269" href="https://academy.hsoub.com/uploads/monthly_2018_03/a05.png.4cf624faa8142ab13e97f57cb06036ad.png" rel=""><img alt="a05.png" class="ipsImage ipsImage_thumbnailed" data-fileid="27269" data-unique="z7q0m615d" src="https://academy.hsoub.com/uploads/monthly_2018_03/a05.thumb.png.fd5b6c407f540c962eca7e3a70c74a4d.png"></a>
</p>

<p>
	أصبح بمقدورك الآن وبعد أن تعلمت أساسيات تطبيق المفكرة Jupyter Notebook ، أن تقوم باستيراد النماذج البرمجية، وأن تستخدم هذه المفكرة كما تريد مع أي بيئة برمجية أخرى.
</p>

<h2 id="ملخص">
	ملخص
</h2>

<p>
	أصبحت قادرا الآن على كتابة أكواد Python والملاحظات القابلة للتطوير والمشاركة، بعد أن تعلمت كيفية تنصيب وتشغيل والعمل على تطبيق المفكرة Jupyter Notebook. يمكن الحصول على مزيد من المعلومات والمساعدة حول كيفية استخدام هذه المفكرة، بالدخول إلى User Interface Tour عن طريق الخيار Help الموجود في الشريط العلوي من واجهة الويب التفاعلية.
</p>

<p>
	ترجمة المقال <a href="https://www.digitalocean.com/community/tutorials/how-to-set-up-jupyter-notebook-for-python-3" rel="external nofollow">How To Set Up Jupyter Notebook for Python 3</a> لصاحبته Lisa Tagliaferri
</p>
]]></description><guid isPermaLink="false">388</guid><pubDate>Tue, 06 Mar 2018 11:00:44 +0000</pubDate></item><item><title>&#x643;&#x64A;&#x641;&#x64A;&#x629; &#x62A;&#x62B;&#x628;&#x64A;&#x62A; Node.js &#x639;&#x644;&#x649; Debian 8</title><link>https://academy.hsoub.com/devops/linux/%D9%83%D9%8A%D9%81%D9%8A%D8%A9-%D8%AA%D8%AB%D8%A8%D9%8A%D8%AA-nodejs-%D8%B9%D9%84%D9%89-debian-8-r385/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2018_02/5a8a718079f3e_20(1).png.ba8be9ff2e3fbda74fc3a56edcedf82d.png" /></p>

<h2 id="مقدمة">
	مقدمة
</h2>

<p>
	<a href="https://nodejs.org/" rel="external nofollow">Node.js</a> هي منصة لجافا سكريبت للبرمجة متعددة الأغراض والتي تسمح للمستخدمين ببناء تطبيقات الشبكة بسرعة. من خلال استخدام جافا سكريبت على كل من الواجهة الأمامية والخلفية، سيكون التطوير أكثر اتساقا وسيُصمم داخل النظام نفسه.<br>
	في هذا الدليل، ستتعلم كيفية تثبيت Node.js على خادم Debian 8. يحتوي Debian 8 على إصدار لـ Node.js في مجلداته الافتراضية، ولكن ذلك الإصدار قديم في الأغلب، سنقوم باستكشاف طريقتين لتثبيت أحدث إصدارات Node.js على نظامك.
</p>

<h3 id="المتطلبات-الأساسية">
	المتطلبات الأساسية
</h3>

<p>
	لمتابعة هذا الدرس، ستحتاج إلى خادم Debian 8 مع مستخدم غير كامل الصلاحيات non-root user ويملك امتيازات <code>sudo</code>.
</p>

<h2 id="كيفية-التثبيت-باستخدام-ppa">
	كيفية التثبيت باستخدام PPA
</h2>

<p>
	أسرع وأسهل وسيلة للحصول على أحدث إصدار من Node.js على خادمك هي بإضافة PPA (personal package archive) الخاص بـ NodeSource. سوف يشتمل على عدد أكبر من تحديثات Node.js مقارنة بمستودعات Debian الرسمية. كما أنه يتيح لك الاختيار بين Node.js v4.x (النسخة القديمة المدعومة على المدى الطويل, مدعومة حتى أبريل 2017)، v6.x (نسخة أحدث من LTS، والتي ستُدعم حتى أبريل 2018)، و Node.js v7.x (النسخة الحالية قيد التطوير).<br>
	أولا، قم بتثبيت PPA للحصول على محتوياته. تأكد من أنك في المجلد الرئيسي home directory، استخدم <code>curl</code> لاستخراج النص البرمجي لتثبيت الإصدار المفضل لديك، مع استبدال 6.x برقم الإصدار الصحيح:
</p>

<pre class="ipsCode" id="ips_uid_9584_7">
cd ~
curl -sL https://deb.nodesource.com/setup_6.x -o nodesource_setup.sh</pre>

<p>
	يمكنك فحص محتويات هذا النص البرمجي بواسطة <code>nano</code> (أو محرر النصوص المفضل لديك):
</p>

<pre class="ipsCode" id="ips_uid_9584_9">
nano nodesource_setup.sh</pre>

<p>
	وقم بتشغيل البرنامج النصي عقِب الأمر <code>sudo</code>:
</p>

<pre class="ipsCode" id="ips_uid_9584_11">
sudo bash nodesource_setup.sh</pre>

<p>
	سيتم إضافة PPA إلى إعداداتك وسوف يتم تحديث حزمتك المحلية المُخزنة تلقائيًا. بعد تشغيل برنامج التنصيب من nodesource، يمكنك تثبيت حزمة Node.js بنفس الطريقة التي اتبعتها أعلاه:
</p>

<pre class="ipsCode" id="ips_uid_9584_13">
sudo apt-get install nodejs</pre>

<p>
	الحزمة nodejs تحتوي رُقامة nodejs (nodejs binary ) إضافة إلى <code>npm</code>، لذلك لا تحتاج إلى تثبيت <code>npm</code> بشكل منفصل. ولكن لكي تعمل بعض حُزم <code>npm</code> (مثل تلك التي تتطلب ترجمة التعليمات البرمجية من المصدر)، فستحتاج إلى تثبيت الحزمة <code>build-essential</code>:
</p>

<pre class="ipsCode" id="ips_uid_9584_15">
sudo apt-get install build-essential</pre>

<h2 id="كيفية-التثبيت-بواسطة-nvm">
	كيفية التثبيت بواسطة nvm
</h2>

<p>
	بدل تثبيت Node.js بواسطة <code>apt</code>، يمكنك استعمال أداة خاصة تسمّى nvm (Node.js version manager). فباستخدام <code>nvm</code>، يمكنك تثبيت عدة إصدارات متكاملة من Node.js ما سيسمح لك بضبط بيئة العمل بشكل أسهل. كما ستعطيك إمكانية الوصول إلى أحدث إصدارات Node.js، ولكن ستسمح لك أيضا باستهداف الإصدارات السابقة التي قد يعتمد عليها تطبيقك.<br>
	بدايةً سوف نحتاج إلى الحصول على حزم البرمجيات من مستودعات Debian والتي ستسمح لنا ببناء الحُزم المصدرية source packages. التعليمة <code>nvm</code> ستستخدم تلك الأدوات لبناء المكونات الضرورية:
</p>

<pre class="ipsCode" id="ips_uid_9584_17">
sudo apt-get update
sudo apt-get install build-essential libssl-dev</pre>

<p>
	حالما يتم تثبيت الحُزم الضرورية، يمكنك حذف سكريبت التثبيت<code>nvm</code> من <a href="https://github.com/creationix/nvm" rel="external nofollow">صفحة المشروع علىGitHub</a> , رقم الإصدار قد يكون مختلفًا، ولكن بشكل عام، يمكنك تحميله بـ <code>curl</code>:
</p>

<pre class="ipsCode" id="ips_uid_9584_19">
curl -sL https://raw.githubusercontent.com/creationix/nvm/v0.32.0/install.sh -o install_nvm.sh
</pre>

<p>
	طالع سكريبت التثبيت بواسطة <code>nano</code>:
</p>

<pre class="ipsCode" id="ips_uid_9584_21">
nano install_nvm.sh</pre>

<p>
	قم بتشغيل النص البرمجي بواسطة <code>bash</code>:
</p>

<pre class="ipsCode" id="ips_uid_9584_23">
bash install_nvm.sh</pre>

<p>
	النص البرمجي سيقوم بتثبيت البرنامج في مجلد في <code>~/.nvm</code>. كما سيقوم بإضافة الأسطر اللازمة للملف <code>~/.profile</code> لجعل التعليمة <code>nvm</code> متاحًا.<br>
	لكسب إمكانية الوصول إلى التعليمة<code>nvm</code> وكذلك وظائفها، ستحتاج إلى تسجيل الخروج ثم تسجيل الدخول مرة أخرى، أو يمكنك إضافة المصدر <code>~/.profile</code> حتى يتم اعتبار التغييرات في الجلسةsession الحالية:
</p>

<pre class="ipsCode" id="ips_uid_9584_25">
source ~/.profile</pre>

<p>
	الآن وبعد تثبيت <code>nvm</code>، يمكنك تثبيت أحد إصدارات Node.js بشكل منفصل.<br>
	لمعرفة إصدارات Node.js المتوفرة للتثبيت، قم بكتابة:
</p>

<pre class="ipsCode" id="ips_uid_9584_27">
nvm ls-remote</pre>

<p style="text-align: left;">
	Output
</p>

<pre class="ipsCode" id="ips_uid_9584_29">
...
         v6.8.0
         v6.8.1
         v6.9.0   (LTS: Boron)
         v6.9.1   (LTS: Boron)
         v6.9.2   (Latest LTS: Boron)
         v7.0.0
         v7.1.0
         v7.2.0</pre>

<p>
	كما ترون، فأحدث إصدار في وقت كتابة هذه السطور هو v7.2.0، ولكن v6.9.2 هو آخر الإصدارات المدعومة على المدى الطويل. يمكنك تثبيته بكتابة:
</p>

<pre class="ipsCode" id="ips_uid_9584_31">
nvm install 6.9.2</pre>

<p>
	سوف ترى المخرجات التالية:
</p>

<pre class="ipsCode" id="ips_uid_9584_33">
Computing checksum with sha256sum
Checksums matched!
Now using node v6.9.2 (npm v3.10.9)
Creating default alias: default -&gt; 6.9.2 (-&gt; v6.9.2)</pre>

<p>
	عادة، سيتحول<code>nvm</code> إلى استخدام الإصدار المثبت حديثًا. لكن يمكنك أن تخبر<code>nvm</code> صراحة باستخدام النسخة التي حمّلناها للتو عن طريق كتابة:
</p>

<pre class="ipsCode" id="ips_uid_9584_35">
nvm use 6.9.2</pre>

<p>
	يمكنك مشاهدة النسخة المستخدمة حاليا عن طريق كتابة في واجهة الأوامر:
</p>

<pre class="ipsCode" id="ips_uid_9584_37">
node -v</pre>

<p style="text-align: left;">
	Output
</p>

<pre class="ipsCode" id="ips_uid_9584_39">
v6.9.2</pre>

<p>
	إن كان لديك عدة إصدارات من Node.js، يمكنك معرفة أيّ منها تم تثبيته بكتابة:
</p>

<pre class="ipsCode" id="ips_uid_9584_41">
nvm ls</pre>

<p>
	إذا كنت ترغب في جعل أحد هذه الإصدارات نسختك الافتراضية، يمكنك كتابة:
</p>

<pre class="ipsCode" id="ips_uid_9584_43">
nvm alias default 6.9.2</pre>

<p>
	هذا الإصدار سيتم اختياره تلقائيًا عند فتح جلسة عمل جديدة على المِطراف terminal. يمكنك أيضًا الإحالة إليه باستخدام الاسم <code>default</code> هكذا:
</p>

<pre class="ipsCode" id="ips_uid_9584_45">
nvm use default</pre>

<p>
	كل نسخة من Node.js ستُتابع حُزمها الخاصة بها، وسيكون<code>npm</code> متاحًا لإدارتها.<br>
	يمكنك وضع حُزم تثبيت <code>npm</code> في المجلد <code>./node_modules</code> الخاص بمشروعNode.js باستخدام الصيغة الطبيعية normal format. على سبيل المثال، بالنسبة للوحدة <code>express</code>:
</p>

<pre class="ipsCode" id="ips_uid_9584_47">
npm install express</pre>

<p>
	إذا كنت ترغب بتثبيته بشكل كلّي (جعْله متاحا للمشاريع الأخرى التي تستخدم نفس إصدار Node.js)، يمكنك إضافة العلم –g كما يلي:
</p>

<pre class="ipsCode" id="ips_uid_9584_49">
npm install -g express</pre>

<p>
	هذا سيثبّت الحزمة في:
</p>

<pre class="ipsCode" id="ips_uid_9584_51">
~/.nvm/node_version/lib/node_modules/package_name</pre>

<p>
	التثبيت الكلي سيتيح لك تشغيل التعليمات من سطر الأوامر، ولكن سيكون عليك ربط الحزمة من مجالك المحلي local sphere للوصول إليه من داخل برنامج ما:
</p>

<pre class="ipsCode" id="ips_uid_9584_53">
npm link express</pre>

<p>
	يمكنك معرفة المزيد حول الخيارات المتاحة لك مع <code>nvm</code> بكتابة:
</p>

<pre class="ipsCode" id="ips_uid_9584_55">
nvm help</pre>

<h2 id="خلاصة">
	خلاصة
</h2>

<p>
	كما رأيت، هناك عدة طرق لتثبيت وتشغيل Node.js على خادم Debian 8. ظروفك ستملي عليك أيّ الطرق المذكورة أعلاه ستكون أفضل لك. وفي حين أن النسخة المحزومة packaged في مستودع Ubuntu هي الأسهل، إلّا أن طريقة<code>nvm</code> أكثر مرونة بالتأكيد.<br>
	ترجمة -وبتصرّف- للمقال <a href="https://www.digitalocean.com/community/tutorials/how-to-install-node-js-on-debian-8" rel="external nofollow">How To Install Node.js on Debian 8</a> لصاحبه Brian Hogan
</p>
]]></description><guid isPermaLink="false">385</guid><pubDate>Mon, 19 Feb 2018 06:43:32 +0000</pubDate></item><item><title>&#x627;&#x633;&#x62A;&#x62E;&#x62F;&#x627;&#x645; Sudo &#x644;&#x62A;&#x641;&#x648;&#x64A;&#x636; &#x627;&#x644;&#x635;&#x644;&#x627;&#x62D;&#x64A;&#x627;&#x62A; &#x641;&#x64A; Linux</title><link>https://academy.hsoub.com/devops/linux/%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-sudo-%D9%84%D8%AA%D9%81%D9%88%D9%8A%D8%B6-%D8%A7%D9%84%D8%B5%D9%84%D8%A7%D8%AD%D9%8A%D8%A7%D8%AA-%D9%81%D9%8A-linux-r379/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2018_01/20-2.png.bce17c5de41e17543b04d480949a9d62.png" /></p>

<p>
	كتبت مؤخّرا برنامج Bash قصير لنسخ ملفّات MP3 من مفتاح USB من مُضيف شبكة (network host) إلى مُضيف شبكة آخر. تُنسَخ الملفّات إلى مجلّد خاصّ على خادوم أقوم بتشغيله لمؤسّسة تطوعيّة، ما يسمح بتشغيل وتنزيل الملفّات.
</p>

<p>
	يقوم برنامجي ببضعة أمور أخرى، مثل تعديل أسماء الملفّات قبل نسخها لتكون مرتّبة تلقائيّا حسب التّاريخ على صفحة الويب. كما تحذف جميع الملفّات على مفتاح USB بعد التّأكد من اكتمال النّقل بنجاح. يأتي هذا البُريْمِج ببضعة خيارات، مثل <code>-h</code> لعرض المُساعدة، و <code>-t</code> لنمط الاختبار (test mode) وبضعة خيارات أخرى.
</p>

<p>
	رغم أنّ برنامجي الصغير هذا جميل، إلّا أنّه يحتاج إلى تشغيله بالمُستخدم الجذر (root) للقيام بالعمليّات الأساسيّة. للأسف، لا تمتلك هذه المؤسّسة أشخاصا مهتمين بإدارة أنظمة الحواسيب، ما يدفعني للبحث عن أشخاص بقدرات تقنيّة متواضعة لتدريبهم على كيفيّة تسجيل الدّخول إلى الحاسوب الذي يعمل على نقل الملفّات وتشغيل هذا البرنامج. صحيح بأنّني أستطيع تشغيل البرنامج بنفسي، إلّا أنّ بضعة أسباب (كالمرض والسّفر) قد تحول دون ذلك. وحتى لو كنتُ متاحا، فبصفتي مدير نُظم كسول، أحب أن يقوم الآخرون بعملي من أجلي. لذا أكتب برامج لأتمتة (automate) هذه المهام وأستعمل Sudo لتمكين بضعة مُستخدمين من تشغيل البرامج.يتطلّب تنفيذ العديد من أوامر Linux صلاحيّات المُستخدم الجذر. هذا يحمي النظام من التخريب الخبيث أو غير المقصود.
</p>

<h2 id="استعمال-أداة-sudo">
	استعمال أداة Sudo
</h2>

<p>
	يُمكنّ برنامج <code>sudo</code> مدراء النّظم ذوي صلاحيّات الجذر من تفويض المسؤوليّة لبضعة مهام أو جميعها لمستخدمين آخرين لنفس الحاسوب. كما يسمح لي بتنفيذ هذا التفويض دون توفير كلمة مرور المُستخدم الجذر، ما يوفّر مستوى عاليّا من الحماية على المُضيف.
</p>

<p>
	لنفترض على سبيل المثال بأنّني أعطيت للمُستخدم <code>ruser</code> أحقيّة الوصول إلى برنامج Bash خاص بي باسم <code>myprog</code>، والذي يحتاج إلى صلاحيّات المستخدم الجذر لتنفيذ بعض من وظائفه. يقوم المستخدم <code>ruser</code> بتسجيل الدّخول أولا باستعمال كلمة المرور الخاصّة به، وبعدها ينفّذ الأمر التّالي لتشغيل <code>myprog</code>.
</p>

<pre>
 </pre>

<pre class="ipsCode" id="ips_uid_5350_7">
sudo myprog
</pre>

<p>
	يقوم برنامج <code>sudo</code> بالاطّلاع على الملفّ <code>/etc/sudoers</code> ويتحقّق من أنّ لـ<code>ruser</code> إذنا يُمكّنه من تشغيل <code>myprog</code>. إن كان الأمر كذلك، يطلب <code>sudo</code> من المُستخدم كلمة مروره -وليس كلمة مرور المُستخدم الجذر-، بعد إدخال كلمة المرور، يتمّ تنفيذ البرنامج. يقوم <code>sudo</code> كذلك بتسجيل معلومات الوصول إلى <code>myprog</code> مع التاريخ والوقت الذي تمّ فيه تشغيل البرنامج إضافة إلى سطر الأمر والمُستخدم الذي قام بتنفيذه. تُسجّل هذه البيانات في ملفّ <code>/var/log/security</code>. أجد بأنّ سجلّ الأوامر التي تم تنفيذها مفيد عند التّدريب. إذ يسمح لي هذا بالتعرّف على من قام بماذا وما إن أدخل الأمر بشكل صحيح. قمت باستخدام هذه الميّزة لتفويض الصلاحيّات لي ولمُستخدم آخر للتمكّن من تشغيل برنامج واحد؛ لكن لـ<code>sudo</code> إمكانيّات أكبر من ذلك. إذ يسمح لمدير النظام بتفويض السُّلطَة لإدارة وظائف الشّبكة أو خدمات مُعيّنة لشخص واحد أو مجموعة من المُستخدمين الموثوقين. يُمكّن هذا من تفويض أحقيّة تشغيل هذه الوظائف ويحمي كلمة مرور المُستخدم الجذر في نفس الوقت.
</p>

<h2 id="ضبط-ملفّ-sudoers">
	ضبط ملفّ <code>sudoers</code>
</h2>

<p>
	بصفتي مدير نُظم، يُمكنني استعمال ملفّ <code>/etc/sudoers</code> للسماح للمستخدمين أو مجموعات من المُستخدمين بالوصول إلى أمر مُعيّن، مجموعة محدّدة من الأوامر أو جميع الأوامر. هذه المرونة هي سرّ كل من قوّة وبساطة استعمال <code>sudo</code> للتفويض.
</p>

<p>
	بدا لي ملفّ <code>sudoers</code> معقّدا في البداية، لذا نسختُ وحلّلت ملفّ <code>sudoers</code> بالكامل من المُضيف الذي أستخدمه. على أمل أن تفهم الأساسيّات بعد قراءة هذا التّحليل. وجدت كذلك بأنّ ملفّات الإعدادات الافتراضيّة في التوزيعات المبنيّة على Red Hat تحتوي على الكثير من التّعليقات والأمثلة التي تُسهّل المأموريّة.
</p>

<p>
	لا تستعمِل محرّر النصوص الاعتياديّ عند تعديل ملفّ <code>sudoers</code>. استعمل الأمر <code>visudo</code> لتطبيق التّغييرات حالما تحفظ الملفّ وتخرجُ من المُحرّر. يُمكن استعمال محرّرات أخرى عوضا عن Vi بنفس الشكل الذي نستعمل فيه <code>visudo</code>. لنبدأ بتحليل هذا الملفّ من البداية مع بضعة أنواع من الأسماء المُستعارة (aliases).
</p>

<h2 id="الأسماء-المُستعارة-الخاصّة-بالمُضيفات-host-aliases">
	الأسماء المُستعارة الخاصّة بالمُضيفات Host aliases
</h2>

<p>
	يُستعمل جزء الأسماء المُستعارة الخاصّة بالمُضيفات لإنشاء مجموعات من المُضيفات التي يُمكن عليها استعمال الأوامر أو الأسماء المستعارة للأوامر لمنح أحقيّة الوصول. الفكرة أن يُصان (maintain) هذا الملفّ الوحيد من أجل جميع المُضيفات في المؤسّسة ويُنسخ إلى مُجلّد <code>/etc</code> الخاص بكل مُضيف. وبالتالي يُمكن ضبط بعض المُضيفات (مثل الخوادم) لتُشكّل مجموعة لمنح بعض المُستخدمين أحقيّة الوصول إلى أوامر مُخصّصة، مثل إمكانيّة تشغيل أو إيقاف خدمات مثل HTTPD، DNS والتشبيك (networking) أو وصل (mount) أنظمة الملفّات وما إلى ذلك.
</p>

<p>
	يُمكن استعمال عناوين IP عوضا عن أسماء المُضيفات في الأسماء المُستعارة الخاصّة بالمُضيفات.
</p>

<pre class="ipsCode" id="ips_uid_5350_7">
<code>## Sudoers allows particular users to run various commands as
## the root user, without needing the root password.
##
## Examples are provided at the bottom of the file for collections
## of related commands, which can then be delegated out to particular
## users or groups.
##
## This file must be edited with the 'visudo' command.

## Host Aliases
## Groups of machines. You may prefer to use hostnames (perhaps using
## wildcards for entire domains) or IP addresses instead.
# Host_Alias     FILESERVERS = fs1, fs2
# Host_Alias     MAILSERVERS = smtp, smtp2

## User Aliases
## These aren't often necessary, as you can use regular groups
## (ie, from files, LDAP, NIS, etc) in this file - just use %groupname
## rather than USERALIAS
# User_Alias ADMINS = jsmith, mikem
User_Alias AUDIO = dboth, ruser

## Command Aliases
## These are groups of related commands...

## Networking
# Cmnd_Alias NETWORKING = /sbin/route, /sbin/ifconfig, /bin/ping, /sbin/dhclient, /usr/bin/net, /sbin/iptables, /usr/bin/rfcomm, /usr/bin/wvdial, /sbin/iwconfig, /sbin/mii-tool

## Installation and management of software
# Cmnd_Alias SOFTWARE = /bin/rpm, /usr/bin/up2date, /usr/bin/yum

## Services
# Cmnd_Alias SERVICES = /sbin/service, /sbin/chkconfig

## Updating the locate database
# Cmnd_Alias LOCATE = /usr/bin/updatedb

## Storage
# Cmnd_Alias STORAGE = /sbin/fdisk, /sbin/sfdisk, /sbin/parted, /sbin/partprobe, /bin/mount, /bin/umount

## Delegating permissions
# Cmnd_Alias DELEGATING = /usr/sbin/visudo, /bin/chown, /bin/chmod, /bin/chgrp

## Processes
# Cmnd_Alias PROCESSES = /bin/nice, /bin/kill, /usr/bin/kill, /usr/bin/killall

## Drivers
# Cmnd_Alias DRIVERS = /sbin/modprobe

# Defaults specification

#
# Refuse to run if unable to disable echo on the tty.
#
Defaults   !visiblepw

Defaults    env_reset
Defaults    env_keep =  "COLORS DISPLAY HOSTNAME HISTSIZE KDEDIR LS_COLORS"
Defaults    env_keep += "MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE"
Defaults    env_keep += "LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES"
Defaults    env_keep += "LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE"
Defaults    env_keep += "LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY"


Defaults    secure_path = /sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin

## Next comes the main part: which users can run what software on
## which machines (the sudoers file can be shared between multiple
## systems).
## Syntax:
##
##      user    MACHINE=COMMANDS
##
## The COMMANDS section may have other options added to it.
##
## Allow root to run any commands anywhere
root    ALL=(ALL)       ALL

## Allows members of the 'sys' group to run networking, software,
## service management apps and more.
# %sys ALL = NETWORKING, SOFTWARE, SERVICES, STORAGE, DELEGATING, PROCESSES, LOCATE, DRIVERS

## Allows people in group wheel to run all commands
%wheel  ALL=(ALL)       ALL

## Same thing without a password
# %wheel        ALL=(ALL)       NOPASSWD: ALL

## Allows members of the users group to mount and unmount the
## cdrom as root
# %users  ALL=/sbin/mount /mnt/cdrom, /sbin/umount /mnt/cdrom

## Allows members of the users group to shutdown this system
# %users  localhost=/sbin/shutdown -h now

## Read drop-in files from /etc/sudoers.d (the # here does not mean a comment)
#includedir /etc/sudoers.d

################################################################################
# Added by David Both, 11/04/2017 to provide limited access to myprog          #
################################################################################
#
AUDIO   guest1=/usr/local/bin/myprog
</code></pre>

<h2 id="الأسماء-المستعارة-الخاصّة-بالمُستخدمين-user-aliases">
	الأسماء المستعارة الخاصّة بالمُستخدمين User aliases
</h2>

<p>
	تُعطي الأسماء المستعارة الخاصّة بالمُستخدمين إمكانيّة ترتيب المُستخدمين إلى مجموعات ذات أسماء مُستعارة للمُستخدم الجذر، بهذه الطّريقة ستتمكّن مجموعة كاملة من المستخدمين من الوصول إلى صلاحيات مدير محدّدة. هذا هو الجزء الذي أضَفْتُ فيه السّطر <code>User_Alias AUDIO = dboth, ruser</code>، والذي يقوم بتعيين مُستخدمَيْنِ للاسم المُستعار <code>AUDIO</code>. يُمكن الاعتماد على المجموعات المنشأة مُسبقا في ملفّ <code>/etc/groups</code> عوضا عن الأسماء المستعارة. إن كانت أحد المجموعات في هذا الملفّ تفي بالغرض، مثل مجموعة <code>audio</code> فيُمكنك استخدام اسم المجموعة مسبوقا بعلامة % كما يلي: <code>%audio</code> عند تعيين الأوامر التي ستُوفَّرُ للمجموعات في ملفّ <code>sudoers</code>.
</p>

<h2 id="الأسماء-المستعارة-للأوامر-command-aliases">
	الأسماء المستعارة للأوامر Command aliases
</h2>

<p>
	في جزء الأسماء المستعارة للأوامر، نقوم بتوفير قائمة للأوامر ذات الصّلة، مثل أوامر التّشبيك أو الأوامر التي تقوم بتنصيب التّحديثات أو حزم RPM جديدة. تُمكّن هذه الأسماء المستعارة مدير النّظام من منح تصريح للوصول إلى مجموعة من الأوامر. تم مُسبقا إعداد عدد من هذه الأسماء المستعارة في هذا الجزء، ما يجعل تفويض أحقية الوصول لنوع محدد من الأوامر أمرا سهلا.
</p>

<h2 id="القيم-الافتراضيّة-للبيئة-environment-defaults">
	القيم الافتراضيّة للبيئة Environment defaults
</h2>

<p>
	يقوم الجزء التّالي بتعيين عدد من متغيّرات البيئة (environment variables). أكثر سطر مثير للاهتمام في هذا الجزء هو السّطر <code>!visiblepw</code>، والذي يمنع تشغيل <code>sudo</code> إن كانت بيئة المُستخدم تسمح بعرض كلمة المرور. هذا إجراء وقائي لا يجب تعديله.
</p>

<h2 id="قسم-الأوامر-command-section">
	قسم الأوامر Command section
</h2>

<p>
	قسم الأوامر هو الجزء الرّئيسي في ملفّ <code>sudoers</code>. يمكن القيام بأي شيء ترغب به دون الحاجة إلى الأسماء المستعارة عبر إضافة خانات هنا. لكنّ الأسماء المستعارة تجعل الأمر في غاية السّهولة. يقوم هذا القسم باستخدام الأسماء المُستعارة التي تم تعريفها أعلاه لإخبار <code>sudo</code> من لديه الحقّ للقيام بماذا وعلى أي مُضيف. الأمثلة تشرح نفسها ما دمت تفهم القواعد (Syntax) في هذا القسم. لننظر إلى القواعد في قسم الأوامر:
</p>

<pre class="ipsCode" id="ips_uid_5350_7">
<code>ruser           ALL=(ALL) ALL 
</code></pre>

<p>
	المثال أعلاه يقول بأنّ للمُستخدم <code>ruser</code> صلاحيات تُمكّنه من تنفيذ أي برنامج على أي مُضيف بصفة أي مُستخدم.
</p>

<p>
	هذه خانة عامّة للمُستخدم <code>ruser</code>. المقطع <code>ALL</code> الأول يدلّ على أنّ هذه القاعدة تُطبَّق على جميع المُضيفات. <code>ALL</code> الثّانيّة تسمح لـ<code>ruser</code> بتنفيذ الأوامر بصفة أي مُستخدم آخر. افتراضيّا، تُنفَّذُ الأوامر بصفة المُستخدم الجذر، لكنّ لـ<code>ruser</code> القدرة على انتحال صفة أي مُستخدم آخر عند استعمال الأمر <code>sudo</code>. المقطع <code>ALL</code> الأخير يعني بأنّ <code>ruser</code> يستطيع تنفيذ جميع الأوامر دون أية قيود. ما يمنح لـ<code>ruser</code> جميع صلاحيّات المُدير. لاحظ الخانة التي تمنح للمُستخدم <code>root</code> جميع صلاحيات الوصول لجميع الأوامر على جميع المُضيفات:
</p>

<pre class="ipsCode" id="ips_uid_5350_7">
<code>root    ALL=(ALL) ALL 
</code></pre>

<p>
	لتجربة هذا، قمت بتعليق (comment) السّطر أعلاه وحاولتُ تنفيذ الأمر <code>chown</code> بصفة المُستخدم الجذر دون <code>sudo</code>. تمّ تنفيذ الأمر. بعدها حاولت استخدام الأمر <code>sudo chown</code>، والذي فشل مع الرّسالة <code>root غير موجود على ملفّ sudoers. سيتم الإبلاغ عن هذه الحادثة</code>. ما يعني بأنّ المُستخدم الجذر قادر على تنفيذ أي أمر بصفته المُستخدم الجذر، لكن أي أمر سيفشل عند استعمال الأمر <code>sudo</code>. سيمنع هذا المُستخدمَ الجذر من تنفيذ أية أوامر بصفته مُستخدما آخر عبر الأمر <code>sudo</code>. لكنّ <code>root</code> يستطيع التحايل على هذا القيد بالعديد من الطّرق.
</p>

<p>
	الشّيفرة أسفله هي ما أضفته للتحكم بأحقية الوصول إلى برنامج <code>myprog</code>. يقول السّطر بأنّ المستخدمين الذين ينتمون إلى المجموعة <code>AUDIO</code> التي تم تعريفها أعلى الملفّ لديهم أحقيّة الوصول إلى برنامج واحد فقط (<code>myprog</code>) على مُضيف واحد (<code>guest1</code>).
</p>

<pre class="ipsCode" id="ips_uid_5350_7">
<code>AUDIO   guest1=/usr/local/bin/myprog
</code></pre>

<p>
	سيُمكّن السّطر أعلاه المستخدمين المنتمين إلى مجموعة <code>AUDIO</code> من الوصول إلى البرنامج <code>myprog</code> على المُضيف <code>guest1</code>.
</p>

<p>
	لاحظ بأنّ السّطر أعلاه لا يُحدّد سوى المُضيف الذي يُمكن عليه تنفيذ البرنامج. ولا يُحدّد بأنّ للمُستخدم حريّة تنفيذ الأمر بصفة أي مُستخدم آخر.
</p>

<h2 id="تجاوز-كلمات-المرور">
	تجاوز كلمات المرور
</h2>

<p>
	يُمكنك استخدام الكلمة المفتاحيّة <code>NOPASSWORD</code> لتمكين المُستخدمين المنتمين إلى المجموعة <code>AUDIO</code> من تشغيل برنامج <code>myprog</code> دون الحاجة إلى إدخال كلمة المرور الخاصّة بهم كما يلي:
</p>

<pre class="ipsCode" id="ips_uid_5350_7">
<code>AUDIO   guest1=NOPASSWORD : /usr/local/bin/myprog
</code></pre>

<p>
	لم أُفعِّل هذا الخيار لبرنامجي، إذ يجب على مُستخدمي <code>sudo</code> التوقف والتفكير في ما يقومون به، وهذا يُساعد قليلا على ذلك. والسّطر أعلاه مُجرّد مثال توضيحيّ.
</p>

<h2 id="المجموعة-wheel">
	المجموعة wheel
</h2>

<p>
	معيار <code>wheel</code> المُحدّد في جزء الأوامر داخل ملفّ <code>sudoers</code> (كما هو موضّح أسفله) يقوم بالسماح لجميع المُستخدمين المُنتمين إلى المجموعة <code>wheel</code> بتنفيذ جميع الأوامر على أي مُضيف. تُعرَّف مجموعة <code>wheel</code> على الملفّ <code>/etc/group</code>، ومن الواجب إضافة المُستخدمين هناك. علامة <code>%</code> التي تسبق اسم المجموعة تعني بأنّ على <code>sudo</code> البحث عن هذه المجموعة في ملفّ <code>/etc/group</code>.
</p>

<pre class="ipsCode" id="ips_uid_5350_7">
<code>%wheel          ALL = (ALL) ALL 
</code></pre>

<p>
	يسمح السّطر أعلاه لجميع المُستخدمين الذين ينتمون إلى المجموعة <code>wheel</code> المعرّفة في ملفّ <code>/etc/group</code> بتشغيل جميع الأوامر على أي مُضيف.
</p>

<p>
	هذه طريقة جيّدة لتفويض كامل صلاحيّات المُستخدم الجذر لعدّة مُستخدمين دون توفير كلمة المرور الخاصّة بالمُستخدم الجذر. مجرّد إضافة مُستخدم إلى مجموعة <code>wheel</code> يُعطيهم كامل إمكانيّات المُستخدم الجذر. يسمح هذا كذلك بمُراقبة نشاطات المُستخدمين عبر مُدخلات التّسجيلات التي يقوم sudo بإنشائها. تُضيف بعض التوزيعات (مثل توزيعة Ubuntu) مُعرّفات المُستخدمين (user ID) إلى المجموعة <code>wheel</code> في ملفّ <code>/etc/group</code>، ما يسمح لهم باستخدام <code>sudo</code> لتنفيذ جميع الأوامر التي تتطلّب صلاحيّات المُستخدم الجذر.
</p>

<h2 id="ختاما">
	ختاما
</h2>

<p>
	استعملت <code>sudo</code> هنا لغرض محدود (تمكين مستخدم أو مُستخدمَيْن من الوصول إلى أمر واحد). تمكّنت من تحقيق هذا الغرض عبر كتابة سطرَيْن فقط (دون احتساب التّعليقات). تفويض صلاحيات تنفيذ مهام مُحدّدة لمُستخدمين لا يمتلكون إمكانيّة الوصول إلى المستخدم الجذر عمليّة بسيطة يُمكن لها اقتصاد كم جيّد من الوقت لمُدير النظم. بالإضافة إلى ميّزة تسجيل نشاطات المُستخدمين التي تُساعد على إيجاد المشاكل.
</p>

<p>
	يُوفّر ملفّ <code>sudoers</code> كمًّا هائلًا من الإمكانيّات والخيارات. ألقِ نظرة على ملفّات <code>man</code> الخاصّة بـ<code>sudo</code> و<code>sudoers</code> لمزيد من التّفاصيل.
</p>

<p>
	ترجمة -بتصرّف- للمقال <a href="https://opensource.com/article/17/12/using-sudo-delegate" rel="external nofollow">Using sudo to delegate permissions in Linux</a> لصاحبه David Both.
</p>
]]></description><guid isPermaLink="false">379</guid><pubDate>Sat, 20 Jan 2018 06:04:04 +0000</pubDate></item><item><title>&#x643;&#x64A;&#x641;&#x64A;&#x629; &#x625;&#x639;&#x62F;&#x627;&#x62F; &#x648;&#x627;&#x633;&#x62A;&#x62E;&#x62F;&#x627;&#x645; LXD &#x639;&#x644;&#x649; &#x623;&#x648;&#x628;&#x648;&#x646;&#x62A;&#x648; 16.04 &#x2013; &#x62A;&#x643;&#x648;&#x64A;&#x646; &#x648;&#x62A;&#x648;&#x62C;&#x64A;&#x647; &#x648;&#x625;&#x632;&#x627;&#x644;&#x629; &#x62D;&#x627;&#x648;&#x64A;&#x629; Nginx</title><link>https://academy.hsoub.com/devops/linux/%D9%83%D9%8A%D9%81%D9%8A%D8%A9-%D8%A5%D8%B9%D8%AF%D8%A7%D8%AF-%D9%88%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-lxd-%D8%B9%D9%84%D9%89-%D8%A3%D9%88%D8%A8%D9%88%D9%86%D8%AA%D9%88-1604-%E2%80%93-%D8%AA%D9%83%D9%88%D9%8A%D9%86-%D9%88%D8%AA%D9%88%D8%AC%D9%8A%D9%87-%D9%88%D8%A5%D8%B2%D8%A7%D9%84%D8%A9-%D8%AD%D8%A7%D9%88%D9%8A%D8%A9-nginx-r375/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2018_01/04-2.png.569c564005cb0a88947bc0e362168413.png" /></p>

<p>
	تعلمنا في <a href="https://academy.hsoub.com/devops/linux/%D9%83%D9%8A%D9%81%D9%8A%D8%A9-%D8%A5%D8%B9%D8%AF%D8%A7%D8%AF-%D9%88%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-lxd-%D8%B9%D9%84%D9%89-%D8%A3%D9%88%D8%A8%D9%88%D9%86%D8%AA%D9%88-1604-%E2%80%93-%D8%A7%D9%84%D8%A5%D8%B9%D8%AF%D8%A7%D8%AF-%D9%88%D8%A5%D9%86%D8%B4%D8%A7%D8%A1-%D8%AD%D8%A7%D9%88%D9%8A%D8%A9-nginx-r374/" rel="">الدرس السابق</a> كيفية إعداد LXD وإعداد الشبكة بالإضافة إلى إنشاء حاوية Nginx والآن لنقم بإعداد Nginx داخل الحاوية:
</p>

<h2 id="الخطوة-4-تكوين-حاوية-nginx">
	الخطوة 4 : تكوين حاوية Nginx
</h2>

<p>
	لِنتصلْ بالحاوية webserver ولنقم بإعداد خادوم الويب. اتصل بالحاوية بالأمر <code>lxc exec</code> الذي يأخذ اسم الحاوية وأوامر التنفيذ كمدخلات:
</p>

<pre class="ipsCode" id="ips_uid_3216_7">
lxc exec webserver -- sudo --login --user ubuntu </pre>

<p>
	يشير المحرف “–” الأول إلى أن مدخلات الأمر <code>lxc</code> يجب أن تتوقف عندها وسيتم تمرير بقية السطر كأمر يتم تنفيذه داخل الحاوية. الأمر هو <code>sudo --login –user Ubuntu</code> وهو الذي سوف يوفر صدفة تسجيل الدخول للحساب ubuntu السابق الإعداد داخل الحاوية.<br><strong>ملاحظة</strong>: إذا كنت بحاجة إلى الاتصال بالحاوية باعتبارك جذرًا استخدم الأمر
</p>

<pre class="ipsCode" id="ips_uid_3216_7">
<code class="hljs bash"><span class="pln">lxc </span><span class="hljs-keyword"><span class="kwd">exec</span></span><span class="pln"> webserver </span><span class="pun">--</span><span class="pln"> </span><span class="pun">/</span><span class="pln">bin</span><span class="pun">/</span><span class="pln">bash </span></code></pre>

<p>
	بدلًا من ذلك. بعدما تدخل إلى الحاوية ستبدو الصدفة الآن كما يلي.
</p>

<pre class="ipsCode" id="ips_uid_3216_7">
<code class="hljs ruby"><span class="pln">ubuntu</span><span class="hljs-variable"><span class="pln">@webserver</span></span><span class="hljs-symbol"><span class="pun">:~</span></span><span class="pln">$</span></code></pre>

<p>
	المستخدم ubuntu في الحاوية لديه صلاحيات sudo مُعَدَّة مسبقًا ويمكنه تنفيذ أوامر بصلاحيات الجذر دون المطالبة بإدخال كلمة السر. تقتصر هذه الصدفة على حدود الحاوية. أيُّ شيء تقوم بتشغيله في هذه الصدفة سيبقى في الحاوية ولا يمكن الذهاب به إلى الخادوم المضيف. لنقم بإعداد Nginx في هذه الحاوية. حدّث قائمة حزم ubuntu داخل الحاوية وثبت Nginx:
</p>

<pre class="ipsCode" id="ips_uid_3216_7">
<code class="hljs bash"><span class="hljs-built_in"><span class="pln">sudo</span></span><span class="pln"> apt</span><span class="pun">-</span><span class="kwd">get</span><span class="pln"> update
</span><span class="hljs-built_in"><span class="pln">sudo</span></span><span class="pln"> apt</span><span class="pun">-</span><span class="kwd">get</span><span class="pln"> install nginx</span></code></pre>

<p>
	ثم قم بتحرير صفحة الويب الافتراضية لهذا الموقع وأضف بعض الجمل التي تجعل من الواضح أن هذا الموقع يتم استضافته في الحاوية webserver .<br>
	افتح الملف :
</p>

<pre class="ipsCode" id="ips_uid_3216_7">
<code class="hljs avrasm"><span class="pln">sudo nano </span><span class="pun">/</span><span class="kwd">var</span><span class="pun">/</span><span class="pln">www</span><span class="pun">/</span><span class="pln">html</span><span class="pun">/</span><span class="pln">index</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">nginx</span></span><span class="pun">-</span><span class="pln">debian</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">html</span></span></code></pre>

<p>
	أدخل التغيير التالي على الملف:
</p>

<pre class="ipsCode" id="ips_uid_3216_7">
<code class="hljs xml"><span class="hljs-doctype"><span class="dec">&lt;!DOCTYPE html&gt;</span></span><span class="pln">
</span><span class="hljs-tag"><span class="tag">&lt;</span><span class="hljs-title"><span class="tag">html</span></span><span class="tag">&gt;</span></span><span class="pln">
</span><span class="hljs-tag"><span class="tag">&lt;</span><span class="hljs-title"><span class="tag">head</span></span><span class="tag">&gt;</span></span><span class="pln">
</span><span class="hljs-tag"><span class="tag">&lt;</span><span class="hljs-title"><span class="tag">title</span></span><span class="tag">&gt;</span></span><span class="pln">Welcome to nginx on LXD container webserver!</span><span class="hljs-tag"><span class="tag">&lt;/</span><span class="hljs-title"><span class="tag">title</span></span><span class="tag">&gt;</span></span><span class="pln">
</span><span class="hljs-tag"><span class="tag">&lt;</span><span class="hljs-title"><span class="tag">style</span></span><span class="tag">&gt;</span></span><span class="css"><span class="pln">
    </span><span class="hljs-tag"><span class="pln">body</span></span><span class="pln"> </span><span class="hljs-rules"><span class="pun">{</span><span class="pln">
        </span><span class="hljs-rule"><span class="hljs-attribute"><span class="pln">width</span></span><span class="pun">:</span><span class="hljs-value"><span class="pln"> </span><span class="hljs-number"><span class="lit">35</span></span><span class="lit">em</span></span></span><span class="pun">;</span><span class="pln">
        </span><span class="hljs-rule"><span class="hljs-attribute"><span class="pln">margin</span></span><span class="pun">:</span><span class="hljs-value"><span class="pln"> </span><span class="hljs-number"><span class="lit">0</span></span><span class="pln"> </span><span class="kwd">auto</span></span></span><span class="pun">;</span><span class="pln">
        </span><span class="hljs-rule"><span class="hljs-attribute"><span class="pln">font</span><span class="pun">-</span><span class="pln">family</span></span><span class="pun">:</span><span class="hljs-value"><span class="pln"> </span><span class="typ">Tahoma</span><span class="pun">,</span><span class="pln"> </span><span class="typ">Verdana</span><span class="pun">,</span><span class="pln"> </span><span class="typ">Arial</span><span class="pun">,</span><span class="pln"> sans</span><span class="pun">-</span><span class="pln">serif</span></span></span><span class="pun">;</span><span class="pln">
    </span><span class="hljs-rule"><span class="pun">}</span></span></span><span class="pln">
</span></span><span class="hljs-tag"><span class="tag">&lt;/</span><span class="hljs-title"><span class="tag">style</span></span><span class="tag">&gt;</span></span><span class="pln">
</span><span class="hljs-tag"><span class="tag">&lt;/</span><span class="hljs-title"><span class="tag">head</span></span><span class="tag">&gt;</span></span><span class="pln">
</span><span class="hljs-tag"><span class="tag">&lt;</span><span class="hljs-title"><span class="tag">body</span></span><span class="tag">&gt;</span></span><span class="pln">
</span><span class="hljs-tag"><span class="tag">&lt;</span><span class="hljs-title"><span class="tag">h1</span></span><span class="tag">&gt;</span></span><span class="pln">Welcome to nginx on LXD container webserver!</span><span class="hljs-tag"><span class="tag">&lt;/</span><span class="hljs-title"><span class="tag">h1</span></span><span class="tag">&gt;</span></span><span class="pln">
</span><span class="hljs-tag"><span class="tag">&lt;</span><span class="hljs-title"><span class="tag">p</span></span><span class="tag">&gt;</span></span><span class="pln">If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</span><span class="hljs-tag"><span class="tag">&lt;/</span><span class="hljs-title"><span class="tag">p</span></span><span class="tag">&gt;</span></span></code></pre>

<p>
	لقد قمنا بتحرير الملف في مكانين، وعلى وجه التحديد أضفنا العبارة ” on LXD container webserver”. احفظ الملف وأغلق المحرر. الآن سجل الخروج من الحاوية وعُد إلى الخادوم المضيف:
</p>

<pre class="ipsCode" id="ips_uid_3216_7">
<code class="hljs "><span class="typ">Logout</span></code></pre>

<p>
	استخدم الأمر curl لاختبار أن خادوم الويب في الحاوية يعمل. ستحتاج إلى عناوين IP لحاويات الويب التي يمكنك أن تجدها بتنفيذ الأمر lxd list.
</p>

<pre class="ipsCode" id="ips_uid_3216_7">
<code class="hljs cs"><span class="pln">curl http</span><span class="pun">:</span><span class="hljs-comment"><span class="com">//10.10.10.100/</span></span></code></pre>

<p>
	يجب أن تكون المخرجات:
</p>

<pre class="ipsCode" id="ips_uid_3216_7">
<code class="hljs xml"><span class="hljs-doctype"><span class="dec">&lt;!DOCTYPE html&gt;</span></span><span class="pln">
</span><span class="hljs-tag"><span class="tag">&lt;</span><span class="hljs-title"><span class="tag">html</span></span><span class="tag">&gt;</span></span><span class="pln">
</span><span class="hljs-tag"><span class="tag">&lt;</span><span class="hljs-title"><span class="tag">head</span></span><span class="tag">&gt;</span></span><span class="pln">
</span><span class="hljs-tag"><span class="tag">&lt;</span><span class="hljs-title"><span class="tag">title</span></span><span class="tag">&gt;</span></span><span class="pln">Welcome to nginx on LXD container webserver!</span><span class="hljs-tag"><span class="tag">&lt;/</span><span class="hljs-title"><span class="tag">title</span></span><span class="tag">&gt;</span></span><span class="pln">
</span><span class="hljs-tag"><span class="tag">&lt;</span><span class="hljs-title"><span class="tag">style</span></span><span class="tag">&gt;</span></span><span class="css"><span class="pln">
    </span><span class="hljs-tag"><span class="pln">body</span></span><span class="pln"> </span><span class="hljs-rules"><span class="pun">{</span><span class="pln">
        </span><span class="hljs-rule"><span class="hljs-attribute"><span class="pln">width</span></span><span class="pun">:</span><span class="hljs-value"><span class="pln"> </span><span class="hljs-number"><span class="lit">35</span></span><span class="lit">em</span></span></span><span class="pun">;</span><span class="pln">
        </span><span class="hljs-rule"><span class="hljs-attribute"><span class="pln">margin</span></span><span class="pun">:</span><span class="hljs-value"><span class="pln"> </span><span class="hljs-number"><span class="lit">0</span></span><span class="pln"> </span><span class="kwd">auto</span></span></span><span class="pun">;</span><span class="pln">
        </span><span class="hljs-rule"><span class="hljs-attribute"><span class="pln">font</span><span class="pun">-</span><span class="pln">family</span></span><span class="pun">:</span><span class="hljs-value"><span class="pln"> </span><span class="typ">Tahoma</span><span class="pun">,</span><span class="pln"> </span><span class="typ">Verdana</span><span class="pun">,</span><span class="pln"> </span><span class="typ">Arial</span><span class="pun">,</span><span class="pln"> sans</span><span class="pun">-</span><span class="pln">serif</span></span></span><span class="pun">;</span><span class="pln">
    </span><span class="hljs-rule"><span class="pun">}</span></span></span><span class="pln">
</span></span><span class="hljs-tag"><span class="tag">&lt;/</span><span class="hljs-title"><span class="tag">style</span></span><span class="tag">&gt;</span></span><span class="pln">
</span><span class="hljs-tag"><span class="tag">&lt;/</span><span class="hljs-title"><span class="tag">head</span></span><span class="tag">&gt;</span></span><span class="pln">
</span><span class="hljs-tag"><span class="tag">&lt;</span><span class="hljs-title"><span class="tag">body</span></span><span class="tag">&gt;</span></span><span class="pln">
</span><span class="hljs-tag"><span class="tag">&lt;</span><span class="hljs-title"><span class="tag">h1</span></span><span class="tag">&gt;</span></span><span class="pln">Welcome to nginx on LXD container webserver!</span><span class="hljs-tag"><span class="tag">&lt;/</span><span class="hljs-title"><span class="tag">h1</span></span><span class="tag">&gt;</span></span><span class="pln">
</span><span class="hljs-tag"><span class="tag">&lt;</span><span class="hljs-title"><span class="tag">p</span></span><span class="tag">&gt;</span></span><span class="pln">If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</span><span class="hljs-tag"><span class="tag">&lt;/</span><span class="hljs-title"><span class="tag">p</span></span><span class="tag">&gt;</span></span></code></pre>

<p>
	خادوم الويب يعمل، ولكن لا يمكننا الوصول إليه إلا من خلال الـ IP الخاص. لِنوجِّهْ الطلبات الخارجية إلى هذه الحاوية حتى يتمكن العالم من الدخول إلى موقعنا على الويب.
</p>

<h2 id="الخطوة-5-إعادة-توجيه-الاتصالات-الواردة-إلى-حاوية-nginx">
	الخطوة 5 : إعادة توجيه الاتصالات الواردة إلى حاوية Nginx
</h2>

<p>
	الجزء الأخير من اللغز هو ربط حاوية خادوم الويب بالإنترنت. Nginx مثبت في حاوية، وبشكل افتراضي لا يمكن الوصول إليه من الإنترنت. نحتاج إلى إعداد الخادوم المضيف لإعادة توجيه أيّ اتصالات قد يتلقاها من الإنترنت على المنفذ 80 إلى الحاوية webserver . للقيام بذلك سننشئ قاعدة iptables لإعادة توجيه الاتصالات. يتطلب الأمر iptables اثنين من عناوين IP: عنوان IP العام للخادوم (your_server_ip) وعنوان IP الخاص بحاوية nginx (<code>your_webserver_container_ip</code>) ، والذي يمكنك الحصول عليه باستخدام الأمر <code>lxc list</code> . نفذ هذا الأمر لإنشاء القاعدة:
</p>

<pre class="ipsCode" id="ips_uid_3216_7">
<code class="hljs parser3"><span class="xml"><span class="pln">PORT</span><span class="pun">=</span></span><span class="hljs-number"><span class="lit">80</span></span><span class="xml"><span class="pln"> PUBLIC_IP</span><span class="pun">=</span><span class="pln">your_server_ip CONTAINER_IP</span><span class="pun">=</span><span class="pln">your_container_ip \
sudo </span><span class="pun">-</span><span class="pln">E bash </span><span class="pun">-</span><span class="pln">c </span><span class="str">'iptables -t nat -I PREROUTING -i eth0 -p TCP -d </span></span><span class="hljs-variable"><span class="str">$PUBLIC_IP</span></span><span class="xml"><span class="str"> --dport </span></span><span class="hljs-variable"><span class="str">$PORT</span></span><span class="xml"><span class="str"> -j DNAT --to-destination </span></span><span class="hljs-variable"><span class="str">$CONTAINER_IP:</span></span><span class="hljs-variable"><span class="str">$PORT</span></span><span class="xml"><span class="str"> -m comment --comment "forward to the Nginx container"'</span></span></code></pre>

<p>
	وإليك شرح هذا الأمر:
</p>

<ul>
<li>
		<code>-t nat</code> يعني أننا نستخدم جدول nat لترجمة العنوان.
	</li>
	<li>
		<code>-I PREROUTING</code> يعني أننا نقوم بإضافة القاعدة إلى سلسلة PREROUTING.
	</li>
	<li>
		<code>-i eth0</code> يعني الواجهة <code>eth0</code>، وهي الواجهة العامة الافتراضية في Droplets.
	</li>
	<li>
		<code>-p TCP</code> يعني أننا نستخدم البروتوكول TCP.
	</li>
	<li>
		<code>-d $PUBLIC_IP</code> يحدد عنوان IP الوجهة .
	</li>
	<li>
		<code>--dport $PORT</code> : يحدد منفذ الوجهة (مثل 80 ).
	</li>
	<li>
		<code>-j DNAT</code> تعني أننا نريد إجراء قفزة إلى الوجهة NAT (DNAT).
	</li>
	<li>
		<code>--to-destination $CONTAINER_IP:$PORT</code> تعني أننا نريد الذهاب إلى عنوان IP الخاص بالحاوية المذكورة ومنفذ الوجهة.
	</li>
</ul>
<p>
	<strong>ملاحظة: </strong>يمكنك إعادة استخدام هذا الأمر لإعداد قواعد إعادة التوجيه ببساطة عن طريق تعيين متغيرات <code>PORT و PUBLIC_IP</code> و <code>CONTAINER_IP</code> في بداية السطر.<br>
	فقط قم بتغيير القيم الملونة بالأحمر.
</p>

<p>
	يمكنك الاطلاع على قواعد IPTables عن طريق تشغيل هذا الأمر:
</p>

<pre class="ipsCode" id="ips_uid_3216_7">
<code class="hljs lasso"><span class="pln">sudo iptables </span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">t</span></span><span class="pln"> nat </span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">L</span></span><span class="pln"> PREROUTING </span></code></pre>

<p>
	سترى مخرجًا مماثلًا لهذا:
</p>

<pre class="ipsCode" id="ips_uid_3216_7">
<code class="hljs r"><span class="typ">Chain</span><span class="pln"> PREROUTING </span><span class="pun">(</span><span class="pln">policy ACCEPT</span><span class="pun">)</span><span class="pln">
target     prot opt </span><span class="hljs-keyword"><span class="pln">source</span></span><span class="pln">               destination         
DNAT       tcp  </span><span class="pun">--</span><span class="pln">  anywhere             your_server_ip       tcp dpt</span><span class="pun">:</span><span class="pln">http </span><span class="com">/* forward to this container */</span><span class="pln"> to</span><span class="pun">:</span><span class="pln">your_container_ip</span><span class="pun">:</span><span class="hljs-number"><span class="lit">80</span></span><span class="pln">
</span><span class="hljs-keyword"><span class="pun">...</span></span></code></pre>

<p>
	اختبر الآن إمكانية الوصول إلى خادوم الويب، وذلك بالدخول إليه من جهاز الكمبيوتر المحلي باستخدام الأمر curl مثل هذا:
</p>

<pre class="ipsCode" id="ips_uid_3216_7">
<code class="hljs bash"><span class="pln">curl </span><span class="pun">--</span><span class="pln">verbose  </span><span class="hljs-string"><span class="str">'http://your_server_ip'</span></span><span class="pln"> </span></code></pre>

<p>
	سترى رأس صفحة الويب التي أنشأتها في الحاوية متبوعًا بمحتوياتها:
</p>

<pre class="ipsCode" id="ips_uid_3216_7">
<code class="hljs r"><span class="pun">*</span><span class="pln"> </span><span class="typ">Trying</span><span class="pln"> your_server_ip</span><span class="pun">...</span><span class="pln">
</span><span class="pun">*</span><span class="pln"> </span><span class="typ">Connected</span><span class="pln"> to your_server_ip </span><span class="pun">(</span><span class="pln">your_server_ip</span><span class="pun">)</span><span class="pln"> port </span><span class="hljs-number"><span class="lit">80</span></span><span class="pln"> </span><span class="pun">(</span><span class="hljs-comment"><span class="pun">#</span><span class="lit">0</span><span class="pun">)</span></span><span class="pln">
</span><span class="pun">&gt;</span><span class="pln"> GET </span><span class="pun">/</span><span class="pln"> HTTP</span><span class="pun">/</span><span class="hljs-number"><span class="lit">1.1</span></span><span class="pln">
</span><span class="pun">&gt;</span><span class="pln"> </span><span class="typ">User</span><span class="pun">-</span><span class="typ">Agent</span><span class="pun">:</span><span class="pln"> curl</span><span class="pun">/</span><span class="hljs-number"><span class="lit">7.47</span></span><span class="hljs-number"><span class="pun">.</span><span class="lit">0</span></span><span class="pln">
</span><span class="pun">&gt;</span><span class="pln"> </span><span class="typ">Accept</span><span class="pun">:</span><span class="pln"> </span><span class="pun">*</span><span class="com">/*
&gt; 
&lt; HTTP/</span><span class="hljs-number"><span class="com">1.1</span></span><span class="com"> </span><span class="hljs-number"><span class="com">200</span></span><span class="com"> OK
&lt; Server: nginx/</span><span class="hljs-number"><span class="com">1.10</span></span><span class="hljs-number"><span class="com">.0</span></span><span class="com"> (Ubuntu)
</span><span class="hljs-keyword"><span class="com">...</span></span><span class="com">
&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
&lt;title&gt;Welcome to nginx on LXD container webserver!&lt;/title&gt;
&lt;style&gt;
    body {
</span><span class="hljs-keyword"><span class="com">...</span></span></code></pre>

<p>
	هذا يؤكد أن الطلبات ستذهب إلى الحاوية.
</p>

<p>
	وأخيرًا .. لحفظ قاعدة جدار الحماية ثبت الحزمة iptables-persistent الحماية لكي يتم إعادة تطبيقها بعد إعادة التشغيل
</p>

<pre class="ipsCode" id="ips_uid_3216_7">
<code class="hljs lasso"><span class="pln">sudo apt</span><span class="hljs-attribute"><span class="pun">-</span><span class="kwd">get</span></span><span class="pln"> install iptables</span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">persistent</span></span></code></pre>

<p>
	عند تثبيت الحزمة ستتم مطالبتك بحفظ قواعد جدار الحماية الحالية. اقبل واحفظ جميع القواعد الحالية. عند إعادة تشغيل جهازك ستكون قاعدة جدار الحماية موجودة. بالإضافة إلى ذلك سيتم إعادة تشغيل خدمة Nginx في الحاوية الخاصة بك تلقائيا. الآن بعد أن قمنا بإعداد كل شيء لننظر في كيفية إزالته.
</p>

<h2 id="الخطوة-6-إيقاف-وإزالة-الحاوية">
	الخطوة 6 : إيقاف وإزالة الحاوية
</h2>

<p>
	ربما تقرر إزالة الحاوية واستبدالها. لنعرف كيف نقوم بذلك:<br>
	لإيقاف الحاوية استخدم lxc stop :
</p>

<pre class="ipsCode" id="ips_uid_3216_7">
<code class="hljs vbnet"><span class="pln">  lxc </span><span class="hljs-keyword"><span class="pln">stop</span></span><span class="pln"> webserver</span></code></pre>

<p>
	استخدم الأمر lxc list للتحقق من الحالة، ستكون المخرجات:
</p>

<pre class="ipsCode" id="ips_uid_3216_7">
<code class="hljs asciidoc"><span class="hljs-code"><span class="pun">+-----------+</span></span><span class="pun">---------</span><span class="hljs-code"><span class="pun">+------+</span></span><span class="pun">------</span><span class="hljs-code"><span class="pun">+------------+</span></span><span class="pun">-----------+</span><span class="pln">
</span><span class="hljs-header"><span class="pun">|</span><span class="pln">   NAME    </span><span class="pun">|</span><span class="pln">  STATE  </span><span class="pun">|</span><span class="pln"> IPV4 </span><span class="pun">|</span><span class="pln"> IPV6 </span><span class="pun">|</span><span class="pln">    TYPE    </span><span class="pun">|</span><span class="pln"> SNAPSHOTS </span><span class="pun">|</span><span class="pln">
</span><span class="pun">+-----------+---------+------+------+------------+-----------+</span></span><span class="pln">
</span><span class="hljs-header"><span class="pun">|</span><span class="pln"> webserver </span><span class="pun">|</span><span class="pln"> STOPPED </span><span class="pun">|</span><span class="pln">      </span><span class="pun">|</span><span class="pln">      </span><span class="pun">|</span><span class="pln"> PERSISTENT </span><span class="pun">|</span><span class="pln"> </span><span class="lit">0</span><span class="pln">         </span><span class="pun">|</span><span class="pln">
</span><span class="pun">+-----------+---------+------+------+------------+-----------+</span></span></code></pre>

<p>
	لإزالة الحاوية استخدم lxc delete :
</p>

<pre class="ipsCode" id="ips_uid_3216_7">
<code class="hljs javascript"><span class="pln">lxc </span><span class="hljs-keyword"><span class="kwd">delete</span></span><span class="pln"> webserver</span></code></pre>

<p>
	نفذ الأمر lxc list مرة أخرى ليظهر لك أنه لا يوجد حاوية قيد التشغيل:
</p>

<pre class="ipsCode" id="ips_uid_3216_7">
<code class="hljs asciidoc"><span class="hljs-code"><span class="pun">+------+</span></span><span class="pun">-------</span><span class="hljs-code"><span class="pun">+------+</span></span><span class="pun">------</span><span class="hljs-code"><span class="pun">+------+</span></span><span class="pun">-----------+</span><span class="pln">
</span><span class="hljs-header"><span class="pun">|</span><span class="pln"> NAME </span><span class="pun">|</span><span class="pln"> STATE </span><span class="pun">|</span><span class="pln"> IPV4 </span><span class="pun">|</span><span class="pln"> IPV6 </span><span class="pun">|</span><span class="pln"> TYPE </span><span class="pun">|</span><span class="pln"> SNAPSHOTS </span><span class="pun">|</span><span class="pln">
</span><span class="pun">+------+-------+------+------+------+-----------+</span></span></code></pre>

<p>
	استخدم الأمر lxc help للاطلاع على خيارات إضافية.
</p>

<p>
	لإزالة قاعدة الجدار الناري التي توجه حركة المرور إلى الحاوية حدد أولا القاعدة في قائمة القواعد بهذا الأمر والذي يربط رقم سطر مع كل قاعدة:
</p>

<pre class="ipsCode" id="ips_uid_3216_7">
<code class="hljs lasso"><span class="pln">sudo iptables </span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">t</span></span><span class="pln"> nat </span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">L</span></span><span class="pln"> PREROUTING </span><span class="hljs-subst"><span class="pun">--</span></span><span class="pln">line</span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">numbers</span></span></code></pre>

<p>
	سترى القاعدة، مسبوقة برقم سطر، كما يلي:
</p>

<pre class="ipsCode" id="ips_uid_3216_7">
<code class="hljs css"><span class="hljs-tag"><span class="typ">Chain</span></span><span class="pln"> </span><span class="hljs-tag"><span class="pln">PREROUTING</span></span><span class="pln"> </span><span class="pun">(</span><span class="hljs-tag"><span class="pln">policy</span></span><span class="pln"> </span><span class="hljs-tag"><span class="pln">ACCEPT</span></span><span class="pun">)</span><span class="pln">
</span><span class="hljs-tag"><span class="pln">num</span></span><span class="pln">  </span><span class="hljs-tag"><span class="pln">target</span></span><span class="pln">     </span><span class="hljs-tag"><span class="pln">prot</span></span><span class="pln"> </span><span class="hljs-tag"><span class="pln">opt</span></span><span class="pln"> </span><span class="hljs-tag"><span class="pln">source</span></span><span class="pln">               </span><span class="hljs-tag"><span class="pln">destination</span></span><span class="pln">
</span><span class="lit">1</span><span class="pln">    </span><span class="hljs-tag"><span class="pln">DNAT</span></span><span class="pln">       </span><span class="hljs-tag"><span class="pln">tcp</span></span><span class="pln">  </span><span class="hljs-tag"><span class="pun">--</span></span><span class="pln">  </span><span class="hljs-tag"><span class="pln">anywhere</span></span><span class="pln">             </span><span class="hljs-tag"><span class="pln">your_server_ip</span></span><span class="pln">      </span><span class="hljs-tag"><span class="pln">tcp</span></span><span class="pln"> </span><span class="hljs-tag"><span class="pln">dpt</span></span><span class="hljs-pseudo"><span class="pun">:</span><span class="pln">http</span></span><span class="pln"> </span><span class="hljs-comment"><span class="com">/* forward to the Nginx container */</span></span><span class="pln"> </span><span class="hljs-tag"><span class="pln">to</span></span><span class="hljs-pseudo"><span class="pun">:</span><span class="pln">your_container_ip</span></span></code></pre>

<p>
	استخدم رقم السطر هذا لإزالة القاعدة:
</p>

<pre class="ipsCode" id="ips_uid_3216_7">
<code class="hljs lasso"><span class="pln">sudo iptables </span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">t</span></span><span class="pln"> nat </span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">D</span></span><span class="pln"> PREROUTING </span><span class="hljs-number"><span class="lit">1</span></span></code></pre>

<p>
	تأكد من إلغاء القاعدة من خلال مشاهدة القواعد مرة أخرى بالأمر:
</p>

<pre class="ipsCode" id="ips_uid_3216_7">
<code class="hljs bash"><span class="str">`</span><span class="hljs-built_in"><span class="str">sudo</span></span><span class="str"> iptables -t nat -L PREROUTING --line-numbers`</span></code></pre>

<p>
	سترى أنه تمت إزالة القاعدة:
</p>

<pre class="ipsCode" id="ips_uid_3216_7">
<code class="hljs bash"><span class="typ">Chain</span><span class="pln"> PREROUTING </span><span class="pun">(</span><span class="pln">policy ACCEPT</span><span class="pun">)</span><span class="pln">
num  target     prot opt </span><span class="hljs-built_in"><span class="pln">source</span></span><span class="pln">               destination </span></code></pre>

<p>
	احفظ التغييرات الآن حتى لا يتم العمل بالقاعدة بعد إعادة تشغيل الخادوم:
</p>

<pre class="ipsCode" id="ips_uid_3216_7">
<code class="hljs bash"><span class="hljs-built_in"><span class="pln">sudo</span></span><span class="pln"> netfilter</span><span class="pun">-</span><span class="pln">persistent save</span></code></pre>

<p>
	يمكنك الآن إنشاء حاوية أخرى مع الإعدادات الخاصة بك وإضافة قاعدة جدار حماية جديدة لإعادة توجيه حركة المرور إليها.
</p>

<h2 id="خلاصة">
	خلاصة
</h2>

<p>
	لقد قمت بإعداد موقع ويب باستخدام Nginx في حاوية LXD. يمكنك من هنا إعداد المزيد من مواقع الويب حيث يقتصر كل واحد منها على حاويته الخاصة به، ويمكنك ايضا استخدام بروكسي عكسي لتوجيه حركة المرور إلى الحاوية المناسبة. سيعلمك كيف تفعل ذلك هذا المقال: <a href="https://academy.hsoub.com/devops/servers/web/nginx/%D9%83%D9%8A%D9%81-%D8%AA%D8%B3%D8%AA%D8%B6%D9%8A%D9%81-%D9%85%D8%AC%D9%85%D9%88%D8%B9%D8%A9-%D9%85%D9%88%D8%A7%D9%82%D8%B9-%D8%A8%D8%B4%D9%83%D9%84-%D8%A2%D9%85%D9%86-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-nginx-%D9%88-php-fpm-%D8%B9%D9%84%D9%89-%D8%A3%D9%88%D8%A8%D9%86%D8%AA%D9%88-1404-r251/" rel="">كيف تستضيف مجموعة مواقع بشكل آمن باستخدام Nginx و Php-fpm على أوبنتو 14.04</a>
</p>

<p>
	يتيح لك LXD أيضا التقاط لقطات من الحالة الكاملة للحاويات، مما يجعل من السهل إنشاء نسخ احتياطية من أجل الرجوع إليها لاحقا. وإذا قمت بتثبيت LXD على خادومين مختلفين فمن الممكن توصيل الحاويات بعضها ببعض وترحيلها بين الخوادم عبر الإنترنت.
</p>

<p>
	لمعرفة المزيد عن LXD اقرأ <a href="https://stgraber.org/2016/03/11/lxd-2-0-blog-post-series-012/" rel="external nofollow">هذه التدوينات عن LXD</a> التي كتبها مطورو LXD<br>
	يمكنك أيضا تجربة <a href="https://linuxcontainers.org/lxd/try-it/" rel="external nofollow">LXD على الانترنت</a> واتباع البرنامج التعليمي على شبكة الإنترنت للحصول على مزيد من الممارسة.
</p>

<p>
	ترجمة -وبتصرّف- للمقال <a href="https://www.digitalocean.com/community/tutorials/how-to-set-up-and-use-lxd-on-ubuntu-16-04" rel="external nofollow">How to Set Up and Use LXD on Ubuntu 16.04</a> لصاحبه Simos Xenitellis
</p>
]]></description><guid isPermaLink="false">375</guid><pubDate>Thu, 04 Jan 2018 14:00:00 +0000</pubDate></item><item><title>&#x643;&#x64A;&#x641;&#x64A;&#x629; &#x625;&#x639;&#x62F;&#x627;&#x62F; &#x648;&#x627;&#x633;&#x62A;&#x62E;&#x62F;&#x627;&#x645; LXD &#x639;&#x644;&#x649; &#x623;&#x648;&#x628;&#x648;&#x646;&#x62A;&#x648; 16.04 &#x2013; &#x627;&#x644;&#x625;&#x639;&#x62F;&#x627;&#x62F; &#x648;&#x625;&#x646;&#x634;&#x627;&#x621; &#x62D;&#x627;&#x648;&#x64A;&#x629; Nginx</title><link>https://academy.hsoub.com/devops/linux/%D9%83%D9%8A%D9%81%D9%8A%D8%A9-%D8%A5%D8%B9%D8%AF%D8%A7%D8%AF-%D9%88%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-lxd-%D8%B9%D9%84%D9%89-%D8%A3%D9%88%D8%A8%D9%88%D9%86%D8%AA%D9%88-1604-%E2%80%93-%D8%A7%D9%84%D8%A5%D8%B9%D8%AF%D8%A7%D8%AF-%D9%88%D8%A5%D9%86%D8%B4%D8%A7%D8%A1-%D8%AD%D8%A7%D9%88%D9%8A%D8%A9-nginx-r374/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2017_12/28.png.57358e38b8027ea7bbe07515d00dd87e.png" /></p>

<p>
	حاوية لينكس هي مجموعة من العمليات المعزولة عن بقية النظام من خلال استخدام ميزات أمان نواة لينكس، مثل مساحات الأسماء ومجموعات التحكم. إنها بناء مماثل للآلة الافتراضية، و لكنه أكثر خفة منها، فإن لم يكن لديك النفقات الكافية لتشغيل أنوية إضافية أو آلات افتراضية فلا تقلق من ذلك، لأنه يمكنك بسهولة إنشاء حاويات متعددة على نفس الخادوم. على سبيل المثال، تخيل أن لديك خادوم يقوم بتشغيل مواقع ويب متعددة لعملائك. في حال التثبيت التقليدي سيكون كل موقع على شبكة الانترنت مضيفًا افتراضيًا من نفس حالة خادوم apache أو Nginx. ولكن مع حاويات لينكس يمكن لكل موقع على شبكة الإنترنت أن يثبت في حاوية خاصة به مع خادوم الويب الخاص بها. باستخدام حاويات لينكس يمكنك تجميع التطبيق الخاص بك واعتمادياته في حاوية دون التأثير على بقية النظام. يتيح لك LXD إنشاء هذه الحاويات وإدارتها. يوفر LXD خدمة مراقب الأجهزة الافتراضية لإدارة دورة الحياة الكاملة للحاويات. في هذا الدرس سوف نقوم بإعداد LXD واستخدامه لتشغيل Nginx في حاوية. وستقوم بعد ذلك بتوجيه حركة المرور إلى الحاوية من أجل جعل موقع الويب ممكن الوصول إليه من الإنترنت.
</p>

<h2 id="المتطلبات-الأساسية">
	المتطلبات الأساسية
</h2>

<p>
	لإكمال هذا الدرس ستحتاج إلى ما يلي:
</p>

<ol>
<li>
		خادوم أوبونتو 16.04 مُعَد مسبقا ، يمكنك الرجوع إلى هذه المقال لتعرف كيف تفعل ذلك: <a href="https://academy.hsoub.com/devops/servers/%D8%A7%D9%84%D8%A5%D8%B9%D8%AF%D8%A7%D8%AF-%D8%A7%D9%84%D8%A7%D8%A8%D8%AA%D8%AF%D8%A7%D8%A6%D9%8A-%D9%84%D8%AE%D8%A7%D8%AF%D9%88%D9%85-%D8%A3%D9%88%D8%A8%D9%86%D8%AA%D9%88-1404-r4/" rel="">الإعداد الابتدائي لخادوم أوبنتو 14.04</a>
	</li>
	<li>
		مستخدم غير جذر يملك صلاحيات الجذر وجدار الحماية.
	</li>
	<li>
		اختياريًا أضف 20 جيغا أو أكثر من مساحة التخزين ، يمكنك استخدام ذلك لتخزين كافة البيانات المتعلقة بالحاويات.
	</li>
</ol>
<h2 id="الخطوة-1-إعداد-lxd">
	الخطوة 1 : إعداد LXD
</h2>

<p>
	تم تثبيت LXD بالفعل على أوبونتو، ولكن يجب أن يتم إعداده بشكل مناسب قبل أن تتمكن من استخدامه على الخادوم. يجب عليك إعداد حساب المستخدم لإدارة الحاويات، ثم إعداد نوع قاعدة التخزين لتخزين الحاويات وإعداد الشبكة. قم بتسجيل الدخول إلى الخادوم باستخدام حساب المستخدم غير الجذر. ثم أضف المستخدم إلى مجموعة LXD بحيث يمكنك استخدامه لأداء جميع مهام إدارة الحاويات:
</p>

<pre class="ipsCode" id="ips_uid_6942_7">
sudo usermod --append --groups lxd Sammy</pre>

<p>
	قم بتسجيل الخروج من الخادوم وتسجيل الدخول مرة أخرى لكي يتم تحديث جلسة <abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">SSH</abbr> الجديدة الخاصة بك مع عضوية المجموعة الجديدة. بعد تسجيل الدخول يمكنك البدء في تهيئة LXD. الآن قم بإعداد قاعدة التخزين. قاعدة التخزين الموصى بها ل LXD هو نظام ملفات ZFS، المخزنة إما في ملف مخصص مسبقًا أو باستخدام كتلة التخزين . لاستفادة من دعم ZFS في LXD حدّث قائمة الحزم الخاصة بك ثم ثبت الحزمة zfsutils-linux :
</p>

<pre class="ipsCode" id="ips_uid_6942_7">
<code class="hljs lasso"><span class="pln">sudo apt</span><span class="hljs-attribute"><span class="pun">-</span><span class="kwd">get</span></span><span class="pln"> update
sudo apt</span><span class="hljs-attribute"><span class="pun">-</span><span class="kwd">get</span></span><span class="pln"> install zfsutils</span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">linux</span></span></code></pre>

<p>
	يمكنك الآن إعداد LXD. ابدأ بعملية تهيئة LXD مع الأمر LXD init :
</p>

<pre class="ipsCode" id="ips_uid_6942_7">
<code class="hljs bash"><span class="hljs-built_in"><span class="pln">sudo</span></span><span class="pln"> lxd init</span></code></pre>

<p>
	ستتم مطالبتك بتعيين تفاصيل قاعدة التخزين. بعد الانتهاء من هذا الإعداد يتوجب عليك إعداد الشبكة من أجل الحاويات.
</p>

<p>
	أولاً سوف يُقترح عليك أن تختار بشأن قاعدة التخزين، وستُخَير بين أمرين: dir أو zfs . الخيار dir يخبر LXD بتخزين الحاويات في مجلدات تابعة لنظام ملفات الخادوم. وأما الخيار zfs فيستخدم نظام الملفات zfs ونظام إدارة القرص الصلب LVM. اختر zfs. باستخدام zfs نحصل على كلٍّ من كفاءة التخزين وتحسين الاستجابة. على سبيل المثال إذا أنشأنا عشرة حاويات من نفس صورة الحاوية الأولية، فإنها جميعا تستخدم من القرص مساحةَ حاوية واحدة فقط. وبعد ذلك سيتم فقط تخزين التغييرات على صورة الحاوية الأولى في قاعدة التخزين.
</p>

<pre class="ipsCode" id="ips_uid_6942_7">
<code class="hljs fsharp"><span class="typ">Name</span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">of</span></span><span class="pln"> the storage backend </span><span class="hljs-keyword"><span class="pln">to</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">use</span></span><span class="pln"> </span><span class="pun">(</span><span class="pln">dir </span><span class="hljs-keyword"><span class="kwd">or</span></span><span class="pln"> zfs</span><span class="pun">)</span><span class="pln"> </span><span class="pun">[</span><span class="hljs-keyword"><span class="kwd">default</span></span><span class="pun">=</span><span class="pln">zfs</span><span class="pun">]:</span><span class="pln"> zfs</span></code></pre>

<p>
	بعد اختيار zfs سيُطلَب منك إنشاء تجمع (pool) zfs جديد واسم لهذا التجمع. اختر نعم لإنشاء التجمع، وسمه ب lxd :
</p>

<pre class="ipsCode" id="ips_uid_6942_7">
<code class="hljs coffeescript"><span class="typ">Create</span><span class="pln"> a </span><span class="hljs-keyword"><span class="kwd">new</span></span><span class="pln"> ZFS pool </span><span class="pun">(</span><span class="hljs-literal"><span class="pln">yes</span></span><span class="pun">/</span><span class="hljs-literal"><span class="kwd">no</span></span><span class="pun">)</span><span class="pln"> </span><span class="pun">[</span><span class="hljs-reserved"><span class="kwd">default</span></span><span class="pun">=</span><span class="hljs-literal"><span class="pln">yes</span></span><span class="pun">]?</span><span class="pln"> </span><span class="hljs-literal"><span class="pln">yes</span></span><span class="pln">
</span><span class="typ">Name</span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">of</span></span><span class="pln"> the </span><span class="hljs-keyword"><span class="kwd">new</span></span><span class="pln"> ZFS pool </span><span class="pun">[</span><span class="hljs-reserved"><span class="kwd">default</span></span><span class="pun">=</span><span class="pln">lxd</span><span class="pun">]:</span><span class="pln"> lxd</span></code></pre>

<p>
	ثم ستُسأل إذا كنت ترغب في استخدام عتاد التخزين الموجود:
</p>

<pre class="ipsCode" id="ips_uid_6942_7">
<code class="hljs vhdl"><span class="typ">Would</span><span class="pln"> you like </span><span class="hljs-keyword"><span class="pln">to</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">use</span></span><span class="pln"> an existing </span><span class="hljs-keyword"><span class="pln">block</span></span><span class="pln"> device </span><span class="pun">(</span><span class="pln">yes</span><span class="pun">/</span><span class="kwd">no</span><span class="pun">)</span><span class="pln"> </span><span class="pun">[</span><span class="hljs-keyword"><span class="kwd">default</span></span><span class="pun">=</span><span class="kwd">no</span><span class="pun">]</span></code></pre>

<p>
	إذا أجبت بنعم فعليك أن تخبر LXD أين يجد هذا العتاد. إذا أجبت بلا فسوف يقوم LXD باستخدام ملف مخصص مسبقًا. مع هذا الخيار سوف تستخدم المساحة الفارغة على الخادوم نفسه. هناك حالتان يتبعان ذلك اعتمادًا على ما إذا كنت تريد استخدام ملف مخصص مسبقًا أو عتاد التخزين. اتبع الخطوة المناسبة لحالتك. بعد تحديد آلية التخزين ستعمل على تهيئة خيارات الشبكة من أجل حاوياتك.
</p>

<h3>
	الخيار 1 : استخدام التخصيص المسبق
</h3>

<p>
	يمكنك استخدام ملف مخصص مسبقًا إذا لم تتمكن من الوصول إلى عتاد التخزين من أجل تخزين الحاويات. اتبع هذه الخطوات لإعداد LXD لكي يستخدم ملف مخصص مسبقًا لتخزين الحاويات.<br>
	أولًا، عندما يطلب منك استخدام عتاد التخزين الموجود أجب بلا :
</p>

<pre class="ipsCode" id="ips_uid_6942_7">
<code class="hljs coffeescript"><span class="typ">Would</span><span class="pln"> you like to </span><span class="kwd">use</span><span class="pln"> an existing block device </span><span class="pun">(</span><span class="hljs-literal"><span class="pln">yes</span></span><span class="pun">/</span><span class="hljs-literal"><span class="kwd">no</span></span><span class="pun">)</span><span class="pln"> </span><span class="pun">[</span><span class="hljs-reserved"><span class="kwd">default</span></span><span class="pun">=</span><span class="hljs-literal"><span class="kwd">no</span></span><span class="pun">]?</span><span class="pln"> </span><span class="hljs-literal"><span class="kwd">no</span></span></code></pre>

<p>
	بعد ذلك، سيطلب منك تحديد حجم loop device ، الذي يستدعيه الملف المخصص مسبقًا من LXD. استخدام الحجم الافتراضي المقترح للملف المخصص مسبقًا :
</p>

<pre class="ipsCode" id="ips_uid_6942_7">
<code class="hljs vbnet"><span class="typ">Size</span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">in</span></span><span class="pln"> GB </span><span class="hljs-keyword"><span class="pln">of</span></span><span class="pln"> the </span><span class="hljs-keyword"><span class="kwd">new</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">loop</span></span><span class="pln"> device </span><span class="pun">(</span><span class="hljs-number"><span class="lit">1</span></span><span class="lit">GB</span><span class="pln"> minimum</span><span class="pun">)</span><span class="pln"> </span><span class="pun">[</span><span class="hljs-keyword"><span class="kwd">default</span></span><span class="pun">=</span><span class="hljs-number"><span class="lit">15</span></span><span class="pun">]:</span><span class="pln"> </span><span class="hljs-number"><span class="lit">15</span></span></code></pre>

<p>
	وكقاعدة عامة 15 جيغا هو أصغر حجم يجب عليك إنشاؤه. فأنت تريد تخصيص مساحة كافية لكي يكون لديك 10 غيغابايت على الأقل من المساحة المتبقية بعد إنشاء الحاويات الخاصة بك.<br>
	بعد تهيئة الجهاز سيطلب منك إعداد الشبكة. انتقل إلى الخطوة 2 لمتابعة الإعداد.
</p>

<h3>
	<br>
	الخيار 2 : استخدام عتاد التخزين
</h3>

<p>
	إذا كنت تريد استخدام عتاد التخزين قاعدةً للتخزين فستحتاج إلى العثور على العتاد الذي يتوافق مع حجم كتلة التخزين التي قمت بإنشائها في تهيئة LXD. انتقل إلى تبويب المجلدات في لوحة التحكم الخاصة ب DigitalOcean، ثم حدد موقع وحدة التخزين الخاصة بك، انقر فوق المزيد من القائمة المنبثقة، ثم انقر فوق تعليمات الإعداد. حدد موقع العتاد بتطبيق أمر تهيئة وحدة التخزين. بعبارة أدق ابحث عن المسار المحدد بتنفيذ الأمر sudo mkfs.ext4 -F . لا تقم بتشغيل أيٍّ من الأوامر الظاهرة في تلك الصفحة، نحن لا نريد سوى العثور على اسم الجهاز الصحيح لإعطاءه لـ LXD.<br>
	يوضح الشكل التالي مثالا عن اسم الجهاز الخاص بوحدة التخزين. تحتاج فقط إلى الجزء المسطر عليه بالأحمر:
</p>

<p style="text-align: center;">
	<img alt="001.png" class="ipsImage ipsImage_thumbnailed" data-fileid="26073" data-unique="z8ppfy7me" src="https://academy.hsoub.com/uploads/monthly_2017_12/001.png.22af5601cad4b4dc7bdbbc2afcad366f.png"></p>

<p>
	يمكنك أيضا تحديد اسم الجهاز بالأمر التالي:
</p>

<pre class="ipsCode" id="ips_uid_6942_7">
<code class="hljs lasso"><span class="pln">ls </span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">l</span></span><span class="pln"> </span><span class="pun">/</span><span class="pln">dev</span><span class="pun">/</span><span class="pln">disk</span><span class="pun">/</span><span class="hljs-keyword"><span class="kwd">by</span></span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">id</span></span><span class="hljs-subst"><span class="pun">/</span></span><span class="pln">
total </span><span class="hljs-number"><span class="lit">0</span></span><span class="pln">
lrwxrwxrwx </span><span class="hljs-number"><span class="lit">1</span></span><span class="pln"> root root  </span><span class="hljs-number"><span class="lit">9</span></span><span class="pln"> </span><span class="typ">Sep</span><span class="pln">  </span><span class="hljs-number"><span class="lit">16</span></span><span class="pln"> </span><span class="hljs-number"><span class="lit">20</span></span><span class="pun">:</span><span class="hljs-number"><span class="lit">30</span></span><span class="pln"> scsi</span><span class="hljs-subst"><span class="pun">-</span></span><span class="hljs-number"><span class="lit">0</span></span><span class="lit">DO</span><span class="typ">_Volume_volume</span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">fra1</span></span><span class="hljs-subst"><span class="pun">-</span></span><span class="hljs-number"><span class="lit">01</span></span><span class="pln"> </span><span class="hljs-subst"><span class="pun">-&gt;</span><span class="pln"> </span></span><span class="hljs-built_in"><span class="pun">..</span></span><span class="hljs-subst"><span class="pun">/</span></span><span class="hljs-built_in"><span class="pun">..</span></span><span class="pun">/</span><span class="pln">sda </span></code></pre>

<p>
	في هذه الحالة اسم الجهاز لوحدة التخزين هو
</p>

<pre class="ipsCode" id="ips_uid_6942_7">
<code class="hljs lasso"><span class="str">/dev/</span><span class="pln">disk</span><span class="pun">/</span><span class="hljs-keyword"><span class="kwd">by</span></span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">id</span></span><span class="pun">/</span><span class="pln">scsi</span><span class="hljs-subst"><span class="pun">-</span></span><span class="hljs-number"><span class="lit">0</span></span><span class="lit">D0</span><span class="typ">_Volume_volume</span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">fra1</span></span><span class="hljs-subst"><span class="pun">-</span></span><span class="hljs-number"><span class="lit">01</span></span></code></pre>

<p>
	وقد يختلف الأمر لديك. بعد تحديد اسم عتاد وحدة التخزين تابع مع تثبيت LXD . عندما تُسأل هل تود أن تستخدم عتاد التخزين الموجود، اختر نعم وقدّم المسار الذي وجدته سابقا:
</p>

<pre class="ipsCode" id="ips_uid_6942_7">
<code class="hljs vhdl"><span class="typ">Would</span><span class="pln"> you like </span><span class="hljs-keyword"><span class="pln">to</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">use</span></span><span class="pln"> an existing </span><span class="hljs-keyword"><span class="pln">block</span></span><span class="pln"> device </span><span class="pun">(</span><span class="pln">yes</span><span class="pun">/</span><span class="kwd">no</span><span class="pun">)</span><span class="pln"> </span><span class="pun">[</span><span class="hljs-keyword"><span class="kwd">default</span></span><span class="pun">=</span><span class="kwd">no</span><span class="pun">]?</span><span class="pln"> yes
</span><span class="typ">Path</span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">to</span></span><span class="pln"> the existing </span><span class="hljs-keyword"><span class="pln">block</span></span><span class="pln"> device</span><span class="pun">:</span><span class="pln"> </span><span class="str">/dev/</span><span class="pln">disk</span><span class="pun">/</span><span class="kwd">by</span><span class="pun">-</span><span class="pln">id</span><span class="pun">/</span><span class="pln">scsi</span><span class="pun">-</span><span class="hljs-number"><span class="lit">0</span></span><span class="lit">DO</span><span class="typ">_Volume_volume</span><span class="pun">-</span><span class="pln">fra1</span><span class="pun">-</span><span class="hljs-number"><span class="lit">01</span></span></code></pre>

<p>
	بعد تحديد القرص الصلب سيطلب منك إعداد خيارات الشبكة.
</p>

<h2 id="الخطوة-2-إعدادات-الشبكة">
	الخطوة 2 : إعدادات الشبكة
</h2>

<p>
	بعد تهيئة وحدة التخزين ستتم مطالبتك بتهيئة الشبكة وإعدادها. أولاً سيسألك LXD عما إذا كنت تريد جعله متاحًا عبر الشبكة. اختيار “نعم” سوف يمكّنك من إدارة LXD من جهاز الكمبيوتر المحلي الخاص بك، دون الحاجة إلى جلسة <abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">SSH</abbr> للوصول إلى هذا الخادوم. اقبل القيمة الافتراضية “لا” :
</p>

<pre class="ipsCode" id="ips_uid_6942_7">
<code class="hljs applescript"><span class="typ">Output</span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">of</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">the</span></span><span class="pln"> </span><span class="hljs-string"><span class="str">"lxd init"</span></span><span class="pln"> command </span><span class="pun">—</span><span class="pln"> LXD </span><span class="hljs-keyword"><span class="pln">over</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">the</span></span><span class="pln"> network
</span><span class="typ">Would</span><span class="pln"> you like LXD </span><span class="hljs-keyword"><span class="pln">to</span></span><span class="pln"> be available </span><span class="hljs-keyword"><span class="pln">over</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">the</span></span><span class="pln"> network </span><span class="pun">(</span><span class="pln">yes</span><span class="pun">/</span><span class="kwd">no</span><span class="pun">)</span><span class="pln"> </span><span class="pun">[</span><span class="kwd">default</span><span class="pun">=</span><span class="kwd">no</span><span class="pun">]?</span><span class="pln"> </span><span class="kwd">no</span></code></pre>

<p>
	ثم سيطلب منك إنشاء جسر الشبكة من أجل حاويات LXD. وهذا يتيح لك الميزات التالية:
</p>

<ul>
<li>
		كل حاوية تحصل تلقائيًا على عنوان IP خاص.
	</li>
	<li>
		يمكن للحاويات التواصل مع بعضها البعض عبر الشبكة الخاصة.
	</li>
	<li>
		يمكن لكل حاوية انشاء اتصال بالإنترنت.
	</li>
	<li>
		تبقى الحاويات التي تقوم بإنشائها غير قابلة للوصول إليها من الإنترنت.
	</li>
</ul>
<p>
	لا يمكنك إجراء اتصال من الإنترنت والوصول إلى حاوية إلا إذا قمت بتمكينه صراحة. سوف تتعلم كيفية السماح بالوصول إلى حاوية معينة في الخطوة التالية.
</p>

<p>
	عندما يطلب منك تكوين جسر LXD، اختر نعم :
</p>

<pre class="ipsCode" id="ips_uid_6942_7">
<code class="hljs livecodeserver"><span class="typ">Output</span><span class="pln"> </span><span class="hljs-operator"><span class="pln">of</span></span><span class="pln"> </span><span class="hljs-operator"><span class="pln">the</span></span><span class="pln"> </span><span class="hljs-string"><span class="str">"lxd init"</span></span><span class="pln"> </span><span class="hljs-command"><span class="hljs-keyword"><span class="pln">command</span></span><span class="pln"> </span><span class="pun">—</span><span class="pln"> </span><span class="hljs-title"><span class="typ">Networking</span></span><span class="pln"> </span><span class="hljs-title"><span class="kwd">for</span></span><span class="pln"> </span><span class="hljs-title"><span class="pln">the</span></span><span class="pln"> </span><span class="hljs-title"><span class="pln">containers</span></span></span><span class="pln">
</span><span class="typ">Do</span><span class="pln"> you want </span><span class="hljs-built_in"><span class="pln">to</span></span><span class="pln"> configure </span><span class="hljs-operator"><span class="pln">the</span></span><span class="pln"> LXD bridge </span><span class="pun">(</span><span class="pln">yes</span><span class="pun">/</span><span class="kwd">no</span><span class="pun">)</span><span class="pln"> </span><span class="pun">[</span><span class="kwd">default</span><span class="pun">=</span><span class="pln">yes</span><span class="pun">]?</span><span class="pln"> </span><span class="typ">Yes</span></code></pre>

<p>
	سيتم عرض الرسالة التالية:
</p>

<p style="text-align: center;">
	<img alt="002.png" class="ipsImage ipsImage_thumbnailed" data-fileid="26072" data-unique="djw2qsnwk" src="https://academy.hsoub.com/uploads/monthly_2017_12/002.png.e7e6c291387311f9d8eaf461de7a9c5a.png"></p>

<ul>
<li>
		أكّد أنك تريد إعداد جسر الشبكة.
	</li>
	<li>
		سيطلب منك تسمية الجسر. اقبل القيمة الافتراضية.
	</li>
	<li>
		سيطلب منك إجراء تهيئة الشبكة لكلٍّ من IPv4 و IPv6. في هذا الدرس سنعمل فقط مع IPv4.
	</li>
	<li>
		عندما يطلب منك إعداد شبكة فرعية IPv4 اختر نعم . سوف يتم إعلامك بأنه تم إنشاء شبكة فرعية عشوائية بالنسبة لك. اختر موافق للمتابعة.
	</li>
	<li>
		عند المطالبة بعنوان IPv4 صحيح قم بقبول القيمة الافتراضية.
	</li>
	<li>
		عندما يطلب منك قناع CIDR صحيح، اقبل القيمة الافتراضية.
	</li>
	<li>
		عند المطالبة بعنوان DHCP الأول اقبل القيمة الافتراضية. افعل الشيء نفسه مع عنوان DHCP الأخير وذلك حسب الحد الأقصى لعدد عملاء DHCP.
	</li>
	<li>
		اختر نعم عندما يطلب إلى NAT حركة مرور IPv4.
	</li>
	<li>
		عندما يطلب منك إعداد شبكة فرعية لـ IPv6 اختر “لا” . ستشاهد المخرجات التالية بعد اكتمال إعداد الشبكات:
	</li>
</ul>
<pre class="ipsCode" id="ips_uid_6942_7">
<code class="hljs livecodeserver"><span class="typ">Warning</span><span class="pun">:</span><span class="pln"> </span><span class="typ">Stopping</span><span class="pln"> lxd</span><span class="pun">.</span><span class="pln">service</span><span class="pun">,</span><span class="pln"> but </span><span class="hljs-keyword"><span class="pln">it</span></span><span class="pln"> can still be activated </span><span class="hljs-keyword"><span class="kwd">by</span></span><span class="pun">:</span><span class="pln">
  lxd</span><span class="pun">.</span><span class="hljs-built_in"><span class="pln">socket</span></span><span class="pln">
LXD has been successfully configured</span><span class="pun">.</span></code></pre>

<p>
	أنت مستعد الآن لإعداد حاوياتك.
</p>

<h2 id="الخطوة-3-إنشاء-حاوية-nginx">
	الخطوة 3 : إنشاء حاوية Nginx
</h2>

<p>
	لقد نجحت في تهيئة LXD وأصبحت الآن جاهزا لإنشاء الحاوية الأولى وإدارتها. يمكنك إدارة الحاويات مع الأمر lxc.<br>
	استخدم lxc list لعرض الحاويات المثبتة المتاحة:
</p>

<pre class="ipsCode" id="ips_uid_6942_7">
<code class="hljs php"><span class="pln">lxc </span><span class="hljs-keyword"><span class="pln">list</span></span><span class="pln"> </span></code></pre>

<p>
	سترى الإخراج التالي:
</p>

<pre class="ipsCode" id="ips_uid_6942_7">
<code class="hljs asciidoc"><span class="typ">Generating</span><span class="pln"> a client certificate</span><span class="pun">.</span><span class="pln"> </span><span class="typ">This</span><span class="pln"> may take a minute</span><span class="pun">...</span><span class="pln">
</span><span class="typ">If</span><span class="pln"> </span><span class="kwd">this</span><span class="pln"> </span><span class="kwd">is</span><span class="pln"> your first time </span><span class="kwd">using</span><span class="pln"> LXD</span><span class="pun">,</span><span class="pln"> you should also run</span><span class="pun">:</span><span class="pln"> sudo lxd init
</span><span class="typ">To</span><span class="pln"> start your first container</span><span class="pun">,</span><span class="pln"> </span><span class="kwd">try</span><span class="pun">:</span><span class="pln"> lxc launch ubuntu</span><span class="pun">:</span><span class="lit">16.04</span><span class="pln">

</span><span class="hljs-code"><span class="pun">+------+</span></span><span class="pun">-------</span><span class="hljs-code"><span class="pun">+------+</span></span><span class="pun">------</span><span class="hljs-code"><span class="pun">+------+</span></span><span class="pun">-----------+</span><span class="pln">
</span><span class="hljs-header"><span class="pun">|</span><span class="pln"> NAME </span><span class="pun">|</span><span class="pln"> STATE </span><span class="pun">|</span><span class="pln"> IPV4 </span><span class="pun">|</span><span class="pln"> IPV6 </span><span class="pun">|</span><span class="pln"> TYPE </span><span class="pun">|</span><span class="pln"> SNAPSHOTS </span><span class="pun">|</span><span class="pln">
</span><span class="pun">+------+-------+------+------+------+-----------+</span></span></code></pre>

<p>
	وبما أن هذه هي المرة الأولى التي يتواصل فيها الأمر lxc مع مراقب الأجهزة الافتراضية لـ LXD تتيح لك مخرجاته معرفة أنه قام تلقائيًا بإنشاء شهادة للعميل من أجل الاتصال الآمن مع LXD، وبعض المعلومات حول كيفية تشغيل حاوية، وقائمة فارغة من الحاويات، وهو أمر متوقع لأننا لم ننشئ أي واحدة حتى الآن. دعنا ننشئ حاوية تقوم بتشغيل Nginx. للقيام بذلك سوف نستخدم الأمر lxc launch لإنشاء وبدء حاوية أوبونتو 16.04 اسمها webserver. لإنشاء الحاوية webserver ننفذ الأمر:
</p>

<pre class="ipsCode" id="ips_uid_6942_7">
<code class="hljs css"><span class="hljs-tag"><span class="pln">lxc</span></span><span class="pln"> </span><span class="hljs-tag"><span class="pln">launch</span></span><span class="pln"> </span><span class="hljs-tag"><span class="pln">ubuntu</span></span><span class="hljs-pseudo"><span class="pun">:</span><span class="pln">x</span></span><span class="pln"> </span><span class="hljs-tag"><span class="pln">webserver</span></span></code></pre>

<p>
	x في ubuntu:x هو اختصار للحرف الأول من Xenial ، الاسم الرمزي لأوبونتو 16.04. ubuntu: هو معرف للمستودع الذي تم تكوينه مسبقا لصور LXD . يمكنك أيضا استخدام ubuntu:16.04 لاسم الصورة.
</p>

<p>
	<strong>ملاحظة :</strong> يمكنك العثور على القائمة الكاملة لجميع صور ubuntu المتاحة عن طريق تشغيل الأمر:
</p>

<pre class="ipsCode" id="ips_uid_6942_12">
lxc image list Ubuntu:</pre>

<p>
	وفي التوزيعات الأخرى عن طريق تشغيل الأمر:
</p>

<pre class="ipsCode" id="ips_uid_6942_14">
lxc image list images:</pre>

<p>
	نظرًا لأن هذه هي المرة الأولى التي تقوم فيها بإنشاء حاوية ينزّل هذا الأمرُ صورةَ الحاوية من الإنترنت ويخزنها محليًا بحيث إذا أنشأت حاوية جديدة فسيتم إنشاؤها بسرعة أكبر. سترى هذه المخرجات عند إنشاء الحاوية الجديدة:
</p>

<pre class="ipsCode" id="ips_uid_6942_7">
<code class="hljs livecodeserver"><span class="typ">Generating</span><span class="pln"> </span><span class="hljs-operator"><span class="pln">a</span></span><span class="pln"> client certificate</span><span class="pun">.</span><span class="pln"> </span><span class="typ">This</span><span class="pln"> may take </span><span class="hljs-operator"><span class="pln">a</span></span><span class="pln"> minute</span><span class="pun">...</span><span class="pln">
</span><span class="typ">If</span><span class="pln"> </span><span class="kwd">this</span><span class="pln"> </span><span class="kwd">is</span><span class="pln"> your </span><span class="hljs-keyword"><span class="pln">first</span></span><span class="pln"> </span><span class="hljs-built_in"><span class="pln">time</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">using</span></span><span class="pln"> LXD</span><span class="pun">,</span><span class="pln"> you should also run</span><span class="pun">:</span><span class="pln"> sudo lxd init
</span><span class="typ">To</span><span class="pln"> start your </span><span class="hljs-keyword"><span class="pln">first</span></span><span class="pln"> container</span><span class="pun">,</span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">try</span></span><span class="pun">:</span><span class="pln"> lxc launch ubuntu</span><span class="pun">:</span><span class="hljs-number"><span class="lit">16.04</span></span><span class="pln">

</span><span class="typ">Creating</span><span class="pln"> webserver
</span><span class="typ">Retrieving</span><span class="pln"> image</span><span class="pun">:</span><span class="pln"> </span><span class="hljs-number"><span class="lit">100</span></span><span class="pun">%</span><span class="pln">
</span><span class="typ">Starting</span><span class="pln"> webserver </span></code></pre>

<p>
	الآن ..بعد تشغيل الحاوية استخدم الأمر lxc list لعرض معلومات حولها:
</p>

<pre class="ipsCode" id="ips_uid_6942_7">
<code class="hljs php"><span class="pln">lxc </span><span class="hljs-keyword"><span class="pln">list</span></span><span class="pln"> </span></code></pre>

<p>
	تظهر المخرجات جدولًا يحمل اسم كل حاوية وحالتها الحالية وعنوان IP خاص بها ونوعها وما إذا كانت هناك لقطات مأخوذة.
</p>

<pre class="ipsCode" id="ips_uid_6942_9">
Output
+-----------+---------+-----------------------+------+------------+-----------+
|  NAME     |  STATE  |         IPV4          | IPV6 |    TYPE    | SNAPSHOTS |
+-----------+---------+-----------------------+------+------------+-----------+
| webserver | RUNNING | 10.10.10.100 (eth0)   |      | PERSISTENT | 0         |
+-----------+---------+-----------------------+------+------------+-----------+ </pre>

<p>
	<strong>ملاحظة:</strong> إذا قمت بتمكين IPv6 في LXD فقد يكون مخرج أمر lxc list كبيرًا جدًا عن أن تسعه الشاشة.<br>
	يمكنك أن تستخدم بدلا عن ذلك الأمر lxc list –columns ns4tS الذي يظهر فقط الاسم والحالة و IPv4 والنوع وما إذا كانت هناك لقطات متاحة.<br>
	لاحظ عنوان IPv4 للحاوية. ستحتاج إلى تهيئة الجدار الناري للسماح بالزيارات الواردة من العالم الخارجي.
</p>

<p>
	سنتابع في الدرس القادم <a href="https://academy.hsoub.com/devops/linux/%D9%83%D9%8A%D9%81%D9%8A%D8%A9-%D8%A5%D8%B9%D8%AF%D8%A7%D8%AF-%D9%88%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-lxd-%D8%B9%D9%84%D9%89-%D8%A3%D9%88%D8%A8%D9%88%D9%86%D8%AA%D9%88-1604-%E2%80%93-%D8%AA%D9%83%D9%88%D9%8A%D9%86-%D9%88%D8%AA%D9%88%D8%AC%D9%8A%D9%87-%D9%88%D8%A5%D8%B2%D8%A7%D9%84%D8%A9-%D8%AD%D8%A7%D9%88%D9%8A%D8%A9-nginx-r375/" rel="">كيفية تكوين وتوجيه وإزالة حاوية Nginx</a>.
</p>

<p>
	ترجمة -وبتصرّف- للمقال <a href="https://www.digitalocean.com/community/tutorials/how-to-set-up-and-use-lxd-on-ubuntu-16-04" rel="external nofollow">How to Set Up and Use LXD on Ubuntu 16.04</a> لصاحبه Simos Xenitellis
</p>
]]></description><guid isPermaLink="false">374</guid><pubDate>Thu, 28 Dec 2017 07:06:00 +0000</pubDate></item><item><title>&#x643;&#x64A;&#x641; &#x62A;&#x631;&#x627;&#x642;&#x628; &#x62A;&#x646;&#x628;&#x64A;&#x647;&#x627;&#x62A; Nagios &#x628;&#x627;&#x633;&#x62A;&#x62E;&#x62F;&#x627;&#x645; Alerta &#x639;&#x644;&#x649; CentOS 7</title><link>https://academy.hsoub.com/devops/linux/%D9%83%D9%8A%D9%81-%D8%AA%D8%B1%D8%A7%D9%82%D8%A8-%D8%AA%D9%86%D8%A8%D9%8A%D9%87%D8%A7%D8%AA-nagios-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-alerta-%D8%B9%D9%84%D9%89-centos-7-r373/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2017_12/26-2.png.62cd0bc9279b818ac2c0ee885848c9b1.png" /></p>

<p>
	Alerta هو تطبيق ويب يُستخدم لتعزيز وإزالة التنبيهات المتكررة من مختلف أنظمة المراقبة ومشاهدة ذلك كله على شاشة واحدة. يمكن أن تدمج Alerta مع العديد من أدوات المراقبة المعروفة مثل Nagios, Zabbix, Sensu, InfluxData Kapacitor وغيرها الكثير. في هذا الدرس سوف نقوم بتثبيت Alerta وإعداده لعرض الإشعارات من <a href="http://nagios.org/_" rel="external nofollow">Nagios</a>، نظام المراقبة المفتوح المصدر الأكثر شعبية.
</p>

<h2 id="المتطلبات-الأساسية">
	المتطلبات الأساسية
</h2>

<p>
	لمتابعة هذا الدرس، سوف تحتاج إلى:
</p>

<ul>
<li>
		خادومين CentOS 7 تم إعدادهما باتباع هذا الدليل <a href="https://academy.hsoub.com/devops/linux/%D8%A7%D9%84%D8%B6%D8%A8%D8%B7-%D8%A7%D9%84%D9%85%D8%A8%D8%AF%D8%A6%D9%8A-%D9%84%D8%AE%D8%A7%D8%AF%D9%88%D9%85-centos-7-r345/" rel="">الضبط المبدئي لخادوم CentOS 7</a> ، مع مستخدم sudo غير جذر وجدار الحماية.
	</li>
	<li>
		على الخادوم CentOS الأول، حيث ستشغل Nagios، قم بتثبيت المكونات التالية:
		<ul>
<li>
				Apache و MySQL و PHP, ، باتباع هذا الدليل: <a href="https://academy.hsoub.com/devops/servers/%D9%83%D9%8A%D9%81-%D8%AA%D8%AB%D8%A8%D8%AA-%D8%AD%D8%B2%D9%85-mysql-%D8%8Capache-%D8%8Clinux-lamp-%D9%88-php-%D8%B9%D9%84%D9%89-%D8%A3%D9%88%D8%A8%D9%86%D8%AA%D9%88-1404-r27/" rel="">كيف تثبت حزم MySQL ،Apache ،Linux :LAMP و PHP</a>
			</li>
			<li>
				Nagios 4، مع متطلباته باتباع هذا الدليل: <a href="https://academy.hsoub.com/devops/servers/%D9%83%D9%8A%D9%81-%D8%AA%D8%B3%D8%AA%D8%AE%D8%AF%D9%85-nagios-4-%D9%84%D9%85%D8%B1%D8%A7%D9%82%D8%A8%D8%A9-%D8%AE%D9%88%D8%A7%D8%AF%D9%8A%D9%85-ubuntu-1404-r145/" rel="">كيف تستخدم Nagios 4 لمراقبة خواديم Ubuntu 14.04</a>
			</li>
		</ul>
</li>
	<li>
		على الخادوم CentOS الثاني حيث سنقوم بتثبيت Alerta في هذه المقالة ، قم بتثبيت Nginx و MongoDB و Alerta.
	</li>
</ul>
<h2 id="الخطوة-1-تثبيت-وحدة-وسيط-الأحداث-nagios-to-alerta">
	الخطوة 1 – تثبيت وحدة وسيط الأحداث Nagios-to-Alerta
</h2>

<p>
	يمكنك توسيع وظائف Nagios مع وحدات وسائط الأحداث الخاصة بــ (Nagios (Nagios Event Broker (NEB).<br>
	NEB هي آلية دمج أحداث (Event) الخاصة بـ Nagios، ووحدات NEB هي المكتبات المشتركة التي تمكنك من دمج خدمات أخرى مع Nagios. في هذه الخطوة سنقوم بتثبيت بوابة Nagios-to-Alerta ، وهي وحدة NEB التي سوف ترسل إشعارات إلى Alerta.
</p>

<p>
	سجل الدخول إلى خادوم Nagios بمستخدم غير جذر:
</p>

<pre class="ipsCode" id="ips_uid_7910_11">
<abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">ssh</abbr> sammy@your_nagios_server_ip</pre>

<p>
	بوابة Nagios-to-Alerta لا تحتوي على حزم جاهزة مسبقًا في نظام التشغيل، لذلك سيكون عليك بناؤها من المصدر. للقيام بذلك ستحتاج إلى تثبيت بعض أدوات التطوير والملفات. ستحتاج أيضًا إلى تثبيت Git حتى تتمكن من جلب شفرة المصدر من GitHub.
</p>

<pre class="ipsCode" id="ips_uid_7910_9">
sudo yum install -y git curl gcc make libcurl-devel</pre>

<p>
	استخدم Git الآن لاستنساخ الملفات المصدرية من مستودع GitHub للمشروع:
</p>

<pre class="ipsCode" id="ips_uid_7910_11">
<code class="hljs php"><span class="pln">git </span><span class="hljs-keyword"><span class="pln">clone</span></span><span class="pln"> https</span><span class="pun">:</span><span class="hljs-comment"><span class="com">//github.com/alerta/nagios-alerta.git </span></span></code></pre>

<p>
	ثم اذهب إلى مجلد nagios-alerts الجديد:
</p>

<pre class="ipsCode" id="ips_uid_7910_11">
<code class="hljs bash"><span class="hljs-built_in"><span class="pln">cd</span></span><span class="pln"> nagios</span><span class="pun">-</span><span class="pln">alerta</span></code></pre>

<p>
	ثم جمّع وحدة nagios-alerta باستخدام الأمر make :
</p>

<pre class="ipsCode" id="ips_uid_7910_11">
<code class="hljs go"><span class="hljs-built_in"><span class="pln">make</span></span><span class="pln"> nagios4 </span></code></pre>

<p>
	سترى المخرجات التالية:
</p>

<pre class="ipsCode" id="ips_uid_7910_11">
<code class="hljs asciidoc"><span class="pln">cd </span><span class="pun">./</span><span class="pln">src </span><span class="pun">&amp;&amp;</span><span class="pln"> make nagios4
make</span><span class="pun">[</span><span class="lit">1</span><span class="pun">]:</span><span class="pln"> </span><span class="typ">Entering</span><span class="pln"> directory </span><span class="hljs-smartquote"><span class="str">`/root/nagios-alerta/src'</span></span><span class="str">
gcc -fPIC -g -O2 -DHAVE</span><span class="hljs-emphasis"><span class="str">_CONFIG_</span></span><span class="str">H -I../include -I../include/nagios4 -lcurl -o alerta-neb.o alerta-neb.c -shared  -lcurl
make[1]: Leaving directory </span><span class="hljs-smartquote"><span class="str">`</span><span class="pun">/</span><span class="pln">root</span><span class="pun">/</span><span class="pln">nagios</span><span class="pun">-</span><span class="pln">alerta</span><span class="pun">/</span><span class="pln">src</span><span class="str">'</span></span></code></pre>

<p>
	إذا كنت ترى شيئا مختلفا فتأكد من تثبيت كافة المتطلبات الأساسية.<br>
	الآن.. قم بالبدء في عملية التثبيت:
</p>

<pre class="ipsCode" id="ips_uid_7910_11">
<code class="hljs bash"><span class="hljs-built_in"><span class="pln">sudo</span></span><span class="pln"> make install</span></code></pre>

<p>
	سترى هذه المخرجات، وهي تشير إلى أن الوحدة تم تثبيتها في /usr/lib/nagios :
</p>

<pre class="ipsCode" id="ips_uid_7910_11">
<code class="hljs asciidoc"><span class="pln">cd </span><span class="pun">./</span><span class="pln">src </span><span class="pun">&amp;&amp;</span><span class="pln"> make nagios4
make</span><span class="pun">[</span><span class="lit">1</span><span class="pun">]:</span><span class="pln"> </span><span class="typ">Entering</span><span class="pln"> directory </span><span class="hljs-smartquote"><span class="str">`/root/nagios-alerta/src'</span></span><span class="str">
gcc -fPIC -g -O2 -DHAVE</span><span class="hljs-emphasis"><span class="str">_CONFIG_</span></span><span class="str">H -I../include -I../include/nagios4 -lcurl -o alerta-neb.o alerta-neb.c -shared  -lcurl
make[1]: Leaving directory </span><span class="hljs-smartquote"><span class="str">`</span><span class="pun">/</span><span class="pln">root</span><span class="pun">/</span><span class="pln">nagios</span><span class="pun">-</span><span class="pln">alerta</span><span class="pun">/</span><span class="pln">src</span><span class="str">'</span></span></code></pre>

<p>
	بعد تثبيت الوحدة يمكننا إعداد Nagios لاستخدام هذه الوحدة.
</p>

<h2 id="الخطوة-2-إعداد-الوحدة-nagios-to-alerta">
	الخطوة 2 – إعداد الوحدة Nagios-to-Alerta
</h2>

<p>
	لنقم بإعداد Nagios لإرسال رسائل الإشعار إلى Alerta.<br>
	أولًا، مكّن وحدة الوسيط Alerta المثبتة حديثًا في ملف الإعدادات الرئيسي لــ Nagios. افتح ملف إعدادات Nagios في المحرر:
</p>

<pre class="ipsCode" id="ips_uid_7910_11">
<code class="hljs bash"><span class="hljs-built_in"><span class="pln">sudo</span></span><span class="pln"> vi </span><span class="pun">/</span><span class="pln">usr</span><span class="pun">/</span><span class="kwd">local</span><span class="pun">/</span><span class="pln">nagios</span><span class="pun">/</span><span class="pln">etc</span><span class="pun">/</span><span class="pln">nagios</span><span class="pun">.</span><span class="pln">cfg</span></code></pre>

<p>
	ثم ابحث عن الجزء الذي يحتوي على توجيهات broker_module :
</p>

<pre class="ipsCode" id="ips_uid_7910_11">
<code class="hljs r"><span class="pun">..</span><span class="pln">
</span><span class="hljs-comment"><span class="com"># EVENT BROKER MODULE(S)</span></span><span class="pln">
</span><span class="hljs-comment"><span class="com"># This directive is used to specify an event broker module that should</span></span><span class="pln">
</span><span class="hljs-comment"><span class="com"># by loaded by Nagios at startup.  Use multiple directives if you want</span></span><span class="pln">
</span><span class="hljs-comment"><span class="com"># to load more than one module.  Arguments that should be passed to</span></span><span class="pln">
</span><span class="hljs-comment"><span class="com"># the module at startup are separated from the module path by a space.</span></span><span class="pln">
</span><span class="hljs-comment"><span class="com">#</span></span><span class="pln">
</span><span class="pun">[</span><span class="hljs-keyword"><span class="pun">...</span></span><span class="pun">]</span><span class="pln">
</span><span class="hljs-comment"><span class="com">#broker_module=/somewhere/module1.o</span></span><span class="pln">
</span><span class="hljs-comment"><span class="com">#broker_module=/somewhere/module2.o arg1 arg2=3 debug=0</span></span><span class="pln">
</span><span class="hljs-keyword"><span class="pun">...</span></span></code></pre>

<p>
	لإعداد الوحدة Alerta تحتاج إلى اثنين من المدخلات الإلزامية:
</p>

<ul>
<li>
		URL: العنوان الذي يتم استخدامه للتواصل مع Alerta <abbr title="Application Programming Interface | واجهة برمجية">API</abbr>.
	</li>
	<li>
		key: مفتاح <abbr title="Application Programming Interface | واجهة برمجية">API</abbr> ، لقد قمت بإنشائه في الخطوة 4 من البرنامج التعليمي السابق. ستحتاج إليه في المصادقة مع Alerta وإرسال الأحداث.
	</li>
</ul>
<p>
	أضف هذا السطر إلى الملف لإعداد دمج Alerta:
</p>

<pre class="ipsCode" id="ips_uid_7910_11">
<code class="hljs r"><span class="hljs-keyword"><span class="pun">...</span></span><span class="pln">
broker_module</span><span class="pun">=</span><span class="str">/usr/</span><span class="pln">lib</span><span class="pun">/</span><span class="pln">nagios</span><span class="pun">/</span><span class="pln">alerta</span><span class="pun">-</span><span class="pln">neb</span><span class="pun">.</span><span class="pln">o http</span><span class="pun">:</span><span class="com">//your_alerta_server_ip/api key=ALERTA_API_KEY</span><span class="pln">
</span><span class="hljs-keyword"><span class="pun">...</span></span></code></pre>

<p>
	هناك بعض المخلات الاختيارية الإضافية التي يمكنك تعيينها أيضا:
</p>

<ul>
<li>
		env: يحدد هذا اسم البيئة. اسم البيئة الافتراضي هو Production.
	</li>
	<li>
		hard_only : تجاوز النتائج في الحالة الصعبة فقط. يمكنك العثور على مزيد من المعلومات حول أنواع حالات Nagios في <a href="https://assets.nagios.com/downloads/nagioscore/docs/nagioscore/4/en/statetypes.html" rel="external nofollow">وثائق Nagios</a> . عين هذا إلى 1 لتمكين هذا الوضع.
	</li>
	<li>
		debug: تمكين وضع معالجة وتصحيح الأخطاء. عيّن هذا إلى 1 لتمكين هذا الوضع.
	</li>
</ul>
<p>
	لتحديد كل هذه الخيارات استخدم هذا السطر بدلًا من السابق:
</p>

<pre class="ipsCode" id="ips_uid_7910_11">
<code class="hljs r"><span class="hljs-keyword"><span class="pun">...</span></span><span class="pln">
broker_module</span><span class="pun">=</span><span class="str">/usr/</span><span class="pln">lib</span><span class="pun">/</span><span class="pln">nagios</span><span class="pun">/</span><span class="pln">alerta</span><span class="pun">-</span><span class="pln">neb</span><span class="pun">.</span><span class="pln">o http</span><span class="pun">:</span><span class="com">//your_alerta_server_ip/api key=ALERTA_API_KEY env=Production hard_only=</span><span class="hljs-number"><span class="com">1</span></span><span class="com"> debug=</span><span class="hljs-number"><span class="com">1</span></span><span class="pln">
</span><span class="hljs-keyword"><span class="pun">...</span></span></code></pre>

<p>
	احفظ الملف وأغلق المحرر. من أجل تعيين التنبيهات حسب البيئة واسم الخدمة ستحتاج إلى إعداد أسماء البيئة والخدمات باستخدام: <a href="https://assets.nagios.com/downloads/nagioscore/docs/nagioscore/4/en/customobjectvars.html" rel="external nofollow">Nagios Custom Object Variables</a><br>
	للقيام بذلك استخدم المتغيرات _Environment و _Service في الإعداد الخاص بك. دعنا نهيئ ذلك الآن. افتح ملف إعدادات كائنات Nagios الافتراضي، ستجده في الدليل /usr/local/nagios/etc/objects/ :
</p>

<pre class="ipsCode" id="ips_uid_7910_11">
<code class="hljs bash"><span class="hljs-built_in"><span class="pln">sudo</span></span><span class="pln"> vi </span><span class="pun">/</span><span class="pln">usr</span><span class="pun">/</span><span class="kwd">local</span><span class="pun">/</span><span class="pln">nagios</span><span class="pun">/</span><span class="pln">etc</span><span class="pun">/</span><span class="pln">objects</span><span class="pun">/</span><span class="pln">localhost</span><span class="pun">.</span><span class="pln">cfg</span></code></pre>

<p>
	سوف نجعل جميع التنبيهات في هذا المضيف من نوع تنبيهات “Production”، وسنسمي الخدمة الافتراضية بـ “Nagios” . ابحث عن تعريف المضيف التالي:
</p>

<pre class="ipsCode" id="ips_uid_7910_11">
<code class="hljs r"><span class="hljs-keyword"><span class="pun">...</span></span><span class="pln">
define host</span><span class="pun">{</span><span class="pln">
        </span><span class="kwd">use</span><span class="pln">                     linux</span><span class="pun">-</span><span class="pln">server            </span><span class="pun">;</span><span class="pln"> </span><span class="typ">Name</span><span class="pln"> of host </span><span class="kwd">template</span><span class="pln"> to </span><span class="kwd">use</span><span class="pln">
                                                        </span><span class="pun">;</span><span class="pln"> </span><span class="typ">This</span><span class="pln"> host definition will inherit all variables that are </span><span class="kwd">defined</span><span class="pln">
                                                        </span><span class="pun">;</span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">in</span></span><span class="pln"> </span><span class="pun">(</span><span class="kwd">or</span><span class="pln"> inherited </span><span class="kwd">by</span><span class="pun">)</span><span class="pln"> the linux</span><span class="pun">-</span><span class="pln">server host </span><span class="kwd">template</span><span class="pln"> definition</span><span class="pun">.</span><span class="pln">
        host_name               localhost
        </span><span class="kwd">alias</span><span class="pln">                   localhost
        address                 </span><span class="hljs-number"><span class="lit">127.0</span></span><span class="hljs-number"><span class="pun">.</span><span class="lit">0</span></span><span class="hljs-number"><span class="lit">.1</span></span><span class="pln">
        </span><span class="pun">}</span><span class="pln">

</span><span class="hljs-keyword"><span class="pun">...</span></span></code></pre>

<p>
	أضف القيم _Environment و _Service إلى الإعدادات:
</p>

<pre class="ipsCode" id="ips_uid_7910_11">
<code class="hljs r"><span class="hljs-keyword"><span class="pun">...</span></span><span class="pln">
        host_name               localhost
        </span><span class="kwd">alias</span><span class="pln">                   localhost
        address                 </span><span class="hljs-number"><span class="lit">127.0</span></span><span class="hljs-number"><span class="pun">.</span><span class="lit">0</span></span><span class="hljs-number"><span class="lit">.1</span></span><span class="pln">
        </span><span class="typ">_Environment</span><span class="pln">            </span><span class="typ">Production</span><span class="pln">
        </span><span class="typ">_Service</span><span class="pln">                </span><span class="typ">Nagios</span><span class="pln">
        </span><span class="pun">}</span><span class="pln">
</span><span class="hljs-keyword"><span class="pun">...</span></span></code></pre>

<p>
	الآن ضع علامة ” System ” على جميع الأحداث المرتبطة بانعدام المساحة أو قلتها في مساحة التخزين المخصصة للنظام. حدد موقع هذا الجزء من الملف الذي يحدد كيفية التحقق من المساحة الفارغة:
</p>

<pre class="ipsCode" id="ips_uid_7910_11">
<code class="hljs r"><span class="hljs-keyword"><span class="pun">...</span></span><span class="pln">
define service</span><span class="pun">{</span><span class="pln">
        </span><span class="kwd">use</span><span class="pln">                             </span><span class="kwd">local</span><span class="pun">-</span><span class="pln">service         </span><span class="pun">;</span><span class="pln"> </span><span class="typ">Name</span><span class="pln"> of service </span><span class="kwd">template</span><span class="pln"> to </span><span class="kwd">use</span><span class="pln">
        host_name                       localhost
        service_description             </span><span class="typ">Root</span><span class="pln"> </span><span class="typ">Partition</span><span class="pln">
        check_command                   check_local_disk</span><span class="pun">!</span><span class="hljs-number"><span class="lit">20</span></span><span class="pun">%!</span><span class="hljs-number"><span class="lit">10</span></span><span class="pun">%!/</span><span class="pln">
        </span><span class="pun">}</span><span class="pln">
</span><span class="hljs-keyword"><span class="pun">...</span></span></code></pre>

<p>
	قم بتعديله لربطه بخدمة System:
</p>

<pre class="ipsCode" id="ips_uid_7910_11">
<code class="hljs r"><span class="hljs-keyword"><span class="pun">...</span></span><span class="pln">
define service</span><span class="pun">{</span><span class="pln">
        </span><span class="kwd">use</span><span class="pln">                             </span><span class="kwd">local</span><span class="pun">-</span><span class="pln">service         </span><span class="pun">;</span><span class="pln"> </span><span class="typ">Name</span><span class="pln"> of service </span><span class="kwd">template</span><span class="pln"> to </span><span class="kwd">use</span><span class="pln">
        host_name                       localhost
        service_description             </span><span class="typ">Root</span><span class="pln"> </span><span class="typ">Partition</span><span class="pln">
        check_command                   check_local_disk</span><span class="pun">!</span><span class="hljs-number"><span class="lit">20</span></span><span class="pun">%!</span><span class="hljs-number"><span class="lit">10</span></span><span class="pun">%!/</span><span class="pln">
        </span><span class="typ">_Service</span><span class="pln">                        </span><span class="typ">System</span><span class="pln">
        </span><span class="pun">}</span><span class="pln">
</span><span class="hljs-keyword"><span class="pun">...</span></span></code></pre>

<p>
	احفظ الملف ثم أغلق المحرر. أعد تشغيل Nagios لتطبيق هذه الإعدادات الجديدة:
</p>

<pre class="ipsCode" id="ips_uid_7910_11">
<code class="hljs bash"><span class="hljs-built_in"><span class="pln">sudo</span></span><span class="pln"> systemctl restart nagios</span><span class="pun">.</span><span class="pln">service </span></code></pre>

<p>
	تأكد من تشغيل الخدمة عن طريق التحقق من حالتها:
</p>

<pre class="ipsCode" id="ips_uid_7910_11">
<code class="hljs avrasm"><span class="pln">systemctl status nagios</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">service</span></span><span class="pln"> </span></code></pre>

<p>
	سترى المخرج التالي:
</p>

<pre class="ipsCode" id="ips_uid_7910_11">
<code class="hljs r"><span class="hljs-keyword"><span class="pun">...</span></span><span class="pln">
</span><span class="typ">Jul</span><span class="pln"> </span><span class="hljs-number"><span class="lit">01</span></span><span class="pln"> </span><span class="hljs-number"><span class="lit">08</span></span><span class="pun">:</span><span class="hljs-number"><span class="lit">44</span></span><span class="pun">:</span><span class="hljs-number"><span class="lit">31</span></span><span class="pln"> nagios nagios</span><span class="pun">[</span><span class="hljs-number"><span class="lit">8914</span></span><span class="pun">]:</span><span class="pln"> </span><span class="pun">[</span><span class="pln">alerta</span><span class="pun">]</span><span class="pln"> </span><span class="typ">Initialising</span><span class="pln"> </span><span class="typ">Nagios</span><span class="pun">-</span><span class="typ">Alerta</span><span class="pln"> </span><span class="typ">Gateway</span><span class="pln"> </span><span class="kwd">module</span><span class="pun">,</span><span class="pln"> v3</span><span class="pun">.</span><span class="lit">4.1</span><span class="pln">
</span><span class="typ">Jul</span><span class="pln"> </span><span class="hljs-number"><span class="lit">01</span></span><span class="pln"> </span><span class="hljs-number"><span class="lit">08</span></span><span class="pun">:</span><span class="hljs-number"><span class="lit">44</span></span><span class="pun">:</span><span class="hljs-number"><span class="lit">31</span></span><span class="pln"> nagios nagios</span><span class="pun">[</span><span class="hljs-number"><span class="lit">8914</span></span><span class="pun">]:</span><span class="pln"> </span><span class="pun">[</span><span class="pln">alerta</span><span class="pun">]</span><span class="pln"> debug </span><span class="kwd">is</span><span class="pln"> off
</span><span class="typ">Jul</span><span class="pln"> </span><span class="hljs-number"><span class="lit">01</span></span><span class="pln"> </span><span class="hljs-number"><span class="lit">08</span></span><span class="pun">:</span><span class="hljs-number"><span class="lit">44</span></span><span class="pun">:</span><span class="hljs-number"><span class="lit">31</span></span><span class="pln"> nagios nagios</span><span class="pun">[</span><span class="hljs-number"><span class="lit">8914</span></span><span class="pun">]:</span><span class="pln"> </span><span class="pun">[</span><span class="pln">alerta</span><span class="pun">]</span><span class="pln"> states</span><span class="pun">=</span><span class="typ">Hard</span><span class="pun">/</span><span class="typ">Soft</span><span class="pln">
</span><span class="typ">Jul</span><span class="pln"> </span><span class="hljs-number"><span class="lit">01</span></span><span class="pln"> </span><span class="hljs-number"><span class="lit">08</span></span><span class="pun">:</span><span class="hljs-number"><span class="lit">44</span></span><span class="pun">:</span><span class="hljs-number"><span class="lit">31</span></span><span class="pln"> nagios nagios</span><span class="pun">[</span><span class="hljs-number"><span class="lit">8914</span></span><span class="pun">]:</span><span class="pln"> </span><span class="pun">[</span><span class="pln">alerta</span><span class="pun">]</span><span class="pln"> </span><span class="typ">Forward</span><span class="pln"> service checks</span><span class="pun">,</span><span class="pln"> host checks </span><span class="kwd">and</span><span class="pln"> downtime to http</span><span class="pun">:</span><span class="com">//your_alerta_server_ip/api</span><span class="pln">
</span><span class="typ">Jul</span><span class="pln"> </span><span class="hljs-number"><span class="lit">01</span></span><span class="pln"> </span><span class="hljs-number"><span class="lit">08</span></span><span class="pun">:</span><span class="hljs-number"><span class="lit">44</span></span><span class="pun">:</span><span class="hljs-number"><span class="lit">31</span></span><span class="pln"> nagios nagios</span><span class="pun">[</span><span class="hljs-number"><span class="lit">8914</span></span><span class="pun">]:</span><span class="pln"> </span><span class="typ">Event</span><span class="pln"> broker </span><span class="kwd">module</span><span class="pln"> </span><span class="hljs-string"><span class="str">'/usr/lib/nagios/alerta-neb.o'</span></span><span class="pln"> initialized successfully</span><span class="pun">.</span><span class="pln">
</span><span class="typ">Jul</span><span class="pln"> </span><span class="hljs-number"><span class="lit">01</span></span><span class="pln"> </span><span class="hljs-number"><span class="lit">08</span></span><span class="pun">:</span><span class="hljs-number"><span class="lit">44</span></span><span class="pun">:</span><span class="hljs-number"><span class="lit">31</span></span><span class="pln"> nagios nagios</span><span class="pun">[</span><span class="hljs-number"><span class="lit">8914</span></span><span class="pun">]:</span><span class="pln"> </span><span class="typ">Successfully</span><span class="pln"> launched command file worker </span><span class="kwd">with</span><span class="pln"> pid </span><span class="hljs-number"><span class="lit">8920</span></span></code></pre>

<p>
	الآن Nagios سوف يرسل إشعارًا في أقرب وقت عن أيّ نظام أو خدمة وقع فيه مشكل. لنقم بإنشاء حدث اختبار.
</p>

<h2 id="الخطوة-3-توليد-إشعار-اختبار-للتحقق-من-دمج-nagios-alerta">
	الخطوة 3 - توليد إشعار اختبار للتحقق من دمج Nagios-Alerta
</h2>

<p>
	لنقم بتوليد إشعار لاختبار أن كل شيء متصل. افتراضيًا Nagios يحتفظ بمقدار مساحة القرص الحرة على الخادوم الخاص بك. سننشئ ملفًا مؤقتًا كبيرًا بما يكفي لتشغيل تنبيه استخدام نظام الملفات في Nagios.
</p>

<p>
	أولًا، حدد مقدار المساحة الحرة لديك على خادوم Nagios. يمكنك استخدام الأمر df لمعرفة ذلك:
</p>

<pre class="ipsCode" id="ips_uid_7910_11">
<code class="hljs "><span class="pln">df </span><span class="pun">–</span><span class="pln">h</span></code></pre>

<p>
	ستشاهد الناتج مثل ما يلي:
</p>

<pre class="ipsCode" id="ips_uid_7910_11">
<code class="hljs livecodeserver"><span class="pln">  </span><span class="typ">Filesystem</span><span class="pln">      </span><span class="typ">Size</span><span class="pln">  </span><span class="typ">Used</span><span class="pln"> </span><span class="typ">Avail</span><span class="pln"> </span><span class="typ">Use</span><span class="pun">%</span><span class="pln"> </span><span class="typ">Mounted</span><span class="pln"> </span><span class="hljs-command"><span class="hljs-keyword"><span class="pln">on</span></span></span><span class="pln">
    </span><span class="pun">/</span><span class="pln">dev</span><span class="pun">/</span><span class="pln">vda1        </span><span class="hljs-number"><span class="lit">20</span></span><span class="lit">G</span><span class="pln">  </span><span class="hljs-number"><span class="lit">3.1</span></span><span class="lit">G</span><span class="pln">   </span><span class="hljs-number"><span class="lit">16</span></span><span class="lit">G</span><span class="pln">   </span><span class="hljs-number"><span class="lit">17</span></span><span class="pun">%</span><span class="pln"> </span><span class="pun">/</span></code></pre>

<p>
	انظر إلى مقدار المساحة الحرة المتاحة. في هذه الحالة المساحة الحرة هي 16GB. قد تختلف المساحة الحرة لديك. استخدم الأمر fallocate لإنشاء ملف يستهلك أكثر من 80٪ من مساحة القرص المتوفرة والتي يجب أن تكون كافية لتحريك التنبيه:
</p>

<pre class="ipsCode" id="ips_uid_7910_11">
<code class="hljs bash"><span class="pln">fallocate </span><span class="hljs-operator"><span class="pun">-</span><span class="pln">l</span></span><span class="pln"> </span><span class="hljs-number"><span class="lit">14</span></span><span class="lit">G</span><span class="pln"> </span><span class="pun">/</span><span class="pln">tmp</span><span class="pun">/</span><span class="pln">temp</span><span class="pun">.</span><span class="pln">img</span></code></pre>

<p>
	في غضون بضع دقائق سوف يقوم Nagios بتشغيل تنبيه حول مقدار المساحة الحرة على القرص وسوف يرسل إشعارًا إلى Alerta. سترى هذا الإشعار الجديد في لوحة التحكم الخاصة بــ Alerta:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="26068" href="https://academy.hsoub.com/uploads/monthly_2017_12/001.png.d09c08ad648d6e1f7ccad60e634a2aab.png" rel=""><img alt="001.png" class="ipsImage ipsImage_thumbnailed" data-fileid="26068" data-unique="cb1hig5ih" src="https://academy.hsoub.com/uploads/monthly_2017_12/001.thumb.png.10dfadedeff2a9efc06e141f948216c9.png"></a>
</p>

<p>
	الآن بعد أن عرفت أن التنبيهات تعمل، احذف الملف المؤقت الذي قمت بإنشائه حتى تتمكن من استعادة مساحة القرص:
</p>

<pre class="ipsCode" id="ips_uid_7910_11">
<code class="hljs bash"><span class="pln">rm </span><span class="hljs-operator"><span class="pun">-</span><span class="pln">f</span></span><span class="pln"> </span><span class="pun">/</span><span class="pln">tmp</span><span class="pun">/</span><span class="pln">temp</span><span class="pun">.</span><span class="pln">img</span></code></pre>

<p>
	بعد دقيقة واحدة سوف يقوم Nagios بإرسال رسالة الاسترداد. سوف يختفي الإشعار من لوحة التحكم الرئيسية لــ Alerta، ولكن يمكنك عرض جميع الأحداث المغلقة عن طريق اختيار Closed.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="26069" href="https://academy.hsoub.com/uploads/monthly_2017_12/002.png.6de96fbbffc86380998b9215568c536d.png" rel=""><img alt="002.png" class="ipsImage ipsImage_thumbnailed" data-fileid="26069" data-unique="wchzhgvao" src="https://academy.hsoub.com/uploads/monthly_2017_12/002.thumb.png.8ed2946903c893d98cb93a7acf054c7c.png"></a>
</p>

<p>
	يمكنك النقر على صف الحدث لعرض مزيد من التفاصيل.
</p>

<h2 id="الخلاصة">
	الخلاصة
</h2>

<p>
	في هذا المقال قمت بإعداد Nagios لإرسال إشعارات إلى خادوم آخر يقوم بتشغيل Alerta.<br>
	Alerta يعطيك مكانًا مناسبًا لتتبع التنبيهات من العديد من الأنظمة. على سبيل المثال، إذا كانت بعض أجزاء البنية الأساسية تستخدم Nagios وأخرى تستخدم Zabbix فيمكنك دمج الإشعارات من كلا النظامين في لوحة واحدة.
</p>

<p>
	ترجمة -وبتصرّف- للمقال <a href="https://www.digitalocean.com/community/tutorials/how-to-monitor-nagios-alerts-with-alerta-on-centos-7" rel="external nofollow"> How To Monitor Nagios Alerts with Alerta on CentOS 7</a> لصاحبه Vadym Kalsin
</p>
]]></description><guid isPermaLink="false">373</guid><pubDate>Tue, 26 Dec 2017 05:05:00 +0000</pubDate></item><item><title>&#x62F;&#x644;&#x64A;&#x644; &#x627;&#x644;&#x645;&#x633;&#x62A;&#x62E;&#x62F;&#x645; &#x644;&#x644;&#x631;&#x648;&#x627;&#x628;&#x637; &#x641;&#x64A; &#x646;&#x638;&#x627;&#x645; &#x645;&#x644;&#x641;&#x627;&#x62A; &#x644;&#x64A;&#x646;&#x643;&#x633;</title><link>https://academy.hsoub.com/devops/linux/%D8%AF%D9%84%D9%8A%D9%84-%D8%A7%D9%84%D9%85%D8%B3%D8%AA%D8%AE%D8%AF%D9%85-%D9%84%D9%84%D8%B1%D9%88%D8%A7%D8%A8%D8%B7-%D9%81%D9%8A-%D9%86%D8%B8%D8%A7%D9%85-%D9%85%D9%84%D9%81%D8%A7%D8%AA-%D9%84%D9%8A%D9%86%D9%83%D8%B3-r371/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2017_12/13-2.jpg.11f01cb425757be7270e26971fc6d07f.jpg" /></p>

<p>
	تعرف على كيفية استخدام الروابط التي تجعل أعمالك أسهل من خلال توفير إمكانية الوصول إلى الملفات من مواقع متعددة من شجرة المجلدات في نظام ملفات لينكس. في مقالاتٍ لي كَتبتُ عن جوانب مختلفة من أنظمة ملفات لينوكس ، بما في ذلك <a href="https://academy.hsoub.com/devops/linux/%D9%85%D9%82%D8%AF%D9%85%D8%A9-%D8%A5%D9%84%D9%89-%D9%86%D8%B8%D8%A7%D9%85-%D9%85%D9%84%D9%81%D8%A7%D8%AA-%D9%84%D9%8A%D9%86%D9%83%D8%B3-ext4-r343/" rel="">مقدمة عن نظام الملفات EXT4</a> لينكس و إدارة الأجهزة في لينكس و مقدمة عن نظام ملفات لينكس و دليل مستخدم لينكس لإدارة وحدة التخزين المنطقية ، وقد أشرت فيها إلى ميزة مثيرة للاهتمام من أنظمة الملفات في لينكس، يمكن أن تجعل هذه الميزة بعض المهام أسهل من خلال توفير إمكانية الوصول إلى الملفات من مواقع متعددة من شجرة المجلدات في نظام الملفات. هناك نوعان من روابط الملفات في لينكس: صلب و لين . والفرق بين هذين النوعين كبير، ولكن كلا النوعان يستخدمان لحل مشاكل مماثلة. كلاهما يوفر مداخل ( أو مراجع) إلى ملف واحد، لكنها تفعل ذلك بشكل مختلف تمامًا . الروابط مفيدة جدًا وإضافة مرنة إلى أنظمة ملفات لينكس فكل شيء فيه هو ملف.<br>
	لقد وجدت -على سبيل المثال- أن بعض البرامج تتطلب نسخة معينة من المكتبات . عندما تقوم بترقية النظام تحل مكتبة جديدة محل أخرى، سوف يتعطل البرنامج الذي تمت برمجته لاعتماد المكتبة القديمة. عادة يكون التغيير الوحيد في اسم المكتبة هو رقم الإصدار، ببساطة أضفت رابطًا يشير إلى المكتبة الجديدة ولكن باسم المكتبة القديمة. شغلت البرنامج مرة أخرى وقد عمل بشكل جيد. في الواقع ترتبط جميع التطبيقات تقريبًا بالمكتبات باستخدام اسم عام مع رقم إصدار رئيسي فقط ، وهذا الارتباط يشير إلى ملف المكتبة الفعلي الذي يحتوي أيضًا على رقم الإصدار الثانوي. وفي حالات أخرى يتم نقل الملفات المطلوبة من مجلد إلى آخر لتتوافق مع مواصفات لينكس، وتبقى في المجلدات القديمة روابط تشير إلى الملفات التي تم نقلها ، حتى إذا كان البرنامج لا يزال مرتبطًا بالمجلد القديم وملفاته لم يقع في مشكلة فقدان الملفات ، إذا عرضت الملفات في المجلد /lib64 فستجد العديد من الأمثلة على كلا الأمرين.
</p>

<pre class="ipsCode" id="ips_uid_7563_11">
lrwxrwxrwx.  1 root root       36 Dec  8  2016 cracklib_dict.hwm -&gt; ../../usr/share/cracklib/pw_dict.hwm 
lrwxrwxrwx.  1 root root       36 Dec  8  2016 cracklib_dict.pwd -&gt; ../../usr/share/cracklib/pw_dict.pwd 
lrwxrwxrwx.  1 root root       36 Dec  8  2016 cracklib_dict.pwi -&gt; ../../usr/share/cracklib/pw_dict.pwi
lrwxrwxrwx.  1 root root       27 Jun  9  2016 libaccountsservice.so.0 -&gt; libaccountsservice.so.0.0.0 
-rwxr-xr-x.  1 root root   288456 Jun  9  2016 libaccountsservice.so.0.0.0 
lrwxrwxrwx   1 root root       15 May 17 11:47 libacl.so.1 -&gt; libacl.so.1.1.0 
-rwxr-xr-x   1 root root    36472 May 17 11:47 libacl.so.1.1.0 
lrwxrwxrwx.  1 root root       15 Feb  4  2016 libaio.so.1 -&gt; libaio.so.1.0.1 
-rwxr-xr-x.  1 root root     6224 Feb  4  2016 libaio.so.1.0.0 
-rwxr-xr-x.  1 root root     6224 Feb  4  2016 libaio.so.1.0.1 
lrwxrwxrwx.  1 root root       30 Jan 16 16:39 libakonadi-calendar.so.4 -&gt; libakonadi-calendar.so.4.14.26 
-rwxr-xr-x.  1 root root   816160 Jan 16 16:39 libakonadi-calendar.so.4.14.26 
lrwxrwxrwx.  1 root root       29 Jan 16 16:39 libakonadi-contact.so.4 -&gt; libakonadi-contact.so.4.14.26</pre>

<p>
	بعض الروابط في الدليل / lib64. تظهر القائمة الطويلة من الدليل /lib64 أعلاه أن الحرف الأول في الملف هو الحرف “l”، وهو ما يعني أن كلاً منها رابط لين ( رمزي).
</p>

<h2 id="الروابط-الصلبة-hard-links">
	الروابط الصلبة Hard links
</h2>

<p>
	في <a href="https://academy.hsoub.com/devops/linux/%D9%85%D9%82%D8%AF%D9%85%D8%A9-%D8%A5%D9%84%D9%89-%D9%86%D8%B8%D8%A7%D9%85-%D9%85%D9%84%D9%81%D8%A7%D8%AA-%D9%84%D9%8A%D9%86%D9%83%D8%B3-ext4-r343/" rel="">مقدمة لنظام الملفات EXT4</a> لينكس ، ناقشت حقيقة أن كل ملف يحتوي على inode واحد يحتوي على معلومات حول هذا الملف، بما في ذلك موقع البيانات الذي ينتمي إلى هذا الملف. الشكل 2 في تلك المقالة يظهر مدخل دليل واحد يشير إلى inode ، يجب أن يكون لكل ملفٍ مدخلُ دليل واحدٌ على الأقل يشير إلى inode الذي يصف الملف. مدخل الدليل عبارة عن رابط صلب Hard links ، وبالتالي يكون لكل ملف رابط صلب واحد على الأقل.<br>
	في الشكل 1 أدناه، تشير مداخل الأدلة المتعددة إلى inode واحد. هذه كلها روابط صلبة. لقد اختصرت مواقع ثلاثة من مداخل الأدلة باستخدام التلدة ( ~ ) وهي تشير إلى المجلد الرئيسي، بحيث ( ~ ) يعادل /home/user . لاحظ أن مدخل الدليل الرابع مختلف تماما، (/home/shared ) والذي قد يكون موقعا لتبادل الملفات بين مستخدمي الكمبيوتر.
</p>

<p style="text-align: center;">
	<img alt="2.png" class="ipsImage ipsImage_thumbnailed" data-fileid="25837" data-unique="ip0p6pod3" src="https://academy.hsoub.com/uploads/monthly_2017_12/2.png.e0e3cccbc353a6159da1057815dd832a.png"></p>

<p style="text-align: center;">
	<span style="color:#bdc3c7;">شكل 1</span>
</p>

<p>
	تقتصر الروابط الصلبة على الملفات الموجودة في نظام ملفات واحد، “نظام الملفات” يستخدم هنا بمعنى التقسيم من القرص الصلب أو الحجم المنطقي( logical volume) الذي وُصِل إلى نقطة توصيل معينة ( specified mount point)، في هذه الحالة /home . وذلك لأن أرقام inode فريدة من نوعها فقط داخل نظام ملفات الواحد، وفي حال اختلف نظام ملفات -على سبيل المثال- /var أو /opt سيكون inode له نفس رقم inode لملفنا. كل الروابط الصلبة تشير إلى inode واحدٍ يحتوي على البيانات الوصفية للملف، لذلك فإن كل هذه البيانات تعتبر جزءا من الملف، مثل الملكية والأذونات وعدد الروابط الصلبة إلى تلك inode ، هذه البيانات لا تختلف باختلاف الروابط الصلبة. السمة الوحيدة التي يمكن أن تكون مختلفة هي اسم الملف فلذلك لا يضمن في inode ، الروابط الصلبة إلى file/inode واحد موجود في نفس الدليل يجب أن يكون لها أسماء مختلفة، نظرا لأنه لا يمكن أن يكون هناك أسماء ملفات مكررة داخل دليل واحد.<br>
	يتم عرض الروابط الصلبة لملف بالأمر ls -l ، إذا كنت ترغب في عرض أرقام ال inode الفعلية، فإن الأمر ls -li يفعل ذلك.
</p>

<h2 id="الروابط-الرمزية-اللينة">
	الروابط الرمزية (اللينة)
</h2>

<p>
	الفرق بين الرابط الصلب والرابط اللين ( والمعروف أيضا باسم الرابط الرمزي أو الرابط التشعبي)، هو أن الروابط الصلبة تشير مباشرة إلى inode ، وأما الروابط اللينة فتشير إلى مدخل الدليل، أي واحدة من الروابط الصلبة. ولأن الروابط اللينة تشير إلى رابط صلب للملف وليس inode فإنها لا تعتمد على رقم inode ، ويمكن أن تعمل عبر أنظمة ملفات مختلفة.<br>
	الجانب السلبي لهذا هو أنه إذا حذف الرابط الصلب الذي يشير إليه الرابط اللين أو غُيِّر اسمه فإن الرابط الرمزي سوف يتعطل، لحسن الحظ الأمر ls يوضح الروابط المعطلة بالنص الأبيض بخلفية حمراء في قائمة طويلة.
</p>

<h2 id="مشروع-مختبر-تجربة-الروابط">
	مشروع مختبر: تجربة الروابط
</h2>

<p>
	أعتقد أن أسهل طريقة لفهم استخدام والاختلاف بين الروابط الصلبة واللينة هي مع مشروع المختبر. يجب أن يتم هذا المشروع في دليل فارغ بمستخدم غير جذر . لقد أنشأت الدليل ~/temp لهذا الغرض، ويجب عليك فعل ذلك أيضا. هذا يهيئ مكانا آمنا للقيام بالمشروع ويوفر دليلا جديدا فارغا للعمل فيه بحيث تكون فيه فقط الملفات المرتبطة بهذا المشروع.
</p>

<h3 id="الإعداد-الأولي">
	الإعداد الأولي
</h3>

<p>
	أولا، أنشئ الدليل المؤقت الذي سوف تؤدي فيه المهام اللازمة لهذا المشروع. تأكد من أن مجلد العمل الحالي (PWD) هو المجلد الرئيسي الخاص بك، ثم أدخل الأمر التالي.
</p>

<pre class="ipsCode" id="ips_uid_7563_9">
mkdir temp </pre>

<p>
	ادخل إلى الدليل ~/temp بالأمر
</p>

<pre class="ipsCode" id="ips_uid_7563_11">
<code class="hljs bash"><span class="hljs-built_in"><span class="pln">cd</span></span><span class="pln"> temp </span></code></pre>

<p>
	للبدء نحتاج إلى إنشاء ملف يمكننا الربط إليه. الأمر التالي يفعل ذلك ويوفر بعض المحتويات أيضا.
</p>

<pre class="ipsCode" id="ips_uid_7563_11">
<code class="hljs avrasm"><span class="pln">du </span><span class="pun">-</span><span class="pln">h </span><span class="pun">&gt;</span><span class="pln"> main</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">file</span></span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">txt</span></span><span class="pln"> </span></code></pre>

<p>
	استخدم الأمر ls -l للتحقق من إنشاء الملف بشكل صحيح . يجب أن يكون الإخراج مشابه لنتائجي. لاحظ أن حجم الملف هو 7 بايت فقط، لكن قد يختلف حجم الملف عن بايت أو اثنين.
</p>

<pre class="ipsCode" id="ips_uid_7563_11">
<code class="hljs mel"><span class="pun">[</span><span class="pln">dboth</span><span class="hljs-variable"><span class="pln">@david</span></span><span class="pln"> temp</span><span class="pun">]</span><span class="pln">$ </span><span class="hljs-keyword"><span class="pln">ls</span></span><span class="pln"> </span><span class="pun">-</span><span class="pln">l 
total </span><span class="hljs-number"><span class="lit">4</span></span><span class="pln"> 
</span><span class="pun">-</span><span class="pln">rw</span><span class="pun">-</span><span class="pln">rw</span><span class="pun">-</span><span class="pln">r</span><span class="pun">--</span><span class="pln"> </span><span class="hljs-number"><span class="lit">1</span></span><span class="pln"> dboth dboth </span><span class="hljs-number"><span class="lit">7</span></span><span class="pln"> </span><span class="typ">Jun</span><span class="pln"> </span><span class="hljs-number"><span class="lit">13</span></span><span class="pln"> </span><span class="hljs-number"><span class="lit">07</span></span><span class="pun">:</span><span class="hljs-number"><span class="lit">34</span></span><span class="pln"> main</span><span class="pun">.</span><span class="hljs-keyword"><span class="pln">file</span></span><span class="pun">.</span><span class="pln">txt</span></code></pre>

<p>
	لاحظ الرقم “1” الذي يتبع وضع الملف في القائمة . يمثل هذا العدد عدد الروابط الصلبة الموجودة للملف. في الوقت الحالي، يجب أن تكون 1 لأننا لم ننشئ أي روابط صلبة إضافية لملف الاختبار.
</p>

<h3 id="تجربة-الروابط-الصلبة">
	تجربة الروابط الصلبة
</h3>

<p>
	تنشئ الروابطُ الصلبة مدخلَ دليل جديد يشير إلى نفس inode ، لذلك عند إضافة روابط صلبة إلى ملف، سترى زيادة عدد الروابط. تأكد من أنك لا تزال في المجلد ~/temp ثم أنشئ رابطا صلبا إلى الملف main.file.txt ، وقم بعرض القائمة الطويلة بالأمر ls -l :
</p>

<pre class="ipsCode" id="ips_uid_7563_11">
<code class="hljs avrasm"><span class="pun">[</span><span class="pln">dboth@david temp</span><span class="pun">]</span><span class="pln">$ ln main</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">file</span></span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">txt</span></span><span class="pln"> link1</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">file</span></span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">txt</span></span><span class="pln"> 
</span><span class="pun">[</span><span class="pln">dboth@david temp</span><span class="pun">]</span><span class="pln">$ ls </span><span class="pun">-</span><span class="pln">l 
total </span><span class="hljs-number"><span class="lit">8</span></span><span class="pln"> 
</span><span class="pun">-</span><span class="pln">rw</span><span class="pun">-</span><span class="pln">rw</span><span class="pun">-</span><span class="pln">r</span><span class="pun">--</span><span class="pln"> </span><span class="hljs-number"><span class="lit">2</span></span><span class="pln"> dboth dboth </span><span class="hljs-number"><span class="lit">7</span></span><span class="pln"> </span><span class="typ">Jun</span><span class="pln"> </span><span class="hljs-number"><span class="lit">13</span></span><span class="pln"> </span><span class="hljs-number"><span class="lit">07</span></span><span class="pun">:</span><span class="hljs-number"><span class="lit">34</span></span><span class="pln"> link1</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">file</span></span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">txt</span></span><span class="pln"> 
</span><span class="pun">-</span><span class="pln">rw</span><span class="pun">-</span><span class="pln">rw</span><span class="pun">-</span><span class="pln">r</span><span class="pun">--</span><span class="pln"> </span><span class="hljs-number"><span class="lit">2</span></span><span class="pln"> dboth dboth </span><span class="hljs-number"><span class="lit">7</span></span><span class="pln"> </span><span class="typ">Jun</span><span class="pln"> </span><span class="hljs-number"><span class="lit">13</span></span><span class="pln"> </span><span class="hljs-number"><span class="lit">07</span></span><span class="pun">:</span><span class="hljs-number"><span class="lit">34</span></span><span class="pln"> main</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">file</span></span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">txt</span></span></code></pre>

<p>
	لاحظ أن كلا الملفين يحتوي على رابطين، وهما بنفس الحجم والتاريخ. فهو ملف واحد مع inode واحد ورابطين صلبين اثنين. أنشئ رابطا صلبا ثانيا إلى هذا الملف واعرض محتويات المجلد . يمكنك إنشاء رابط إلى أي من الروابط الموجودة link1.file.txt أو main.file.txt
</p>

<pre class="ipsCode" id="ips_uid_7563_11">
<code class="hljs avrasm"><span class="pun">[</span><span class="pln">dboth@david temp</span><span class="pun">]</span><span class="pln">$ ln link1</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">file</span></span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">txt</span></span><span class="pln"> link2</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">file</span></span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">txt</span></span><span class="pln"> </span><span class="hljs-comment"><span class="pun">;</span><span class="pln"> ls </span><span class="pun">-</span><span class="pln">l</span></span><span class="pln">
total </span><span class="hljs-number"><span class="lit">16</span></span><span class="pln"> 
</span><span class="pun">-</span><span class="pln">rw</span><span class="pun">-</span><span class="pln">rw</span><span class="pun">-</span><span class="pln">r</span><span class="pun">--</span><span class="pln"> </span><span class="hljs-number"><span class="lit">3</span></span><span class="pln"> dboth dboth </span><span class="hljs-number"><span class="lit">7</span></span><span class="pln"> </span><span class="typ">Jun</span><span class="pln"> </span><span class="hljs-number"><span class="lit">13</span></span><span class="pln"> </span><span class="hljs-number"><span class="lit">07</span></span><span class="pun">:</span><span class="hljs-number"><span class="lit">34</span></span><span class="pln"> link1</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">file</span></span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">txt</span></span><span class="pln"> 
</span><span class="pun">-</span><span class="pln">rw</span><span class="pun">-</span><span class="pln">rw</span><span class="pun">-</span><span class="pln">r</span><span class="pun">--</span><span class="pln"> </span><span class="hljs-number"><span class="lit">3</span></span><span class="pln"> dboth dboth </span><span class="hljs-number"><span class="lit">7</span></span><span class="pln"> </span><span class="typ">Jun</span><span class="pln"> </span><span class="hljs-number"><span class="lit">13</span></span><span class="pln"> </span><span class="hljs-number"><span class="lit">07</span></span><span class="pun">:</span><span class="hljs-number"><span class="lit">34</span></span><span class="pln"> link2</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">file</span></span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">txt</span></span><span class="pln"> 
</span><span class="pun">-</span><span class="pln">rw</span><span class="pun">-</span><span class="pln">rw</span><span class="pun">-</span><span class="pln">r</span><span class="pun">--</span><span class="pln"> </span><span class="hljs-number"><span class="lit">3</span></span><span class="pln"> dboth dboth </span><span class="hljs-number"><span class="lit">7</span></span><span class="pln"> </span><span class="typ">Jun</span><span class="pln"> </span><span class="hljs-number"><span class="lit">13</span></span><span class="pln"> </span><span class="hljs-number"><span class="lit">07</span></span><span class="pun">:</span><span class="hljs-number"><span class="lit">34</span></span><span class="pln"> main</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">file</span></span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">txt</span></span></code></pre>

<p>
	لاحظ أن كل رابط صلب جديد في هذا الدليل يجب أن يكون لها اسم مختلف لأنه لا يمكن أن يكون للملفين نفس الاسم داخل نفس الدليل. حاول إنشاء رابط آخر باسم ملف موجود حاليا.
</p>

<pre class="ipsCode" id="ips_uid_7563_11">
<code class="hljs vhdl"><span class="pun">[</span><span class="pln">dboth@david temp</span><span class="pun">]</span><span class="pln">$ ln main</span><span class="pun">.</span><span class="hljs-keyword"><span class="pln">file</span></span><span class="pun">.</span><span class="pln">txt link2</span><span class="pun">.</span><span class="hljs-keyword"><span class="pln">file</span></span><span class="pun">.</span><span class="pln">txt 
ln</span><span class="pun">:</span><span class="pln"> failed </span><span class="hljs-keyword"><span class="pln">to</span></span><span class="pln"> create hard link </span><span class="hljs-attribute"><span class="str">'link2</span></span><span class="str">.</span><span class="hljs-keyword"><span class="str">file</span></span><span class="str">.txt'</span><span class="pun">:</span><span class="pln"> </span><span class="hljs-keyword"><span class="typ">File</span></span><span class="pln"> exists</span></code></pre>

<p>
	من الواضح أن هذا لن ينجح، لأن link2.file.txt موجود بالفعل.<br>
	حتى الآن، أنشأنا فقط الروابط الصلبة في نفس الدليل. لذلك، أنشئ رابطا في الدليل الرئيسي الخاص بك، حيث يوجد مجلد المشروع الذي نعمل عليه.
</p>

<pre class="ipsCode" id="ips_uid_7563_11">
<code class="hljs avrasm"><span class="pun">[</span><span class="pln">dboth@david temp</span><span class="pun">]</span><span class="pln">$ ln main</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">file</span></span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">txt</span></span><span class="pln"> </span><span class="pun">../</span><span class="pln">main</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">file</span></span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">txt</span></span><span class="pln"> </span><span class="hljs-comment"><span class="pun">;</span><span class="pln"> ls </span><span class="pun">-</span><span class="pln">l </span><span class="pun">../</span><span class="pln">main</span><span class="pun">*</span></span><span class="pln">
</span><span class="pun">-</span><span class="pln">rw</span><span class="pun">-</span><span class="pln">rw</span><span class="pun">-</span><span class="pln">r</span><span class="pun">--</span><span class="pln">    </span><span class="hljs-number"><span class="lit">4</span></span><span class="pln"> dboth dboth     </span><span class="hljs-number"><span class="lit">7</span></span><span class="pln"> </span><span class="typ">Jun</span><span class="pln"> </span><span class="hljs-number"><span class="lit">13</span></span><span class="pln"> </span><span class="hljs-number"><span class="lit">07</span></span><span class="pun">:</span><span class="hljs-number"><span class="lit">34</span></span><span class="pln"> main</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">file</span></span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">txt</span></span></code></pre>

<p>
	يظهر الأمر ls في القائمة المذكورة أعلاه أن الملف main.file.txt موجود في الدليل الرئيسي بنفس اسم الملف في الدليل المؤقت . وبطبيعة الحال، هذه ليست ملفات مختلفة. فهي الملف نفسه مع عدة روابط (مداخل الأدلة) إلى نفس Inode . للمساعدة في توضيح النقطة التالية أضف ملفا لا رابطا.
</p>

<pre class="ipsCode" id="ips_uid_7563_11">
<code class="hljs avrasm"><span class="pun">[</span><span class="pln">dboth@david temp</span><span class="pun">]</span><span class="pln">$ touch unlinked</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">file</span></span><span class="pln"> </span><span class="hljs-comment"><span class="pun">;</span><span class="pln"> ls </span><span class="pun">-</span><span class="pln">l</span></span><span class="pln">
total </span><span class="hljs-number"><span class="lit">12</span></span><span class="pln">
</span><span class="pun">-</span><span class="pln">rw</span><span class="pun">-</span><span class="pln">rw</span><span class="pun">-</span><span class="pln">r</span><span class="pun">--</span><span class="pln"> </span><span class="hljs-number"><span class="lit">4</span></span><span class="pln"> dboth dboth </span><span class="hljs-number"><span class="lit">7</span></span><span class="pln"> </span><span class="typ">Jun</span><span class="pln"> </span><span class="hljs-number"><span class="lit">13</span></span><span class="pln"> </span><span class="hljs-number"><span class="lit">07</span></span><span class="pun">:</span><span class="hljs-number"><span class="lit">34</span></span><span class="pln"> link1</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">file</span></span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">txt</span></span><span class="pln">
</span><span class="pun">-</span><span class="pln">rw</span><span class="pun">-</span><span class="pln">rw</span><span class="pun">-</span><span class="pln">r</span><span class="pun">--</span><span class="pln"> </span><span class="hljs-number"><span class="lit">4</span></span><span class="pln"> dboth dboth </span><span class="hljs-number"><span class="lit">7</span></span><span class="pln"> </span><span class="typ">Jun</span><span class="pln"> </span><span class="hljs-number"><span class="lit">13</span></span><span class="pln"> </span><span class="hljs-number"><span class="lit">07</span></span><span class="pun">:</span><span class="hljs-number"><span class="lit">34</span></span><span class="pln"> link2</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">file</span></span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">txt</span></span><span class="pln">
</span><span class="pun">-</span><span class="pln">rw</span><span class="pun">-</span><span class="pln">rw</span><span class="pun">-</span><span class="pln">r</span><span class="pun">--</span><span class="pln"> </span><span class="hljs-number"><span class="lit">4</span></span><span class="pln"> dboth dboth </span><span class="hljs-number"><span class="lit">7</span></span><span class="pln"> </span><span class="typ">Jun</span><span class="pln"> </span><span class="hljs-number"><span class="lit">13</span></span><span class="pln"> </span><span class="hljs-number"><span class="lit">07</span></span><span class="pun">:</span><span class="hljs-number"><span class="lit">34</span></span><span class="pln"> main</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">file</span></span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">txt</span></span><span class="pln">
</span><span class="pun">-</span><span class="pln">rw</span><span class="pun">-</span><span class="pln">rw</span><span class="pun">-</span><span class="pln">r</span><span class="pun">--</span><span class="pln"> </span><span class="hljs-number"><span class="lit">1</span></span><span class="pln"> dboth dboth </span><span class="hljs-number"><span class="lit">0</span></span><span class="pln"> </span><span class="typ">Jun</span><span class="pln"> </span><span class="hljs-number"><span class="lit">14</span></span><span class="pln"> </span><span class="hljs-number"><span class="lit">08</span></span><span class="pun">:</span><span class="hljs-number"><span class="lit">18</span></span><span class="pln"> unlinked</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">file</span></span></code></pre>

<p>
	انظر في عدد الروابط الصلبة للملف الأول والملف الجديد باستخدام الخيار -i إلى الأمر ls
</p>

<pre class="ipsCode" id="ips_uid_7563_11">
<code class="hljs avrasm"><span class="pun">[</span><span class="pln">dboth@david temp</span><span class="pun">]</span><span class="pln">$ ls </span><span class="pun">-</span><span class="pln">li
total </span><span class="hljs-number"><span class="lit">12</span></span><span class="pln">
</span><span class="hljs-number"><span class="lit">657024</span></span><span class="pln"> </span><span class="pun">-</span><span class="pln">rw</span><span class="pun">-</span><span class="pln">rw</span><span class="pun">-</span><span class="pln">r</span><span class="pun">--</span><span class="pln"> </span><span class="hljs-number"><span class="lit">4</span></span><span class="pln"> dboth dboth </span><span class="hljs-number"><span class="lit">7</span></span><span class="pln"> </span><span class="typ">Jun</span><span class="pln"> </span><span class="hljs-number"><span class="lit">13</span></span><span class="pln"> </span><span class="hljs-number"><span class="lit">07</span></span><span class="pun">:</span><span class="hljs-number"><span class="lit">34</span></span><span class="pln"> link1</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">file</span></span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">txt</span></span><span class="pln">
</span><span class="hljs-number"><span class="lit">657024</span></span><span class="pln"> </span><span class="pun">-</span><span class="pln">rw</span><span class="pun">-</span><span class="pln">rw</span><span class="pun">-</span><span class="pln">r</span><span class="pun">--</span><span class="pln"> </span><span class="hljs-number"><span class="lit">4</span></span><span class="pln"> dboth dboth </span><span class="hljs-number"><span class="lit">7</span></span><span class="pln"> </span><span class="typ">Jun</span><span class="pln"> </span><span class="hljs-number"><span class="lit">13</span></span><span class="pln"> </span><span class="hljs-number"><span class="lit">07</span></span><span class="pun">:</span><span class="hljs-number"><span class="lit">34</span></span><span class="pln"> link2</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">file</span></span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">txt</span></span><span class="pln">
</span><span class="hljs-number"><span class="lit">657024</span></span><span class="pln"> </span><span class="pun">-</span><span class="pln">rw</span><span class="pun">-</span><span class="pln">rw</span><span class="pun">-</span><span class="pln">r</span><span class="pun">--</span><span class="pln"> </span><span class="hljs-number"><span class="lit">4</span></span><span class="pln"> dboth dboth </span><span class="hljs-number"><span class="lit">7</span></span><span class="pln"> </span><span class="typ">Jun</span><span class="pln"> </span><span class="hljs-number"><span class="lit">13</span></span><span class="pln"> </span><span class="hljs-number"><span class="lit">07</span></span><span class="pun">:</span><span class="hljs-number"><span class="lit">34</span></span><span class="pln"> main</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">file</span></span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">txt</span></span><span class="pln">
</span><span class="hljs-number"><span class="lit">657863</span></span><span class="pln"> </span><span class="pun">-</span><span class="pln">rw</span><span class="pun">-</span><span class="pln">rw</span><span class="pun">-</span><span class="pln">r</span><span class="pun">--</span><span class="pln"> </span><span class="hljs-number"><span class="lit">1</span></span><span class="pln"> dboth dboth </span><span class="hljs-number"><span class="lit">0</span></span><span class="pln"> </span><span class="typ">Jun</span><span class="pln"> </span><span class="hljs-number"><span class="lit">14</span></span><span class="pln"> </span><span class="hljs-number"><span class="lit">08</span></span><span class="pun">:</span><span class="hljs-number"><span class="lit">18</span></span><span class="pln"> unlinked</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">file</span></span></code></pre>

<p>
	لاحظ الرقم 657024 على يسار وضع الملف في المثال أعلاه. هذا هو رقم Inode، وتشير جميع الروابط الثلاثة إلى Inode نفسه . يمكنك استخدام الخيار -i لعرض رقم Inode للروابط التي أنشأناها في الدليل الرئيسي أيضا، والتي سوف تظهر أيضا نفس القيمة. رقم Inode للملف الذي يحتوي على رابط واحد يختلف عن الروابط الأخرى. لاحظ أن أرقام Inode ستكون مختلفة على النظام الخاص بك.<br>
	لنقم بتغيير حجم رابط من الروابط الصلبة.
</p>

<pre class="ipsCode" id="ips_uid_7563_11">
<code class="hljs avrasm"><span class="pun">[</span><span class="pln">dboth@david temp</span><span class="pun">]</span><span class="pln">$ df </span><span class="pun">-</span><span class="pln">h </span><span class="pun">&gt;</span><span class="pln"> link2</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">file</span></span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">txt</span></span><span class="pln"> </span><span class="hljs-comment"><span class="pun">;</span><span class="pln"> ls </span><span class="pun">-</span><span class="pln">li</span></span><span class="pln">
total </span><span class="hljs-number"><span class="lit">12</span></span><span class="pln">
</span><span class="hljs-number"><span class="lit">657024</span></span><span class="pln"> </span><span class="pun">-</span><span class="pln">rw</span><span class="pun">-</span><span class="pln">rw</span><span class="pun">-</span><span class="pln">r</span><span class="pun">--</span><span class="pln"> </span><span class="hljs-number"><span class="lit">4</span></span><span class="pln"> dboth dboth </span><span class="hljs-number"><span class="lit">1157</span></span><span class="pln"> </span><span class="typ">Jun</span><span class="pln"> </span><span class="hljs-number"><span class="lit">14</span></span><span class="pln"> </span><span class="hljs-number"><span class="lit">14</span></span><span class="pun">:</span><span class="hljs-number"><span class="lit">14</span></span><span class="pln"> link1</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">file</span></span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">txt</span></span><span class="pln">
</span><span class="hljs-number"><span class="lit">657024</span></span><span class="pln"> </span><span class="pun">-</span><span class="pln">rw</span><span class="pun">-</span><span class="pln">rw</span><span class="pun">-</span><span class="pln">r</span><span class="pun">--</span><span class="pln"> </span><span class="hljs-number"><span class="lit">4</span></span><span class="pln"> dboth dboth </span><span class="hljs-number"><span class="lit">1157</span></span><span class="pln"> </span><span class="typ">Jun</span><span class="pln"> </span><span class="hljs-number"><span class="lit">14</span></span><span class="pln"> </span><span class="hljs-number"><span class="lit">14</span></span><span class="pun">:</span><span class="hljs-number"><span class="lit">14</span></span><span class="pln"> link2</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">file</span></span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">txt</span></span><span class="pln">
</span><span class="hljs-number"><span class="lit">657024</span></span><span class="pln"> </span><span class="pun">-</span><span class="pln">rw</span><span class="pun">-</span><span class="pln">rw</span><span class="pun">-</span><span class="pln">r</span><span class="pun">--</span><span class="pln"> </span><span class="hljs-number"><span class="lit">4</span></span><span class="pln"> dboth dboth </span><span class="hljs-number"><span class="lit">1157</span></span><span class="pln"> </span><span class="typ">Jun</span><span class="pln"> </span><span class="hljs-number"><span class="lit">14</span></span><span class="pln"> </span><span class="hljs-number"><span class="lit">14</span></span><span class="pun">:</span><span class="hljs-number"><span class="lit">14</span></span><span class="pln"> main</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">file</span></span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">txt</span></span><span class="pln">
</span><span class="hljs-number"><span class="lit">657863</span></span><span class="pln"> </span><span class="pun">-</span><span class="pln">rw</span><span class="pun">-</span><span class="pln">rw</span><span class="pun">-</span><span class="pln">r</span><span class="pun">--</span><span class="pln"> </span><span class="hljs-number"><span class="lit">1</span></span><span class="pln"> dboth dboth    </span><span class="hljs-number"><span class="lit">0</span></span><span class="pln"> </span><span class="typ">Jun</span><span class="pln"> </span><span class="hljs-number"><span class="lit">14</span></span><span class="pln"> </span><span class="hljs-number"><span class="lit">08</span></span><span class="pun">:</span><span class="hljs-number"><span class="lit">18</span></span><span class="pln"> unlinked</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">file</span></span></code></pre>

<p>
	حجم الملف سيتغير في جميع الروابط الصلبة وذلك لأن هناك ملفا واحدا يرتبط بمداخل متعددة.<br>
	أنا أعلم أن التجربة المقبلة سوف تعمل على جهاز الكمبيوتر الخاص بي لأن المجلد /tmp على تقسيم ( partition ) منفصل ، إن كان لك ذلك تأكد أن لديك إمكانية الوصول إلى التقسيم. إذا لم تقم بذلك، يمكنك إدراج إصبع ذاكرة USB وتركيبه. إذا كان أحد هذه الخيارات يناسبك، يمكنك إجراء هذه التجربة.<br>
	حاول إنشاء رابط إلى أحد الملفات في الدليل ~/temp في /tmp أو في أي مكان حيث نظام الملفات مختلف.
</p>

<pre class="ipsCode" id="ips_uid_7563_11">
<code class="hljs vhdl"><span class="pun">[</span><span class="pln">dboth@david temp</span><span class="pun">]</span><span class="pln">$ ln link2</span><span class="pun">.</span><span class="hljs-keyword"><span class="pln">file</span></span><span class="pun">.</span><span class="pln">txt </span><span class="pun">/</span><span class="pln">tmp</span><span class="pun">/</span><span class="pln">link3</span><span class="pun">.</span><span class="hljs-keyword"><span class="pln">file</span></span><span class="pun">.</span><span class="pln">txt
ln</span><span class="pun">:</span><span class="pln"> failed </span><span class="hljs-keyword"><span class="pln">to</span></span><span class="pln"> create hard link </span><span class="str">'/tmp/link3.</span><span class="hljs-keyword"><span class="str">file</span></span><span class="str">.txt'</span><span class="pln"> </span><span class="pun">=&gt;</span><span class="pln"> </span><span class="hljs-attribute"><span class="str">'link2</span></span><span class="str">.</span><span class="hljs-keyword"><span class="str">file</span></span><span class="str">.txt'</span><span class="pun">:</span><span class="pln"> 
</span><span class="typ">Invalid</span><span class="pln"> cross</span><span class="pun">-</span><span class="pln">device link</span></code></pre>

<p>
	لماذا يحدث هذا الخطأ؟ السبب هو أن كل نظام ملفات منفصل لديه مجموعة خاصة من أرقام Inode ، ببساطة الإشارة إلى ملف من رقم Inode معين عبر كامل أدلة لينكس يمكن أن يؤدي إلى الارتباك، لأن نفس رقم Inode يمكن أن يوجد في كل نظام الملفات المختلفة.<br>
	ربما تريد تحديد مواقع كل الروابط الصلبة التي تنتمي إلى Inode واحد . يمكنك العثور على رقم Inode باستخدام الأمر ls –li ثم يمكنك استخدام الأمر find لتحديد كافة الروابط المتعلقة برقم Inode هذا.
</p>

<pre class="ipsCode" id="ips_uid_7563_11">
<code class="hljs avrasm"><span class="pun">[</span><span class="pln">dboth@david temp</span><span class="pun">]</span><span class="pln">$ find </span><span class="pun">.</span><span class="pln"> </span><span class="pun">-</span><span class="pln">inum </span><span class="hljs-number"><span class="lit">657024</span></span><span class="pln"> 
</span><span class="pun">./</span><span class="pln">main</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">file</span></span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">txt</span></span><span class="pln">
</span><span class="pun">./</span><span class="pln">link1</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">file</span></span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">txt</span></span><span class="pln">
</span><span class="pun">./</span><span class="pln">link2</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">file</span></span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">txt</span></span><span class="pln">  </span></code></pre>

<p>
	لاحظ أن الأمر find لم يجد كل الروابط الأربعة إلى هذا Inode لأننا بدأنا في الدليل الحالي من ~/temp . لا يجد الأمر find سوى الملفات في الدليل الحالي. للعثور على جميع الروابط، يمكننا استخدام الأمر التالي الذي يحدد الدليل الرئيسي الخاص بك كمكان للبدء بالبحث.
</p>

<pre class="ipsCode" id="ips_uid_7563_11">
<code class="hljs avrasm"><span class="pun">[</span><span class="pln">dboth@david temp</span><span class="pun">]</span><span class="pln">$ find </span><span class="pun">~</span><span class="pln"> </span><span class="pun">-</span><span class="pln">samefile main</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">file</span></span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">txt</span></span><span class="pln"> 
</span><span class="pun">/</span><span class="pln">home</span><span class="pun">/</span><span class="pln">dboth</span><span class="pun">/</span><span class="pln">temp</span><span class="pun">/</span><span class="pln">main</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">file</span></span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">txt</span></span><span class="pln">
</span><span class="pun">/</span><span class="pln">home</span><span class="pun">/</span><span class="pln">dboth</span><span class="pun">/</span><span class="pln">temp</span><span class="pun">/</span><span class="pln">link1</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">file</span></span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">txt</span></span><span class="pln">
</span><span class="pun">/</span><span class="pln">home</span><span class="pun">/</span><span class="pln">dboth</span><span class="pun">/</span><span class="pln">temp</span><span class="pun">/</span><span class="pln">link2</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">file</span></span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">txt</span></span><span class="pln">
</span><span class="pun">/</span><span class="pln">home</span><span class="pun">/</span><span class="pln">dboth</span><span class="pun">/</span><span class="pln">main</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">file</span></span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">txt</span></span></code></pre>

<p>
	قد تشاهد رسائل خطأ إذا لم يكن لديك أذونات كمستخدم غير جذر. يستخدم هذا الأمر أيضا الخيار -samefile بدلا من تحديد رقم Inode . هذا يعمل كما لو استخدمت رقم Inode ويمكن أن يكون هذا أسهل إذا كنت تعرف اسم واحد من الروابط الصلبة.
</p>

<h3 id="تجربة-الروابط-اللينة-الرمزية">
	تجربة الروابط اللينة (الرمزية)
</h3>

<p>
	كما رأيت للتو، إنشاء روابط صلبة غير ممكن خارج حدود نظام الملفات. الروابط اللينة هي وسيلة لحل هذه المشكلة، رغم أنها يمكن أن تحقق نفس الغاية، فهي مختلفة جدا، ومعرفة هذه الاختلافات هو المهم.<br>
	لنبدأ من خلال إنشاء رابط رمزي في مجلد الاختبار ~/temp لبدء الاستكشاف
</p>

<pre class="ipsCode" id="ips_uid_7563_11">
<code class="hljs avrasm"><span class="pun">[</span><span class="pln">dboth@david temp</span><span class="pun">]</span><span class="pln">$ ln </span><span class="pun">-</span><span class="pln">s link2</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">file</span></span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">txt</span></span><span class="pln"> link3</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">file</span></span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">txt</span></span><span class="pln"> </span><span class="hljs-comment"><span class="pun">;</span><span class="pln"> ls </span><span class="pun">-</span><span class="pln">li</span></span><span class="pln">
total </span><span class="hljs-number"><span class="lit">12</span></span><span class="pln">
</span><span class="hljs-number"><span class="lit">657024</span></span><span class="pln"> </span><span class="pun">-</span><span class="pln">rw</span><span class="pun">-</span><span class="pln">rw</span><span class="pun">-</span><span class="pln">r</span><span class="pun">--</span><span class="pln"> </span><span class="hljs-number"><span class="lit">4</span></span><span class="pln"> dboth dboth </span><span class="hljs-number"><span class="lit">1157</span></span><span class="pln"> </span><span class="typ">Jun</span><span class="pln"> </span><span class="hljs-number"><span class="lit">14</span></span><span class="pln"> </span><span class="hljs-number"><span class="lit">14</span></span><span class="pun">:</span><span class="hljs-number"><span class="lit">14</span></span><span class="pln"> link1</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">file</span></span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">txt</span></span><span class="pln">
</span><span class="hljs-number"><span class="lit">657024</span></span><span class="pln"> </span><span class="pun">-</span><span class="pln">rw</span><span class="pun">-</span><span class="pln">rw</span><span class="pun">-</span><span class="pln">r</span><span class="pun">--</span><span class="pln"> </span><span class="hljs-number"><span class="lit">4</span></span><span class="pln"> dboth dboth </span><span class="hljs-number"><span class="lit">1157</span></span><span class="pln"> </span><span class="typ">Jun</span><span class="pln"> </span><span class="hljs-number"><span class="lit">14</span></span><span class="pln"> </span><span class="hljs-number"><span class="lit">14</span></span><span class="pun">:</span><span class="hljs-number"><span class="lit">14</span></span><span class="pln"> link2</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">file</span></span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">txt</span></span><span class="pln">
</span><span class="hljs-number"><span class="lit">658270</span></span><span class="pln"> lrwxrwxrwx </span><span class="hljs-number"><span class="lit">1</span></span><span class="pln"> dboth dboth   </span><span class="hljs-number"><span class="lit">14</span></span><span class="pln"> </span><span class="typ">Jun</span><span class="pln"> </span><span class="hljs-number"><span class="lit">14</span></span><span class="pln"> </span><span class="hljs-number"><span class="lit">15</span></span><span class="pun">:</span><span class="hljs-number"><span class="lit">21</span></span><span class="pln"> link3</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">file</span></span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">txt</span></span><span class="pln"> </span><span class="pun">-&gt;</span><span class="pln"> 
link2</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">file</span></span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">txt</span></span><span class="pln">
</span><span class="hljs-number"><span class="lit">657024</span></span><span class="pln"> </span><span class="pun">-</span><span class="pln">rw</span><span class="pun">-</span><span class="pln">rw</span><span class="pun">-</span><span class="pln">r</span><span class="pun">--</span><span class="pln"> </span><span class="hljs-number"><span class="lit">4</span></span><span class="pln"> dboth dboth </span><span class="hljs-number"><span class="lit">1157</span></span><span class="pln"> </span><span class="typ">Jun</span><span class="pln"> </span><span class="hljs-number"><span class="lit">14</span></span><span class="pln"> </span><span class="hljs-number"><span class="lit">14</span></span><span class="pun">:</span><span class="hljs-number"><span class="lit">14</span></span><span class="pln"> main</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">file</span></span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">txt</span></span><span class="pln">
</span><span class="hljs-number"><span class="lit">657863</span></span><span class="pln"> </span><span class="pun">-</span><span class="pln">rw</span><span class="pun">-</span><span class="pln">rw</span><span class="pun">-</span><span class="pln">r</span><span class="pun">--</span><span class="pln"> </span><span class="hljs-number"><span class="lit">1</span></span><span class="pln"> dboth dboth    </span><span class="hljs-number"><span class="lit">0</span></span><span class="pln"> </span><span class="typ">Jun</span><span class="pln"> </span><span class="hljs-number"><span class="lit">14</span></span><span class="pln"> </span><span class="hljs-number"><span class="lit">08</span></span><span class="pun">:</span><span class="hljs-number"><span class="lit">18</span></span><span class="pln"> unlinked</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">file</span></span></code></pre>

<p>
	الروابط الصلبة -وهي تلك التي تحتوي على رقم Inode 657024 - لم تتغير، وعدد الروابط الصلبة المعروضة لم يتغير أيضا . الروابط الجديدة التي تم إنشاؤها لديها رقم Inode مختلف حيث رقمها658270 .<br>
	الرابط اللين المسمى link3.file.txt يشير إلى link2.file.txt ، استخدم الأمر cat لعرض محتويات link3.file.txt .<br>
	معلومات الملف للرابط الرمزي يبدأ بالحرف ” l ” الذي يشير إلى أن هذا الملف هو في الواقع رابط رمزي.<br>
	حجم الرابط الرمزي link3.file.txt في المثال أعلاه هو 14 بايت فقط. هذا هو حجم النص link3.file.txt -&gt; link2.file.txt” “، وهو المحتوى الفعلي للرابط الرمزي.<br>
	الرابط الرمزي link3.file.txt لا يشير إلى Inode ، بل يشير إلى مدخل دليل آخر (رابط صلب أو رمزي) ، هذا يجعل من المفيد إنشاء روابط تمتد خارج حدود نظام الملفات . لذلك، دعونا ننشئ هذا الرابط.
</p>

<pre class="ipsCode" id="ips_uid_7563_11">
<code class="hljs avrasm"><span class="pun">[</span><span class="pln">dboth@david temp</span><span class="pun">]</span><span class="pln">$ ln </span><span class="pun">-</span><span class="pln">s </span><span class="pun">/</span><span class="pln">home</span><span class="pun">/</span><span class="pln">dboth</span><span class="pun">/</span><span class="pln">temp</span><span class="pun">/</span><span class="pln">link2</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">file</span></span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">txt</span></span><span class="pln"> 
</span><span class="pun">/</span><span class="pln">tmp</span><span class="pun">/</span><span class="pln">link3</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">file</span></span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">txt</span></span><span class="pln"> </span><span class="hljs-comment"><span class="pun">;</span><span class="pln"> ls </span><span class="pun">-</span><span class="pln">l </span><span class="pun">/</span><span class="pln">tmp</span><span class="pun">/</span><span class="pln">link</span><span class="pun">*</span></span><span class="pln">
lrwxrwxrwx </span><span class="hljs-number"><span class="lit">1</span></span><span class="pln"> dboth dboth </span><span class="hljs-number"><span class="lit">31</span></span><span class="pln"> </span><span class="typ">Jun</span><span class="pln"> </span><span class="hljs-number"><span class="lit">14</span></span><span class="pln"> </span><span class="hljs-number"><span class="lit">21</span></span><span class="pun">:</span><span class="hljs-number"><span class="lit">53</span></span><span class="pln"> </span><span class="pun">/</span><span class="pln">tmp</span><span class="pun">/</span><span class="pln">link3</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">file</span></span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">txt</span></span><span class="pln"> </span><span class="pun">-&gt;</span><span class="pln"> 
</span><span class="str">/home/</span><span class="pln">dboth</span><span class="pun">/</span><span class="pln">temp</span><span class="pun">/</span><span class="pln">link2</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">file</span></span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">txt</span></span></code></pre>

<h3 id="حذف-الروابط">
	حذف الروابط
</h3>

<p>
	هناك بعض الأشياء الأخرى التي يجب عليك مراعاتها عندما تحتاج إلى حذف الروابط أو الملفات التي تشير إليها.<br>
	أولا، دعونا نحذف الرابط main.file.txt ، تذكر أن كل مدخل دليل يشير إلى Inode هو مجرد رابط صلب.
</p>

<pre class="ipsCode" id="ips_uid_7563_11">
<code class="hljs avrasm"><span class="pun">[</span><span class="pln">dboth@david temp</span><span class="pun">]</span><span class="pln">$ rm main</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">file</span></span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">txt</span></span><span class="pln"> </span><span class="hljs-comment"><span class="pun">;</span><span class="pln"> ls </span><span class="pun">-</span><span class="pln">li</span></span><span class="pln">
total </span><span class="hljs-number"><span class="lit">8</span></span><span class="pln">
</span><span class="hljs-number"><span class="lit">657024</span></span><span class="pln"> </span><span class="pun">-</span><span class="pln">rw</span><span class="pun">-</span><span class="pln">rw</span><span class="pun">-</span><span class="pln">r</span><span class="pun">--</span><span class="pln"> </span><span class="hljs-number"><span class="lit">3</span></span><span class="pln"> dboth dboth </span><span class="hljs-number"><span class="lit">1157</span></span><span class="pln"> </span><span class="typ">Jun</span><span class="pln"> </span><span class="hljs-number"><span class="lit">14</span></span><span class="pln"> </span><span class="hljs-number"><span class="lit">14</span></span><span class="pun">:</span><span class="hljs-number"><span class="lit">14</span></span><span class="pln"> link1</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">file</span></span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">txt</span></span><span class="pln">
</span><span class="hljs-number"><span class="lit">657024</span></span><span class="pln"> </span><span class="pun">-</span><span class="pln">rw</span><span class="pun">-</span><span class="pln">rw</span><span class="pun">-</span><span class="pln">r</span><span class="pun">--</span><span class="pln"> </span><span class="hljs-number"><span class="lit">3</span></span><span class="pln"> dboth dboth </span><span class="hljs-number"><span class="lit">1157</span></span><span class="pln"> </span><span class="typ">Jun</span><span class="pln"> </span><span class="hljs-number"><span class="lit">14</span></span><span class="pln"> </span><span class="hljs-number"><span class="lit">14</span></span><span class="pun">:</span><span class="hljs-number"><span class="lit">14</span></span><span class="pln"> link2</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">file</span></span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">txt</span></span><span class="pln">
</span><span class="hljs-number"><span class="lit">658270</span></span><span class="pln"> lrwxrwxrwx </span><span class="hljs-number"><span class="lit">1</span></span><span class="pln"> dboth dboth   </span><span class="hljs-number"><span class="lit">14</span></span><span class="pln"> </span><span class="typ">Jun</span><span class="pln"> </span><span class="hljs-number"><span class="lit">14</span></span><span class="pln"> </span><span class="hljs-number"><span class="lit">15</span></span><span class="pun">:</span><span class="hljs-number"><span class="lit">21</span></span><span class="pln"> link3</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">file</span></span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">txt</span></span><span class="pln"> </span><span class="pun">-&gt;</span><span class="pln"> 
link2</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">file</span></span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">txt</span></span><span class="pln">
</span><span class="hljs-number"><span class="lit">657863</span></span><span class="pln"> </span><span class="pun">-</span><span class="pln">rw</span><span class="pun">-</span><span class="pln">rw</span><span class="pun">-</span><span class="pln">r</span><span class="pun">--</span><span class="pln"> </span><span class="hljs-number"><span class="lit">1</span></span><span class="pln"> dboth dboth    </span><span class="hljs-number"><span class="lit">0</span></span><span class="pln"> </span><span class="typ">Jun</span><span class="pln"> </span><span class="hljs-number"><span class="lit">14</span></span><span class="pln"> </span><span class="hljs-number"><span class="lit">08</span></span><span class="pun">:</span><span class="hljs-number"><span class="lit">18</span></span><span class="pln"> unlinked</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">file</span></span></code></pre>

<p>
	لقد كان الرابط main.file.txt هو الرابط الأول الذي تم إنشاؤه عند إنشاء الملف. حذفه الآن لا يزال يترك الملف الأصلي وبياناته على القرص الصلب مع جميع الروابط الصلبة المتبقية. لحذف الملف وبياناته، سيكون عليك حذف كافة الروابط الصلبة المتبقية.<br>
	الآن احذف الرابط الصلب link2.file.txt
</p>

<pre class="ipsCode" id="ips_uid_7563_11">
<code class="hljs avrasm"><span class="pln"> </span><span class="pun">[</span><span class="pln">dboth@david temp</span><span class="pun">]</span><span class="pln">$ rm link2</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">file</span></span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">txt</span></span><span class="pln"> </span><span class="hljs-comment"><span class="pun">;</span><span class="pln"> ls </span><span class="pun">-</span><span class="pln">li </span></span><span class="pln">
total </span><span class="hljs-number"><span class="lit">8</span></span><span class="pln"> 
</span><span class="hljs-number"><span class="lit">657024</span></span><span class="pln"> </span><span class="pun">-</span><span class="pln">rw</span><span class="pun">-</span><span class="pln">rw</span><span class="pun">-</span><span class="pln">r</span><span class="pun">--</span><span class="pln"> </span><span class="hljs-number"><span class="lit">3</span></span><span class="pln"> dboth dboth </span><span class="hljs-number"><span class="lit">1157</span></span><span class="pln"> </span><span class="typ">Jun</span><span class="pln"> </span><span class="hljs-number"><span class="lit">14</span></span><span class="pln"> </span><span class="hljs-number"><span class="lit">14</span></span><span class="pun">:</span><span class="hljs-number"><span class="lit">14</span></span><span class="pln"> link1</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">file</span></span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">txt</span></span><span class="pln"> 
</span><span class="hljs-number"><span class="lit">658270</span></span><span class="pln"> lrwxrwxrwx </span><span class="hljs-number"><span class="lit">1</span></span><span class="pln"> dboth dboth   </span><span class="hljs-number"><span class="lit">14</span></span><span class="pln"> </span><span class="typ">Jun</span><span class="pln"> </span><span class="hljs-number"><span class="lit">14</span></span><span class="pln"> </span><span class="hljs-number"><span class="lit">15</span></span><span class="pun">:</span><span class="hljs-number"><span class="lit">21</span></span><span class="pln"> link3</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">file</span></span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">txt</span></span><span class="pln"> </span><span class="pun">-&gt;</span><span class="pln"> 
link2</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">file</span></span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">txt</span></span><span class="pln"> 
</span><span class="hljs-number"><span class="lit">657024</span></span><span class="pln"> </span><span class="pun">-</span><span class="pln">rw</span><span class="pun">-</span><span class="pln">rw</span><span class="pun">-</span><span class="pln">r</span><span class="pun">--</span><span class="pln"> </span><span class="hljs-number"><span class="lit">3</span></span><span class="pln"> dboth dboth </span><span class="hljs-number"><span class="lit">1157</span></span><span class="pln"> </span><span class="typ">Jun</span><span class="pln"> </span><span class="hljs-number"><span class="lit">14</span></span><span class="pln"> </span><span class="hljs-number"><span class="lit">14</span></span><span class="pun">:</span><span class="hljs-number"><span class="lit">14</span></span><span class="pln"> main</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">file</span></span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">txt</span></span><span class="pln"> 
</span><span class="hljs-number"><span class="lit">657863</span></span><span class="pln"> </span><span class="pun">-</span><span class="pln">rw</span><span class="pun">-</span><span class="pln">rw</span><span class="pun">-</span><span class="pln">r</span><span class="pun">--</span><span class="pln"> </span><span class="hljs-number"><span class="lit">1</span></span><span class="pln"> dboth dboth    </span><span class="hljs-number"><span class="lit">0</span></span><span class="pln"> </span><span class="typ">Jun</span><span class="pln"> </span><span class="hljs-number"><span class="lit">14</span></span><span class="pln"> </span><span class="hljs-number"><span class="lit">08</span></span><span class="pun">:</span><span class="hljs-number"><span class="lit">18</span></span><span class="pln"> unlinked</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">file</span></span></code></pre>

<p>
	لاحظ ما يحدث للرابط اللين (الرمزي). حذف الرابط الصلب الذي يشير إليه الرابط اللين يتركه معطلا. لإصلاحه يمكنك إنشاء رابط صلب آخر في نفس الدليل بنفس اسم القديم، طالما لم يتم حذف كافة الروابط الصلبة.<br>
	يمكنك أيضا إعادة إنشاء الرابط بنفس الاسم ولكن بالإشارة إلى واحد من الروابط الصلبة المتبقية. وبطبيعة الحال، إذا لم يعد هناك حاجة إلى رابط لين يمكن حذفها مع الأمر rm<br>
	يمكن أيضا استخدام الأمر unlink لحذف الملفات والروابط. إنه بسيط جدا وليس لديه خيارات كالأمر rm ، ومع ذلك فإنه يعكس بشكل أكثر دقة العملية الأساسية للحذف، من حيث أنه يزيل الارتباط - مدخل الدليل - عن الملف الذي يتم حذفه.
</p>

<h3 id="الخلاصة">
	الخلاصة
</h3>

<p>
	لقد عملت مع كلا النوعين من الروابط لفترة طويلة قبل أن أبدأ في فهم قدراتها وخصوصياتها. استغرق الأمر كتابة مشروع مختبر لفئة لينكس، لقد علمت أخيرا كيف تعمل الروابط. هذه المقالة هي تبسيط ما تعلمت في تلك الفئة، وآمل أن يسرع ذلك التعلم لديك.
</p>

<p>
	ترجمة -وبتصرّف- للمقال <a href="https://opensource.com/article/17/6/linking-linux-filesystem" rel="external nofollow">A user’s guide to links in the Linux filesystem</a> لصاحبه David Both
</p>

<p>
	حقوق الصورة البارزة محفوظة لـ <a href="https://www.freepik.com/free-photo/iron-chain-with-a-red-link_959036.htm" rel="external nofollow">Freepik</a>
</p>
]]></description><guid isPermaLink="false">371</guid><pubDate>Wed, 13 Dec 2017 17:34:00 +0000</pubDate></item></channel></rss>
