وقتی هنگام استفاده از توزیع های لینوکس اسم از فایروال میاد همیشه اولین مواردی که به ذهن همه میرسه ufw(debian base) و firewalld(RedHat base) هست. این دو interface ها یا رابطهایی برای کاربر هستن که اجازه بررسی و مدیریت شبکه رو به کاربر میدن.
میدونیم که توی توزیعهای مختلف لینوکس کرنلها یکی هستن و فایروال اصلی که مستقیم با کرنل در ارتباط هست IPTABLES هست و موارد بالا فقط یک رابط برای آسانتر شدن درک دستورات و به نوعی user friendly بودن اون به وجود اومدن. حقیقت اینه که اگر نیازهای ما یک مقدار از موارد پایه و basic جلوتر بره ناچار به استفاده از iptables هستیم و یکم جلوتر باهم میبینیم که اتفاقا بعد از فهمیدنش خیلی راحت به مواردی که نیاز داریم میرسیم. توی این مجموعه مطلب قصد داریم بهصورت کاربردی با iptables آشنا بشیم و همزمان با درک مفاهیم از اونها استفاده کنیم.
اگه خیلی ساده بخوایم نگاه کنیم؛ iptables یک سری جدول از قوانین داره که توی موقعیتهای مختلف میاد و اونها رو بررسی میکنه؛ مثلا وقتی یه packet به interface شبکه ما میرسه(INPUT)؛ iptables میره و جدول قانون هایی که برای ورود به شبکه تعریف شده رو بررسی میکنه یا مثلا وقتی یه packet قراره از شبکه ما خارج بشه میره و قوانین که توی جدول خروجی (OUTPUT) وضع شده رو بررسی میکنه و اگه همه اونها رعایت شده بود اجازه خروج رو به packet مورد نظر میده.
برای وضع یک قانون مشخصا یک سری متغیر داریم که بسته به شرایط و جدولی که مدنظرمون هست فرق میکنن. اینجا ما قصد ایجاد rule برای پکت های ورودی رو داریم پس باید چندتا مورد رو بررسی کنیم:
-هر درخواستی برای پورت ۴۴۳ اومد رو DROP کن.
-اگه درخواستی برای پورت ۴۴۳ اومد و آدرس مبدا اون x.x.x.x بود رو ACCEPT کن.
توی این موقعیت هیچ درخواستی برای پورت ۴۴۳ قبول نمیشه چون اول قانون اول بررسی میشه و همونجا همشون DROP میشن و عملا کار به دستور بعدی نمیرسه. برای همین همیشه اول مواردی که نیاز داریم رو ACCEPT میکنیم و بعد از همه مواردی که نیاز نداریم رو DROP میکنیم.
حالا میخوایم باهم دیگه مثلا پورت ۴۴۳ رو فقط برای آیپی ۱۰.۱۰.۱۰.۱۰ باز بذاریم و هر درخواستی از این آدرس اومد رو قبول کنیم:
طبق چیزی که گفتیم اول میایم و درخواست هایی که قراره ACCEPT بشن رو قبول میکنیم:
iptables -I INPUT 1 -p tcp -s 10.10.10.10 --dport 443 -j ACCEPT
iptables -I (جدول مورد نظر و جایگاه قانون) -p (پروتکل) -s (آدرس مبدا) --dport(پورت مقصد در پکت) -j (دستورالعمل)
بعد از اون میایم و هر پکتی که با پورت ۴۴۳ کار داشت رو رد میکنیم
iptables -I INPUT 2 -p tcp --dport 443 -j DROP
به همین سادگی :)
شاید خیلی جاها ببینید بجای -I از -A استفاده میکنن که به معنی Append هست و دیگه نیاز به شماره جایگاه نیست و خودش به آخر جدول اضافه میکنه. حالا میخوایم چک کنیم ببینیم دستوراتمون درست ذخیره شدن یا نه:
iptables -nL --line-numbers
با این دستور همه جدولها همراه با شماره گذاریشون نشون داده میشن.
اگه بخوایم مثلا قانون شماره دوم رو حذف کنیم:
iptables -D INPUT 2
iptables -D (DELETE) (Table with Rule number)
تصور کنید بخوایم برای ssh که روی پورت ۲۲ معمولا اجرا میشه قانون تنظیم کنیم. واضحه که ورودی مثل ۴۴۳ هست ولی از اونجایی که ssh دو طرفه هست و هر درخواست نیاز به پاسخ روی همون پورت داره پس ما باید توی جدول خروجی هم تنظیم کنیم که هر درخواستی از سرور ما به آدرس مورد نظر خواست بره اجازه خروج داره. نکته قابل توجه این هست که باید درنظر بگیریم پکت مورد نظر داره از پورت ۲۲ (Source port) خارج میشه و آدرس مقصدش (Destination) آدرس مدنظر ماست. پس داریم:
iptables -I OUTPUT 1 -p tcp -d 10.10.10.10 --sport 22 -j ACCEPT
iptables -I OUTPUT 2 -p tcp --sport 22 -j DROP
اینجا ما تنظیم کردیم هرکسی قصد خروج از سرور با پورت ۲۲ داره و آدرس مقصدش ۱۰.۱۰.۱۰.۱۰ هست اجازه خروج داره و بعدش خروج همه پکت ها از پورت ۲۲ رو ممنوع کردیم.
لازم به ذکر هست برای کار روی محیط Production نیاز به پرداختن به جزئیات بیشتری مثل فرق DROP و REJECT هست ولی برای درک اولیه موارد بالا کفایت میکنن.
در مطالب بعدی سعی میکنیم درمورد ساختن جدول ها و اساسا مفهموم CHAIN بیشتر صحبت کنیم. راجع به تعامل داکر با iptables؛ و همچین درمورد جزئیات دستورات؛ آپدیت کردن قوانین؛ تنظیم رنج آدرس؛ دیباگ کردن قوانین و کلی موارد دیگه که روی محیط Production باید رعایت بشن.
ممنون از همراهیتون.