Vahid
Vahid
خواندن ۷ دقیقه·۴ سال پیش

درک عمیق‌تری از ssh

اگر با سرور سروکله زده باشین(یا دارید می‌زنید) می‌دونید امورات زندگی به کمک ssh می‌گذره(یادش بخیر چند سال قبل برای کاری یک سرور بهم دادن و چون cli(خط فرمان) بلد نبودم، روی سرور دسکتاپ نصب کردم و با rdp بهش وصل میشدم!!!!! خدایا توبه، جوون بودم خامی کردم! D:). اما نحوه شکل گیری این ارتباط از اون دست مطالبیه که دونستن‌ش باعث درک بهتر ماجرا میشه. مثلا تو ansible اگر اجرای playbook رو با vvvv انجام بدیم، مرحله به مرحله این ماجرا رو نشون میده.

نکته ۱: بعضی از جمله‌ها با م ssh شروع میشه اونم دلیلش اینه که تو ویرگول اگر اولین حرف انگلیسی باشه، align پاراگراف به left to right تبدیل میشه(یا حداقل من بلد نیستم چطوری درستش کنم)، به خاطر همین حرف م اول پاراگراف گذاشته میشه تا alignment راست به چپ حفظ بشه.

نکته ۲: مقدمه به توضیح مفاهیم ابتدایی می‌پردازه، پس اگر با این مفاهیم آشنا هستید می‌تونید از مطالعه این بخش صرف نظر کنید.

مقدمه

م ssh مخفف secure shell هستش و برای ایجاد یک ارتباط امن ایجاد شد، دلیلش هم اینه که استفاده از telnet باعث میشه که رمزنگاری نداشته باشیم و این مقادیر به صورت متن واضح(clear text) انتقال پیدا می‌کنه، که نتیجه این ماجرا هم مشکلات امنیتی خواهد بود. بهتر بخوایم بگیم ssh یک پروتکل برای ارتباط امن بین دو تا کامپیوتر استفاده میشه. مخفف کلمه secure shell که تو فارسی گاها به پوسته امن هم ترجمه شده. ssh روی tcp و پورت ۲۲(البته این پورت پیشفرضه و میشه عوضش کرد) به کانکشن‌ها گوش میده و برای کانکشن‌های ورودی یک سری مراحل طی میشه تا اون‌ها امنیت لازم را داشته باشند. برای برقراری ارتباط امن از رمزنگاری استفاده می‌کنه. بحث رمزنگاری هم به کمک سه تکنیک انجام میشه:

  • کلید مقارن(Symmetrical encryption)

(هر دو طرف با یک کلید یکسان یک چیزی رو رمزنگاری یا رمزگشایی می‌کنند به عنوان مثال الگوریتم AES)

  • کلید نامتقارن(Asymmetrical encryption)

(چیزهایی مثل RSA و استفاده از کلید عمومی و کلید خصوصی)

  • درهم‌سازی(Hashing)

(مثل یک تابع یک طرفه که یک چیزی رو ورودی می‌گیره و یک چیز درهمی رو به عنوان
خروجی تحویل میده. این تابع برای یک ورودی ثابت یک خروجی ثابت خواهد داشت)

https://sudonull.com/post/15682-SSLH-Hide-SSH-HTTPS-OpenVPN-Telegram-behind-a-single-port-443
https://sudonull.com/post/15682-SSLH-Hide-SSH-HTTPS-OpenVPN-Telegram-behind-a-single-port-443

روند مذاکره

به طور کلی خیلی خلاصه بخوام بگم روند کار اینطوریه(بخش پایین برای اینکه اگر خواستین برای یکی توضیح کلی بدین که روند کار چطوریه، یک ایده‌ای داشته باشید D:):

− ماشین اولی به ماشین دومی میرسه ماسکشو میده پایین(متاسفانه بعضیا تو این کرونا پروتکل‌های بهداشتی رو رعایت نمی‌کنند) و میگه: پیس پیس، سلام علیرضا حسینی تویی(مرحله ایجاد ارتباط − این مراحل به صورت فنی پایین‌تر توضیح داده میشه)؟

+ ماشین دومی برمیگرده میگه: سلام، بله بفرمائید یک کارت شناسایی نشون میده(داداش مگه پلیسه بهش کارت شناسایی نشون میدی؟ - مرحله نمایش کلید عمومی سرور).

