SSD Nodes Learn 🎉 VPS از $5.50/ماه
راهنماها Matt Connorتوسط Matt Connor

رفع مشکل قفل شدن دسترسی SSH توسط ufw در لینوکس

اگر با تنظیمات ufw دسترسی SSH خود را از دست داده‌اید، با استفاده از کنسول ارائه‌دهنده و دستور ufw disable مشکل را حل کنید. این راهنما نحوه بازگشت به سرور را توضیح می‌دهد.

بازگشت به دسترسی

اگر ufw شما را از VPS بیرون انداخته است، تنها راه بازگشت، استفاده از کنسول ارائه‌دهنده یا حالت rescue است؛ زیرا پس از فعال شدن قانون مسدودکننده، هیچ راهکار مبتنی بر SSH وجود ندارد. هسته سیستم‌عامل بسته‌های شما را پیش از آنکه به sshd برسند حذف می‌کند، بنابراین هیچ راهی برای ورود یا تعمیر از طریق شبکه باقی نمی‌ماند. کنسول را در پنل کنترل ارائه‌دهنده خود باز کنید، در آنجا لاگین کنید و دستور زیر را اجرا نمایید.

sudo ufw disable

شما باید Firewall stopped and disabled on system startup را مشاهده کنید. اتصالات جدید SSH ظرف یک یا دو ثانیه دوباره کار خواهند کرد. هیچ‌کدام از تنظیمات شما از بین نمی‌رود: disable قوانین را از هسته تخلیه کرده و ENABLED=no را در /etc/ufw/ufw.conf می‌نویسد، در حالی که قوانین شما همچنان در /etc/ufw/user.rules روی دیسک باقی می‌مانند و منتظر ufw enable بعدی هستند.

سیستم را reboot نکنید و به آن امید نبندید. ufw در هنگام بالا آمدن سیستم به‌طور خودکار اجرا می‌شود، بنابراین ENABLED=yes به این معنی است که همان مجموعه قوانین دوباره پیش از برقراری شبکه بارگذاری می‌شوند. reboot کردن هیچ تغییری در وضعیت قفل‌شدگی توسط ufw ایجاد نمی‌کند.

کنسول به رمز عبوری نیاز دارد که ممکن است آن را نداشته باشید

کنسول وب (VNC یا سریال) مانند یک صفحه‌کلید متصل به دستگاه عمل می‌کند. این یک مسیر شبکه نیست، بنابراین هیچ قانون فایروالی نمی‌تواند آن را مسدود کند. این کنسول به ورود محلی نیاز دارد و این دقیقاً همان جایی است که تنظیمات مبتنی بر کلید (key-only) با مشکل مواجه می‌شوند: اگر هرگز برای کاربر sudo خود رمز عبوری تعیین نکرده باشید و ورود کاربر root نیز قفل باشد، کنسول درخواستی را به شما نشان می‌دهد که قادر به پاسخگویی به آن نیستید. همین حالا و تا زمانی که دسترسی SSH دارید، آن رمز عبور را تنظیم کنید: sudo passwd yourname. اکثر پنل‌ها همچنین می‌توانند رمز عبور root را بازنشانی کنند که معمولاً مستلزم راه‌اندازی مجدد (reboot) سیستم است.

اگر کنسول غیرقابل استفاده است، سیستم نجات (rescue system) ارائه‌دهنده را بوت کنید. این سیستم یک سیستم‌عامل جداگانه را اجرا می‌کند که در آن دیسک شما mount نشده است، بنابراین می‌توانید ufw را از خارج از سیستم اصلی غیرفعال کنید.

lsblk
sudo mount /dev/vda1 /mnt
sudo sed -i 's/^ENABLED=yes/ENABLED=no/' /mnt/etc/ufw/ufw.conf
sudo umount /mnt

ابتدا lsblk را اجرا کنید، زیرا پارتیشن root همیشه /dev/vda1 نیست. پس از راه‌اندازی مجدد به سیستم عادی، ufw تا زمانی که خودتان آن را فعال نکنید، غیرفعال باقی می‌ماند.

توالی بازیابی حداقلی

