টোকেন কোডের জন্য অপেক্ষা করা VPN লগইন কীভাবে স্বয়ংক্রিয় করবেন
টার্মিনালে প্রম্পট করা CLI 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: একজন মানুষের কোড কি স্ক্রিপ্টে থাকা উচিত?
এটিই সেই যাচাই যা মানুষ এড়িয়ে যায়। টোকেন একজন মানুষের, আর সময়সূচি অনুযায়ী ওঠা টানেল মেশিনের।
কোনো কাজ যদি অনর্গল পুনঃসংযোগ করতে হয়, প্রশ্ন করুন মেশিন সার্টিফিকেট বা সার্ভিস অ্যাকাউন্ট ইন্টারঅ্যাকটিভ লগইন প্রতিস্থাপন করতে পারে কি না। কারও এক-বারের কোড স্বয়ংক্রিয় করা দ্বিতীয় ফ্যাক্টরকে সংরক্ষিত সিক্রেটে পরিণত করে, যা স্ক্রিপ্টিং সুবিধা নয় বরং নীতি পরিবর্তন। যেখানে সেবা দুটোই সমর্থন করে, সেখানে কাজটি বাস্তবে যেভাবে চলে তার সঙ্গে মেলা ক্রেডেনশিয়াল বাছুন। উত্তরটি লিখে রাখুন, কারণ পরের মানুষটি জিজ্ঞাসা করবে কেন স্ক্রিপ্ট একটি টোকেন ধরে রাখে।
কর্মরত স্ক্রিপ্ট দেখতে কেমন
স্ক্রিপ্ট কোন ধাপে পৌঁছেছে তা ছাপায়, কখনো সিক্রেট নয়, এবং কোনো প্রত্যাশা ব্যর্থ হলে অশূন্য কোডে বেরিয়ে যায়।
ইচ্ছাকৃতভাবে ভেঙে এটি পরীক্ষা করুন: ভুল পাসওয়ার্ড, ভুল গ্রুপ, মেয়াদোত্তীর্ণ টোকেন। প্রতিটি ব্যর্থতা ঝুলে না গিয়ে নামযুক্ত ধাপে থামা উচিত। তারপর আসল সেবার বিপরীতে এটি একবার চালান এবং স্ক্রিপ্টের ভেতর থেকে নয়, বাইরে থেকে টানেল যাচাই করুন.