Mengelola Rahasia dengan HashiCorp Vault

Bagaimana cara menyimpan rahasia? Di repositori, di sistem penyebaran atau di sistem manajemen konfigurasi? Di komputer pribadi, di server, atau mungkin di dalam kotak di bawah tempat tidur? Dan bagaimana mengelola rahasia untuk mencegah kebocoran?

Sergey Noskov ( Albibek ) - kepala kelompok keamanan informasi platform dari Avito , mengetahui jawaban atas pertanyaan-pertanyaan ini dan akan berbagi dengan kami. Di Avito, HashiCorp Vault telah aktif menggunakan HashiCorp Vault selama dua tahun, di mana saat itu mereka mendapatkan tonjolan dan memompa pengalaman ke level "Master".

Dalam artikel ini kita akan berbicara secara komprehensif tentang Vault: apa itu, di mana dan bagaimana itu digunakan di perusahaan, bagaimana Avito mengelola rahasia menggunakan HashiCorp Vault, bagaimana Wayang dan Kubernet digunakan, menggunakan kasing dengan Wayang dan SCM lainnya, masalah apa yang muncul, apa yang mengganggu keamanan dan pengembang, dan, tentu saja, berbagi gagasan tentang cara memperbaikinya.


Apa itu rahasia?


Setiap informasi rahasia:

  • login dan kata sandi, misalnya, ke basis data;
  • Kunci API
  • Kunci Sertifikat Server (* .google.com)
  • kunci sertifikat klien (mitra, uang Yandex, QIWI);
  • kunci untuk menandatangani aplikasi seluler.

Semua informasi yang kami ingin rahasiakan, kami sebut rahasia. Ini menciptakan masalah penyimpanan: menyimpan di repositori buruk, dalam bentuk terenkripsi - Anda perlu menyimpan kunci enkripsi di suatu tempat.

HashiCorp Vault adalah salah satu solusi bagus untuk masalah ini.

  • Secara aman menyimpan dan mengelola kunci.
  • Dipertajam di dunia layanan-mikro, karena layanan-mikro itu sendiri.
  • HashiCorp Vault telah melakukan banyak hal untuk mengotentikasi dan mengotorisasi akses ke rahasia, seperti ACL dan prinsip hak minimum.
  • SISA antarmuka dengan JSON.
  • Keamanan tidak sempurna, tetapi pada tingkat yang cukup tinggi.

Menurut pendapat saya, ini adalah alat yang cukup nyaman.

Apa yang Baru di Gudang HashiCorp


Alat ini berkembang dan dalam beberapa tahun terakhir banyak fitur menarik telah muncul di dalamnya: header CORS untuk GUI tanpa perantara; GUI bawaan; integrasi asli dengan Kubernetes; plugin untuk backend logis dan auth dan kerangka kerja.

Sebagian besar perubahan yang saya sukai secara pribadi adalah kemampuan untuk tidak menulis ekstensi dan tambahan yang akan berdiri di luar alat.

Misalnya, ada Vault, Anda ingin mengembangkannya - tulis logika tambahan atau UI Anda sendiri untuk otomatisasi, yang akan mengotomatisasi sesuatu. Sebelum perubahan, saya harus meningkatkan layanan tambahan yang dihadapi Vault, dan mem-proksi semua permintaan: pertama permintaan pergi ke layanan, lalu ke Vault. Ini buruk karena di layanan perantara mungkin ada tingkat keamanan yang berkurang, dan semua rahasia melewatinya. Risiko keamanan jauh lebih tinggi ketika rahasianya melewati beberapa poin sekaligus!

Masalah Ayam dan Telur


Ketika Anda mengangkat masalah menyimpan informasi rahasia dan memutuskan untuk mengenkripsi, maka segera setelah Anda mengenkripsi sesuatu, rahasia Anda berpindah dari tempat enkripsi ke tempat kunci disimpan. Ini terjadi setiap saat: segera setelah Anda menyimpan rahasia di suatu tempat atau mengubah yang sudah ada, Anda memiliki yang lain dan lingkaran terpesona dimulai - tempat menyimpan rahasia untuk akses ke rahasia itu .

Rahasia untuk mengakses rahasia adalah bagian keamanan yang disebut otentikasi . Keamanan memiliki bagian lain - otorisasi. Dalam proses otorisasi, diperiksa apakah pengguna dapat mengakses secara tepat di mana ia meminta. Dalam kasus Vault, ada pihak ketiga tepercaya yang memutuskan apakah akan memberikan rahasia atau tidak. Otorisasi hanya menyelesaikan sebagian masalah.

HashiCorp Vault di Avito


Di Avito, HashiCorp diinstal di satu-satunya instalasi besar di seluruh jaringan. HashiCorp Vault memiliki banyak backend yang berbeda. Kami menggunakan backend berdasarkan Konsul juga dari HashiCorp, karena Vault hanya dapat mendukung toleransi kesalahannya sendiri melalui Konsul.

