خوب، اول از همه، من میدانم ممکن است افردای نیز هم اکنون درحال خواندن این مطلب باشند که حتی پرسش را متوجه نمیشوند. اینجا، این کد کار نمیکند:
{ echo oldpass; echo newpass; echo newpass; } | passwd # !این کار نمیکند
اصلاً کاری نمیتوانید بکنید که بتواند در bash عملی بشود. passwd(1) از ورودی استاندارد نمیخواند. این مطلب تعمدی است. برای حراست از شماست. هرگز کلمات عبور برای قرار گرفتن در برنامهها یا تولید شدن توسط برنامهها در نظر گرفته نشدهاند. آنها برای آن در نظر گرفته شدهاند که با انگشتان یک انسان حقیقی، با یک ذکاوت عملیاتی وارد بشوند، و هرگز اصلاً در جایی نوشته نشوند. بنابراین قبل از اینکه ادامه بدهید، احتمالی را که مؤلفین passwd(1) در فکر آن بودند، درنظر بگیرید، و شاید شما نباید سعی در اسکریپت نمودن ورودی passwd(1) بنمایید.
با این وجود، انبوهی پرسش از کاربران به دست ما میرسد که آنها چگونه میتوانند 35 سال امنیت یونیکس را خنثی کنند. و همکاری اشخاصی با راه حلهای مطلوبِ حذف امنیت را با این صفحه مشاهده میکنیم. اگر شما بازهم فکر میکنید آنچه میخواهید این است، ادامه دهید.
اولین رویکرد، ساختن کلمه عبور بهم ریخته خودتان(DES، MD5، Blowfish، یا هر چیزی که سیستم عامل شما استفاده میکند) با استفاده از ابزارهای غیر استانداردی از قبیل http://wooledge.org/~greg/crypt/ یا بسته mkpasswd دبیان/اوبونتو، را شامل میشود. سپس باید آن کلمه عبور درهم ریخته را همراه با فیلدهای اضافی در یک سطر از فایل password-hash سیستم محلی خودتان (شاید /etc/passwd، یا /etc/shadow، یا /etc/master.passwd، یا /etc/security/passwd، یا ... باشد) بنویسید. این کار نیاز به آن دارد که شما صفحات man در سیستم خود را بخوانید، تا دریابید پسورد بهمریخته کجا قرار میگیرد، فایل چه قالببندی نیاز دارد، و سپس کُدی ایجاد کنید که آنرا در آن قالب به تفصیل بنویسد.
یک گونه فرعی آن، مستلزم استفاده از یک ابزار سیستمی خاص برای نوشتن سطرِ کلمه عبور درهم ریخته طراحی شده شما، میباشد. برای مثال، در دبیان/اوبونتو، useradd -m joe -s /bin/bash -p "$(mkpasswd "$password")" به طوری که ما فهمیدهایم، میتواند کارکند.
دومین رویکرد استفاده از expect یا معادل python آن است. من گمان میکنم expect حتی دقیقاً این موضوع را به عنوان یکی از مثالهای رسمیاش دارد.
سرانجام، ابزارهای سیستمی طراحی شده برای این مقصود ممکن است از قبل در سیستم شما موجود باشد. برای مثال، بعضی از سیستمهای گنو-لینوکس دارای فرمان newusers(8) هستند که به طور خاص برای این منظور طراحی شدهاند، یا ابزار chpasswd(8) که میتواند وادار به انجام انواعی از این کارها بشود. یا ممکن است یک پرچم --stdin در فرمان passwd خود داشته باشند. همچنین فرمانهایی از قبیل apropos users یا man -k account را برای دیدن مورد دیگری که شاید وجود داشته باشد امتحان کنید. خلاق باشید.
همچنین پرسش و پاسخ 69 -- میخواهم یک ارتباط ssh (یا scp، یا sftp) را خودکار نمایم، اما نمیدانم چطور کلمه عبور را ارسال کنم را ببینید.
در کنار این مطلب، عکس این پرسش نیز مشکلی است. حداقل تحت لینوکس ، پنهان کردن برنامه به نحوی که ترمینال کنترل کننده وادار شود به طور انتزاعی به هر نوع ورودی و خروجی دلخواه شما متصل بشود، امری بدیهی است. این به معنای آنست که از نطر امنیتی بسیار دشوار است تضمین شود که واقعاً یک کاربر با دسترسی محلی است که به طور مستقیم از صفحه کلید، ورودی را به برنامه شما میدهد. غالباً اشخاص این کار را با خواندن از /dev/tty انجام میدهند. این درست مانند روشی است که برنامه passwd عمل میکند، فقط قدم کوچکی در سست کردن عادات امنیتی نا مناسبی نظیر ذخیره کلمات عبور در فایلهای متن ساده است. کد زیر Bash را اجرا میکند، که برنامهای در FD 3 را میخواند که به طور غیر هوشمندانه ورودیاش را از طریق یک لوله (که به آسانی میتوانست دقیقاً یک فایل باشد)، با استفاده از یک تابع کتابخانه استاندارد پایتون میخواند.
~ $ { echo 'o hi there' | python -c 'import pty; pty.spawn(["bash", "/dev/fd/3"])'; } <<"EOF" 3<&0- <&2 # ممانعت میکند، اثر واقعی ندارد echo از قطع ارتباط ورودی استاندارد <&2 { stty -echo read -p 'Password: ' passw printf '\n%s\n' "password is: $passw" stty echo } </dev/tty EOF o hi there Password: password is: o hi there # نگارش بدون استفاده از پایتون #{ echo 'o hi there' | script -c "bash /dev/fd/3" /dev/null; } <<"EOF" 3<&- 3<&0- <&2 # لینوکس { echo 'o hi there' | script -q /dev/null bash /dev/fd/3; } <<"EOF" 3<&- 3<&0- <&2 # FreeBSD و Mac OS X در { stty -echo read -p 'Password: ' passw printf '\n%s\n' "password is: $passw" stty echo } </dev/tty EOF
علاوه بر این، خواندن از /dev/tty کمی رنجش آور است زیرا طریقهای که کاربران انتظار دارند تغییر مسیرهایشان عمل کنند را نقض میکند. پس این کار را انجام ندهید. بهتر است از [[ -t 0 ]] جهت بازرسی tty و رفتار کردن بر طبق موقعیت استفاده کنید. حتی موقعی که یک مدیر سیستم رفتار معینی را انتظار دارد که بر اساس آن I/O را تغییر میدهد، این مطلب میتواند رنجش آور باشد. اگر شما باید یکی از این ترفندها را به کار ببرید، آن را مستند کنید، و گزینهای برای غیر فعال نمودن رفتار مشروط I/O فراهم نمایید.
پرسش و پاسخ 78 (آخرین ویرایش 2013-03-28 10:54:50 توسط p54A33276)