Cara mengotomatiskan login VPN yang menunggu kode token
Klien VPN baris perintah yang meminta input di terminal membuat skrip yang hanya menyalurkan kata sandi berhenti. Lakukan lima pemeriksaan ini sebelum Anda memakai expect.
Skrip yang menjalankan klien VPN dari vendor menggantung sampai waktu habis, dan log menunjukkan klien meminta kode verifikasi yang tidak diketik siapa pun. Kata sandi sudah diberikan, jadi kesimpulan yang tampak jelas adalah kata sandinya salah. Bukan. Permintaan kode adalah percakapan terpisah di kanal terpisah, dan skrip Anda tidak pernah membukanya.
Lakukan lima pemeriksaan di bawah ini secara berurutan. Berhenti pada yang pertama gagal, karena setiap langkah berikutnya mengandaikan yang sebelumnya berlaku.
Pemeriksaan 1: apakah klien membaca input standar sama sekali?
Uji sebelum menulis otomatisasi apa pun: salurkan rahasia palsu ke klien dan lihat apa yang terjadi. Jika ia mencetak permintaannya lalu menunggu, ia tidak membaca pipa.
Banyak klien membuka perangkat terminal secara langsung, atau menolak mengambil rahasia dari aliran yang bukan terminal, agar pipa nyasar tidak bisa membocorkan kata sandi. OpenVPN adalah pengecualian yang didokumentasikan, karena --auth-user-pass menerima jalur berkas. Klien vendor yang meminta kode sekali pakai biasanya tidak punya opsi setara, dan permintaannya menunggu terminal yang tidak pernah disediakan skrip Anda.
Pemeriksaan 2: apakah proses anak punya terminal?
pty mengalokasikan terminal untuk anak, yang mengubah permintaan menjadi keluaran terbaca yang bisa Anda jawab berurutan.
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)Untaian permintaan di atas bersifat ilustratif; salin teks persis yang dicetak klien Anda, termasuk huruf besar-kecil dan tanda baca. Setiap ekspektasi membawa batas waktu, dan anak yang tertutup memunculkan pengecualian alih-alih mengembalikan status, jadi bungkus urutannya dan perlakukan akhir berkas sebagai kegagalan. Perhatikan apa yang tidak dilakukan blok ini: anak mati bersama skrip, karena pty bukan mekanisme pelepasan dan disown adalah perintah bawaan shell yang tidak dapat menjangkau proses yang dibuat skrip Anda.
Pemeriksaan 3: adakah input non-interaktif yang didukung?
Pengikisan layar rusak saat klien diperbarui, jadi cari opsi terdokumentasi lebih dulu.
Periksa keluaran bantuan untuk opsi token atau kode sekali pakai, dan periksa apakah layanan menerima kode yang ditambahkan ke kolom kata sandi. Di tempat klien membaca berkas kredensial, berikan berkas itu alih-alih permintaan:
openvpn --config office.ovpn --auth-user-pass <(printf "%s\n%s\n" "$USER_NAME" "$PASSWORD")Substitusi proses memberi klien jalur terbaca pada sistem yang menyediakan /dev/fd. Rahasia tetap rahasia dari sudut pandang klien, jadi jauhkan dari log, riwayat shell, dan daftar proses. Jika klien menolak /dev/fd atau membuka jalur kredensial lebih dari sekali, tulis berkas sungguhan dengan izin ketat dan hapus di skrip yang sama.
Pemeriksaan 4: apakah terowongan akan hidup lebih lama dari skrip?
Secara bawaan terowongan mati bersama induknya, yang merupakan kebalikan dari yang dibutuhkan skrip penyalaan.
disown -h hanya membantu bila Anda menjalankan klien sebagai tugas shell, karena ia menyunting tabel tugas shell itu dan tidak dapat menjangkau proses yang dibuat skrip Anda lewat pty. Manajer layanan adalah rumah yang lebih baik untuk segala hal yang harus menyambung ulang tanpa pengawasan, karena ia memulai ulang klien dan mencatat mengapa klien mati. Bagaimanapun, harapkan kode baru setelah setiap penyambungan ulang: token sekali pakai terpakai oleh autentikasi pertama yang berhasil.
Perhatikan apa yang dilakukan sudo terhadap urutan itu. Permintaan kata sandi sudo bukan permintaan VPN, dan menjawabnya dengan kata sandi VPN adalah cara paling umum urutan ekspektasi yang sebenarnya benar tetap gagal.
Pemeriksaan 5: haruskah kode seseorang berada di dalam skrip?
Inilah pemeriksaan yang dilewati orang. Token milik seseorang, sedangkan terowongan yang harus naik sesuai jadwal milik mesin.
Jika suatu tugas harus menyambung ulang tanpa pengawasan, tanyakan apakah sertifikat mesin atau akun layanan dapat menggantikan login interaktif. Mengotomatiskan kode sekali pakai seseorang mengubah faktor kedua menjadi rahasia tersimpan, yang merupakan perubahan kebijakan, bukan kemudahan pembuatan skrip. Di tempat layanan mendukung keduanya, pilih kredensial yang sesuai dengan cara tugas itu benar-benar berjalan. Tuliskan jawabannya, karena orang berikutnya akan bertanya mengapa skrip memegang token.
Seperti apa skrip yang bekerja
Skrip mencetak langkah yang telah dicapai, tidak pernah rahasianya, dan keluar dengan kode bukan nol pada setiap ekspektasi yang gagal.
Uji dengan sengaja merusaknya: kata sandi salah, grup salah, token kedaluwarsa. Setiap kegagalan harus berhenti di langkah bernama alih-alih menggantung. Lalu jalankan sekali terhadap layanan sungguhan dan periksa terowongan dari luar skrip, bukan dari dalamnya.