كيفية إعداد جدار ناري باستخدام IPTables على Ubuntu 14.04


محمد هاني صباغ

إعداد جدارٍ ناريّ قوي هو خطوةٌ أساسية يجب فعلها بهدف تأمين أيّ نظام تشغيلٍ حديث. تأتي معظم توزيعات لينكس بأدواتٍ مختلفة يمكننا استخدامها لضبط جداراتنا الناريّة. في هذا الدرس، سنتحدّث عن جدار iptables الناريّ.

Iptables هو عبارة عن جدارٍ ناريّ عادي موجود في معظم توزيعات لينكس افتراضيًا (برنامجٌ آخر يدعى nftables سيبدأ قريبًا باستبداله). هو في الواقع عبارة عن واجهةٍ أمامية لخطّافات netfilter على مستوى النواة (kernel-level netfilter hooks) يمكنه التعامل مع مكدّس شبكة لينكس (Linux network stack). يعمل iptables عن طريق مطابقة كلّ حزمة (packet) تمرّ عبر الشبكة بمجموعة من القواعد (rules) التي تجعله يقرر ما يجب فعله.

ملاحظة: يغطّي هذا الدرس أساسيات الحماية لـIPv4. في نظام لينكس، هناك فرق بين طرق الحماية لـIPv4 و IPv6. كمثال فإنّ iptables يقوم فقط بالتحكّم في قواعد جدار الحماية لعناوين IPv4 إلّا أنّه يمتلك برنامجًا خارجيًا يدعى ip6tables يمكن استخدامه للتحكّم في قواعد جدار الحماية لعناوين IPv6.

إذا كان خادومك الافتراضي الخاصّ مُعدًّا ليستخدم IPv6، فرجاءً تذكّر حماية كلّ من واجهتيّ الشبكة IPv4 و IPv6 باستخدام الأدوات المناسبة. للمزيد من المعلومات عن أدوات IPv6، راجع هذا الدرس: كيفية ضبط بعض الأدوات لاستخدام IPv6 على نظام لينكس.

أوامر iptables الأساسية

الآن وبعد أن صار لديك المفاهيم الأساسية حول iptables، فإنّه يجب علينا تغطية الأوامر الأساسية التي سيتم استعمالها لتشكيل مجموعات قواعد iptables أكبر بالإضافة إلى إدارة واجهة iptables بشكلٍ عام.

أولًا، يجب عليك أن تنتبه إلى أنّ أوامر iptables يجب أن يتم تشغيلها بصلاحيات الجذر (root privileges). هذا يعني أنّه يجب عليك الولوج إلى النظام باسم المستخدم root، استخدم su أو sudo -i للولوج إلى صدفة المستخدم الجذر، أو يمكنك ببساطة وضع sudo قبل جميع الأوامر التي ستطبّقها. سنستخدم sudo في هذا الدرس بما أنّها طريقة شائعة الاستخدام على نظام Ubuntu.

نقطة جيدة للبداية بها هي كيفية سرد قواعد iptables المُستخدمة حاليًا. يمكنك فعل هذا باستخدام الخيار -L :

$ sudo iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination 
Chain FORWARD (policy ACCEPT)
target prot opt source destination 
Chain OUTPUT (policy ACCEPT)
target prot opt source destination

كما يمكنك أن ترى، لدينا ثلاث سلاسل (chains) هنا. يمكننا أيضًا أن نرى السياسة المتّبعة في كلّ سلسلة (كل سلسلة افتراضيًا تمتلك سياسة ACCEPT للاتصالات المارّة منها). يمكننا أيضًا رؤية بعض ترويسات العواميد في ناتج الأمر السابق، إلّا أنّنا فعليًا لا نرى أيّ قواعد مطبّقة. هذا بسبب أنّ Ubuntu لا تأتي مع مجموعةٍ افتراضية من قواعد iptables.

يمكننا رؤية الخرج بصيغةٍ تعكس الأوامر الضرورية لتفعيل كلّ قاعدة وسياستها عبر استخدام الخيار -S :

$ sudo iptables -S
-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT

