فهرست پورت‌های باز فهرست راه‌های رسیدن به سرور شماست. هر چیز دیگری — دیوارهای آتش، دیوارهای آتش برنامه، شناسایی نفوذ — روی همان ساخته می‌شود. به همین دلیل پرسش «اینجا چه چیزی گوش می‌دهد» در هر ممیزی نخست می‌آید، و به همین دلیل هم بررسی‌ای است که بیش از همه پاسخی ناخوشایند می‌دهد: نیمی از آنچه پیدا می‌شود را نه شما بلکه نصب‌کننده بسته‌ای باز کرده است.

خواندن خروجی

sudo ss -tulpn

پرچم‌ها: t برای TCP، u برای UDP، l تنها برای آنچه گوش می‌دهد، p برای فرایند، و n تا عددها عدد بمانند. بدون sudo ستون فرایند تهی است و تمرین معنایش را از دست می‌دهد.

آنچه اهمیت دارد ستون Local Address:Port است، و تفاوت آنجا بنیادی است:

  • 127.0.0.1:3306 — سرویس تنها از خود ماشین دسترس‌پذیر است. این خوب است؛
  • 0.0.0.0:3306 — از هر نشانی IPv4، یعنی از اینترنت. این همان است که باید بررسی شود؛
  • [::]:3306 — همان برای IPv6. سطری جداگانه، و مرتب از قلم می‌افتد؛
  • 203.0.113.25:443 — روی نشانی‌ای مشخص، معمولاً آگاهانه.

سپس برای هر سطری با 0.0.0.0 یا [::] یک پرسش بپرسید: آیا بیگانه‌ای باید بتواند به اینجا برسد. برای ۸۰ و ۴۴۳ پاسخ آری است. برای تقریباً هر چیز دیگر نه.

یافته‌های همیشگی

Redis، پورت 6379. خطرناک‌ترین سطر آنجاست. Redis به‌صورت پیش‌فرض گذرواژه نمی‌خواهد، و فرمان‌هایش نوشتن فایل روی دیسک را ممکن می‌کنند — یعنی کلید بیگانه در authorized_keys. میان پدیدارشدن Redis روی نشانی عمومی و استفاده از آن ساعت‌ها می‌گذرد، گاهی کمتر. بررسی کنید که در پیکربندی bind 127.0.0.1 و protected-mode yes باشد.

Memcached، 11211/UDP. حتی اگر درونش چیز ارزشمندی نباشد، سرور شما به تقویت‌کننده حمله‌های دیگران بدل می‌شود — و شکایت از سوی ارائه‌دهنده خودتان خواهد آمد.

MySQL و PostgreSQL، 3306 و 5432. گذرواژه هست، اما حدس‌زدن علیه آن پیوسته ادامه دارد، و نسخه‌های پایگاه داده دیرتر از آنچه باید به‌روز می‌شوند. تقریباً هرگز نیازی ندارند بیرون را بنگرند: برنامه روی همان ماشین است و برای کار خودتان تونل SSH بس است.

Elasticsearch 9200، MongoDB 27017. تاریخاً به‌صورت پیش‌فرض بدون احراز هویت. نمونه‌های عمومی آن‌ها سرچشمه همیشگی خبرهای نشت داده‌اند.

API داکر، 2375. پورت باز کنترل Docker یعنی root روی میزبان بدون هیچ گذرواژه‌ای. معمولاً پس از آزمایش‌هایی با دسترسی از راه دور به Docker پدیدار می‌شود.

پنل‌های کنترل و phpMyAdmin روی پورت‌های خودشان: 8080، 8083، 10000. نمی‌گوییم هرگز نباید باز شوند، اما دقیقاً همان‌ها بیشترین حجم تلاش‌ها را گرد می‌آورند.

در خود سرویس درستش کنید، نه در دیوار آتش

خواستِ بستنِ هر یافته با یک قاعده UFW فهمیدنی است، اما آن خط دوم است نه نخست. قاعده ممکن است به‌خطا حذف شود، دیوار آتش ممکن است هنگام عیب‌یابی موقتاً خاموش شود، و Docker پورت‌ها را یکسره با دور زدن UFW منتشر می‌کند. اما تنظیم اتصال در پیکربندی خود سرویس از همه اینها جان به در می‌برد:

  • MySQL/MariaDB — bind-address = 127.0.0.1؛
  • PostgreSQL — listen_addresses = 'localhost'؛
  • Redis — bind 127.0.0.1 ::1؛
  • Docker Compose — به‌صورت "127.0.0.1:5432:5432" منتشر کنید.

و دیوار آتش همچون بیمه روی این می‌آید، نه به‌جای آن.

یافتن فرایند وقتی روشن نیست

ss نام و شناسه فرایند را می‌دهد. سپس:

sudo systemctl status <pid>
sudo lsof -i :8080

فرمان نخست واحد systemd‌ای را نام می‌برد که فرایند به آن تعلق دارد — و این معمولاً برای فهمیدن چیستی و لزوم آن بس است. اما فرایندی ناآشنا که روی پورتی بالا گوش می‌دهد و از بیرون پوشه‌های سامانه اجرا شده — مثلاً از /tmp یا /dev/shm — دیگر پرسشی درباره پیکربندی نیست بلکه دلیلی برای بررسی جداگانه است.

بررسی از بیرون الزامی است

ss به پرسش «چه چیزی گوش می‌دهد» پاسخ می‌دهد نه به «به چه چیزی می‌توان رسید». میان این دو دیوار آتش و NAT و قواعد خود ارائه‌دهنده ایستاده‌اند. تنها پاسخ صادقانه از پویشی از ماشینی دیگر می‌آید:

nmap -Pn -p- 203.0.113.25
nmap -Pn -p- -6 2001:db8::1

فرمان دوم را رد نکنید: تقریباً هر VPS نشانی IPv6 دارد، قواعدش جداگانه نوشته می‌شوند، و سرویس روی هر دو نسخه پروتکل هم‌زمان گوش می‌دهد.

این بررسی یک‌باره نیست

فهرست پورت‌های باز خودبه‌خود تغییر می‌کند. بسته‌ای نصب کردید و سرویسی آورد و پورتی گشود. پنلی را به‌روز کردید و مقدار پیش‌فرضی را بازگرداند. ظرفی اجرا کردید و پورتی را با دور زدن دیوار آتش منتشر کرد. بررسی یک‌باره تنها برای امروز پاسخ می‌دهد و نه بیشتر.

ارزش در خود فهرست نیست بلکه در تغییرهای آن است: پورتی تازه که دیروز نبود نشانه‌ای کوتاه و بسیار گویاست. و درست همین‌گونه ارزش پایش دارد — همچون تصویری لحظه‌ای با تاریخچه، نه همچون خروجی ss که از حافظه یادآوری می‌شود. صفحه نمایشی پایین دقیقاً همین را نشان می‌دهد.