− ماشین اولی: حله داداش(مرحله تایید کلید) و اروم در گوشش میگه، اقا من یه کاری باهات داشتم ولی اینجا نمیشه گفت(در حین گفتن این حرف یک نگاهی هم به اطراف میندازه - شروع فرایند دیفی-هلمن)!

+ ماشین دومی: بهش یه چشمک میزنه که یعنی حله( انگار ۱۸۹۴ئه و اینام عضو انجمن زیرزمینی - مرحله توافق بر سر کلید اولیه)

− ماشین اولی: دستشو دراز میکنه که دست بده، در حالی که یک چیزی تو دستشه(به نظرتون دستش تمیزه؟مرحله تبادل کلید)!!

+ماشین دومی: دستش رو دراز می‌کنه اون چیز رو می‌گیره و خودشم همزمان یک چیزی میده به اون ور(بیاین مثبت فکر کنیم بچه‌ها).

−بعد ماشین اول میگه: dsfdsf#$#%$GVSD#$RWR@#F بله متاسفانه ما نامحرم بودیم و دیگه نمی‌تونیم بفهمیم چی گفتن بهم(البته که ما همچنان دیدمون مثبته - استفاده از کلید اشتراکی جلسه و امن شدن ارتباط)!

× این روند اینجا تموم نمیشه و بعد مرحله بالا مرحله احراز هویت شروع میشه.

http://rabexc.org/posts/using-ssh-agent
http://rabexc.org/posts/using-ssh-agent

احتمالا دارید میگید این چرت و پرتا چیه؟ فنی بگو! واقعیت اینه حق با شماست و خودمم نمیدونم در لحظه چه فعل و انفعالی تو مغزم گذشت که این بخش بالا رو نوشتم(شاید به خاطر اینکه ۱۱ شبه و من هنوز شام نخوردم)!! ولی بریم سراغ روند فنی ماجرا.

− ماشین اول یک ارتباط tcp با ماشین هدف ایجاد می‌کنه.

− ماشین دوم لیست پروتکل‌هایی که پشتیبانی می‌کنه رو بهش میده، به همراه کلید عمومی خودش.

− ماشین اول یکی از پروتکل‌ها رو انتخاب می‌کنه. اون کلید عمومی هم برای اینکه بررسی کنه ببینه که آیا ماشینی که باهاش ارتباط گرفته شده، همونی هست که میخوایم یا نه؟

در واقع اونجا که تو ترمینال بهمون یک چیز عجیب غریب بهمون نشون میده تا تایید کنیم این
همون کلید عمومی ماشین هدفه. بعد از اینکه تاییدش کردیم، این کلید عمومی توی ماشین خودمون توی فایل known_hosts در ~/.ssh ذخیره میشه. این ذخیره کردن کلید عمومی(به همراه یکی سری اطلاعات دیگه) باعث میشه تا تو ارتباط‌های بعدی روند تایید کلید عمومی اون به صورت خودکار انجام بگیره و نیازی به تایید دوباره ما نباشه. نمونه‌ای از چیزی که ذخیره میشه رو تو تصویر پایین نشون داده شده:

نمونه اطلاعاتی که توی فایل known_hosts ذخیره شده
نمونه اطلاعاتی که توی فایل known_hosts ذخیره شده

− بعد از این دو تا ماشین با کمک الگوریتم دیفی-هلمن بر روی یک کلید که بهش session key توافق می‌کنند. در واقع این کلید برای بخش رمزنگاری متقارن و کلید اون استفاده خواهد شد. انتقال اطلاعات بین این دو ماشین به کمک این کلید رمز خواهد شد. شاید سوالی پیش بیاد که چرا از همون کلید عمومی و خصوصی برای انتقال اطلاعات استفاده نشد باید عرض کنم که رمزنگاری نامتقارن هزینه بیشتری رو برای رمزنگاری/گشایی داره. به عنوان مثال نسبت به رمزنگاری متقارن کندتر هستند.

