Pertanyaan Bagaimana saya bisa mengimplementasikan ansible dengan password per-host, dengan aman?


Saya ingin menggunakannya ansible untuk mengelola sekelompok server yang ada. Saya telah membuat sebuah ansible_hosts file, dan berhasil diuji (dengan -K opsi) dengan perintah yang hanya menargetkan satu host

ansible -i ansible_hosts host1 --sudo -K # + commands ...

Masalah saya sekarang adalah bahwa kata sandi pengguna pada setiap host berbeda, tetapi saya tidak dapat menemukan cara menangani ini di Ansible.

Menggunakan -K, Saya hanya diminta untuk satu kata sandi sudo di depan, yang kemudian tampaknya dicoba untuk semua host berikutnya tanpa disuruh:

host1 | ...
host2 | FAILED => Incorrect sudo password
host3 | FAILED => Incorrect sudo password
host4 | FAILED => Incorrect sudo password
host5 | FAILED => Incorrect sudo password

Penelitian sejauh ini:

  • Sebuah Pertanyaan StackOverflow dengan satu jawaban yang salah ("gunakan -K") dan satu tanggapan oleh penulis mengatakan" Ketemu saya perlu sudo tanpa sandi "

  • dokumen Ansible, yang mengatakan "Penggunaan sudo tanpa password membuat semuanya lebih mudah untuk diotomatisasi, tetapi itu tidak diperlukan. "(penekanan saya)

  • pertanyaan StackExchange keamanan ini yang menganggapnya sebagai bacaan itu NOPASSWD Dibutuhkan

  • artikel "Penyediaan Scalable and Understandable ..." yang mengatakan:

    "menjalankan sudo mungkin perlu mengetikkan kata sandi, yang merupakan cara pasti untuk memblokir Ansible selamanya. Perbaikan sederhana adalah menjalankan visudo pada host target, dan memastikan bahwa pengguna Ansible akan menggunakan untuk login tidak perlu mengetikkan kata sandi"

  • artikel "Playbook Dasar Ansible", yang mengatakan

    "Ansible dapat masuk ke server target sebagai root dan menghindari kebutuhan untuk sudo, atau membiarkan pengguna ansible memiliki sudo tanpa kata sandi, tetapi pikiran melakukan membuat limpa saya mengancam untuk melompati tenggorokan saya dan memblokir tenggorokan saya, jadi saya jangan "

    Pemikiran saya persis, tetapi kemudian bagaimana cara memperluas lebih dari satu server?

  • masalah yang mungkin terjadi # 1227, "Ansible harus meminta kata sandi sudo untuk semua pengguna dalam buku pedoman", yang ditutup setahun yang lalu oleh mpdehaan dengan komentar "Belum melihat banyak permintaan untuk ini, saya pikir kebanyakan orang sudoing dari hanya satu akun pengguna atau menggunakan kunci sebagian besar waktu. "

Jadi ... bagaimana orang menggunakan Ansible dalam situasi seperti ini? Pengaturan NOPASSWD di /etc/sudoers, menggunakan kembali kata sandi di seluruh host atau mengaktifkan login SSH root semua tampaknya mengurangi keamanan secara drastis.


97
2017-12-09 11:49




Apakah ada alasan Anda tidak menggunakan kunci SSH? - Trondh
Saya sudah menggunakan kunci SSH; mereka tidak mempengaruhi sudo (yang masih membutuhkan kata sandi). - supervacuo
Ini mungkin tidak persis apa yang Anda cari, tetapi pada kotak Ubuntu saya masih menggunakan kunci, yaitu menempatkan kunci publik saya di / root / authorized_keys untuk masuk langsung sebagai root. Kelemahan yang jelas adalah memungkinkan login root melalui ssh ... Saya juga tidak mengizinkan login kata sandi melalui ssh dan menjalankan fail2ban untuk keamanan tambahan. - senorsmile
@senorsmile terima kasih atas tanggapannya! Maukah Anda menjadikannya sebagai jawaban, sehingga saya dapat menghipnotis Anda karena tidak membaca pertanyaan? - supervacuo
yaitu itu ansible_ssh_password pengaturan hanya berlaku untuk kata sandi SSH (petunjuknya ada di nama ...). & Saya sudah menggunakan login SSH berbasis kunci. - supervacuo


Jawaban:


Anda pasti sudah melakukan penelitian ...

Dari semua pengalaman saya dengan apa yang ingin Anda capai, tidak didukung. Seperti yang Anda sebutkan, ansible menyatakan bahwa itu tidak memerlukan sudo tanpa password, dan Anda benar, itu tidak. Tetapi saya belum melihat metode apa pun untuk menggunakan beberapa sudo password dalam suatu yang dapat dilakukan, tanpa tentu menjalankan beberapa konfigurasi.

