Act like a big brother
توسط: vahit
سلام
موقعیتهای کمی پیش میاد ولی تا الان دوبار مجبور شدم دسترسی سروری که مسئولیتش با من هست رو به کسی بدم که هیچ تعهدی نسبت بهش نداره (یا اگر داره خیلی کم) برای همین به نظرم عاقلانهس که در لحظه بتونم ببینم چه کاری داره روش انجام میده. ولی خب چطوری؟
بخوام جوابی که پیدا کردم رو به شکل کوتاه بگم میشه: استفاده از screen
Screen ابزاری هست که امکان ایجاد پنجرههای متعدد از ترمینال رو میده (امیدوارم تونسته باشم خوب تعریفش کنم :-/) میشه باهاش کارهای مختلفی انجام داد ولی چیزی که مد نظر من هست اتصال به یک session از مکانهای مختلفه. (اگر باهاش آشنایی ندارید توصیه میکنم این پست از Tecmint رو بخونید.)
امّا سناریو: همهی کانکشنهای ssh رو میبرین روی یه session تا بتونیم کاری که مهمونمون روی سرور در حال انجامش هست رو ببینیم.
قطعاً من نمیتونم به طرف مقابلم بگم «لطفاً هر موقع خواستی کانکت بشی اوّلاً به من خبر بده، دوّما حتماً داخل فلان session کارهات رو انجام بده تا من هم ببینم.» میخوام غیر از اینکار چارهی دیگهای نداشته باشه (My server, My rules ). پس مییام توی home کاربری که دسترسیش رو بهش دادم یه فایل .bash_profile میسازم با محتویات زیر:
1 2 3 4 5 6 7 8 9 |
HAVE_SOCKET=$(screen -list | grep -i "attached\|detached" | wc --lines) if (( ${HAVE_SOCKET} == 0 )); then # There is no running screen session. # Creating new screen session exec screen -s bash else # Attaching to existing screen session. exec screen -x fi |
این فایل موقع ایجاد session با این کاربر خونده و محتویاتش اجرا میشه. با این فایل من تعداد sessionهای موجود رو میخونم (خط اوّل) و اگر sessionی موجود بود مستقیم به همون وصل میشم (خط هشتم) و اگر هیچ sessionی موجود نبود یکی میسازم و بهش وصل میشم (خط پنجم). خب طبیعی هست که اوّلین کاربر session رو میسازه و کاربرای بعدی همگی به همون وصل میشن.
امّا توی این فایل یکی دوتا نکته هست که به نظرم مهم هستن.
اوّل اینکه برای اجرای دستورات از exec استفاده کردیم، میشد بدون اون هم دستورات رو نوشت و نتیجه هم گرفت امّا نکتهی مهم اینه که با این کار اگر کاربر جدید sessionش رو ببنده (حالا به هر طریقی) دوباره بر میگرده به خود سرور و از دید من خارج میشه. یعنی کاربر خیلی راحت با زدن Ctrl+d میتونه رشتههای من رو پنبه کنه. ولی وقتی من از exec استفاده میکنم وقتی کاربر session رو میبنده به کل ارتباطش با سرور قطع میشه و مجبور هست دوباره کانکت بشه. یعنی بر میگرده به نقطهی اوّلش! حالا هر چند بار که میخواد :-))
نکتهی دوّم این هست که من برای شروع session از دستور screen -s bash استفاده کردم تا موقع ایجاد session جدید دیگه اون متن ابتدایی که نیاز به space یا Enter برای شروع داره رو نبینم و مستقیم برم داخل session. دفعهی قبل از همین طریق لو رفتم. هر چند کاربر بازم با دستور screen -list هم میتونه متوجه بشه که داخل screen هست ولی همون دفعهی اوّل خیلی سخته که اصلاً به موضوع فکر کنه.
یه نکتهی مهم دیگه این هست که وقتی من داخل یه session دارم رفتار مهمون رو نگاه میکنم وقتی مهمون عزیزتر از جانم session خودش رو میبنده من هم از این طرف پرت میشم بیرون. چون کل session screen کیل شده. خب مهمون هنوز دسترسی داره و ممکنه کلاً من رو گول بزنه و دوباره کانکت بشه :-؟
کاری که کردم این بود که یه حلقهی بینهایت نوشتم و توش به سرور وصل شدم. یعنی هر چندبار که ارتباط من با سرور قطع میشد سریع یکی دیگه ایجاد میشد:
1 2 3 |
while True; do ssh <server> done |
و خب چون من با ssh key به سرور کانکت میشم تا مهمونم بخواد پسورد رو بزنه دوباره میبینه من نشستم تو session :-)))
در آخر هم بعد از اینکه پسورد رو عوض کردین کافیه فایل .bash_profile رو به یه چیز دیگه تغییر اسم بدین یا کلاً پاکش کنید تا دسترسیهای بعدی خودتون هم دچار مشکل نشه.
تمرین در خانه: حالا فرض کنید کار مهمون تموم شد و شما پسورد رو عوض کردین، چطوری این حلقهی بینهایت رو میخواین بشکنین؟ :-)))
نمیدونم دقیقا از کجا به اینجا رسیدم ولی، جدای از این داستان بین برنامهنویسها و سیسادمینها و این که چقد این کار خوبه یا بده و این حرفا.
صرفا گفتم بدونی که روشت اصلا قابل اعتماد نیست. سادهترین راه حل اینه که من با یه شل دیگه وصل بشم به سرورت.
ssh -t /bin/sh
و خب اصن وصل نمیشه به bash که بخواد screen تو رو اجرا کنه. یا اصلا هر کامندی که میخوام رو مستقیم با خود کامند ssh اجرا کنم. برای این که screen هم همیشه اجرا باشه هم روشهای خیلی بهتری هست. البته چون استفادههای دیگهای داره.
در مورد درستی و نادرستی کار خیلی قبلتر از این پست باهاش درگیرم و هنوز هم به نتیجهی معقول نرسیدم:
https://twitter.com/VahidMaani/status/1006444324903702528
در مورد غیرقابل اعتماد بودنش و این دوتا ایرادی هم که گفتی دقیقاً حق با شماست. این تنها چیزی بود که توی یک ربع فرجهای که برای ارسال اطلاعات ورود گرفته بودم به ذهنم رسید و برای اون دو مورد جواب قانع کنندهای بهم داد. و هدفش از نوشتن صرفاً ارائهای بود برای دوستانی که درخواست کرده بودن.
خیلی خوشحال شدم که خوندی و ایراداتش رو گفتی.
خوشحالتر میشم اون روشهای دیگهای که گفتی رو هم بهمون یاد بدی :-))
هوم، برای دادن دسترسی به پشتیبانی اگه که من بودم بهش میگفتم ریموت بزن به داخل ویرچوال ماشین من از داخل سیستم من اساساچ بزن.
برای اون هم من از tmux استفاده میکنم و حداقل oh-my-zsh میدونم یه پلاگین داره برای اینکه همیشه وصل بشه به tmux که همینکاری که میخوای رو میکنه. ولی خب برای راحتی کار و اینا استفاده میشه، اگه همیشه وصل میشی سرور 4 5 تا چیز مشخص رو میاری بالا، راحت تره که یه سشن باز بزاری همیشه به اون وصل شی.
نکتههای خوبی بود مرسی.
حالا اگر وقت داشتی یه پست بنویس راهحل خودت رو توضیح بده خوشحال میشم :-)