لإعادة إنتاج الإعدادات وتطبيقها من جديد، سيجب علينا فقط كتابة الأمر sudo iptables متبوعًا بكلّ واحدٍ من السطور الظاهرة في الخرج. (اعتمادًا على الإعدادات، قد يكون الأمر أكثر تعقيدًا في حال كنّا متّصلين عن بعد إلى الخادوم حيث أننا لا نريد إضافة قواعد iptables معيّنة تمنع جميع الاتصالات الواردة إليها مثلًا دون استثناء اتّصالنا الحالي لكي لا ينقطع فجأة ولكي يبقى متّصلًا).

إذا كان لديك قواعد بالفعل لديك في iptables وكنتَ ترغب بإتلافها والبدء من جديد، فيمكنك فعل ذلك عبر تطبيق:

$ sudo iptables -F

مرةً أخرى، سياسة قبول الاتصالات أو رفضها مهمّة هنا، لأنّه وبينما يتم حذف جميع القواعد الأخرى من السلاسل الخاصّة بك، فإنّ السياسة الافتراضية لن تتغيّر باستخدام هذا الأمر. هذا يعني أنّه في حال كنت متّصلًا عن بعد بخادومك، فإنّه يجب عليك التأكّد من أنّ السياسة الافتراضية لسلسلتيّ INPUT و OUTPUT هي ACCEPT بالتزامن مع قيامك بإتلاف قواعدك السابقة. يمكنك فعل ذلك عبر تطبيق الأوامر التاليّة:

$ sudo iptables -P INPUT ACCEPT
$ sudo iptables -P OUTPUT ACCEPT
$ sudo iptables -F

يمكنك تغيير سياسة الحظر أو الترك (drop) مجددًا إلى DROP بعد أن تقوم بإعداد القواعد التي تسمح ببقاء اتّصالك الحالي. سنفصّل كيفيّة ذلك بعد قليل.

إنشاء قاعدتك الأولى

سنبدأ ببناء سياسة جدار الحماية الخاصّ بن حول قبول أو رفض الاتصالات. كما قلنا أعلاه، فإنّنا سنعمل مع سلسلة INPUT بما أنّها المصدر الرئيسي لتدفّق الزوار القادم إلى خادومنا. سنبدأ مع القاعدة التي تحدّثنا عنها مسبقًا من قبل بالأعلى: القاعدة التي تسمح لنا بشكل خاص بمتابعة اتّصال SSH الحالي.

القاعدة الكاملة التي نحتاج إليها هي هذه:

$ sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

قد يبدو هذا معقّدا للغاية لك في الوهلة الأولى، إلّا أنّ معظم مكوّنات الأمر السابق ستكون ذات معنى بالنسبة لك عندما تفهمها:

  • -A INPUT: يقوم الخيار -A بإضافة قاعدةٍ ما إلى نهاية السلسلة المطلوبة. هذا هو الجزء الذي يقوم بإخبار iptables بأنّنا نريد إضافة قاعدةٍ جديدة إلى سلسلة معيّنة، والسلسلة التي نريدها في مثالنا حاليًا هي سلسلة INPUT.

  • -m conntrack: يمتلك iptables عدّة وظائف داخليّة، ولكنّه أيضًا يمتلك مجموعةً من الامتدادات والوحدات التي تقوم بتوفير مزايا إضافيّة. إنّنا نقوم في هذا الجزء من الأمر بإخبار iptables بأنّنا نريد الحصول على إذن بالوصول إلى الوظيفة التي يتم توفيرها عبر الوحدة المسماة "conntrack”. تعطينا هذه الوحدة وصولًا إلى الأوامر التي يمكن أن يتم استخدامها بناءً على علاقة حزمة البيانات الداخلة بالاتّصال السابق.

  • --ctstate: هذا واحدٌ من الأوامر التي أصبحت متوفّرة بعد أن تم استدعاء وحدة "conntrack”. يسمح لنا هذا الأمر بمطابقة حزم البيانات بناءً على ماهيّة ارتباطها بحزم البيانات التي رأيناها من قبل. إننا نقوم بتمرير قيمة ESTABLISHED للسماح بمرور حزم البيانات الداخلة التي هي جزء من اتّصالٍ عاملٍ حاليًا فقط. ونقوم بتمرير قيمة RELATED للسماح بمرور حزم البيانات المرتبطة باتّصالٍ مُنشَئٍ بالفعل. هذا الجزء من القاعدة هو الجزء الذي يتطابق مع جلسة SSH الحالية الخاصّة بنا.

  • -j ACCEPT: يقوم هذا الخيار بتحديد هدف مطابقة حزم البيانات. هنا، نقوم بإخبار iptables أنّ حزم البيانات التي تطابق القاعدة السابقة يجب أن يتم السماح لها بالمرور.

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

