Skrip yang memulakan klien VPN vendor tergantung sehingga tamat masa, dan log menunjukkan klien meminta kod pengesahan yang tiada siapa menaipnya. Kata laluan telah diberikan, jadi kesimpulan yang jelas ialah kata laluan itu salah. Ia bukan. Permintaan kod ialah perbualan berasingan pada saluran berasingan, dan skrip anda tidak pernah membukanya.

Lakukan lima pemeriksaan di bawah mengikut urutan. Berhenti pada yang pertama gagal, kerana setiap langkah seterusnya menganggap yang sebelumnya masih sah.

Pemeriksaan 1: adakah klien membaca input standard sama sekali?

Uji sebelum menulis sebarang automasi: salurkan rahsia palsu ke dalam klien dan lihat apa yang berlaku. Jika ia mencetak permintaannya kemudian menunggu, ia tidak membaca paip itu.

Banyak klien membuka peranti terminal secara terus, atau enggan menerima rahsia daripada aliran yang bukan terminal, supaya paip yang tersesat tidak dapat membocorkan kata laluan. OpenVPN ialah pengecualian yang didokumenkan, kerana --auth-user-pass menerima laluan fail. Klien vendor yang meminta kod sekali guna biasanya tiada pilihan setara, dan permintaannya menunggu terminal yang tidak pernah disediakan skrip anda.

Pemeriksaan 2: adakah proses anak mempunyai terminal?

pty memperuntukkan terminal kepada anak, yang menukar permintaan menjadi output boleh baca yang boleh anda jawab mengikut urutan.

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)

Rentetan permintaan di atas adalah ilustrasi; salin teks tepat yang dicetak klien anda, termasuk huruf besar kecil dan tanda baca. Setiap jangkaan mempunyai had masa, dan anak yang tertutup membuang pengecualian dan bukannya memulangkan status, jadi bungkus urutan itu dan anggap hujung fail sebagai kegagalan. Perhatikan apa yang blok ini tidak lakukan: anak mati bersama skrip, kerana pty bukan mekanisme pelepasan dan disown ialah arahan terbina shell yang tidak dapat mencapai proses yang dimulakan skrip anda.

Pemeriksaan 3: adakah input bukan interaktif yang disokong?

Pengikisan skrin rosak apabila klien dinaik taraf, jadi cari pilihan yang didokumenkan dahulu.

Periksa output bantuan untuk pilihan token atau kod sekali guna, dan periksa sama ada perkhidmatan menerima kod yang ditambah pada medan kata laluan. Di tempat klien membaca fail kelayakan, berikan fail itu dan bukannya permintaan:

openvpn --config office.ovpn --auth-user-pass <(printf "%s\n%s\n" "$USER_NAME" "$PASSWORD")

Penggantian proses memberi klien laluan boleh baca pada sistem yang menyediakan /dev/fd. Rahsia itu kekal rahsia dari sudut pandang klien, jadi jauhkan ia daripada log, sejarah shell dan senarai proses. Jika klien menolak /dev/fd atau membuka laluan kelayakan lebih daripada sekali, tulis fail sebenar dengan kebenaran ketat dan hapuskannya dalam skrip yang sama.

Pemeriksaan 4: adakah terowong akan hidup lebih lama daripada skrip?

Secara lalai terowong mati bersama induknya, iaitu bertentangan dengan apa yang diperlukan skrip but.

disown -h hanya membantu apabila anda memulakan klien sebagai tugas shell, kerana ia menyunting jadual tugas shell itu dan tidak dapat mencapai proses yang dimulakan skrip anda melalui pty. Pengurus perkhidmatan ialah rumah yang lebih baik untuk apa-apa yang perlu menyambung semula tanpa pengawasan, kerana ia memulakan semula klien dan merekodkan mengapa ia mati. Walau apa pun, jangkakan kod baharu selepas setiap sambungan semula: token sekali guna digunakan oleh pengesahan pertama yang berjaya.

Perhatikan apa yang sudo lakukan pada urutan itu. Permintaan kata laluan sudo bukan permintaan VPN, dan menjawabnya dengan kata laluan VPN ialah cara paling biasa urutan jangkaan yang sebaliknya betul masih gagal.

Pemeriksaan 5: patutkah kod seseorang berada dalam skrip?

Inilah pemeriksaan yang orang langkau. Token milik seseorang, manakala terowong yang mesti naik mengikut jadual milik mesin.

Jika sesuatu tugas mesti menyambung semula tanpa pengawasan, tanya sama ada sijil mesin atau akaun perkhidmatan boleh menggantikan log masuk interaktif. Mengautomasikan kod sekali guna seseorang menukar faktor kedua menjadi rahsia tersimpan, yang merupakan perubahan dasar dan bukan kemudahan penulisan skrip. Di tempat perkhidmatan menyokong kedua-duanya, pilih kelayakan yang sepadan dengan cara tugas itu benar-benar berjalan. Tuliskan jawapannya, kerana orang seterusnya akan bertanya mengapa skrip memegang token.

Rupa skrip yang berfungsi

Skrip mencetak langkah yang dicapai, tidak pernah rahsianya, dan keluar dengan kod bukan sifar pada setiap jangkaan yang gagal.

Uji dengan sengaja merosakkannya: kata laluan salah, kumpulan salah, token tamat tempoh. Setiap kegagalan harus berhenti pada langkah bernama dan bukannya tergantung. Kemudian jalankan sekali terhadap perkhidmatan sebenar dan periksa terowong dari luar skrip, bukan dari dalam.

Artikel berkaitan