Jadi, saya tidak bisa menawarkan solusi yang tepat yang Anda cari, tetapi Anda memang bertanya ...

"Jadi ... bagaimana orang menggunakan Ansible dalam situasi seperti ini? Pengaturan   NOPASSWD di / etc / sudoers, menggunakan kembali kata sandi di seluruh host atau memungkinkan   akar SSH login semua tampaknya pengurangan yang agak drastis dalam keamanan. "

Saya bisa memberi Anda satu pandangan tentang itu. Kasus penggunaan saya adalah 1k node di beberapa pusat data yang mendukung perusahaan SaaS global di mana saya harus merancang / menerapkan beberapa kontrol keamanan yang sangat ketat karena sifat bisnis kami. Keamanan selalu menyeimbangkan tindakan, kegunaan lebih sedikit keamanan, proses ini tidak berbeda jika Anda menjalankan 10 server atau 1.000 atau 100.000.

Anda benar-benar benar untuk tidak menggunakan login root baik melalui password atau kunci ssh. Bahkan, login root harus dinonaktifkan sepenuhnya jika server memiliki kabel jaringan yang dicolokkan ke dalamnya.

Mari kita bicara tentang penggunaan kembali kata sandi, dalam sebuah perusahaan besar, apakah masuk akal untuk meminta sysadmin untuk memiliki kata sandi yang berbeda pada setiap node? untuk beberapa node, mungkin, tetapi admin / insinyur saya akan memberontak jika mereka harus memiliki kata sandi yang berbeda pada 1000 node. Menerapkan itu juga hampir tidak mungkin, setiap pengguna harus menyimpan sendiri kata sandi di suatu tempat, semoga keypass, bukan spreadsheet. Dan setiap kali Anda memasukkan kata sandi di lokasi yang dapat ditarik keluar dalam teks biasa, Anda telah sangat mengurangi keamanan Anda. Saya lebih suka mereka tahu, dengan hati, satu atau dua kata sandi yang benar-benar kuat daripada harus memeriksa file keypass setiap kali mereka perlu masuk ke atau memohon sudo pada mesin.

Jadi penggunaan kembali kata sandi dan standardisasi adalah sesuatu yang benar-benar dapat diterima dan standar bahkan dalam lingkungan yang aman. Jika tidak, ldap, keystone, dan layanan direktori lainnya tidak perlu ada.

Ketika kita berpindah ke pengguna otomatis, kunci ssh bekerja sangat baik untuk membuat Anda masuk, tetapi Anda tetap harus melalui sudo. Pilihan Anda adalah kata sandi standar untuk pengguna otomatis (yang dapat diterima dalam banyak kasus) atau untuk mengaktifkan NOPASSWD seperti yang telah Anda tunjukkan. Sebagian besar pengguna otomatis hanya menjalankan beberapa perintah, jadi sangat mungkin dan tentu saja diinginkan untuk mengaktifkan NOPASSWD, tetapi hanya untuk perintah yang disetujui sebelumnya. Saya akan menyarankan menggunakan manajemen konfigurasi Anda (ansible dalam kasus ini) untuk mengelola file sudoers Anda sehingga Anda dapat dengan mudah memperbarui daftar perintah tanpa sandi.

Sekarang, ada beberapa langkah yang dapat Anda ambil setelah Anda mulai meningkatkan risiko untuk mengisolasi lebih lanjut. Meskipun kami memiliki 1000 node, tidak semuanya adalah server 'produksi', beberapa di antaranya adalah lingkungan pengujian, dll. Tidak semua admin dapat mengakses server produksi, tetapi dapat menggunakan kunci SSO user / pass | yang sama seperti yang mereka lakukan di tempat lain. . Namun, pengguna otomatis sedikit lebih aman, misalnya alat otomatis yang dapat diakses oleh admin non-produksi memiliki pengguna & kredensial yang tidak dapat digunakan dalam produksi. Jika Anda ingin meluncurkan ansible pada semua node, Anda harus melakukannya dalam dua batch, sekali untuk non-produksi dan satu kali untuk produksi.

Kami juga menggunakan boneka, karena ini adalah alat manajemen konfigurasi yang menegakkan, jadi sebagian besar perubahan pada semua lingkungan akan terdorong keluar melalui itu.

Tentunya, jika permintaan fitur yang Anda berikan akan dibuka kembali / diselesaikan, apa yang ingin Anda lakukan akan sepenuhnya didukung. Meskipun demikian, keamanan adalah proses penilaian risiko dan kompromi. Jika Anda hanya memiliki beberapa simpul yang dapat Anda ingat kata sandi karena tidak menggunakan catatan post-it, kata sandi terpisah akan sedikit lebih aman. Tetapi bagi sebagian besar dari kita, itu bukan pilihan yang layak.


