آموزش بررسی پورتهای باز در لینوکس با دستور ss
پورتها ترافیک شبکه را به سرویسهای مختلف هدایت میکنند. با دستور ss -tuln یاد بگیرید چگونه پورتهای در حال گوش دادن را پیدا کنید و تفاوت پورتهای عمومی و محلی را درک کنید.
پورت واقعاً چیست
پورت عددی است که به یک سرور اجازه میدهد چندین سرویس را همزمان اجرا کند، بدون آنکه ترافیک آنها با هم تداخل پیدا کند. VPS شما یک آدرس IP دارد، اما ممکن است همزمان یک وبسرور، یک سرور SSH و یک دیتابیس را اجرا کند. وقتی بستهای (packet) میرسد، سیستمعامل باید بداند این بسته متعلق به کدامیک است. شماره پورت پاسخ این پرسش است. ترافیک وب به پورت 443 و ترافیک SSH به پورت 22 میرود. آدرس IP بسته را به سرور شما میرساند؛ پورت آن را به برنامه صحیح در آن سرور هدایت میکند.
پورت یک عدد 16 بیتی است: 16 بیت بازهای از 0 تا 65535 ایجاد میکند و چون 0 رزرو شده است، پورتها در عمل از 1 تا 65535 هستند. پورتهای زیر 1024 «پورتهای شناختهشده» (well-known) هستند و برای باز شدن به دسترسی root نیاز دارند؛ به همین دلیل سرویسهای استاندارد در آنجا قرار دارند: 22 برای SSH، 80 برای HTTP، 443 برای HTTPS و 53 برای DNS. هر عددی بالای 1024 برای برنامههای معمولی قابل استفاده است.
دو نوع پورت وجود دارد: TCP و UDP، و شماره پورت در یکی از دیگری مجزاست. TCP پروتکل مبتنی بر اتصال است که اکثر سرویسها مانند SSH، HTTP و دیتابیسها از آن استفاده میکنند. UDP بدون اتصال است و برای مواردی مانند DNS و برخی VPNها به کار میرود. هنگام باز کردن فایروال، معمولاً باید مشخص کنید کدام نوع مد نظر است، برای مثال 22/tcp.
گوش دادن (Listening) به این معناست که یک برنامه منتظر اتصال روی یک پورت است
برنامهای که قصد دریافت اتصالات را دارد، از هسته سیستمعامل (kernel) میخواهد که روی یک پورت «گوش دهد» (listen). از آن لحظه، پورت روی ماشین باز میشود و برنامه به هر چیزی که به آنجا برسد پاسخ میدهد؛ البته این موضوع تابع تنظیمات فایروال نیز هست. پورتی که هیچ برنامهای روی آن گوش نمیدهد، اتصالات را مستقیماً رد میکند. بنابراین، اولین پرسش در هر بررسی امنیتی این است: چه چیزی و در کجا در حال گوش دادن است.
دستور پاسخ به این پرسش ss است:
sudo ss -tlnpفلگهای این دستور به معنای پروتکل TCP (t)، فقط سوکتهای در حال گوش دادن (l)، پورتهای عددی (n، تا به جای ssh، مقدار 22 را ببینید) و پروسه مالک (p) هستند. یک نتیجه معمول به این صورت است:
State Recv-Q Local Address:Port Process
LISTEN 0 0.0.0.0:22 sshd
LISTEN 0 127.0.0.1:5432 postgres
LISTEN 0 [::]:80 nginxستون Process به شما میگوید که کدام برنامه مالک هر پورت است؛ این همان روشی است که با آن میتوانید برنامهای را که نمیخواستید در حال اجرا باقی بماند، ردیابی کنید.
ستون Local Address بخش مهم ماجراست
آدرس مقابل هر پورت را با دقت بخوانید، زیرا تعیین میکند چه کسی میتواند به آن سرویس دسترسی داشته باشد. سه حالت وجود دارد که دائماً با آنها مواجه خواهید شد.
0.0.0.0:22 به این معنی است که «روی تمام آدرسهای IPv4 موجود در این ماشین گوش بده»، که شامل آدرس عمومی آن نیز میشود. اگر فایروال اجازه دهد، این سرویس از طریق اینترنت و با پروتکل IPv4 قابل دسترسی است.
[::]:80 همین مفهوم را برای IPv6 دارد: گوشدادن روی تمام آدرسهای IPv6، از جمله آدرسهای عمومی. بسیاری از برنامهها بهصورت پیشفرض روی این حالت bind میشوند و در لینوکس، یک سوکت :: اغلب ترافیک IPv4 را نیز میپذیرد.
127.0.0.1:5432 به این معنی است که «فقط روی loopback گوش بده». 127.0.0.1 آدرسی است که یک ماشین برای صحبت با خودش از آن استفاده میکند و از هیچ جای دیگری قابل مسیریابی نیست. سرویسی که روی این آدرس bind شده باشد، فقط از داخل همان سرور قابل دسترسی است و فارغ از تنظیمات فایروال، هرگز از اینترنت در دسترس نخواهد بود. آن خط مربوط به Postgres در بالا، ذاتاً امن است.
قانون کاربردی مستقیماً از همینجا استخراج میشود: یک پایگاه داده، یک کش (cache) یا یک پنل مدیریتی که فقط برنامههای خودتان از آن استفاده میکنند، باید روی 127.0.0.1 تنظیم شود، نه 0.0.0.0. اگر سرویسی هرگز روی یک آدرس عمومی گوش ندهد، هیچ راهی برای دسترسی مهاجم به آن وجود نخواهد داشت.
گوش دادن (Listening) با در دسترس بودن (Reachable) متفاوت است
یک تمایز دیگر، از سردرگمیهای بسیاری جلوگیری میکند. باز بودن یک پورت روی دستگاه، به این معنی که برنامهای در حال گوش دادن است، با در دسترس بودن آن پورت از خارج، به این معنی که فایروال اجازه عبور ترافیک را میدهد، متفاوت است. برای اینکه یک کلاینت از راه دور بتواند متصل شود، هر دو شرط باید برقرار باشند. این دو نوع خطا حتی از دید کلاینت نیز متفاوت به نظر میرسند: اتصالی که رد (refused) میشود به این معنی است که هیچ برنامهای در حال گوش دادن نبوده است، در حالی که اتصالی که معلق میماند و در نهایت با خطای timeout مواجه میشود، معمولاً به این معنی است که فایروال بسته را مسدود کرده است؛ این دقیقاً همان چیزی است که آن دو خطای SSH به شما میگویند.
بنابراین دو لایه کنترل وجود دارد. شما با تنظیم bind address هر سرویس، تعیین میکنید چه چیزی گوش دهد. و با استفاده از فایروال، تعیین میکنید دنیای خارج به چه چیزی دسترسی داشته باشد. یک سرور بهینهسازیشده از هر دو استفاده میکند: سرویسها فقط در جایی که نیاز است bind میشوند و فایروال هر چیزی را که صراحتاً اجازه ندادهاید، مسدود میکند. خواندن وضعیت پورتهای در حال گوش دادن با ss گام اول است؛ تصمیمگیری درباره اینکه فایروال چه چیزی را مجاز میداند گام دوم است که در آموزش مقدماتی فایروال با UFW به آن پرداخته شده است.
نکته ظریفی وجود دارد که بسیاری را دچار مشکل میکند. IPv4 و IPv6 از هم جدا هستند و فایروالی که فقط IPv4 را پوشش میدهد، سرویسهای [::] را روی IPv6 باز میگذارد. این تله خاص، مطلب جداگانهای دارد: تله فایروال IPv6.
FAQ
چگونه میتوانم پورتهای باز روی سرور لینوکس خود را ببینم؟
برای پروتکل TCP دستور sudo ss -tlnp و برای پروتکل UDP دستور sudo ss -ulnp را اجرا کنید. این دستورات تمام سوکتهای در حال گوش دادن (listening)، پورت مربوطه، آدرس محلی که به آن متصل هستند و پردازشی که مالک آنهاست را فهرست میکنند. ستون Local Address را بررسی کنید: مقدار 0.0.0.0 یا [::] به این معنی است که سرویس در شبکه در دسترس است، در حالی که 127.0.0.1 نشان میدهد سرویس فقط روی خودِ ماشین گوش میدهد.
تفاوت بین 0.0.0.0 و 127.0.0.1 چیست؟
0.0.0.0 به معنای «گوش دادن روی تمام آدرسهای IPv4» از جمله آدرس عمومی است، بنابراین سرویس از طریق شبکه قابل دسترسی خواهد بود. 127.0.0.1 آدرس loopback است که ماشین برای صحبت با خودش از آن استفاده میکند و از هیچ جای دیگری قابل مسیریابی نیست؛ بنابراین سرویسی که به این آدرس متصل (bind) شده باشد، فقط بهصورت محلی در دسترس است. سرویسهای داخلی را به 127.0.0.1 متصل کنید تا هرگز در معرض شبکه قرار نگیرند.
آیا برای کارکرد یک سرویس باید پورتی را در فایروال باز کنم؟
فقط برای سرویسهایی که باید از ماشینهای دیگر در دسترس باشند. سرویسی که به 127.0.0.1 متصل است نیازی به قانون فایروال ندارد، زیرا هیچ عامل خارجی نمیتواند به آن دسترسی پیدا کند. سرویسی که روی 0.0.0.0 یا [::] قرار دارد، برای عبور ترافیک به قانون فایروال نیاز دارد و بهصورت پیشفرض باید دسترسی آن مسدود باشد تا زمانی که خودتان قانونی برای آن تعریف کنید.
تفاوت بین پورت TCP و پورت UDP چیست؟
پروتکل TCP مبتنی بر اتصال است و توسط اکثر سرویسها مانند SSH، وبسرورها و دیتابیسها استفاده میشود. پروتکل UDP بدون اتصال است و توسط DNS و برخی VPNها استفاده میشود. شمارههای یکسان در TCP و UDP پورتهای مجزایی هستند، بنابراین 53/tcp و 53/udp با هم متفاوتاند. هنگام نوشتن قوانین فایروال، باید پروتکل را مشخص کنید، برای مثال 22/tcp.