Membuka segel adalah cara untuk tidak menyimpan kunci master di satu tempat. Ketika Vault dimulai, ia mengenkripsi semua yang ada pada kunci, dan sekali lagi masalah ayam dan telur muncul: tempat menyimpan rahasia, yang akan mengenkripsi semua rahasia lainnya. Untuk menghindari masalah ini, Vault menyediakan kunci komposit, yang memerlukan beberapa bagian kunci, yang kami bagikan ke beberapa karyawan. Di Avito, kami mengonfigurasi Unseal di opsi untuk 3 orang dari 7. Jika kami memulai Vault, setidaknya 3 orang harus masuk dan memasukkan bagian kunci mereka agar dapat mulai bekerja. Kuncinya dibagi menjadi 7 bagian dan Anda dapat membawanya.

Kami telah mengumpulkan Vault uji kecil, kotak pasir untuk pengembang tempat mereka dapat bermain. Itu dalam bentuk wadah Docker dan menciptakan rahasia sederhana sehingga orang dapat menyentuh alat dengan tangan mereka, merasa nyaman. Tidak ada Konsul dan pengelompokan di kotak pasir, itu hanya sistem file tempat Vault menyimpan rahasia terenkripsi, dan skrip kecil untuk diinisialisasi.

Inilah yang sekarang kami simpan di Vault:

  • Hampir semua rahasia untuk layanan microsoft Kubernetes: kata sandi basis data, kunci API, semua hal di atas.
  • Rahasia untuk meletakkan di server "besi" dan LXC.
  • Kami juga menaruh rahasia untuk CI / CD builds di TeamCity in Vault. Cakupan tidak 100%, tetapi cukup dapat diterima.
  • Kunci semua sertifikat: PKI internal, CA eksternal, misalnya, GeoTrust dan sejenisnya.
  • Rahasia umum untuk tim.

Di dalam, Vault menyimpan semuanya hanya di JSON, itu tidak selalu nyaman dan memerlukan tindakan tambahan dari pengembang, jadi pada dasarnya kami memposting rahasia dalam bentuk file.

Kami mencoba menyampaikan rahasia dalam bentuk file.

Kami tidak memberi tahu pengembang: "Pergi ke Vault, ambil rahasia!", Tapi letakkan file di disk dan katakan: "Pengembang, file akan muncul di disk Anda, ambil rahasianya, dan kami akan mencari cara mendapatkannya dari Vault dan membawanya untukmu. "


Kami mengadopsi perjanjian sederhana untuk bidang JSON, di mana kami mengindikasikan dengan hak apa untuk mengunggah file. Ini adalah metadata untuk sistem file, dan bidang data adalah string yang disandikan dengan rahasia itu sendiri, yang akan menjadi konten file.

Wayang + Hiera + Vault


Hampir semua infrastruktur Avito menggunakan Puppet, ia menggelar semua server.

Wayang memiliki alat yang nyaman untuk mengatur hierarki - Hiera . Vault terintegrasi sangat baik dengan Hiera melalui modul tambahan, karena permintaan nilai kunci dikirim ke perpustakaan ini, dan Vault sendiri adalah basis data nilai kunci, tetapi dengan semua fitur keamanan - dengan enkripsi transparan dan kemampuan untuk memilih akses ke kunci.

Oleh karena itu, hal pertama yang kami terapkan adalah Vault di Wayang, tetapi dengan satu tambahan - kami memiliki lapisan perantara yang disebut Router backend . Router backend - modul Hiera terpisah, hanya file pada disk yang mengatakan di mana Hiera harus pergi untuk kunci - di Vault atau di tempat lain.

Dia diperlukan agar Hiera tidak pergi ke Vault terus-menerus, karena dia selalu melewati hierarki. Ini bukan masalah Vault atau beban di atasnya, tetapi fitur Hiera itu sendiri. Karena itu, jika Anda hanya menyisakan modul untuk Vault tanpa backend Router, master Wayang akan membutuhkan waktu yang sangat lama untuk mengumpulkan konfigurasi untuk agen Wayang, karena akan memeriksa setiap kunci di Vault.


Untuk boneka, masalah ayam dan telur diselesaikan karena pihak yang berwenang adalah penguasa boneka. Dialah yang memberikan rahasia untuk mengakses rahasia. Master Wayang memiliki akses ke semua rahasia sekaligus, tetapi setiap tuan rumah diizinkan untuk hanya menerima satu yang dimaksudkan untuk itu. Host pada master Wayang sudah disahkan oleh sertifikatnya, yang dihasilkan secara lokal dan tidak meninggalkan batas host. Pada prinsipnya, rahasia untuk mengakses rahasia tetap ada, tetapi ini tidak terlalu kritis.

