آموزش تنظیمات firewalld در Rocky Linux و AlmaLinux
با نحوه مدیریت پورتها در firewalld برای Rocky و AlmaLinux آشنا شوید. یاد بگیرید چگونه با استفاده از فلگ --permanent از حذف قوانین پس از ریبوت جلوگیری کرده و SSH را ایمن کنید.
firewalld چیست و چرا Rocky و AlmaLinux آن را ارائه میدهند
firewalld مدیر فایروالی است که بهصورت پیشفرض روی Rocky Linux، AlmaLinux و سایر توزیعهای مبتنی بر Red Hat Enterprise Linux (RHEL) نصب میشود. این ابزار خود به بررسی مستقیم بستهها نمیپردازد، بلکه یک پیکربندی ذخیرهشده را نگهداری کرده و آن را به قوانین nftables تبدیل میکند. با استفاده از دستور firewall-cmd، میتوانید بدون نیاز به آفلاین کردن سرور، پیکربندی را ویرایش کنید.
اگر پیشتر با نحوه عملکرد ufw در Ubuntu VPS آشنا هستید، وظیفه این ابزار را میدانید. firewalld دو مفهوم اضافه دارد که در ufw وجود ندارند. اولی «ناحیهها» (zones) است: یک سیاست نامگذاریشده که بستهها بر اساس آن دستهبندی میشوند. دومی، تفکیک بین قوانین فعال (live) و قوانین ذخیرهشده (saved) است که با فلگ --permanent کنترل میشود و بزرگترین منبع سردرگمی در این ابزار است.
تمام موارد زیر دستوراتی هستند که باید روی سرور خود اجرا کنید. هر تغییر را از یک ماشین دوم تست کنید، زیرا قانونی که روی خود سرور درست به نظر میرسد، ممکن است از سمت اینترنت اشتباه باشد.
پیش از هر اقدام دیگری، SSH را باز کنید
بیشتر نصبهای Rocky و AlmaLinux بهصورت پیشفرض دارای firewalld هستند و پیکربندی ارائهشده در آن، اجازه دسترسی SSH را میدهد. برخی از ایمیجهای حداقلی (minimal) ابری، این سرویس را حذف میکنند. بهجای فرض کردن، وضعیت را بررسی کنید.
sudo dnf install -y firewalld
sudo systemctl enable --now firewalld
sudo firewall-cmd --statefirewall-cmd --state وضعیت running را چاپ میکند. اگر سرویس متوقف باشد، هر فراخوانی دیگر firewall-cmd پاسخ FirewallD is not running را برمیگرداند و با کد خروجی غیر صفر خارج میشود. این اولین موردی است که هنگام بینتیجه بودن یک دستور باید بررسی کنید.
اکنون آنچه در حال حاضر مجاز است را بخوانید.
sudo firewall-cmd --list-allخروجی واقعی شامل چند خط بیشتر است. این موارد همانهایی هستند که اهمیت دارند:
public (active)
target: default
interfaces: eth0
sources:
services: cockpit dhcpv6-client ssh
ports:
rich rules:وجود ssh در خط services: دلیل فعال ماندن نشست (session) شماست. اگر این مورد وجود ندارد، پیش از دست زدن به هر تنظیم دیگری آن را اضافه کنید؛ زیرا راهاندازی فایروال بدون قانون SSH، نشست شما را قطع کرده و اجازه ورود مجدد نمیدهد.
sudo firewall-cmd --permanent --add-service=ssh
sudo firewall-cmd --reloadtarget: default به این معنی است که بستهای که با هیچ قانونی مطابقت ندارد، با یک پاسخ ICMP (پروتکل پیام کنترل اینترنت) از نوع host-prohibited رد میشود؛ بنابراین کلاینتی که به یک پورت بسته متصل میشود، بلافاصله No route to host را دریافت میکند. تنظیم هدف (target) روی DROP باعث میشود سرور در عوض سکوت کند و در نتیجه اسکنرها منتظر timeout میمانند.
sudo firewall-cmd --permanent --zone=public --set-target=DROP
sudo firewall-cmd --reloadپیش از اجرای آن، هزینه این کار را بدانید: DROP همچنین باعث میشود سرور به ping پاسخ ندهد، بنابراین سیستم مانیتورینگ خودتان نیز خاموش میشود.
چرا قانون من ناپدید شد؟ پرچم --permanent
ابزار firewalld همزمان دو پیکربندی را نگهداری میکند. پیکربندی runtime همان چیزی است که هسته سیستمعامل در همین لحظه اعمال میکند. پیکربندی permanent همان چیزی است که در /etc/firewalld/zones/public.xml ذخیره شده و پس از reload یا reboot دوباره بارگذاری میشود.
دستوری که بدون --permanent اجرا شود، فقط پیکربندی runtime را تغییر میدهد. این تغییر بلافاصله اعمال میشود اما با reload یا reboot بعدی از بین میرود. دستوری که با --permanent اجرا شود، فایل را تغییر میدهد اما تأثیری بر وضعیت جاری ندارد؛ بنابراین پورت تا زمانی که reload نکنید، بسته میماند. هیچکدام از این رفتارها باگ نیستند. هر دو مورد باعث تعجب کاربران میشوند، زیرا دستور در هر دو حالت پیام success را نمایش میدهد.
همیشه هر دو را با هم بنویسید.
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --reloadشما میتوانید هر دو پیکربندی را مشاهده کنید؛ این سریعترین راه برای تشخیص این است که کدامیک از دو اشتباه بالا را مرتکب شدهاید.
sudo firewall-cmd --list-services
sudo firewall-cmd --permanent --list-servicesدستور اول مجموعه قوانین فعال را نمایش میدهد. دستور دوم مجموعه قوانین ذخیرهشده را نشان میدهد. اگر مجموعه فعال شامل سرویسی باشد که در مجموعه ذخیرهشده نیست، آن قانون با reload بعدی حذف میشود. اگر مجموعه ذخیرهشده شامل سرویسی باشد که در مجموعه فعال نیست، شما فراموش کردهاید reload کنید. دستور sudo firewall-cmd --runtime-to-permanent تمام تنظیمات فعال را در فایل ذخیرهشده کپی میکند که پس از یک جلسه آزمایش، بسیار مفید است.
دستور --reload وضعیت رهگیری اتصالات (connection tracking) را حفظ میکند، بنابراین نشست SSH شما قطع نمیشود. دستور --complete-reload ماژولهای هسته را نیز دوباره بارگذاری میکند و آن وضعیت را از دست میدهد، که معمولاً باعث قطع شدن تمام اتصالات باز از جمله اتصال شما میشود. از همان reload ساده استفاده کنید.
یک لایه امنیتی داخلی وجود دارد. یک قانون runtime میتواند بهطور خودکار منقضی شود.
sudo firewall-cmd --add-service=http --timeout=5mاین قانون پس از پنج دقیقه خودبهخود حذف میشود. این قابلیت با --permanent قابل ترکیب نیست و هدف همین است: این دستور برای آزمایش تغییری که از آن مطمئن نیستید، کاربرد دارد. روش امنیتی قدیمیتر بهتر است. همیشه یک نشست SSH دوم باز نگه دارید تا در حین ویرایش قوانین، اگر دسترسی شما قطع شد، بتوانید آن را اصلاح کنید؛ تا زمانی که با یک ورود (login) جدید مطمئن نشدهاید که قوانین جدید کار میکنند، نشست دوم را نبندید.
زونها و دلیل اهمیت زون پیشفرض در VPS
زون (Zone) مجموعهای نامگذاریشده از مجوزها با یک سطح اعتماد مشخص است. firewalld هر بسته ورودی را دقیقاً در یک زون قرار میدهد. این ابزار ابتدا آدرس مبدأ بسته را با لیست sources: هر زون تطبیق میدهد. اگر هیچ تطابقی پیدا نشود، از زونی استفاده میکند که اینترفیس ورودی به آن متصل است. اگر اینترفیس به هیچ زونی متصل نباشد، بسته به زون پیشفرض هدایت میشود.
sudo firewall-cmd --get-default-zone
sudo firewall-cmd --get-active-zonesدر یک VPS با تنها یک اینترفیس شبکه، پاسخ اول تقریباً همیشه public است و این تنها زونی است که شما از آن استفاده خواهید کرد. دستور firewall-cmd بدون آرگومان --zone= روی زون پیشفرض عمل میکند؛ به همین دلیل است که تمام دستورات کوتاه در این راهنما بدون نیاز به نام بردن زون کار میکنند.
خطایی که باعث هدر رفتن وقت میشود این است: اگر اینترفیس به زون دیگری متصل باشد، قوانین شما در public ثبت میشوند در حالی که ترافیک در جای دیگری پردازش میشود؛ بنابراین هر چه اضافه کنید بیاثر خواهد بود و هیچ هشداری هم دریافت نمیکنید. دستور --get-active-zones اتصال را نشان میدهد:
public
interfaces: eth0اگر اینترفیس تحت نام زون متفاوتی ظاهر شد، یا قوانین خود را با --zone= در آنجا بنویسید، یا اینترفیس را جابهجا کنید.
sudo firewall-cmd --permanent --zone=public --change-interface=eth0
sudo firewall-cmd --reloadNetworkManager اینترفیسها را در Rocky و AlmaLinux مدیریت میکند و هنگام بالا آمدن اتصال، زون را مجدداً اعمال میکند. زون را در آنجا نیز تنظیم کنید تا با reboot، تنظیمات شما از بین نرود. نام اتصال را از دستور اول بردارید، زیرا بهندرت با نام دستگاه یکی است.
sudo nmcli connection show
sudo nmcli connection modify "System eth0" connection.zone publicتطبیق بر اساس مبدأ (Source matching) بر تطبیق بر اساس اینترفیس اولویت دارد؛ این همان روشی است که یک آدرس خاص، سیاست متفاوتی دریافت میکند. زون داخلی trusted همه چیز را میپذیرد.
sudo firewall-cmd --permanent --zone=trusted --add-source=203.0.113.10/32
sudo firewall-cmd --reloadدر استفاده از آن دقت کنید. این زون تمام پورتهای سرور را برای آن آدرس باز میکند، از جمله دیتابیسی که تصور میکردید خصوصی است. زمانی که فقط یک پورت را نیاز دارید، نه یک میزبان کامل، از rich rule استفاده کنید.
سرویس در firewalld چیست؟
یک سرویس، مجموعهای نامگذاریشده از پورتهاست که در قالب یک فایل XML ارائه میشود. --add-service=https پورت 443/tcp را باز میکند، زیرا /usr/lib/firewalld/services/https.xml تعریف میکند که https به چه معناست.
sudo firewall-cmd --get-services
sudo firewall-cmd --info-service=https--info-service پورتهایی را که پشت این نام پنهان شدهاند، نمایش میدهد:
https
ports: 443/tcpهرگاه نامی برای یک سرویس وجود دارد، از همان استفاده کنید. این کار باعث میشود که --list-all پس از شش ماه همچنان خوانا باشد و بستههایی مانند Cockpit فایل سرویس اختصاصی خود را نصب میکنند. برای هر چیزی که تعریف مشخصی ندارد، از --add-port استفاده کنید.
شکافی که باید مراقب آن باشید: سرویس ssh فقط به معنای 22/tcp است و هیچ چیز دیگری را شامل نمیشود. اگر طبق ایمنسازی دسترسی SSH روی سرور، پورت SSH را تغییر دادهاید، --add-service=ssh پورتی را که واقعاً استفاده میکنید، باز نخواهد کرد.
sudo firewall-cmd --permanent --add-port=2222/tcp
sudo firewall-cmd --reloadدر توزیعهای مبتنی بر RHEL، قفل دومی نیز روی این در وجود دارد. SELinux (لینوکس با امنیت ارتقایافته) شماره پورتها را برچسبگذاری میکند و sshd اجازه ندارد به پورتی خارج از برچسبهای خود متصل شود (bind شود). در این صورت، سرویس از اجرا امتناع میکند و لاگ خطای error: Bind to port 2222 on 0.0.0.0 failed: Permission denied. را نشان میدهد. ابتدا باید پورت را برچسبگذاری کنید.
sudo dnf install -y policycoreutils-python-utils
sudo semanage port -a -t ssh_port_t -p tcp 2222چگونه میتوانم ببینم در حال حاضر چه چیزی باز است؟
sudo firewall-cmd --list-all
sudo firewall-cmd --list-rich-rules
sudo nft list table inet firewalld | head -n 40دو دستور اول گزارش میدهند که firewalld چه وضعیتی را در نظر دارد. دستور سوم قوانینی را میخواند که هسته (kernel) واقعاً در جدول متعلق به firewalld اعمال کرده است. این موارد باید با هم مطابقت داشته باشند.
هیچکدام از اینها مدرک قطعی نیستند. تست را از یک ماشین دیگر انجام دهید:
nc -zv 203.0.113.20 443تست را روی خود سرور اجرا نکنید. firewalld تمام ترافیک ورودی به رابط loopback را میپذیرد، بنابراین curl http://localhost:8080 فارغ از اینکه قوانین شما چه باشند، با موفقیت انجام میشود. این تست فقط به شما میگوید که سرویس فعال است و هیچ اطلاعاتی درباره وضعیت فایروال به شما نمیدهد.
مجاز کردن یک پورت وب
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload
sudo firewall-cmd --list-servicesدستور آخر اکنون باید http https را در کنار موارد قبلی فهرست کند. اگر سایت همچنان پاسخ نمیدهد، مشکل احتمالاً از فایروال نیست. یک قانون فقط اجازه عبور بسته را میدهد. یک پردازش همچنان باید برای دریافت آن در حال گوش دادن (listening) باشد.
sudo ss -tlnpسوکتی که به صورت 0.0.0.0:443 یا *:443 نمایش داده میشود، اتصالات را از هر آدرسی میپذیرد. سوکتی که به صورت 127.0.0.1:443 نمایش داده میشود، فقط روی loopback پاسخ میدهد و هیچ قانون فایروالی نمیتواند آن را از خارج قابل دسترس کند. پورتها و سوکتهای در حال گوش دادن در لینوکس این تفاوت را با جزئیات بیشتری بررسی میکند.
چگونه میتوانم دوباره یک پورت را ببندم؟
sudo firewall-cmd --permanent --remove-service=http
sudo firewall-cmd --reloadقانون --permanent در اینجا نیز صدق میکند و در این جهت، تأثیر آن جدیتر است. اگر سرویسی را فقط از محیط runtime حذف کنید، پورت بسته به نظر میرسد، اما با reload یا reboot بعدی، تنظیمات از فایل ذخیرهشده دوباره بارگذاری شده و پورت باز میشود. این حفرهای است که متوجه آن نخواهید شد، زیرا بررسی شما با موفقیت انجام شده است.
حذف موردی که اصلاً وجود نداشته است، پیام Warning: NOT_ENABLED: http را چاپ میکند و همچنان با کد خروج 0 پایان مییابد. افزودن یک مورد تکراری نیز پیام Warning: ALREADY_ENABLED: http را در پی دارد. هر دو حالت ایمن هستند. اشتباه تایپی در نام سرویس متفاوت است: Error: INVALID_SERVICE به این معنی است که firewalld هیچ تعریفی با آن نام ندارد و هیچ تغییری اعمال نشده است.
اگر در --list-all خود عبارت cockpit را مشاهده میکنید و از کنسول وب Cockpit روی پورت 9090 استفاده نمیکنید، آن را حذف کنید. هر پورت باز، سرویسی است که باید آن را بهروز و امن نگه دارید.
محدود کردن یک پورت به یک آدرس مبدأ
قوانین Rich برای زمانی که یک نام سرویس ساده نمیتواند منظور شما را بیان کند، به کار میروند. محدود کردن SSH به یک آدرس اداری خاص، نیازمند دو دستور است و دومی همان دستوری است که معمولاً فراموش میشود.
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="203.0.113.10/32" service name="ssh" accept'
sudo firewall-cmd --permanent --remove-service=ssh
sudo firewall-cmd --reloadیک zone مجموعهای از مجوزهاست، نه یک لیست شمارهگذاریشده که با اولین تطبیق متوقف شود. قانون Rich یک مجوز accept برای یک آدرس خاص اضافه میکند. این قانون هیچکس را رد (deny) نمیکند. تا زمانی که ssh در خط services: وجود دارد، کل اینترنت همچنان به پورت 22 دسترسی دارد و قانون Rich هیچ تغییر قابلاندازهگیری ایجاد نمیکند. ورودی کلی را حذف کنید، در غیر این صورت قانون محدودکننده فقط جنبه تزئینی خواهد داشت.
برای پورتی که نام سرویس ندارد، به جای آن از شماره پورت استفاده کنید.
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="203.0.113.10/32" port port="5432" protocol="tcp" accept'برای مسدود کردن (drop) یک شبکه مزاحم و ثبت گزارش آن، عنصر log را پیش از action قرار دهید؛ این همان ترتیبی است که زبان قوانین Rich انتظار دارد.
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="198.51.100.0/24" log prefix="fw-drop " level="info" limit value="3/m" drop'
sudo firewall-cmd --reload
sudo journalctl -k -g fw-dropمقدار limit از پر شدن journal توسط سیل بستههای شبکه جلوگیری میکند. پیش از آنکه دسترسی SSH را به یک آدرس واحد محدود کنید، مطمئن شوید که آن آدرس ثابت است. یک اتصال خانگی با IP متغیر، در روزی که IP تغییر کند شما را از سرور بیرون میاندازد؛ بنابراین ابتدا دسترسی کنسول ارائهدهنده خدمات خود را تست کنید و از عملکرد آن مطمئن شوید.
دستورات ufw و معادلهای آنها در firewall-cmd
وظایف یکسان، ابزار متفاوت. هر خط --permanent به یک sudo firewall-cmd --reload در ادامه نیاز دارد، که این تنها نکتهای است که لیستی مانند این نمیتواند به شما نشان دهد.
- دستور
sudo ufw enableبهsudo systemctl enable --now firewalldتبدیل میشود - دستور
sudo ufw disableبهsudo systemctl disable --now firewalldتبدیل میشود - دستور
sudo ufw status verboseبهsudo firewall-cmd --list-allتبدیل میشود - دستور
sudo ufw allow OpenSSHبهsudo firewall-cmd --permanent --add-service=sshتبدیل میشود - دستور
sudo ufw allow 443/tcpبهsudo firewall-cmd --permanent --add-port=443/tcpتبدیل میشود - دستور
sudo ufw delete allow 443/tcpبهsudo firewall-cmd --permanent --remove-port=443/tcpتبدیل میشود - دستور
sudo ufw allow from 203.0.113.10 to any port 22به rule غنی (rich rule) نمایش داده شده در بالا تبدیل میشود - دستور
sudo ufw reloadبهsudo firewall-cmd --reloadتبدیل میشود - دستور
sudo ufw default deny incomingدر حال حاضر رفتار زونpublicاست و--set-target=DROPنسخه بیصدای (silent) آن محسوب میشود - دستور
sudo ufw logging onبهsudo firewall-cmd --set-log-denied=allتبدیل میشود
یک تفاوت ارزش بیان صریح دارد. ufw یک لیست شمارهگذاریشده نگه میدارد و شما میتوانید یک قانون را در موقعیت 1 درج کنید. firewalld هیچ شماره قانونی ندارد، بنابراین «قرار دادن این قانون در اولویت» در اینجا معنایی ندارد. هنگامی که دو ورودی firewalld با یکدیگر در تضاد به نظر میرسند، قانون accept کلیتر پیروز میشود، زیرا هیچ چیزی در این مجموعه وجود ندارد که دسترسی را رد (deny) کند. شما باید ورودی کلیتر را خودتان حذف کنید.
چرا کانتینر Docker من در حالی که فایروال بسته به نظر میرسد، در دسترس است؟
دلیل این است که پورت منتشرشدهٔ کانتینر هرگز به بخشی از فایروال که توسط zone شما کنترل میشود، نمیرسد. docker run -d -p 8080:80 nginx به Docker دستور میدهد تا قوانین NAT (ترجمه آدرس شبکه) و forwarding اختصاصی خود را بنویسد. بستهای که به پورت 8080 میرسد، بازنویسی شده و به سمت کانتینر هدایت میشود؛ بنابراین این بسته به جای تحویل به میزبان (host)، فوروارد (forward) میشود. خطوط services: و ports: در zone شما، بستههایی را مدیریت میکنند که به خود میزبان تحویل داده میشوند. قوانین Docker مسیر فوروارد را کنترل میکنند و آنها را میپذیرند.
نتیجه، سروری است که در آن sudo firewall-cmd --list-all هیچ پورت 8080 را نشان نمیدهد، اما nc -zv 203.0.113.20 8080 از یک ماشین دیگر همچنان متصل میشود. ببینید Docker چه چیزی نصب کرده است:
sudo iptables -t nat -L DOCKER -nراه حل در استفاده از فلگ publish نهفته است. پورت را به loopback متصل کنید و یک reverse proxy در مقابل آن قرار دهید.
docker run -d -p 127.0.0.1:8080:80 nginxاکنون کانتینر به curl http://127.0.0.1:8080 روی سرور پاسخ میدهد و از بیرون هیچ پاسخی دریافت نمیشود. کاربران Ubuntu نیز با همین مشکل مواجه میشوند که در چرا کانتینرهای Docker پورتها را مستقیماً از ufw عبور میدهند توضیح داده شده است. نسخه Rootful از Podman که در مخازن پایه Rocky و AlmaLinux موجود است، پورتها را با همان رویکرد NAT منتشر میکند؛ بنابراین به جای اعتماد به لیست zone، از یک ماشین دیگر تست بگیرید.
تداوم تنظیمات پس از راهاندازی مجدد و خطاهایی که با آنها مواجه خواهید شد
sudo systemctl is-enabled firewalld
sudo systemctl status firewalldenabled و active (running) همان چیزی هستند که به آن نیاز دارید. فایروالی که در حال اجراست اما فعال (enable) نشده، تنها تا اولین راهاندازی مجدد (reboot) از شما محافظت میکند. این بررسی باید در لیستی که در ده دقیقه اول روی یک VPS جدید انجام میدهید، در کنار کلیدهای SSH و بهروزرسانیها قرار بگیرد.
دستورات خام nftables و firewalld با هم سازگار نیستند. فایروال firewalld مالک جدولی به نام inet firewalld است. دستور sudo nft flush ruleset آن را حذف میکند، در نتیجه سرور در برابر همه چیز باز میشود و firewall-cmd --list-all همچنان پیکربندی مورد نظر شما را نمایش میدهد، زیرا firewalld به جای آنچه در هسته (kernel) وجود دارد، آنچه را که تصور میکند گزارش میدهد. دستور sudo firewall-cmd --reload قوانین را دوباره نصب میکند. قوانین را با firewall-cmd بنویسید تا پس از بارگذاری مجدد (reload) باقی بمانند.
دو مدیریت فایروال روی یک سرور. نصب ufw یا iptables-services در کنار firewalld باعث میشود دو برنامه بدون اطلاع از یکدیگر شروع به نوشتن قوانین کنند و برنده کسی است که سرویسش دیرتر شروع شده باشد. یکی را انتخاب کنید. در Rocky و AlmaLinux، فایروال firewalld همان گزینهای است که توسط توزیع پشتیبانی میشود.
فایروال ارائهدهنده در مقابل سرور. بسیاری از پنلهای VPS یک فایروال شبکه جداگانه دارند. اگر --list-all نشان میدهد که یک پورت باز است اما اتصال از خارج همچنان برقرار نمیشود، پیش از تغییر هر چیزی در سرور، پنل را بررسی کنید. این موضوع برعکس هم صادق است: یک قانون باز در پنل تا زمانی که firewalld بسته را رد (reject) میکند، هیچ تأثیری ندارد.
اجرای firewall-cmd بدون sudo. هر تغییری به دسترسی root نیاز دارد. بدون آن، درخواست توسط بررسی مجوز رد میشود و هیچ چیزی تغییر نمیکند، که در نگاه اول ممکن است به نظر برسد دستور نادیده گرفته شده است.
شش دستور، اکثر نیازهای روزانه را پوشش میدهند: --list-all برای خواندن وضعیت، --permanent --add-service یا --add-port برای باز کردن یک پورت، --permanent --remove-service برای بستن آن، --reload برای اعمال فایل ذخیرهشده، و --runtime-to-permanent پس از یک دوره آزمایش. ناحیه (zone) برابر با public است، فلگ آن --permanent است و تنها بررسی قابلاعتماد، از طریق یک ماشین دیگر انجام میشود.
FAQ
چرا قانون firewalld من پس از راهاندازی مجدد ناپدید شد؟
این قانون فقط در پیکربندی runtime اعمال شده است. sudo firewall-cmd --add-service=http بلافاصله اعمال میشود و در reload یا reboot بعدی حذف میگردد، زیرا پیکربندی ذخیرهشده در /etc/firewalld/zones/public.xml هرگز تغییر نکرده است. از --permanent استفاده کنید و سپس sudo firewall-cmd --reload را اجرا نمایید. برای حفظ قوانینی که قبلاً بهصورت دستی اضافه کردهاید، sudo firewall-cmd --runtime-to-permanent را اجرا کنید که مجموعه فعال را در فایل ذخیرهشده کپی میکند.
چرا پس از افزودن یک قانون با --permanent هیچ تغییری رخ نمیدهد؟
زیرا --permanent فایل را مینویسد و فایروال در حال اجرا را تغییر نمیدهد. پورت تا زمانی که sudo firewall-cmd --reload پیکربندی ذخیرهشده را در kernel بارگذاری نکند، بسته میماند. sudo firewall-cmd --list-services را با sudo firewall-cmd --permanent --list-services مقایسه کنید: اگر لیست ذخیرهشده ورودیای دارد که در لیست فعال نیست، یعنی شما مرحله reload را انجام ندادهاید.
آیا باید از --add-service استفاده کنم یا --add-port؟
زمانی که نامی برای سرویس در حال اجرا وجود دارد، از --add-service استفاده کنید. این کار هدف را مشخص میکند و sudo firewall-cmd --info-service=https دقیقاً نشان میدهد که آن نام چه پورتهایی را پوشش میدهد. زمانی که هیچ تعریفی برای سرویس شما وجود ندارد یا سرویس روی پورت غیر استاندارد گوش میدهد، از --add-port استفاده کنید. سرویس ssh فقط شامل 22/tcp است، بنابراین اگر SSH را به 2222 منتقل کردهاید، به --add-port=2222/tcp و یک برچسب SELinux برای آن پورت نیاز دارید.
چرا کانتینر Docker من در دسترس است در حالی که firewall-cmd نشان میدهد پورت بسته است؟
پورت منتشرشده توسط قوانین NAT خودِ Docker بازنویسی شده و به کانتینر هدایت میشود، بنابراین بسته هرگز به host تحویل داده نمیشود و لیستهای سرویس و پورتِ zone فقط بستههای تحویلدادهشده به host را پوشش میدهند. کانتینر از اینترنت پاسخ میدهد در حالی که --list-all چیزی نشان نمیدهد. با استفاده از docker run -d -p 127.0.0.1:8080:80 nginx، پورت را فقط روی loopback منتشر کنید و یک reverse proxy در مقابل آن قرار دهید.
آیا میتوانم به جای firewalld، ابزار ufw را روی Rocky Linux نصب کنم؟
دو مدیریت فایروال روی یک سرور، قوانین را بدون اطلاع از یکدیگر مینویسند و اینکه کدام مجموعه باقی بماند، به این بستگی دارد که کدام سرویس آخرین بار شروع شده است. firewalld ابزار پشتیبانیشده در Rocky Linux و AlmaLinux است، از قبل نصب شده و همان backend مربوط به nftables را مدیریت میکند که ufw مدیریت میکرد. zone پیشفرض و پرچم --permanent را یاد بگیرید تا بر کل ابزار مسلط شوید.