يمكننا الآن رؤية حالة التغييرات التي قمنا بها عن طريق:

$ sudo iptables -L

Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED

Chain FORWARD (policy ACCEPT)
target prot opt source destination

Chain OUTPUT (policy ACCEPT)
target prot opt source destination

الآن وبعد أن صرتَ تعرف الصياغة العامّة لقواعد iptables، فلنتابع عبر استعراض المزيد من الحالات التي سنحتاج فيها إلى قبول الاتّصالات.

قبول الاتّصالات المهمّة الأخرى

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

نريد إبقاء منفذين اثنين مفتوحين بالتحديد. نريد إبقاء منفذ اتّصال SSH الخاصّ بنا مفتوحًا (سنفترض في هذا الدرس أنّ المنفذ الافتراضي له هو المنفذ 22. إذا كنتَ غيّرت هذا المنفذ على خادومك من إعدادات SSH فقم بتعديل قيمته هنا). سنقوم أيضًا بافتراض أنّ هذا الحاسوب يقوم أيضًا بتشغيل خادوم ويب يعمل على المنفذ 80. إذا لم يكن هذا هو نفس الوضع بالنسبة لك فلن تحتاج تطبيق القاعدة التالية.

السطران اللذان سنستعملهما لتطبيق هذه القواعد هما:

sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT

كما يمكنك أن ترى، هذه القواعد مشابهة جدًا لقاعدتنا الأولى التي كتبناها، ولكنها ربما تكون أكثر بساطةً. الخيارات الجديدة هي:

  • -p tcp: يقوم هذا الخيار بمطابقة حزم البيانات في حال كان البروتوكول المستخدم هو TCP. هذا البروتوكول هو بروتوكولٌ مستخدم بواسطة معظم التطبيقات لأنّه يسمح بتواصلٌ مرن وقوي بين المستخدم والتطبيق.

  • --dport: يكون هذا الخيار متوفّرًا للاستخدام فقط في حال كان الخيار -p tcp موجودًا في الأمر. إنّه يقوم أيضًا بتحديد رقم المنفذ الذي يجب مطابقة حزم البيانات عبره. تقوم القاعدة الأولى بمطابقة حزم البيانات المارّة عبر بروتوكول TCP بالمنفذ 22، بينما تقوم الثانية بمطابقتها عبر المنفذ 80.

هناك قاعدة ACCEPT أخرى يجب علينا التأكّد من أنّ خادومنا يقبلها بشكل صحيح. غالبًا، تتواصل الخدمات (services) مع بعضها البعض على الحاسوب عبر إرسال حزم بياناتٍ فيما بينها، وهي تقوم بذلك عبر الاستفادة من واجهة شبكةٍ زائفة تدعى loopback device ، والتي تقوم بتوجيه التدفّق إلى نفسها عوضًا عن الأجهزة الأخرى.

لذا إذا كانت واحدة من الخدمات تريد التواصل مع خدمةٍ أخرى تستمع إلى المنفذ 4555، فإنّه بمقدورها إرسال حزمة بيانات إلى المنفذ 4555 على الشبكة الزائفة loopback device. نريد أن يتم السماح بهذا النوع من السلوك بين الخدمات لأنّه ضروري للعديد من برامج نظام التشغيل.

القاعدة التي نحتاج تطبيقها هي هذه:

$ sudo iptables -I INPUT 1 -i lo -j ACCEPT

يبدو هذا الأمر مختلفًا قليلًا عن الأوامر السابقة. فلنشرح ما يفعله:

  • -I INPUT 1: يقوم الخيار -I بإخبار iptables بإدراج قاعدةٍ جديدة. هذا الخيار مختلف عن الخيار -A والذي يقوم بإضافة القاعدة الجديدة إلى نهاية قواعد iptables. يحتاج الخيار -I إلى اسم السلسلة والمكان الذي تريد إدراج القاعدة الجديدة فيه.