Proses kami mengungkap rahasia baru di Wayang terdiri dari langkah-langkah berikut.

  • Kami mengambil rahasia di suatu tempat - seseorang memberikannya kepada kami atau memadamkannya.
  • Menempatkan rahasia di Vault, dengan hierarki seperti di Hiera: /puppet/role/www/site.ssl.key .
  • Kami mendaftarkan awalan di manifes Wayang, yang menunjukkan bahwa file tersebut ada di Vault dan di mana mendapatkannya.
  • Kami menulis path di Vault di YAML untuk router Hiera dan backend sehingga Hiera dapat menemukannya.
  • Tarik permintaan melalui GIT ke repositori manifes.
  • Lari atau tunggu sampai agen Wayang lari.

Agen boneka melarikan diri bersama kami setiap 30 menit, jadi Anda harus menunggu sedikit sampai rahasia keluar. Ini tidak menimbulkan masalah - kami tidak membagikan rahasia setiap hari . Selama Kubernetes tidak terlibat dalam bisnis, tidak ada banyak biaya overhead dan kami siap untuk meletakkan rahasia di Vault dengan tangan kami dengan otomatisasi minimal.

Tambahan tambahan kita mendapatkan "chip" Hiera - rahasia dapat ditata segera untuk sekelompok host atau tergantung pada peran host, yang kita atur dalam peran variabel.

Satu-satunya bahaya : jika Anda memiliki Wayang dan Anda menggunakan Hiera, jangan mengganti apa pun yang masuk ke templat variabel karena banyak fakta dan variabel dikumpulkan di sisi klien. Jika seorang penyerang mengganti fakta pada klien, Master Wayang akan memberinya rahasia orang lain. Pastikan untuk memeriksa variabel : hanya gunakan variabel yang tidak bisa ditentukan oleh Puppet-master di sisi klien.

Apa yang harus dilakukan dengan SCM tanpa penyihir?


Jika tiba-tiba Anda tidak memiliki Wayang, maka kemungkinan besar Ansible. Untuk Chef dan SCM terpusat lainnya, solusi mereka adalah plugin yang dapat mengakses Vault. Saya menawarkan beberapa opsi yang dapat diimplementasikan dengan Ansible.

Agen lokal


Secara lokal untuk server, buat token, yang sebenarnya adalah kata sandi untuk mengakses Vault. Token itu berlaku sepanjang waktu. Anda dapat memperbarui atau mengotomatiskannya. Dengan token ini, Anda pergi ke Vault dan mengambil rahasia Anda.

Idenya adalah bahwa di server Anda di mana Anda perlu mengirimkan rahasia, agen yang datang ke Vault berputar, melihat semua rahasia dan menempatkannya dalam bentuk file. Kami menggunakan agen di beberapa server terpisah di mana tidak ada Wayang.

Cons:

  • Token mudah dimasukkan dalam segmen kecil, tetapi jika Anda memiliki beberapa lusin server yang digunakan per hari, Anda harus membuat token untuk setiap server dan menentukan kebijakan. Ini tidak nyaman.
  • Token perlu diperbarui.
  • Mengelompokkan server berdasarkan peran, tujuan, atau fakta sulit, harus disinkronkan dengan Vault.

Enkripsi transit


Vault memiliki fungsi enkripsi transit, intinya adalah bahwa Vault bertindak sebagai server enkripsi . Anda hanya perlu memberinya plaintext, dan dia, di kunci pribadinya, yang hanya dia miliki, mengenkripsi dan mengeluarkan teks tertutup. Kemudian Anda memilih siapa yang dapat mendekripsi teks tertutup ini.

Ansible memiliki entitas, juga disebut Vault. Ini bukan Vault HashiCorp, tetapi Vault Ansible . Tidak perlu bingung, dan rahasia dapat disimpan dalam yang pertama dan kedua. Ansible memiliki plugin yang sudah jadi untuk mengirimkan rahasia dari Hashicorp Vault. Jika Anda memberikan akses pribadi ke Vault, maka Anda dapat mendekripsi rahasia. Saat Anda menggulung Ansible, ia pergi ke Vault atas nama Anda, mendekripsi rahasia yang dienkripsi dalam repositori, dan menggulungnya ke dalam produksi.

Ada juga kelemahan - setiap administrator mendapat akses ke rahasia . Tetapi ada audit: Vault tahu cara menyimpan log aktivitas tentang pengguna mana yang masuk, rahasia apa yang mereka baca, yang mana yang dapat diakses. Anda selalu tahu siapa, kapan dan apa yang dilakukan dengan rahasia. Pilihan ini sepertinya baik untuk saya.

Kesalahan Besar # 1


Kerugian terbesar yang menyebabkan rasa sakit terbesar di kami adalah bahwa di Vault Anda tidak dapat mendelegasikan kendali penuh ke bagian mana pun dari data kepada siapa pun. Di Vault, akses ke rahasia dilakukan dengan cara yang mirip dengan jalur UNIX - nama biasanya dipisahkan oleh garis miring, dan hasilnya adalah "direktori". Ketika Anda memiliki jalan seperti itu, kadang-kadang Anda ingin mengambil bagian dari jalan itu dan memberikannya kepada orang lain untuk kontrol.