به این ترتیب عمل کنید. چهار مرحله اول ایمن هستند. مرحله بعدی ایمن نیست.

  1. دستور sudo ufw disable را برای تخلیه قوانین و بازیابی دسترسی خود اجرا کنید.
  2. دستور sudo ufw show added را برای چاپ قوانینی که اضافه کرده‌اید، به شکل دستوراتی که آن‌ها را ایجاد کرده‌اند، اجرا کنید. این کار زمانی که ufw غیرفعال است نیز کار می‌کند، در حالی که ufw status این‌گونه نیست.
  3. دستور sudo sshd -T | grep -i '^port' را برای تأیید پورتی که sshd واقعاً روی آن گوش می‌دهد، اجرا کنید. این دستور مقدار port 22 را چاپ می‌کند، مگر اینکه آن را تغییر داده باشید.
  4. دستور sudo ufw allow 22/tcp را با استفاده از پورت واقعی خود اجرا کنید تا فعال‌سازی بعدی باعث قفل شدن مجدد شما نشود.
  5. دستور sudo ufw enable را اجرا کنید، در حالی که ابتدا یک بازگشت به وضعیت قبل (rollback) برنامه‌ریزی شده باشد. این مورد در ادامه همین صفحه آمده است.

دستور ufw reset واقعاً چه کاری انجام می‌دهد

ufw reset آخرین راهکار است، نه اولین اقدام. این دستور فایروال را غیرفعال می‌کند، از تمام فایل‌های قوانین نسخه پشتیبان تهیه می‌کند و تنظیمات پیش‌فرض را به مسدود کردن ترافیک ورودی (deny incoming) و مجاز کردن ترافیک خروجی (allow outgoing) بازمی‌گرداند. این دستور برای هر فایل یک خط حاوی مسیر نسخه پشتیبان چاپ می‌کند:

Backing up 'user.rules' to '/etc/ufw/user.rules.20260813_101500'

پس از یک بار reset، شما هیچ قانون مجازکننده‌ای (allow rule) نخواهید داشت؛ بنابراین این دستور را به جای SSH، از طریق کنسول اجرا کنید و پیش از فعال‌سازی مجدد، قانون مربوط به SSH را اضافه کنید. آن نسخه‌های پشتیبان فایل‌های متنی ساده هستند. sudo grep -n dport /etc/ufw/user.rules.20260813_101500 نشان می‌دهد که قوانین قبلی چه بوده‌اند؛ این همان روشی است که می‌توانید مجموعه‌قوانینی را که قصد حذف آن‌ها را نداشتید، دوباره بازسازی کنید.

محل ذخیره‌سازی قوانین ufw

خواندن فایل‌ها بسیار مطمئن‌تر از تکیه بر حافظه است. پنج مسیر، کل وضعیت را در خود نگه می‌دارند:

  • /etc/ufw/user.rules و /etc/ufw/user6.rules: قوانینی که شما اضافه کرده‌اید، به همان ترتیبی که ارزیابی می‌شوند.
  • /etc/ufw/before.rules و /etc/ufw/after.rules، به علاوه نسخه‌های 6: چارچوبی که ufw پیرامون قوانین شما ایجاد می‌کند، شامل پذیرش اتصالات برقرار شده و قوانین loopback.
  • /etc/default/ufw: سیاست‌های پیش‌فرض و سوئیچ IPV6.
  • /etc/ufw/ufw.conf: ENABLED و سطح لاگ‌گیری.
  • /var/log/ufw.log: آنچه مسدود شده است، در صورتی که لاگ‌گیری فعال باشد.

ابزار ufw پیش از بازنویسی هر فایل، یک نسخه با برچسب زمانی از آن تهیه می‌کند، بنابراین ls /etc/ufw/ با نام‌هایی مانند user.rules.20260813_101500 پر می‌شود. این همان تاریخچه undo شماست و پیش از آنکه بخواهید تغییرات را به حالت قبل برگردانید، ارزش خواندن دارد.

برای مشاهده آنچه در هسته (kernel) بارگذاری شده است (به جای آنچه روی دیسک قرار دارد)، از sudo ufw show raw، یا sudo iptables -S و sudo ip6tables -S استفاده کنید. در نسخه‌های Ubuntu 22.04 و 24.04، این دستورات نسخه‌های مبتنی بر nft هستند، بنابراین sudo nft list ruleset همان قوانین را با سینتکس جدیدتر چاپ می‌کند.

