چگونه ورود به VPN را که منتظر کد توکن است خودکار کنیم
یک کلاینت VPN خط فرمان که در ترمینال پرسش میکند، اسکریپتی را که فقط رمز عبور را از طریق لوله میفرستد متوقف میکند. پیش از توسل به expect این پنج بررسی را انجام دهید.
اسکریپتی که کلاینت VPN یک فروشنده را اجرا میکند تا پایان مهلت معلق میماند و گزارش نشان میدهد کلاینت کد تأییدی میخواهد که کسی آن را تایپ نکرده است. رمز عبور ارائه شده بود، پس نتیجه آشکار این است که رمز اشتباه است. اینطور نیست. درخواست کد گفتگویی جداگانه روی کانالی جداگانه است و اسکریپت شما هرگز آن را باز نکرد.
پنج بررسی زیر را به ترتیب انجام دهید. در اولین بررسیای که شکست میخورد بایستید، زیرا هر مرحله بعدی فرض میکند مراحل قبلی برقرارند.
بررسی 1: آیا کلاینت اصلاً ورودی استاندارد را میخواند؟
پیش از نوشتن هر خودکارسازی آزمایش کنید: یک رمز ساختگی را از طریق لوله به کلاینت بفرستید و ببینید چه میشود. اگر درخواستش را چاپ کند و سپس منتظر بماند، لوله را نمیخواند.
بسیاری از کلاینتها دستگاه ترمینال را مستقیم باز میکنند، یا از گرفتن رمز از جریانی که ترمینال نیست خودداری میکنند تا لولهای سرگردان رمز عبور را افشا نکند. OpenVPN استثنای مستند است، زیرا --auth-user-pass مسیر فایل را میگیرد. کلاینتهای فروشندگان که کد یکبارمصرف میخواهند معمولاً گزینه معادلی ندارند و درخواستشان منتظر ترمینالی است که اسکریپت شما هرگز فراهم نکرد.
بررسی 2: آیا فرایند فرزند ترمینال دارد؟
pty ترمینالی به فرزند اختصاص میدهد که درخواستها را به خروجی خوانا تبدیل میکند و میتوانید به ترتیب پاسخ دهید.
import pexpect
child = pexpect.spawn("openconnect vpn.example.net", encoding="utf-8", timeout=30)
child.expect("GROUP:")
child.sendline("staff")
child.expect("USERNAME:")
child.sendline("alice")
child.expect("PASSWORD:")
child.sendline(PASSWORD)
child.expect("Connected as", timeout=60)رشتههای درخواست بالا نمونهاند؛ متن دقیقی را که کلاینت شما چاپ میکند کپی کنید، با حروف بزرگ و کوچک و نشانهگذاری. هر انتظار مهلت دارد و فرزند بسته بهجای بازگرداندن وضعیت استثنا میاندازد، پس دنباله را بپیچید و پایان فایل را شکست بدانید. توجه کنید این بخش چه نمیکند: فرزند با اسکریپت میمیرد، زیرا pty سازوکار جداسازی نیست و disown یک دستور توکار پوسته است که به فرایندی که اسکریپت شما ساخته نمیرسد.
بررسی 3: آیا ورودی غیرتعاملی پشتیبانیشدهای وجود دارد؟
خراشیدن صفحه در ارتقای کلاینت میشکند، پس نخست گزینه مستند را جستجو کنید.
خروجی راهنما را برای گزینه توکن یا کد یکبارمصرف بررسی کنید و ببینید سرویس کدِ افزوده به فیلد رمز عبور را میپذیرد یا نه. جایی که کلاینت فایل اعتبارنامه میخواند، فایل را به آن بدهید نه درخواست:
openvpn --config office.ovpn --auth-user-pass <(printf "%s\n%s\n" "$USER_NAME" "$PASSWORD")جانشینی فرایند به کلاینت مسیر خوانا میدهد در سامانههایی که /dev/fd را فراهم میکنند. رمز از دید کلاینت هنوز رمز است، پس آن را از گزارشها، تاریخچه پوسته و فهرست فرایندها دور نگه دارید. اگر کلاینت /dev/fd را رد کند یا مسیر اعتبارنامه را بیش از یک بار باز کند، فایلی واقعی با مجوزهای محدود بنویسید و در همان اسکریپت پاکش کنید.
بررسی 4: آیا تونل از اسکریپت بیشتر زنده میماند؟
بهطور پیشفرض تونل با والدش میمیرد، که عکس چیزی است که اسکریپت راهاندازی لازم دارد.
disown -h تنها زمانی کمک میکند که کلاینت را بهعنوان کاری در پوسته اجرا کرده باشید، زیرا جدول کارهای همان پوسته را ویرایش میکند و به فرایندی که اسکریپت شما با pty ساخته نمیرسد. مدیر سرویس خانه بهتری برای هر چیزی است که باید بینظارت دوباره متصل شود، زیرا کلاینت را دوباره اجرا میکند و ثبت میکند چرا مرد. در هر حال، پس از هر اتصال دوباره کد تازهای انتظار داشته باشید: توکن یکبارمصرف با نخستین احراز هویت موفق مصرف میشود.
ببینید sudo با دنباله چه میکند. درخواست رمز sudo درخواست VPN نیست و پاسخ دادن به آن با رمز VPN شایعترین راهی است که ترتیب انتظارِ درست در بقیه موارد باز هم شکست میخورد.
بررسی 5: آیا کد یک شخص باید در اسکریپت باشد؟
این همان بررسی است که مردم از آن میگذرند. توکن به یک شخص تعلق دارد، در حالی که تونلی که باید طبق برنامه بالا بیاید به ماشین تعلق دارد.
اگر کاری باید بینظارت دوباره متصل شود، بپرسید آیا گواهی ماشین یا حساب سرویس میتواند جای ورود تعاملی را بگیرد. خودکار کردن کد یکبارمصرف کسی، عامل دوم را به رمزی ذخیرهشده تبدیل میکند، که تغییری در سیاست است نه آسودگی در نوشتن اسکریپت. جایی که سرویس هر دو را پشتیبانی میکند، اعتبارنامهای را برگزینید که با نحوه واقعی اجرای کار میخواند. پاسخ را بنویسید، زیرا نفر بعدی میپرسد چرا اسکریپت توکنی نگه میدارد.
اسکریپت کارآمد چه شکلی است
اسکریپت مرحلهای را که به آن رسیده چاپ میکند، هرگز رمز را نه، و در هر انتظار ناموفق با کد غیرصفر خارج میشود.
آن را با شکستن عمدی آزمایش کنید: رمز اشتباه، گروه اشتباه، توکن منقضی. هر شکست باید در مرحلهای نامدار بایستد نه اینکه معلق بماند. سپس یک بار آن را در برابر سرویس واقعی اجرا کنید و تونل را از بیرون اسکریپت بررسی کنید، نه از درون آن.