Misalnya, Anda mendapat sertifikat, dipanggil / sertifikat , dan Anda ingin memberikannya kepada petugas keamanan individu yang berurusan dengan PKI. Vault tidak dapat melakukan ini. Anda tidak dapat memberikan hak untuk mengeluarkan hak di dalam awalan ini - sehingga penjaga keamanan itu sendiri dapat mendistribusikan hak untuk sertifikat kepada orang lain.

Vault tidak memiliki kemampuan untuk secara selektif memberikan hak untuk memberikan hak . Segera setelah Anda memberikan hak untuk memberikan hak, Anda juga memberi kesempatan untuk mendapatkan akses penuh ke semua rahasia. Dengan kata lain, Anda tidak dapat memberikan akses ke bagian Vault.

Ini adalah salah satu masalah terbesar. Saya punya ide bagaimana menyelesaikannya, saya akan memberi tahu Anda nanti.

Kubernetes


Di RIT ++, saya berbicara tentang sistem terpisah yang kami terapkan untuk Kubernetes : ini berfungsi sebagai pihak ketiga, pergi ke API, memeriksa akses dan kemudian meminta rahasia di Vault.

Sekarang sistem kami telah kehilangan relevansi, karena di Vault 0.9, dukungan asli untuk Kubernetes telah muncul. Sekarang Vault sendiri tahu cara pergi ke Kubernetes dan memastikan bahwa akses ke rahasia diizinkan. Dia melakukan ini dengan Token Akun Layanan . Misalnya, ketika pod Anda diluncurkan, ada JWT khusus, bertanda tangan dan resmi untuknya, dirancang untuk permintaan ke API Kubernetes. Dengan token, Anda juga dapat masuk ke Vault dan mendapatkan rahasia khusus untuk namespace Anda.

Semuanya dilakukan pada level Vault itu sendiri. Benar, akan diperlukan untuk memulai peran untuk setiap namespace, yaitu, beri tahu Vault bahwa ada namespace seperti itu, akan ada otorisasi di dalamnya, dan mendaftar ke mana harus pergi ke Kubernetes. Ini dilakukan sekali, dan kemudian Vault akan pergi ke API itu sendiri, mengkonfirmasi validitas JWT dan mengeluarkan token aksesnya sendiri.

Aturan Kubernetes


Dalam hal nama layanan dan metadata tambahan, kami mempercayai pengembang. Ada kemungkinan kecil bahwa pengembang mungkin secara tidak sengaja atau sengaja mendapatkan rahasia layanan lain yang berputar di namespace yang sama, jadi kami memperkenalkan aturan: satu layanan - satu namespace.

Layanan microser baru? Dapatkan namespace baru dengan rahasia Anda. Anda tidak dapat melintasi perbatasan ke perbatasan - mereka memiliki Token Akun Layanan mereka sendiri. Batas keamanan di Kubernetes saat ini adalah namespace. Jika dalam dua ruang nama yang berbeda Anda perlu satu rahasia - salinlah.

Kubernetes memiliki rahasia kubernetes . Mereka disimpan di etcd di Kubernetes dalam bentuk yang tidak terenkripsi dan dapat "menyala" di dasbor atau ketika kubectl mendapatkan pod dimulai. Jika otentikasi di etcd dinonaktifkan di cluster Anda, atau jika Anda memberi seseorang akses read-only penuh, maka semua rahasia dapat dilihat olehnya. Itulah sebabnya kami memperkenalkan dua aturan: dilarang menggunakan rahasia kubernet dan dilarang untuk menentukan rahasia dalam variabel lingkungan dalam manifes . Jika Anda menulis rahasia di lingkungan di deployment.yaml, ini buruk, karena manifes itu sendiri dapat dilihat oleh siapa saja yang tidak malas.

Pengiriman Kubernetes


Seperti yang saya katakan, kita harus entah bagaimana meletakkan file di Kubernetes. Kami memiliki rahasia: entitas, kata sandi yang ditulis dalam VSON di Vault. Bagaimana mengubahnya menjadi file di dalam wadah di Kubernet sekarang?


Opsi pengiriman pertama.

  • Kami memulai init-container khusus.
  • Itu dimulai dari gambar kita.
  • Gambar berisi utilitas kecil yang masuk ke Vault dengan Token Akun Layanan, mengambil rahasia dan memasukkannya ke dalam volume Bersama.
  • Untuk utilitas, volume Bersama khusus dipasang hanya di memori TMPFS sehingga rahasia tidak melewati disk.
  • Init-container pergi ke Vault, memasukkan volume ini dalam bentuk file semua rahasia yang ditemukan di jalur yang ditentukan.
  • Selanjutnya, volume Bersama dipasang di wadah utama di mana diperlukan.
  • Ketika wadah utama diluncurkan, segera mendapatkan apa yang dibutuhkan pengembang - rahasia dalam bentuk file pada disk.