چرا فعال‌سازی ufw باعث قطع نشست SSH من شد؟

سیاست پیش‌فرض برای ترافیک ورودی، deny است. فعال کردن ufw بدون تعریف قانونی برای پورت SSH، تمام اتصالات جدید را مسدود می‌کند. ابزار ufw به شما هشدار می‌دهد: Command may disrupt existing ssh connections. Proceed with operation (y|n)? پاسخ دادن به y بدون ایجاد قانون allow برای SSH، رایج‌ترین دلیل بروز تمام مشکلات ذکر شده در این صفحه است.

بخش گیج‌کننده، تأخیر در اعمال این محدودیت است. ابزار /etc/ufw/before.rules بسته‌هایی را که در وضعیت ESTABLISHED,RELATED قرار دارند، پیش از بررسی قوانین شما می‌پذیرد؛ بنابراین نشستی که در آن دستور را وارد کرده‌اید، به کار خود ادامه می‌دهد. قفل شدن دسترسی تنها در اتصال بعدی رخ می‌دهد که ممکن است ساعت‌ها بعد باشد؛ در آن زمان، تغییر فایروال دیگر به نظر مرتبط نمی‌رسد. همیشه پیش از بستن نشست اول، یک نشست SSH دوم باز کنید و از صحت عملکرد آن اطمینان حاصل کنید.

چرا پس از تغییر سیاست، apt و DNS از کار افتادند؟

sudo ufw default deny outgoing کوئری‌های خروجی DNS (سیستم نام دامنه) و HTTP خروجی را مسدود می‌کند، بنابراین تفکیک نام (name resolution) متوقف شده و به‌روزرسانی بسته‌ها از کار می‌افتد. apt update خطای Temporary failure resolving 'archive.ubuntu.com' را گزارش می‌دهد. SSH ورودی همچنان کار می‌کند، زیرا پاسخ‌های آن در وضعیت ESTABLISHED قرار دارند و از قوانین فایروال عبور می‌کنند؛ این موضوع باعث می‌شود فایروال بی‌گناه به نظر برسد، در حالی که دقیقاً عامل اصلی مشکل است.

اگر به سیاست deny outgoing نیاز دارید، دسترسی‌های مورد نیاز واقعی ماشین را باز کنید:

sudo ufw allow out 53
sudo ufw allow out 80/tcp
sudo ufw allow out 443/tcp
sudo ufw allow out 123/udp

بدون قانون آخر، ساعت سیستم دچار انحراف (drift) می‌شود و ساعت نادرست باعث شکست اعتبارسنجی گواهی TLS (امنیت لایه انتقال) می‌گردد؛ در نتیجه curl به جای خطا در پورت‌ها، با خطای تاریخ مواجه می‌شود. این نشانه معمولاً چند روز پس از تغییر ظاهر می‌شود، به همین دلیل سیاست deny outgoing برای ماشین‌هایی مناسب است که آن‌ها را مانیتور می‌کنید، نه برای سیستمی که فقط یک بار آن را راه‌اندازی کرده‌اید.

چرا قانون ufw من هرگز اعمال نمی‌شود؟

ابزار ufw قوانین کاربر را به ترتیب بررسی می‌کند و در اولین تطابق متوقف می‌شود. یک deny که پس از یک allow کلی اضافه شده باشد، هرگز اجرا نمی‌شود؛ زیرا قانون allow پیش از آن در مورد بسته تصمیم‌گیری کرده است. ترتیب قوانین را با شماره مشاهده کنید و سپس قانون جدید را در موقعیت مناسب درج کنید.

sudo ufw status numbered
sudo ufw insert 1 deny from 203.0.113.10 to any port 22
sudo ufw delete 4

دستور sudo ufw --dry-run allow 8080/tcp قوانینی را که قرار است نوشته شوند نمایش می‌دهد و هیچ تغییری ایجاد نمی‌کند. این روشی امن برای خواندن یک قانون پیش از اعمال نهایی آن است.

