Bagaimana cara membuat kata sandi Kemungkinan menggunakan jika kunci ditolak?

14

Mesin virtual server baru saya dikonfigurasikan untuk masuk secara root melalui ssh dengan kata sandi. Saya ingin playbook Ansible saya mengkonfigurasi ulang untuk menggunakan kunci saja dan menonaktifkan login root dengan kata sandi saat dijalankan, jadi saya perlu sesuatu seperti ini:

  • coba masuk dengan kunci
  • jika tidak bisa masuk dengan kunci:

    • login dengan kata sandi
    • tambahkan kunci ke otor_keys
    • nonaktifkan login root dengan kata sandi
    • secara opsional sambungkan kembali menggunakan kunci
  • lakukan tugas lain

Bagaimana saya bisa mencapai itu?

EDIT : Agar lebih jelas, saya tidak bertanya bagaimana cara menambahkan kunci atau menonaktifkan root, itu hanya untuk konteks. Saya bertanya bagaimana cara mundur ke kata sandi jika tidak dapat mengautentikasi dengan kunci. Dengan --ask-passatau ansible_ssh_passset, Ansible bahkan tidak akan mencoba menggunakan otentikasi kunci publik

petr0
sumber
Pertanyaan bagus, apa yang sudah Anda coba sejauh ini?
dawud
1
Saya mengambil konfigurasi ssh ke playbook terpisah dan saya menjalankannya dengan opsi -k, kemudian saya menjalankan playbook utama tanpa -k (menggunakan kunci dari agen). Saya berharap itu bisa dibungkus dalam satu buku pedoman tunggal ...
petr0
@ petr0 Ini berfungsi untuk saya ketika kata sandi pass-pass untuk pengguna yang berbeda dari kunci (yaitu ketika Anda mengganti pengguna jarak jauh setelah menonaktifkan kata sandi ssh). Tidak yakin apakah itu membantu.
DylanYoung

Jawaban:

6

Anda dapat mencoba PreferredAuthenticationsopsi, mengaturnya ke publickey,password. Defaultnya meliputi ini dalam urutan ini, bersama dengan opsi lain, sehingga mungkin pengaturan ini. Menambahkannya melalui -oatau klien ssh_configdapat mencegah hal ini.

Anda mungkin dapat menggunakan skrip wrapper. Misalnya, dengan ini dalam key_or_password.shdan pass.shyang memberikan kata sandi, menjalankan bash key_or_password.sh root@hostakan mencoba publickey diikuti oleh login kata sandi non-interaktif.

export DISPLAY=dummy:0
export SSH_ASKPASS=$PWD/pass.sh
exec setsid ssh -v -o 'PreferredAuthentications publickey,password' "$@"

Log menunjukkan metode mana yang berhasil, misalnya

debug1: Authentication succeeded (publickey).
eisd
sumber
7

Inilah yang saya lakukan jika ansible_userberbeda untuk 'jalankan pertama' dari buku pedoman (misalnya jika Anda hanya memiliki rootpengguna dan Anda akan mengatur pengguna baru dengan kunci SSH):

  • Simpan kata sandi ansible_passseperti yang Anda lakukan jika Anda menggunakan kata sandi login (ingat untuk menggunakan Vault) ini harus menjadi kata sandi pengguna yang Anda gunakan untuk 'jalankan pertama' dari buku pedoman.
  • Setel ansible_userke nama pengguna pengguna yang ingin Anda gunakan setelah dijalankan pertama kali saat Anda mengatur pengguna dengan benar di server.
  • Tetapkan variabel ansible_user_first_rununtuk pengguna yang akan Anda gunakan untuk 'jalankan pertama' dari buku pedoman, misalnya root.
  • Gunakan perintah lokal untuk mencoba menyambung ke server dengan kunci SSH yang benar, menggunakan ignore_errorsdanchanged_when: False
  • Jika gagal, perbarui ansible_userke nilaiansible_user_first_run

Berikut kodenya:

---
- name: Check if connection is possible
  command: ssh -o User={{ ansible_user }} -o ConnectTimeout=10 -o PreferredAuthentications=publickey -o PubkeyAuthentication=yes {{ inventory_hostname }} echo "Worked"
  register: result
  connection: local
  ignore_errors: yes
  changed_when: False
- name: If no connection, change user_name
  connection: local
  set_fact:
    ansible_user: "{{ ansible_user_first_run }}"
  when: result|failed

Catatan: Layak transport = sshdiatur karena paramiko secara tak terduga dapat gagal masuk ke server dalam beberapa konfigurasi (misalnya ketika server diatur untuk tidak menerima kata sandi, dan Anda mencoba terlebih dahulu dengan kunci lalu kata sandi ... aneh!) Juga transportasi ssh lebih cepat, jadi tetap layak.

Catatan lebih lanjut: Jika Anda menggunakan metode ini, Anda perlu menentukan gather_facts: falsedalam file definisi playbook Anda sehingga tugas-tugas pengaturan / pengumpulan fakta tidak berjalan secara otomatis sebelum Anda sampai ke tahap pengujian kata sandi. Jika Anda memerlukan salah satu fakta yang mungkin, Anda perlu secara eksplisit memanggil setupperan Anda sebelum mengakses data yang biasanya tersedia di tempat-tempat seperti itu ansible_devices, dll. Salah satu cara yang baik untuk melakukan ini adalah dengan menelepon setupdengan whenklausa yang memeriksa untuk melihat apakah fakta yang Anda gunakan kosong atau tidak sebelum Anda menyebutnya dalam peran Anda.

Tom Bull
sumber
Solusi Anda baik tetapi Anda harus menambahkan gather_facts: nountuk menghentikan kemungkinan mencoba terhubung ketika meluncurkan playbook :)
k4cy
Anda benar. Saya telah mengumpulkan assemb_facts untuk semua buku pedoman saya sehingga saya harus memanggil 'setup' secara eksplisit. Saya lupa menyebutkan ini dalam jawabannya, saya akan memperbaruinya sekarang.
Tom Bull
5

Anda dapat menggunakannya --ask-passsaat menjalankan playbook yang memungkinkan.

Untuk tugas-tugas lain yang Anda minta, ini dapat dicapai dengan berbagai cara, misalnya, menyalin modul.
Menonaktifkan login root juga bisa dilakukan misalnya. dengan templating sshd_confatau memasukkan baris dalam file conf.

titus
sumber
--ask-pass (yang sama dengan -k) adalah apa yang saya lakukan dan saya menulis tentang itu di komentar di atas
petr0