Pengembang hanya perlu mengingat jalan di mana rahasianya terletak.

Kami menggunakan sesuatu seperti awalan ini:

/k8s/<cluster>/<namespace>/<service>/some_secret 

Nama awalan berisi nama cluster, namespace, dan nama layanan. Setiap layanan memiliki rahasia sendiri, setiap namespace memiliki rahasia sendiri.

Opsi kedua adalah titik masuk Anda sendiri . Kami sekarang beralih ke Avito, karena pengembang memiliki masalah dengan init-container. Dalam diagram, opsi ini ada di sebelah kanan.

Tidak semua orang mampu membayar titik masuk mereka sendiri. Kami bisa, jadi di setiap wadah kami memaksakan titik masuk khusus kami.

Titik masuk kami melakukan hal yang sama dengan init-container: masuk ke Vault dengan Token Akun Layanan, mengambil rahasia dan mengeluarkannya. Selain file, ia menempatkannya kembali di lingkungan. Anda mendapatkan kesempatan untuk menjalankan aplikasi seperti yang direkomendasikan oleh konsep Aplikasi Dua Belas-Faktor : aplikasi mengambil semua pengaturan, termasuk rahasia, dari variabel lingkungan.

Variabel lingkungan tidak terlihat di manifes dan dasbor, karena mereka ditetapkan oleh PID 1 (proses wadah utama) saat startup. Ini bukan variabel lingkungan dari deployment.yaml, tetapi variabel lingkungan yang ditetapkan oleh titik masuk dalam proses. Mereka tidak terlihat di dasbor, mereka tidak terlihat, bahkan jika Anda membuat exec kubectl dalam wadah, karena dalam kasus ini proses lain diluncurkan, sejajar dengan PID1.

Alur kerja


Dari sudut pandang organisasi, prosesnya adalah sebagai berikut. Pengembang belajar dari juara keamanan atau dari dokumentasi bahwa ia tidak boleh menyimpan rahasia di repositori, tetapi hanya di Vault. Lalu dia datang kepada kami dan bertanya di mana harus menyimpan rahasia - ia mengajukan aplikasi ke keamanan untuk membuat awalan. Di masa mendatang, Anda dapat membuat awalan tanpa permintaan, segera saat membuat layanan.

Pengembang sedang menunggu, dan ini buruk, karena hal utama baginya adalah waktu-ke-pasar. Kemudian dia membaca instruksi, berurusan dengan file-file panjang - "masukkan baris itu di sana, masukkan baris ini di sini". Seorang pengembang belum pernah memulai init-container sebelumnya, tetapi ia dipaksa untuk mencari tahu dan mendaftarkannya di deployment.yaml (grafik kemudi).

Commit -> deploy -> feel pain -> fix -> repeat

Itu berkomitmen, menunggu TeamCity untuk meluncurkan, melihat kesalahan dalam TeamCity, mulai merasakan sakit, mencoba untuk memperbaiki sesuatu, mengalami rasa sakit lagi. Selain itu, ditumpangkan bahwa setiap peluncuran di TeamCity masih dapat antri. Terkadang seorang pengembang tidak dapat menemukannya sendiri, mendatangi kami, dan kami mengatasinya bersama-sama.

Pada dasarnya, pengembang menderita karena kesalahannya sendiri: init-container tidak ditentukan dengan benar atau tidak membaca dokumentasi .

Keamanan juga memiliki masalah. Petugas keamanan menerima aplikasi di mana selalu ada sedikit informasi, dan kami masih menemukan pertanyaan yang hilang: cari tahu nama cluster, namespace layanan, karena pengembang tidak menunjukkannya dalam aplikasi dan bahkan tidak selalu tahu apa itu. Ketika kami mengetahui semuanya, membuat kebijakan dan peran di Vault, menentukan kebijakan untuk grup, dan bersama dengan pengembang kami mulai mencari tahu di mana dan mengapa dia melakukan kesalahan, dan bersama-sama kami membaca log.

Unit "Arsitektur" membantu menyelesaikan masalah dengan bersembunyi dari pengembang deployment.yaml. Mereka mengembangkan karya yang menghasilkan segalanya untuk pengembang, termasuk titik masuk. Karena kami mengganti entri kami, kami dapat menggunakannya tidak hanya untuk memberikan rahasia, tetapi juga untuk hal-hal lain yang mungkin perlu Anda lakukan saat startup.