یک دام دیگر در پروفایل‌های برنامه نهفته است. sudo ufw allow OpenSSH از پروفایل موجود در /etc/ufw/applications.d/openssh-server استفاده می‌کند و آن پروفایل به معنای پورت 22 است. اگر sshd روی پورت 2222 گوش می‌دهد، این قانون پورتی را باز می‌کند که هیچ سرویسی از آن استفاده نمی‌کند و شما را با مجموعه‌ای از قوانین که ظاهراً درست به نظر می‌رسند، پشت در قفل‌شده باقی می‌گذارد. پس از تغییر پورت، حتماً از شماره پورت استفاده کنید. باقی سینتکس در اصول فایروال ufw برای VPS پوشش داده شده است.

چرا قوانین IPv4 آنچه را که می‌بینم توضیح نمی‌دهند؟

زیرا نیمی از ترافیک، IPv4 نیست. اوبونتو IPV6=yes را در /etc/default/ufw ارائه می‌دهد و ufw سپس یک مجموعه قوانین موازی v6 را در /etc/ufw/user6.rules نگهداری می‌کند. قانونی که با یک آدرس IPv4 نوشته شده باشد، مانند ufw allow from 203.0.113.10 to any port 22، هیچ قانون v6 ایجاد نمی‌کند. اگر VPS شما دارای رکورد AAAA باشد، کلاینت شما IPv6 را ترجیح می‌دهد و اتصال شما با وقفه مواجه می‌شود، در حالی که ufw status قانونی را نشان می‌دهد که درست به نظر می‌رسد. تفاوت را با استفاده از ssh -4 user@host در برابر ssh -6 user@host آزمایش کنید. اگر اولی کار می‌کند و دومی خیر، شکاف موجود در مجموعه قوانین v6 است.

حالت معکوس برای امنیت بدتر است. با IPV6=no، ابزار ufw اصلاً ip6tables را مدیریت نمی‌کند، بنابراین سیاست v6 در حالت پیش‌فرض هسته یعنی ACCEPT باقی می‌ماند. پورتی که تصور می‌کنید بسته است، روی آدرس IPv6 خود پاسخ می‌دهد و هیچ دستور ufw هرگز به آن اشاره نخواهد کرد. با استفاده از sudo ip6tables -S و ss -tlnp بررسی کنید و برای درک کامل موضوع، نحوه مدیریت پورت‌های IPv6 توسط ufw را مطالعه کنید.

چرا با وجود مسدود بودن پورت در ufw، پورت Docker همچنان باز است؟

Docker با نوشتن قوانین DNAT (ترجمه آدرس شبکه مقصد) در جدول nat و وارد کردن زنجیره اختصاصی خود به FORWARD، پورت را منتشر می‌کند. قوانین ufw در مسیر INPUT قرار دارند. ترافیک ارسالی به container به جای تحویل به میزبان، فوروارد (foward) می‌شود؛ بنابراین ترافیک هرگز به زنجیره‌ای که قانون deny شما در آن قرار دارد، نمی‌رسد. docker run -p 5432:5432 حتی با وجود فعال بودن ufw و مسدود کردن همه اتصالات، از طریق اینترنت قابل دسترسی است.

sudo iptables -t nat -S DOCKER

ساده‌ترین راهکار، انتشار پورت روی loopback است: -p 127.0.0.1:5432:5432 سمت میزبان را به 127.0.0.1 متصل می‌کند و فارغ از تنظیمات ufw، هیچ منبع خارجی نمی‌تواند به آن دسترسی پیدا کند. مطلب انتشار پورت‌های Docker با وجود ufw مواردی را بررسی می‌کند که سرویس واقعاً نیاز به دسترسی عمومی دارد.

پیش از اعمال قانون، بازگشت به وضعیت قبل (rollback) را زمان‌بندی کنید

این عادتی است که مدیریت فایروال را ممکن و ایمن می‌سازد. پیش از هر تغییر پرخطر، عملیات بازگشت را زمان‌بندی کنید. اگر تغییرات باعث قطع دسترسی شما شود، سیستم پس از 5 دقیقه خود را بازیابی می‌کند و نیازی به باز کردن کنسول نخواهید داشت.

sudo systemd-run --on-active=5m --unit=ufw-rollback /usr/sbin/ufw disable

systemd دستور Running timer as unit: ufw-rollback.timer را اجرا می‌کند. اکنون تغییرات خود را اعمال کنید. اگر پس از آن همچنان توانستید یک نشست SSH جدید باز کنید، عملیات بازگشت را لغو کنید:

