ایجاد یک ارتباط امن با Reverse SSH

 

تقریبا همه حداقل یکبار ارتباط ssh بین سرور و کلاینت را ایجاد کرده اند. در اکثر شبکه ها این ارتیاط یکطرفه است یعنی فقط از کلاینت به سرور ssh میشه وصل شد. حالا تصور کنید از یک سرور روی اینترنت میخواهید به یک کلاینت ارتباط بگیرید ولی پشت فایروال و همینطور NATبر روی شبکه قرار دارید که این‌کار غیر ممکن میشه. اینجا راه حلی که خیلی به درد بخور  Reverse SSH هست.

به شکل زیر دقت کنید شما ارتباط یکطرفه از A  به سرور B دارید همینطور از C به B  و حالا تصمیم دارید برخلاف میل مدیر شبکه فایروال و قواعد سازمان را دور بزنید 🙂 و یک ارتباط از C به A برقرار کنید.

 

 

راه حل این هست که یک تونل Reverse SSH از B به A برقرار کرده و سرور B را به عنوان SSH Server Gateway استفاده کنید، که باید یک سرور لینوکس باشه.

اگر از کلاینت و سرور ویندوز استفاده میکنید برنامه putty را روی هر دو سیستم مبدا و مقصد نصب کنید.

از روی سرور A برنامه putty را اجرا کرده و در بخش SSH – Connection – Tunnel را انتخاب و مقدار Source Port را یک پورت آزاد مثل 50000 انتخاب کنید این پورتی هست که بر روی سرور SSH باز خواهد شد. مقدار Destination برابر با پورتی که میخواهید بر روی سرور دسترسی داشته باشید انتخاب کنید برای مثال 8080 پس مقدار این فیلد برابر با localhost:8080 خواهد شد. حالا گزینه  Remote را انتخاب و ارتباط SSH را با سرور B یرقرار کنید. در اینجا پورت 50000 بر روی SSH Server باز و ارتباط تونل بین دو سرور برقرار خواهد شد.

حالا بر روی کلاینت C برنامه putty را اجرا کنید و در همان بخش SSH – Connection – Tunnel مقدار Source Port برابر با یک پورت آزاد مثل 50005 قرار داده و در فیلد Destination مقدار localhost:8080 را قرار داده و ارتباط SSH از کلاینت C به سرور B را برقرار کنید.

حالا اگر شما بر روی کلاینت C پورت 50005 را فراخوانی کنید به پورت و یا برنامه ای که بر روی سرور A بر روی این پورت در حال اجرا هست دسترسی خواهید داشت.

سیستم های لینوکسی مراحل خیلی ساده تر هست.

بر روی سرور A دستور زیر را اجرا کنید:

user@server-a:~$ ssh -R 50000:localhost:22 user@ssh-server-b

از روی کلاینت C دستور زیر را اجرا کنید:

user@client-c:~$ ssh user@ssh-server-b

user@ssh-server-b:~$ ssh localhost -p 50000

الان دسترسی شما به سرور A و پورت 22 برقرار خواهد بود.

 

تقسیم یک فایل به چند بخش با dd

 

دیروز یه فایل تقریبا بزرگ در حدود 250GiB روی یک datastore متصل به سرور ESXi داشتیم که باید به یک سرور لینوکس دیگه منتقل میشد. امکان اتصال storage به سرور وجود نداشت، وضعیت شبکه هم بسیار کند و ناپایدار بود. راحترین راه که به ذهن رسید انتقال با scp از روی esxi به سرور بود ولی اگر شبکه در موقع انتقال قطع می شد یا اختلال داشت باید تمام مراحل را از اول انجام می‌دادیم پس فایل را به چند قسمت تقسیم کردیم و انتقال دادیم که در صورت خرابی فقط مجبور به انتقال یک بخش از فایل باشیم.

حجم فایل در حدود 250GiB بود، اون را به بخش‌های 50GiB تقسیم می کنیم.

 

dd if=/vmfs/volumes/ds-04/xyz.img bs=1MB count=51200  | ssh user@192.168.66.6 dd of=/home/user/xyz.img.pt01

 

اینجا چون اندازه هر بلاک را 1MiB در نظر گرفتیم و به 50 گیگابایت ابتدای فایل نیاز داشتیم تعداد 51200 بلاک اول را جدا کردیم. و خروجی را با دستور ssh مستقیما به سرور remote ارسال کردیم تا فایل در هنگام تقسیم بر روی دیسک مقصد نوشته شود.

برای بخش بعدی می نویسیم:

 

dd if=/vmfs/volumes/ds-04/xyz.img bs=1MB count=51200  skip=51200 | ssh user@192.168.66.6 dd of=/home/user/xyz.img.pt02

 

که با سوئیچ skip از 51200 بلاک اول صرف نظر کردیم. و همینطور تعداد بلاک‌ها را افزایش می‌دهیم تا به انتهای فایل برسیم:

 

dd if=/vmfs/volumes/ds-04/xyz.img bs=1MB count=51200  skip=102400 | ssh user@192.168.66.6 dd of=/home/user/xyz.img.pt03

dd if=/vmfs/volumes/ds-04/xyz.img bs=1MB count=51200  skip=153600 | ssh user@192.168.66.6 dd of=/home/user/xyz.img.pt04

dd if=/vmfs/volumes/ds-04/xyz.img bs=1MB count=51200  skip=204800 | ssh user@192.168.66.6 dd of=/home/user/xyz.img.pt05

 

حالا بر روی دیسک مقصد پنج فایل داریم که باید به یک فایل تبدیل بشوند برای این کار این دستور را می نویسیم:

 

cat /home/user/xyz.img.pt0* | dd of=/home/user/xyz.img

 

این ساده‌ترین راهی بود که با دستورات عادی به ذهن من رسید، مسلما دستورات و روش‌های دیگه ای هم وجود دارند 🙂