Masalah yang jelas dengan rahasia Kubernetes.


  • Alur kerja yang sangat rumit untuk pengembang dan penjaga keamanan.
  • Anda tidak dapat mendelegasikan apa pun kepada siapa pun. Petugas keamanan memiliki akses penuh ke Vault, dan akses parsial tidak dimungkinkan (lihat Cacat Besar # 1).
  • Kesulitan muncul ketika memindahkan pengembang dari cluster ke cluster, dari namespace ke namespace, ketika rahasia bersama diperlukan, karena pada awalnya diasumsikan bahwa rahasia yang berbeda berbeda dalam kelompok yang berbeda.

Kami berkata: β€œMengapa Anda membutuhkan rahasia produksi di klaster dev? Dapatkan rahasia tes, ikuti saja! ” Akibatnya, ada tambang dan rahasia yang sulit dikelola. Jika rahasia telah berubah, Anda tidak boleh melupakannya, pergi dan ubah di mana-mana, dan sementara tidak ada cara untuk menentukan bahwa itu adalah rahasia yang sama, kecuali dengan nama layanan.

Ide: Kubernetes KMS


Dalam versi baru Kubernetes, subsistem KMS, Layanan Manajemen Kunci, adalah fitur enkripsi rahasia Kubernetes yang baru. Di v1.11 itu dalam kondisi alfa, di v1.12 itu dipindahkan ke beta.

Gambar tersebut berasal dari situs proyek penyedia KMS untuk Vault, dan ada kesalahan padanya. Jika Anda menemukan - tulis di komentar.

Arti KMS adalah untuk menghilangkan satu kelemahan tunggal - penyimpanan data tidak terenkripsi di etcd.

KMS, seperti Ansible, dapat melakukan ini.

  • Pergi ke suatu tempat, mengenkripsi rahasia asli Kubernetes dan memasukkannya ke dalam bentuk terenkripsi.
  • Jika perlu, kirim ke pod, dekripsi, dan masukkan ke dalam format dekripsi.

Pengembang telah menulis layanan khusus yang melakukan ini menggunakan enkripsi transit. Gagasan itu tampaknya berhasil, tetapi penting untuk diingat bahwa rahasia tidak lagi berada di bawah kendali Vault dan pergi ke tempat lain, ke dalam area tanggung jawab administrator Kubernet.

Kontra KMS.

  • Desentralisasi Penyimpanan - Pengalihan dari Vault ke Kubernetes (etcd) . Rahasia menjadi tidak terkendali oleh Vault, dan itu bagus sebagai tempat penyimpanan rahasia yang terpusat. Ternyata setengah dari rahasia di Vault, dan setengah di tempat lain.
  • Solusi khusus Kubernetes . Jika Anda memiliki infrastruktur khusus Kubernetes, Anda mengambil Vault, dan Anda hampir tidak berpikir apa yang disimpan di sana, karena itu hanya berisi kunci enkripsi yang Anda kelola dengan benar - berputar secara teratur, dll ... Rahasia itu sendiri ada di Kubernetes, dan ini nyaman.
  • Sulit berbagi rahasia antar cluster . Untuk setiap cluster baru, Anda harus memulai dari awal lagi, menyalin rahasia seperti dalam kasus Vault tunggal mungkin tidak berfungsi.

Pro KMS.

  • Dukungan asli di Kubernetes, termasuk bersembunyi saat menunjukkan lingkungan.
  • Otorisasi di wilayah Kubernetes menjadi tanggung jawab .
  • Hampir tidak ada dukungan Vault yang diperlukan .
  • Rotasi kunci keluar dari kotak .

CI / CD: TeamCity


Semuanya sederhana di TeamCity, karena JetBrains menulis sebuah plug-in yang dengan sendirinya dapat menentukan rahasia untuk mengakses rahasia, mengenkripsi mereka dengan TeamCity, dan kemudian menggantinya di templat di suatu tempat sebagai parameter dalam persen. Pada saat ini, agen TeamCity sendiri pergi ke Vault, mengambil rahasia dan membawanya ke build sebagai parameter.

Beberapa rahasia diperlukan selama penyebaran, misalnya, migrasi basis data atau peringatan di Slack. AppRole dimulai untuk setiap proyek - pengaturan juga mengandung rahasia (data untuk AppRole), tetapi dimasukkan dalam mode tulis-saja - TeamCity tidak mengizinkan membacanya nanti.

TeamCity sendiri berhati-hati bahwa ketika sebuah rahasia memasuki log bangunan, ia secara otomatis menyamar. Akibatnya, rahasianya tidak "melewati" sama sekali disk, atau dihapus dari disk menggunakan alat TeamCity. Akibatnya, semua keamanan rahasia dijamin dengan baik oleh TeamCity sendiri dan plugin, dan tarian tambahan dengan rebana tidak diperlukan

CI / CD bukan TeamCity?


Ini adalah masalah utama yang perlu dipertimbangkan jika Anda menggunakan sistem yang berbeda (bukan TeamCity) sebagai CI.

  • Isolasi: batasi ruang lingkup rahasia untuk proyek, tim, dll.
  • Siapa yang memberi otorisasi akses ke rahasia.
  • Kecualikan kemampuan untuk melihat rahasia pihak yang berwenang.
  • Tahap terpisah dari build adalah untuk mengimpor rahasia ke file.
  • Bersihkan dirimu.

Akibatnya, kemungkinan besar Anda akan menulis sesuatu yang sangat mirip dengan plugin TeamCity untuk CI / CD Anda. Pihak yang berwenang di sini kemungkinan besar adalah CI / CD, dan dialah yang akan memutuskan apakah bangunan ini dapat memiliki akses ke rahasia ini, dan apakah akan memberikan rahasia itu sendiri atau tidak berdasarkan hasil.

Penting untuk tidak lupa membersihkan hasil build di akhir perakitan , jika diletakkan di disk, atau untuk memastikan bahwa mereka hanya di memori.

Sertifikasi


Tidak ada yang istimewa dengan sertifikat - kami menggunakan Vault terutama untuk penyimpanannya.


Vault memiliki backend PKI khusus untuk menerbitkan sertifikat, di mana Anda dapat membuat Otoritas Sertifikat dan menandatangani sertifikat baru. Kami memiliki satu PKI internal ... CA root dan CA tingkat kedua ada secara terpisah, dan kami sudah mengelola CA tingkat ketiga melalui Vault. Untuk menyimpan sertifikat yang dikeluarkan dari tingkat mana pun, termasuk sertifikat yang ditandatangani oleh CA eksternal, kami menggunakan awalan terpisah, dan menempatkan hampir semua sertifikat yang valid di sana untuk keperluan akuntansi dan pemantauan. Format untuk menyimpan sertifikat adalah hak milik, cocok untuk menyimpan kunci pribadi yang terpisah dan sertifikat itu sendiri.

Ringkasan


Terlalu banyak pekerjaan manual untuk penjaga keamanan, terlalu banyak ambang masuk untuk pengembang, dan tidak ada alat delegasi bawaan, meskipun saya benar-benar ingin ...

Bagaimana menjadi Kemudian mimpi dimulai.

Gagasan: bagaimana melakukan yang lebih baik


Bagaimana saya bisa menyingkirkan banyak salinan rahasia?

Master-slave pengiriman


Kami memiliki rahasia utama dan daemon khusus yang berjalan di sekitar, melihat rahasia dan metadata-nya, meletakkannya di tempat yang diperlukan, ternyata menjadi rahasia budak. Di jalan di mana daemon memposting budak, tidak ada yang bisa diubah dengan tangan, karena daemon akan datang dan meletakkan kembali rahasia master di atas budak.

Pada awalnya kami ingin membuat mekanisme symlink untuk hanya menunjukkan: "Carilah rahasia ini di sana!", Seperti di Linux. Ternyata ada masalah dengan hak akses: tidak diketahui cara memeriksa hak akses - seperti di Linux atau tidak, dengan jalur induk, dengan transisi antara titik mount. Ada terlalu banyak momen ambigu dan peluang untuk membuat kesalahan, jadi kami menolak symlink.

Otorisasi Kepemilikan


Hal kedua yang ingin kita lakukan adalah menentukan pemilik untuk setiap rahasia . Secara default, rahasia itu milik orang yang membuatnya. Jika perlu, Anda dapat memperluas area tanggung jawab ke unit dengan mengeluarkan grup pemilik.

Ketika kita belajar untuk mendelegasikan, kita akan memberikan pemiliknya suatu rahasia, dan dia akan dapat melakukan dengan rahasia apa yang dia inginkan.

  • Sebarkan dalam k8s - kebijakan dibuat, salinan budak dibuat.
  • Sebarkan di server - kebijakan dibuat, salinan budak dibuat.
  • Spread dalam CI / CD - ...
  • Transfer ke pemilik lain.
  • Berikan akses baru, hasilkan ACL baru.

Sekarang kami bertanggung jawab atas semua rahasia dan keamanan, tetapi kami ingin mengalihkan tanggung jawab kepada pencipta. Keamanan tidak akan terpengaruh , karena orang yang datang kepada kami dengan permintaan untuk menjaga rahasia memahami bahwa ia perlu menjaga rahasia dengan aman dan menyadari tanggung jawabnya.

Karena dia adalah pemilik rahasia, untuk opsi pengiriman tuan-budak, dia bisa memilih di mana dan dalam format apa rahasia itu harus dikirimkan kepadanya. Ternyata pemiliknya mengelola semuanya sendiri, tidak perlu mengirimkan aplikasi, Anda dapat mengambil sendiri awalan yang diperlukan, Anda juga dapat membuat dan menghapus rahasia sendiri.

Delegasi melalui ACL Templates


Kebijakan akses Daftar Akses Kontrol di Vault dibagi menjadi dua bagian:

  • Daftar Kontrol Akses dalam tampilan klasik, yang menjelaskan akses ke awalan, cara membaca dan menulis, yang hanya membaca, dll.
  • Saat membuat ACL di dalamnya, Anda dapat menulis tanda bintang di bagian akhir, yang berarti "awalan ini, dan semua yang ada di bawahnya." Awalan dapat ditugaskan sebagai operasi terpisah, diberikan kepada pengguna atau grup, yaitu, dilampirkan ke beberapa entitas yang berbeda.

Saat ini, hanya administrator Vault yang dapat mengubah ACL. Setelah mendapatkan akses ke ACL seperti itu, Anda dapat meresepkan semua yang Anda inginkan di dalam, misalnya, path β€œ*” { capabilities = [sudo, ...] } , dan dapatkan akses penuh. Ini adalah inti dari Kesalahan Terbesar # 1 - tidak mungkin untuk melarang mengubah isi ACL.

Kami ingin menetapkan ACL dengan templat yang sudah jadi yang berisi path dan placeholder yang memungkinkannya menghasilkan ACL baru untuk templat ini.

Contoh


Di bawah ini adalah font kuning, jalur ACL standar selesai dari Vault, dan selanjutnya tindakan yang diizinkan pada jalur ini. Kami menganggapnya sebagai ACL untuk izin untuk mengubah ACL lain di bawah ini, yang diberikan dalam bentuk templat.


Kami ingin mendelegasikan akses ke / k8s, kami hanya mengizinkan templat yang dihasilkan. Misalnya, berikan akses hanya baca ke kluster khusus, ruang nama, layanan, tetapi jangan ubah bidang kemampuan.


Selain itu, kami ingin memberikan izin untuk mengikat ACL ini dan mengeluarkan hak yang berbeda.

Kami menerapkan templat untuk memberikan hak kepada pengembang. Ketika templating, ia menjalankan perintah $ vault write policy-mgr/create/k8s-microservice ... Dan sebagai hasilnya, kami mendapat ACL yang menyatakan cluster = prod, namespace = ..., service = ... dll. Hak ditetapkan secara otomatis, kebijakan dibuat dengan nama /k8s/some-srv - ini hanya nama ACL yang dapat dihasilkan dari templat.


Akibatnya, pengembang, atas kebijakan kami, memberikan ACL ini kepada siapa pun yang ingin, dan menjadi pemiliknya sendiri, dapat mengelolanya sebagai rahasia: hapus, beri, dan ambil dari pengguna dan grup. Sekarang orang itu sendiri yang bertanggung jawab atas awalannya: dia mengelola semua rahasia, menghasilkan ACL sesuai dengan templat, dapat menetapkan ACL kepada yang dia inginkan. Secara alami, kita dapat membatasi itu juga.

Semua sulap berfungsi dengan entitas Vault baru - plugin . Mereka adalah layanan terpisah, sangat mirip dengan yang saya sebutkan di awal, dan bekerja hampir persis sama. Satu-satunya perbedaan penting adalah bahwa mereka bukan proxy. Plugin diluncurkan "di samping" Vault, dan meluncurkan proses Vault utama mereka. Karena ini, semua permintaan tidak melalui layanan, tetapi ke Vault, yang sudah berinteraksi dengan plug-in, mengirimkannya permintaan yang diverifikasi dan dihapus.

Tentang plugin, cara mengaturnya, dan cara menulisnya, Anda dapat membaca di situs web Vault . Yang terbaik untuk menulisnya di Go, yang cukup sederhana, karena Ada kerangka kerja untuk Go. Vault berkomunikasi dengan plugin melalui grpc, meluncurkannya sebagai layanan, tetapi jangan takut, Anda tidak menyentuhnya - semuanya sudah ada dalam framework. Anda hanya menulis aplikasi REST standar lebih atau kurang di mana Anda menentukan titik akhir, memberi mereka fungsi siap pakai, penangan yang akan memiliki logika pada mereka.

Jangan takut bahwa Anda akan merusak sesuatu di Vault utama. Plugin adalah layanan terpisah. Bahkan jika plugin Anda panik dan jatuh, itu tidak akan merusak Vault. Vault hanya akan memulai ulang plugin dan terus bekerja.

Selain itu, ada pengaturan tambahan untuk plugin itu sendiri: selalu memeriksa jumlah hash sehingga tidak ada yang mengubah biner. Keamanan menjalankan plugin disediakan .

Tautan yang bermanfaat:



Kita akan berbicara tentang DevOps dan keamanan, CI / CD, k8s, Puppet dan semua itu di HighLoad ++ (yang terdekat di St. Petersburg pada bulan April) dan DevOpsConf . Ayo bagikan pengalaman Anda atau lihat orang lain. Agar tidak lupa, berlanggananlah ke blog dan buletin , di mana kami akan mengingatkan Anda tentang tenggat waktu dan mengumpulkan materi yang bermanfaat.

Source: https://habr.com/ru/post/id438740/


All Articles