sudo systemctl stop ufw-rollback.timer

اگر نتوانستید آن نشست را باز کنید، منتظر بمانید. ufw به‌طور خودکار غیرفعال می‌شود و تلاش بعدی شما برای اتصال موفق خواهد بود. ترفند کلاسیک shutdown -r +5 در مورد ufw کارساز نیست، زیرا ufw در زمان بوت، همان مجموعه قوانین قبلی را دوباره بارگذاری می‌کند.

حفظ یک راه دسترسی جایگزین

  • پیش از آنکه به آن نیاز پیدا کنید، یک بار از طریق کنسول ارائه‌دهنده وارد شوید و از صحت رمز عبور اطمینان حاصل کنید. کنسولی که هرگز آن را تست نکرده‌اید، یک راهکار پشتیبان محسوب نمی‌شود.
  • یک کاربر sudo دوم با کلید اختصاصی خود ایجاد کنید تا خرابی یک فایل authorized_keys منجر به قطع کامل دسترسی شما نشود.
  • بررسی کنید که آیا ارائه‌دهنده شما در پنل کاربری خود از فایروال شبکه، جدا از ufw، استفاده می‌کند یا خیر. این فایروال همان پورت‌ها را مسدود می‌کند و ufw status هرگز در مورد آن هشداری نخواهد داد.
  • اگر آدرس IP شما پویا (dynamic) است، ufw allow from <your home address> را به تنها قانون SSH خود تبدیل نکنید. ارائه‌دهنده ممکن است آن را در طول شب تغییر دهد و دسترسی شما قطع شود.

بهترین زمان برای انجام تمام این موارد، هنگام راه‌اندازی اولیه سرور و همزمان با سایر تنظیمات در ده دقیقه اول روی یک VPS جدید است.

خطای Refused یا timed out نشان می‌دهد کدام لایه با شکست مواجه شده است

Connection refused به این معناست که بسته به سرور رسیده و چیزی یک TCP reset بازگردانده است. مسیر شبکه سالم است، بنابراین sshd متوقف شده یا روی پورت دیگری در حال گوش دادن است. فایروال به‌ندرت عامل این مشکل است، زیرا ufw به‌صورت پیش‌فرض بسته‌ها را drop می‌کند و نه reject.

Connection timed out به این معناست که هیچ پاسخی دریافت نشده است. این نشانه یک drop است: ufw، فایروال شبکه ارائه‌دهنده خدمات، یا آدرس اشتباه. خواندن صحیح این دو خطا، یک ساعت از زمان شما را برای حدس‌زدن هدر نمی‌دهد و تفاوت بین connection refused و timed out سایر موارد باقی‌مانده را بررسی می‌کند.

پیش از اعمال تغییر بعدی، لاگ‌گیری را فعال کنید

sudo ufw logging on
sudo tail -f /var/log/ufw.log

بسته (packet) مسدودشده به این صورت نمایش داده می‌شود:

[UFW BLOCK] IN=eth0 OUT= SRC=203.0.113.10 DST=192.0.2.5 LEN=60 PROTO=TCP SPT=51234 DPT=22 WINDOW=64240 SYN

DPT=22 به همراه آدرس خودتان در SRC=، اثباتی بر این است که ufw عامل مسدودکننده شماست، نه شبکه و نه sshd. در یک image حداقلی که فاقد rsyslog است، فایل /var/log/ufw.log وجود ندارد و همان خطوط از طریق sudo journalctl -k | grep UFW دریافت می‌شوند. ابزار ufw برای قوانین لاگ‌گیری خود محدودیت نرخ (rate limit) اعمال می‌کند، بنابراین نبود یک خط به معنای مجاز بودن بسته نیست.

اگر قوانینی یافتید که خودتان اضافه نکرده‌اید

تغییر خودکار قوانین فایروال، مشکل فایروال نیست. شخصی با دسترسی root آن‌ها را نوشته است. دستور sudo grep ufw /var/log/auth.log را اجرا کنید تا ببینید چه دستورات sudo و با چه کاربری اجرا شده‌اند، سپس برای بررسی ورودهای سیستم در آن بازه زمانی، last را اجرا کنید. اگر حساب‌های کاربری با هیچ‌کدام از افراد مورد اعتماد شما مطابقت ندارند، عیب‌یابی فایروال را متوقف کرده و به‌جای آن مراحل بررسی سرور مجازی نفوذشده را دنبال کنید. فعال‌سازی مجدد فایروال روی سروری که تحت کنترل شخص دیگری است، تنها صورت‌مسئله را پنهان می‌کند.