52
2017-12-30 16:53



Terima kasih, @Zeb - Saya membayangkan bahwa pengguna dengan puluhan-hingga-ribuan server akan menggunakannya NOPASSWD untuk alasan kewarasan pula (mungkin didukung oleh aturan firewall yang lebih ketat dll.), tapi ada baiknya membaca use case dan pemikiran Anda tentang model ancaman. - supervacuo
Satu komentar, meskipun, atas saran Anda tentang membatasi untuk "pra-disetujui" sudo perintah (yang terpikir oleh saya ketika saya menemukan itu NOPASSWD cukup banyak dibutuhkan). Sayangnya, ini sepertinya benar-benar tidak didukung juga - ansible tidak membuat janji tentang panggilan misalnya  chown atau mkdir binari secara langsung, dan harus bisa sudo /bin/sh untuk sebagian besar modul berfungsi. - supervacuo
Saya ingat salah satu teknisi saya mengeluh tentang hal itu beberapa waktu lalu, itu menjengkelkan. - Zeb


Dari Ansible 1.5 on, dimungkinkan untuk menggunakan kubah terenkripsi untuk host_vars dan variabel lainnya. Ini setidaknya memungkinkan Anda untuk menyimpan per-host (atau per-grup) ansible_sudo_passvariabel dengan aman. Sayangnya, --ask-vault-pass hanya akan meminta satu kata sandi vault per permintaan yang mungkin, jadi Anda masih terkendala dengan satu kata sandi lemari besi untuk semua host yang akan Anda gunakan bersama.

Namun demikian, untuk beberapa penggunaan ini mungkin merupakan peningkatan daripada memiliki password sudo tunggal di beberapa host, sebagai penyerang tanpa akses ke host_vars terenkripsi Anda masih memerlukan kata sandi sudo terpisah untuk setiap mesin (atau kelompok mesin) yang dia serang.


36
2018-05-10 20:32



Itu ansible_sudo_pass pilihan tampaknya baru juga - dan tampaknya melakukan apa yang saya minta. Kata sandi lemari besi tunggal sangat ideal untuk tujuan saya juga. Terima kasih! - supervacuo
Apakah ada cara untuk menghindari enkripsi semua  host_vars menggunakan metode ini? (Keterbatasan potensial dicatat oleh Alex Dupuy) - supervacuo
@supervacuo - Untuk menghindari mengenkripsi semua var host, cukup gunakan direktori var host yang berisi main.yml (tidak terenkripsi) dan secret.yml (terenkripsi) - lihat bagian terakhir dari bagian dokumen ini di mana ia berbicara tentang grup "raleigh" - teknik yang sama berlaku untuk var host dan vars grup. Saya menggunakan ini banyak, satu-satunya variasi adalah bahwa jika sebuah rahasia hanya diperlukan untuk beberapa playbook, akan berguna untuk menyimpannya di pohon yang berbeda sepenuhnya dan termasuk melalui jalur yang mencakup host atau var name. - RichVel
Jika saya telah mengenkripsi nilai 'ansible_ssh_pass' di dalam lemari besi, maka saya juga perlu menduplikasi nilai 'ansible_sudo_pass'? Apakah ada cara untuk nilai sudo_pass kedua untuk membenarkan nilai 'ssh_pass' pertama? - emeraldjava


Dengan Ansible 1.5, dimungkinkan untuk mengatur ansible_sudo_pass variabel menggunakan lookup('password', …):

ansible_sudo_pass: "{{ lookup('password', 'passwords/' + inventory_hostname) }}"

Saya menemukan ini lebih nyaman daripada menggunakan file host_vars/ untuk beberapa alasan:

  • Saya benar-benar menggunakannya with_password: "passwords/{{ inventory_hostname}} encrypt=sha256_crypt" untuk menyediakan kata sandi untuk menyebarkan pengguna jarak jauh (yang kemudian diperlukan untuk sudo), jadi mereka sudah ada di file (meskipun melakukan pencarian plaintext ini kehilangan nilai garam disimpan dalam file ketika nilai hash dihasilkan).

  • Ini hanya menyimpan kata sandi dalam file (no ansible_sudo_pass: dikenal plaintext) untuk beberapa peningkatan epsilon dalam keamanan kriptografi. Lebih signifikan, itu berarti bahwa Anda tidak mengenkripsi semua variabel khusus host lainnya, sehingga mereka dapat dibaca tanpa kata sandi kubah.

  • Menempatkan kata sandi di direktori terpisah membuatnya lebih mudah untuk menyimpan file dari kontrol sumber, atau menggunakan alat seperti git-crypt untuk menyimpannya dalam bentuk terenkripsi (Anda dapat menggunakan ini dengan Ansible sebelumnya yang tidak memiliki fitur vault). Saya menggunakan git-crypt dan karena saya hanya memeriksa repositori dalam bentuk didekripsi pada sistem file terenkripsi, saya tidak peduli dengan vault dan dengan demikian tidak perlu mengetikkan kata sandi kubah. (Menggunakan keduanya tentu akan lebih aman.)