في حالتنا، فإننا نقوم بإضافة هذه القاعدة كأول قاعدة في سلسلة INPUT. هذا سيدفع بقية القواعد إلى الأسفل بدرجةٍ واحدة تلقائيًا. نحتاج لهذه القاعدة أن تكون بالأعلى لأنّها أساسية ولا يجب أن يتم التأثير عليها عبر قواعد فرعيّة أخرى.

  • -i lo: يقوم هذا المكوّن من القاعدة بمطابقة ما إذا كانت الواجهة التي تستخدمها حزمة البيانات هي واجهة "lo”. واجهة "lo” هي عبارة عن اسمٍ آخر لـloopback device. هذا يعني أنّ أيّ حزمةِ بياناتٍ تستعمل تلك الواجهة الشبكيّة للتواصل (حزم البيانات الناتجة في خادومنا، إلى خادومنا) يجب أن يتم قبولها من طرف iptables.

لرؤية قواعدنا الحاليّة، يجب أن نستخدم الخيار -a . هذا بسبب أنّ الخيار -L لا يتضمّن بعض المعلومات، مثل اسم الواجهة المرتبطة بالقواعد، والذي يعتبر جزءًا مهمًّا في القاعدة التي قمنا بإضافتها:

$ sudo iptables -S

-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT

تضمين قاعدة حظر (Drop)

نمتلك الآن 4 قواعد منفصلة تقبل الاتصالات بناءً على معايير معيّنة. وبالرغم من ذلك، فإنّا خادومنا حاليًا لا يحظر وصول أيّ شيء إليه.

إذا دخلت حزمة بياناتٍ إلى سلسلة INPUT ولم تكن مطابقة لأيٍّ من القواعد الأربعة التي أدخلناها، فإنّه سيتم تحويلها إلى السياسة الافتراضية للتعامل مع حزم البيانات، والتي هي حاليًا "قبول حزم البيانات جميعها"، ونحتاج لتغيير هذا الأمر.

هناك طريقتان يمكننا فعل ذلك بهما، مع بعض الاختلافات الجوهرية.

الطريقة الأولى التي يمكننا من خلالها القيام بهذا هي عن طريق تعديل السياسة الافتراضية لسلسلة INPUT. يمكننا القيام بذلك عبر كتابة:

$ sudo iptables -P INPUT DROP

ستقوم القاعدة السابقة بالتقاط أيّ حزم بياناتٍ تفشل بالمرور عبر سلسلة INPUT الخاصّة بنا ويمنع وصولها إلى الخادوم. هذا ما ندعوه بسياسة المنع الافتراضيّة (default drop policy)، من مساوئ هذه الطريقة هي أنّ قاعدة الـDROP هذه يتم إلغاؤها في حال تم مسح قواعد iptables (حيث أنّها قاعدة هي الأخرى وبالتالي سيتم مسحها معها).

قد تكون هذه الطريقة أكثر أمنًا، ولكنك قد تواجه عواقب وخيمة في حال لم يكن لديك طريقةٌ أخرى للوصول إلى خادومك. في DigitalOcean، يمكنك الولوج عبر لوحة التحكّم إلى خادومك والوصول إلى طرفيّة ويب تمكّنك من التحكّم به إذا حصل هذا. طرفيّة الويب هذه تعرّف نفسها على أنّها اتصال وهمي محلّي ولذلك فإنّ قواعد iptables لا تؤثّر عليها.

قد تودّ لخادومك أن يقوم بحظر جميع الاتصالات في حال مسح جميع القواعد. قد يمنع هذا من ترك خادومك مفتوحًا للجميع. وهذا يعني أيضًا أنّه بمقدورك بسهولة إضافة القواعد إلى نهاية أيّ سلسلة تريدها بينما تحظر حزم البيانات التي لا تريدها بسهولة.

إذا قمتَ بتغيير السياسة الافتراضيّة لسلسلة INPUT، فإنّه يمكنك إرجاعها عبر تطبيق:

$ sudo iptables -P INPUT ACCEPT

الآن، يمكنك إضافة قاعدة إلى نهاية السلسلة والتي ستقوم بحظر أيّ حزم بياناتٍ متبقية:

$ sudo iptables -A INPUT -j DROP

النتائج تحت شروطٍ تشغيلية عادية ستكون بالضبط هي نفس سياسة الحظر الافتراضيّة. تعمل هذه القاعدة عبر مطابقة كلّ حزمة بياناتٍ متبقية تصل إليها. يمنع هذا حزمةَ البيانات من الوصول إلى الخادوم في حال فشلت بتجاوز القواعد السابقة التي قمنا بإنشائها.

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