بازگرداندن وضعیت به حالت عادی

هنگامی که علت مشکل را شناسایی کردید، ufw را به‌گونه‌ای فعال کنید که از قفل شدن مجدد دسترسی جلوگیری شود. پورت SSH اصلی خود را مجاز کنید، دستور rollback را زمان‌بندی کرده و سپس فایروال را فعال کنید. پس از آن، یک نشست SSH جدید از ترمینال دیگری باز کنید و از برقراری اتصال اطمینان حاصل نمایید. تنها پس از تأیید اتصال نشست جدید، نشست فعلی را ببندید. ثبت لاگ‌ها را برای یک روز فعال نگه دارید، زیرا لاگ‌ها بسیار سریع‌تر از خواندن user.rules به شما نشان می‌دهند که چه موردی را فراموش کرده‌اید مجاز کنید.

FAQ

آیا ufw disable قوانین من را حذف می‌کند؟

خیر. disable مجموعه قوانین را از هسته (kernel) تخلیه می‌کند و ENABLED=no را در /etc/ufw/ufw.conf می‌نویسد. قوانین شما در /etc/ufw/user.rules و /etc/ufw/user6.rules باقی می‌مانند و sudo ufw show added آن‌ها را در حالی که فایروال غیرفعال است، فهرست می‌کند. ufw reset دستوری است که آن‌ها را پاک می‌کند و ابتدا از هر فایل یک نسخه پشتیبان تهیه کرده و خطی مانند Backing up 'user.rules' to '/etc/ufw/user.rules.20260813_101500' را چاپ می‌کند.

آیا راه‌اندازی مجدد (reboot) VPS باعث رفع قفل‌شدگی ufw می‌شود؟

خیر. ufw در زمان بالا آمدن سیستم از ENABLED=yes در /etc/ufw/ufw.conf شروع به کار می‌کند، بنابراین همان قوانین پیش از برقراری شبکه بارگذاری می‌شوند و شما دوباره قفل می‌شوید. راه‌اندازی مجدد تنها زمانی کمک می‌کند که ufw را خاموش کرده باشید، یا آن فایل را از طریق حالت rescue و در حالی که دیسک mount شده است، ویرایش کرده باشید. از کنسول ارائه‌دهنده استفاده کنید و دستور sudo ufw disable را در آنجا اجرا کنید.

چرا کانتینر Docker من در حالی که ufw پورت را مسدود کرده، در دسترس است؟

Docker برای هر پورت منتشرشده، قوانین DNAT و FORWARD مخصوص به خود را می‌نویسد. آن ترافیک به جای تحویل به میزبان (host)، به کانتینر هدایت می‌شود، بنابراین هرگز از زنجیره INPUT که قانون deny شما در آن قرار دارد، عبور نمی‌کند. زمانی که پورت فقط برای میزبان است، آن را با -p 127.0.0.1:5432:5432 روی loopback منتشر کنید و آنچه Docker نصب کرده است را با sudo iptables -t nat -S DOCKER بررسی کنید.

من رمز عبور کنسول و حالت rescue ندارم. چه گزینه‌هایی دارم؟

گزینه‌های باقی‌مانده به ارائه‌دهنده شما بستگی دارد: بازنشانی رمز عبور از طریق پنل کنترل که معمولاً سرور را راه‌اندازی مجدد می‌کند، یا متصل کردن دیسک به یک instance دیگر تا بتوانید /etc/ufw/ufw.conf را از آنجا ویرایش کنید. پیش از بازسازی (rebuild) سرور با پشتیبانی تماس بگیرید، زیرا بازسازی باعث از بین رفتن داده‌های روی آن می‌شود. هنگامی که دسترسی شما برقرار شد، sudo passwd yourname را اجرا کنید و ورود به کنسول را یک بار تست کنید تا قفل‌شدگی بعدی فقط دو دقیقه از وقت شما را بگیرد.

#ufw#firewall#lockout#console#recovery