اتصال SSH قطع میشود، دوباره میزنی، باز هم قطع. نه پیام خطایی میبینی، نه پاسخی. فقط Connection timed out یا Connection refused روی صفحه میماند و تو میدانی که چند دقیقه پیش خودت با یک دستور iptables یا یک خط sshd_config این در را بستی. این وضعیت را در محافل فنی «قفل شدن از سرور» میگویند و اولین کاری که اکثر آدمها میکنند اشتباه است: ریست کردن ماشین.
ریاستارت سرور تقریباً هیچوقت مشکل را حل نمیکند، چون قاعدهای که نوشتی روی دیسک ذخیره شده و بعد از بوت دوباره بارگذاری میشود. اگر سرویس فایروال را enable کرده باشی، حتی بدتر: با هر بوت همان قاعده برمیگردد. پس قبل از هر چیز، دست از ریبوت بردار و به دنبال یک راه ورود دوم بگرد.
کنسول نجات: تنها دری که هنوز باز است
هر ارائهدهندهٔ زیرساخت یک مسیر دسترسی خارج از شبکهٔ عمومی دارد. در سرورنت این مسیر از پنل کنترل و به شکل کنسول سریال یا VNC در دسترس است. این کنسول از پشتهٔ شبکهٔ سرور عبور نمیکند، پس قاعدهٔ فایروالی که SSH را بسته، روی آن اثری ندارد. اگر سرور اختصاصی یا VPS داری، همین حالا قبل از اینکه به آن نیاز پیدا کنی، جای این دکمه را در پنل پیدا کن.
وقتی از طریق کنسول وارد شدی، اول وضعیت واقعی را ببین، نه آنچه فکر میکنی:
iptables -L INPUT -n -v --line-numbers
nft list ruleset
ss -tlnp | grep :22
systemctl status sshd
خروجی ss به تو میگوید سرویس SSH اصلاً بالا هست یا نه. اگر پورت 22 در لیست LISTEN نبود، مشکل فایروال نیست؛ سرویس کرش کرده یا کانفیگش خراب است. این تفکیک، نیمی از وقت تو را نجات میدهد. اگر پورت گوش میدهد ولی از بیرون جواب نمیگیری، مقصر لایهٔ فیلتر است.
پاک کردن قاعدهٔ مقصر بدون از دست دادن بقیه
قاعدهها را با شماره ببین و فقط همان یک خط را حذف کن. حذف کل زنجیره با iptables -F کار احمقانهای است؛ چون بقیهٔ قواعد محافظتی را هم با خودش میبرد و سرور را لخت میکند.
iptables -D INPUT 3
# یا برای nftables
nft delete rule inet filter input handle 12
بعد از حذف، فوراً از یک ترمینال دیگر تست کن که SSH برمیگردد. تا وقتی این تست موفق نشده، ترمینال کنسول را نبند.
قاعدهٔ زماندار: قبل از اعمال، پشتوانه بساز
مشکل اصلی این نیست که قاعده اشتباه بود؛ این است که بدون راه بازگشت اعمالش کردی. راهحل استانداردی که سالهاست در سرورهای تولیدی استفاده میکنم، زمانبندی خودکار بازگشت است. قبل از هر تغییر روی فایروال، یک job بگذار که اگر تو تأیید نکردی، خودش قواعد قبلی را برگرداند.
# ذخیره وضعیت سالم
iptables-save > /root/fw-good.rules
# بازگشت خودکار بعد از 5 دقیقه اگر تأیید نکردی
echo "iptables-restore < /root/fw-good.rules" | at now + 5 minutes
حالا قاعدهٔ جدید را اعمال کن. اگر اتصالت قطع شد، پنج دقیقه صبر کن و دوباره وصل شو. اگر همهچیز درست بود، job را با atrm لغو کن و وضعیت جدید را ذخیره کن. این الگو در nftables هم با nft list ruleset > /root/fw-good.nft و nft -f کار میکند. هزینهاش این است که پنج دقیقه باید منتظر بمانی و در آن فاصله سرور با قواعد قدیمی میچرخد. برای محیط تولیدی، این پنج دقیقه ارزانترین بیمهای است که میخری.
نکتهٔ مهم دربارهٔ at: روی بسیاری از توزیعهای مینیمال نصب نیست. اگر at نداری، همان کار را با systemd-run انجام بده:
systemd-run --on-active=5min /sbin/iptables-restore /root/fw-good.rules
ترتیبی که هرگز به قطع دسترسی نمیرسد
ترتیب کارها مهمتر از خود دستورهاست. این ترتیبی است که در عمل جواب میدهد:
- یک نشست SSH دوم باز کن و باز نگه دار. هرگز روی یک اتصال تغییر فایروال نده.
- وضعیت سالم را در فایل ذخیره کن.
- job بازگشت خودکار را فعال کن.
- قاعدهٔ جدید را اعمال کن.
- از نشست دوم تست کن. اگر جواب داد، نشست اول را ببند و job را لغو کن.
اگر پورت SSH را عوض میکنی، قاعدهٔ جدید را قبل از ریاستارت sshd اضافه کن، نه بعدش. خطای رایج این است که آدم پورت را در sshd_config عوض میکند، سرویس را ریاستارت میکند و بعد یادش میآید فایروال فقط پورت قدیمی را باز کرده. نتیجه: قفل شدن از سرور در حالی که سرویس سالم است. برای جزئیات این کار و تنظیم fail2ban، راهنمای امنیت SSH؛ از تغییر پورت تا fail2ban و کلید عمومی را ببین.
اینجا اشتباه میکنند
خطای واقعی که بارها دیدهام: کسی با ufw دستور ufw enable میزند بدون اینکه ufw allow 22/tcp را قبلش اجرا کرده باشد. سیمپتوم دقیقاً این است که SSH بلافاصله قطع میشود، ولی ping هنوز جواب میدهد و وبسایت هم بالا میآید. چون ufw بهصورت پیشفرض ترافیک ورودی را میبندد اما ICMP و پورتهای بازشدهٔ قبلی را دست نمیزند. همین باعث میشود آدم فکر کند شبکه سالم است و مشکل از جای دیگری است. اگر این علائم را دیدی، اول ufw status verbose را از کنسول نجات چک کن.
اشتباه دوم: اعمال قاعده روی زنجیرهٔ OUTPUT بدون درک اینکه پاسخهای SSH از همانجا برمیگردند. اتصال برقرار میشود، احراز هویت رد میشود، بعد قطع. این را با iptables -L OUTPUT -n -v و شمردن بستههای drop تشخیص بده.
وقتی کنسول نجات هم در دسترس نیست
اگر روی سرور فیزیکی هستی و دسترسی فیزیکی نداری، یا VPSای داری که کنسولش کار نمیکند، تنها گزینه بوت در حالت rescue از طریق پنل ارائهدهنده است. در این حالت سیستم از یک محیط مینیمال بالا میآید و دیسک اصلی را mount میکنی تا فایل قواعد را دستی اصلاح کنی. این مسیر کند است و برای همین است که مرحلهٔ «job بازگشت خودکار» را قبل از هر تغییری جدی میگیرم.
برای سرویسهایی که دسترسی به آنها حیاتی است، لایهٔ محافظت را جایی بگذار که خودت قفلش نکنی. محافظت در برابر DDoS سرورنت این کار را در لبهٔ شبکه انجام میدهد و قواعد فیلتر از پشتهٔ سیستمعامل تو جدا میمانند؛ یعنی حتی اگر فایروال محلیات را خراب کنی، ترافیک مخرب همانجا متوقف میشود و تو با یک سیستم تمیزتر سر و کله میزنی.
بعد از بازیابی، اینها را چک کن
برگشتن اتصال پایان کار نیست. سه چیز را حتماً بررسی کن:
- قواعد ذخیرهشده با وضعیت فعلی حافظه یکی باشند.
iptables-saveرا باiptables -Lمقایسه کن. - سرویس فایروال روی بوت فعال باشد تا بعد از ریاستارت غافلگیر نشوی:
systemctl is-enabled nftables. - لاگ تغییرات را نگه دار. هر تغییری روی فایروال باید یک رکورد داشته باشد تا وقتی دوباره قفل شدی، بدانی کدام قاعده مقصر است. روش نگهداشتن این رکوردها را در لاگ ممیزی چیست و چگونه آن را دستنخورده نگه داریم؟ توضیح دادهام.
اگر شک داری قاعدهای که مینویسی درست است یا نه، قبل از اعمال روی سرور اصلی، همان قواعد را روی یک ماشین تست با همان نسخهٔ توزیع اجرا کن. تفاوت نسخهٔ nftables بین Debian 11 و 12 در نحو برخی دستورها کم نیست و همین باعث میشود قاعدهای که روی تست کار میکرد، روی تولید خطا بدهد.
یک نکتهٔ آخر دربارهٔ ترتیب: همیشه قبل از بستن پورتها، ابزارهای بررسی شبکه را در دسترس داشته باش تا بتوانی از بیرون تأیید کنی چه چیزی باز است. ابزارهای بررسی DNS و شبکه برای همین لحظههاست.
پرسشهای پرتکرار
چرا بعد از ریاستارت سرور هنوز نمیتوانم SSH بزنم؟
چون قواعد فایروال روی دیسک ذخیره شدهاند و سرویس در بوت دوباره آنها را بارگذاری میکند. ریاستارت فقط وضعیت حافظه را پاک میکند، نه فایل قواعد را. تا وقتی فایل /etc/nftables.conf یا خروجی iptables-save اصلاح نشود، هر بوت همان قفل را برمیگرداند.
چطور بفهمم مشکل از فایروال است یا از خود سرویس SSH؟
از کنسول نجات دستور ss -tlnp | grep :22 را بزن. اگر پورت در حالت LISTEN بود، سرویس سالم است و مقصر لایهٔ فیلتر است. اگر نبود، مشکل در sshd یا کانفیگ آن است و دستزدن به فایروال بیفایده است.
آیا حذف همهٔ قواعد با iptables -F راهحل سریعی است؟
نه. این دستور همهٔ قواعد ورودی، خروجی و فوروارد را پاک میکند و سرور را در برابر هر ترافیکی باز میگذارد. درست این است که با --line-numbers قاعدهٔ مقصر را پیدا کنی و فقط همان یک خط را با -D حذف کنی.
قاعدهٔ زماندار بازگشت را چطور روی سروری که at ندارد اجرا کنم؟
از systemd-run --on-active=5min استفاده کن. این دستور یک واحد گذرا میسازد که بعد از پنج دقیقه دستور بازگشت را اجرا میکند و به نصب بودن at نیازی ندارد. اگر همهچیز درست بود، واحد را با systemctl stop لغو کن.
دیدگاهها ۰
هنوز دیدگاهی ثبت نشده؛ اولین نفر باشید!