بالطبع، هذا يعني أيضًا أنّ أيّ قاعدةٍ إضافية تودّ إضافتها إلى نهاية السلسلة يجب أن تكون قبل قاعدة الحظر أو الـdrop. يمكنك فعل هذا عبر حذف قاعدة الحظر مؤقتًا عبر:

$ sudo iptables -D INPUT -j DROP
$ sudo iptables -A INPUT new_rule_here
$ sudo iptables -A INPUT -j DROP

أو، يمكنك إدراج القواعد التي تحتاجها في نهاية السلسلة (ولكن قبل قاعدة الـdrop) عبر تحديد رقم السطر. لإدراج قاعدةٍ في السطر رقم 4، يمكنك كتابة:

$ sudo iptables -I INPUT 4 new_rule_here

إذا كنتَ تواجه مشاكل في معرفة إلى أيّ سطرٍ تنتمي أيّ قاعدة، فيمكنك إخبار iptables بأن يقوم بسرد السطور المتوفّرة عبر:

$ sudo iptables -L –line-numbers
Chain INPUT (policy DROP)
num target prot opt source destination
1 ACCEPT all -- anywhere anywhere
2 ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED
3 ACCEPT tcp -- anywhere anywhere tcp dpt:ssh
4 ACCEPT tcp -- anywhere anywhere tcp dpt:http

Chain FORWARD (policy ACCEPT)
num target prot opt source destination

Chain OUTPUT (policy ACCEPT)
num target prot opt source destination

يمكن لهذا أن يكون مفيدًا للتأكّد من أنّك تضيف القاعدة إلى مكانها الصحيح.

حفظ إعدادات iptables الخاصّة بك

افتراضيًا، تكون القواعد التي تضيفها إلى iptables غير دائمة. هذا يعني أنّك عندما تقوم بإعادة تشغيل خادومك، فإنّ جميع قواعد iptables ستختفي.

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

هناك عدّة طرق لفعل هذا، لكنّ أسهلها هو باستخدام حزمة iptables-presistent، يمكنك تحميل هذه الحزمة من مستودعات Ubuntu الافتراضيّة:

$ sudo apt-get update
$ sudo apt-get install iptables-persistent

أثناء التثبيت، سيتم سؤالك عمّا إذا كنتَ تحبّ حفظ قواعد iptables الحاليّة ليتم تحميلها تلقائيًا. إذا كنتَ مسرورًا مع إعداداتك الحاليّة (واختبرت قدرتك على الوصول إلى اتصالات SSH جديدة مستقلة) فإنّه يمكنك الموافقة على ذلك.

سيتم سؤالك أيضًا عمّا إذا كنتَ تريد حفظ قواعد IPv6 التي قمتَ بإعدادها، يتم إعداد هذه القواعد عبر أداة منفصلة تدعى ip6tables والتي تتحكم بحزم بيانات IPv6 بنفس الطريقة.

بمجرّد اكتمال التثبيت، ستتوفر خدمة جديدة لديك تدعى iptables-presistent وهي مُعدّة ليتم تشغيلها عند الإقلاع. ستقوم هذه الخدمة بتحميل قواعد iptables الحاليّة وتطبيقها من جديد في كلّ مرّة يتم إعادة تشغيل النظام فيها.

الخاتمة

يجب أن تكون الآن قد امتلكت نقطة بداية جيّدة للبدء في تطوير جدارٍ ناري يلبي احتياجاتك. هناك العديد من أدوات الجدران الناريّة الأخرى التي يمكنك استخدامها والتي قد تكون أسهل، ولكن iptables أداةٌ جيّدة لتعلّمها، ذلك لأنّها توفّر بنية netfilter تحتية جيّدة للاستعمال ولأنّها متوفّرة افتراضيًا في العديد من أنظمة التشغيل.

ترجمة -وبتصرّف- للمقال: How To Set Up a Firewall Using IPTables on Ubuntu 14.04.



2 اشخاص أعجبوا بهذا


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




يجب أن تكون عضوًا لدينا لتتمكّن من التعليق

انشاء حساب جديد

يستغرق التسجيل بضع ثوان فقط


سجّل حسابًا جديدًا

تسجيل الدخول

تملك حسابا مسجّلا بالفعل؟


سجّل دخولك الآن