Anda juga bisa menggunakan menengadah berfungsi dengan ansible_ssh_pass; ini bahkan dimungkinkan dengan versi Ansible sebelumnya yang tidak memilikinya ansible_sudo_pass.


22
2018-05-26 19:33



saya akhirnya sempat mencoba ini (terima kasih!), tetapi tidak bisa melihat bagaimana itu akan berhasil git-crypt; sejauh yang saya bisa lihat. Sepertinya Ansible belum memiliki dukungan untuk menggunakan lookup pada lemari besi yang dienkripsi. Itu password dokumen modul mengatakan bahwa ada beberapa dukungan yang belum terdokumentasi untuk penyimpanan terenkripsi, tetapi saya belum menemukan detailnya. Ada petunjuk apa? - supervacuo


Menggunakan lulus adalah metode sederhana untuk memberikan jawaban dengan kata sandi sudo. pass store satu kata sandi per file yang memudahkan untuk berbagi kata sandi melalui git atau metode lainnya. Ini juga aman (menggunakan GnuPG) dan jika Anda menggunakan gpg-agent, ini memungkinkan Anda menggunakan ansible tanpa memasukkan kata sandi pada setiap penggunaan.

Untuk memberikan kata sandi disimpan sebagai servers/foo untuk server foo ke ansible, gunakan dalam file inventaris seperti ini:

[servers]
foo ansible_sudo=True \
    ansible_sudo_pass="{{ lookup('pipe', 'pass servers/foo') }}"

Karena Anda telah membuka kunci kunci untuk gpg-agent tadi, ini akan berjalan ansible tanpa perlu memasukkan kata sandi.


17
2018-01-19 19:51



Solusi yang sangat bagus - terima kasih! - Leng


Ini adalah thread yang cukup tua, meskipun demikian:

  • Kami menggunakan dua sistem otentikasi berbeda di-rumah, manajemen mesin dilakukan dari workstation lokal di tim saya.
  • Saya menulis a vars_plugin untuk Ansible (implementasi yang agak lengkap dapat ditemukan di https://gist.github.com/mfriedenhagen/e488235d732b7becda81) yang membedakan beberapa sistem otentikasi:
  • Nama sistem autentikasi adalah khusus grup.
  • Pengguna login / sudo yang digunakan adalah grup dan admin tertentu.
  • Jadi saya menarik pengguna dari lingkungan admin dan kata sandi yang bersangkutan melalui pustaka kode-python dari kata sandi yang aman (kami menggunakan keychain Mac OS X, tetapi dari dokumentasi kwallet Gnome dan _win_crypto juga didukung).
  • Saya mengatur izin pada kata sandi dalam keychain Mac OS X untuk memberi tahu saya tentang fakta, bahwa permintaan keamanan jalur perintah mengakses kata sandi untuk setiap sistem otentikasi yang digunakan oleh host, jadi saya menjalankan "ansible -s all -m ping" dan mendapatkan dua petunjuk (satu untuk setiap sistem otentikasi) di mana saya menekan tombol spasi dan ansible mengambil kata sandi.

3
2018-03-03 17:33



Ini terlihat sangat rapi, terima kasih - saya suka ide tidak harus menyimpan kata sandi di dua tempat. Saat ini saya terjebak menggunakan KeepassX (karena keyring GNOME tidak tampak portabel) tapi mungkin saya bisa membuatnya python-keepass kerja? - supervacuo
Sejauh yang saya pahami, python-keyring adalah abstraksi untuk ini, jadi rekan Anda mungkin menggunakan OS lain. Atau apakah Anda menyimpan dm keepassx Anda pada USB stick dan harus mengatur dari workstation dengan OS yang berbeda? - Mirko Friedenhagen
dipahami; Maksud saya, saya sudah menggunakan KeepassX untuk memiliki akses ke kata sandi pada sistem non-GNOME, jadi simpanlah di dalamnya gnome-keyring akan berarti menyimpan catatan duplikat. Masih jauh lebih baik daripada menggunakan NOPASSWD, meskipun ... - supervacuo


Salah satu cara yang mungkin untuk melakukan ini adalah menggunakan variabel lingkungan.

misalnya

pass1=foo pass2=bar ansible-playbook -i production servers.xml

Kemudian dalam drama, Anda dapat mencari kata sandi sudo menggunakan:

lookup('env', 'pass1') 
lookup('env', 'pass2') 

0
2017-07-21 08:57