بزارید برای درک بهتر یک توضیح خلاصه‌ای هم از الگوریتم دیفی-هلمن داشته باشیم، این توضیح رو هم به کمک رنگ‌ها انجام میدیم تا ملموس‌تر باشه. اول کار دو طرف روی یک رنگ با هم توافق می‌کنند(مثلا روی رنگ زرد). این انتخاب عمومیه و اگر کسی اون ارتباط رو شنود کنه از این رنگ آگاه هستش. بعد هر طرف برای خودش یک رنگ رو در نظر می‌گیره و به هیچ کس نمیگه(مثلا من قرمز رو انتخاب میکنم و طرف مقابل هم سبز رو). چون این رنگ رو به کسی نگفتم پس پیش من محرمانه مونده و شنود هم تاثیری تو ماجرا نداره. حالا این رنگ زردی که اول کار توافق کرده بودیم رو با رنگی که خودم انتخاب کردم(قرمز) قاطی می‌کنم و میدم به طرف مقابل(طرف مقابل من هیچ ایده‌ای نداره من چه رنگی انتخاب کردم). اون هم همین کار رو می‌کنه، یعنی رنگ زرد رو با سبز که خودش انتخاب کرده قاطی می‌کنه و میده به من(منم هیچ ایده‌ای از انتخاب اون ندارم). حالا بخش جالب ماجرا اتفاق میوفته. من رنگ خودم یعنی قرمز رو به ترکیب طرف مقابل(یعنی ترکیب زرد و سبز) اضافه می‌کنم و طرف مقابل من هم سبز رو به ترکیب من(یعنی زرد و قرمز) اضافه می‌کنه و بووم هر دو می‌رسیم به یک ترکیب رنگ ثابت(کلید)!! [نکته اینکه تو ریاضی ترتیب ضرب کردن اعداد تاثیری تو نتیجه نهایی نداره]

https://skerritt.blog/diffie-hellman-merkle/
https://skerritt.blog/diffie-hellman-merkle/

خب بالاخره ارتباط ما امن شد و حالا تازه می‌رسیم به اینکه ببینیم که آیا طرفی که میخواد به ماشین هدف دسترسی داشته باشه، آدم درستی هست یا نه(یعنی رمز عبور یا هر چیزی که داده درسته یا نه)؟

احراز هویت

برای احراز هویت چند روش وجود دارد که راحت‌ترین روش، استفاده از رمز عبوره، یعنی کاربر میگه می‌خوام به عنوان فلان کاربر وصل شم اینم رمزش. ماشین هدف هم خیلی عادی میره چک میکنه ببینه که اطلاعاتی که داده شده درسته یا نه؟ این ارسال اطلاعات(رمزعبور اینا) هم توی همون ارتباط امن ایجاد شده انجام میشه.

اما روش پیشنهاد شده استفاده از احراز هویت با استفاده از جفت کلیدهای ssh هستش(تو این روش باید کلید عمومی ماشین اول تو ماشین هدف کپی شده باشه یا یک جفت کلیدی باشه که به هر نحوی کلید عمومی دست ماشین هدف و کلید خصوصی دست ماشین اول باشه)! روند کار چطوریه؟

− ماشین اول یک شناسه برای ماشینی که میخواد بهش وصل بشه رو میفرسته و میگه این شناسه کلید منه.

− ماشین هدف میره سراغ کلیدهایی که تو خودش ذخیره داره و دنبال اون کلیدی که ماشین اول گفته میگرده.

− بعد از اینکه کلید رو پیدا کرد(اگر پیدا نکرد میگه به سلامت ما شمارو نمی‌شناسیم) یک عدد تصادفی ایجاد می‌کنه و اون با کلید عمومی ماشین اول رمز می‌کنه و برای ماشین می‌فرسته(و میگه اگر راست میگی این عبارت رو رمزگشایی کن ببینم).

− ماشین اول پیام دریافتی رو با کلید خصوصی رمزگشایی می‌کنه و عدد تصادفی که ماشین هدف ایجاد کرده بود را با کلید جلسه(session key) که تو مرحله امن کردن ارتباط ایجاد شده بود ترکیب می‌کنه و از MD5 استفاده می‌کنه تا درهم‌ش رو پیدا کنه(hashing) و به ماشین هدف ارسال می‌کنه.

− ماشین هدف عدد تصادفی که ایجاد کرده بود رو با کلید جلسه ترکیب و MD5 می‌گیره اگر با این مقدار با مقداری که ماشین اول فرستاده یکی باشه میگه بله درسته شما احراز هویت شدی و یک shell بهش میده میگه بیا کاراتو بکن.

https://spectralops.io/blog/guide-to-ssh-keys-in-gitlab/
https://spectralops.io/blog/guide-to-ssh-keys-in-gitlab/

همین! لبخند بزنین لطفا :)

منابع:

  • https://www.digitalocean.com/community/tutorials/understanding-the-ssh-encryption-and-connection-process
sshserverssh serverdevops
یه وحید از نوع برنامه نویسش :)
شاید از این پست‌ها خوشتان بیاید