Bagaimana Saya Merotasi Kredensial yang Diandalkan Tujuh Service Tanpa Merusak Satu Pun
On this page
- Pendahuluan
- A. Kenapa salinan lebih gampang beredar daripada kedengarannya
- B. Tak semua nilai yang tampak rahasia itu password
- C. Kenapa ini lebih sulit daripada mengganti password
- D. Apa yang sedang saya hadapi
- E. Enam hambatan yang menghalangi
- Metode
- A. Kenapa rotation tool tak boleh mencari nilai lama
- B. Daftar apa yang tak boleh dirotasi, dan kenapa
- C. Mengganti file konfigurasi tidak mengganti password-nya
- D. Restart, bukan reload
- E. Verifikasi yang sanggup menyadari kegagalan
- F. Dua detail yang cuma muncul di sistem yang berjalan
- G. Dry run sebagai bawaan, dan backup sebelum apa pun
- Hasil dan Pembahasan
- A. Saat pengaman bisa merusak yang dijaganya
- B. Kenapa daftar eksplisit mengalahkan otomatisasi yang pintar
- C. Berapa ongkos rotasi selama ia berjalan
- D. Apa yang berlaku umum
- Simpulan
- Istilah
Merotasi kredensial terdengar seperti pekerjaan bersih-bersih, padahal lebih menyerupai pembedahan. Passwordnya tak berada di satu tempat. Menggantinya di tempat yang paling terpikirkan ternyata tak mengganti apa pun. Dan sebagian nilai yang tampak seperti password, kalau ikut dirotasi, akan memusnahkan data yang tak bisa dikembalikan.
Inilah yang saya pelajari saat membangun tool untuk mengerjakannya di sistem yang sudah berjalan.
Pendahuluan
Kredensial adalah apa pun yang disodorkan sistem untuk membuktikan ia boleh melakukan sesuatu. Contoh yang paling akrab tentu password, tapi keluarganya lebih luas: access key yang membuat satu service bisa membaca file milik service lain, kunci untuk menandatangani dokumen, token yang dibawa service sebagai bukti ia sudah diizinkan sebelumnya.
Jumlahnya menumpuk diam-diam. Tiap kali sistem bertambah satu komponen — database, cache, penyimpan file — ia bertambah pula minimal satu kredensial untuk menggapainya. Sistem berisi selusin service gampang saja memegang tiga puluh, dan tak pernah ada yang duduk lalu memutuskan begitu; ia terjadi sendiri, satu penambahan demi satu penambahan.
Rotasi berarti mengganti kredensial dengan nilai baru. Anjuran melakukannya secara berkala itu standar, dan alasannya masuk akal: kredensial yang tak pernah berganti akan selamanya berguna bagi siapa pun yang pernah memegang salinannya.
A. Kenapa salinan lebih gampang beredar daripada kedengarannya
Kalimat terakhir itu layak diperlambat, sebab "siapa pun yang pernah memegang salinannya" terdengar seperti merujuk penyerang, padahal kebanyakan bukan.
Kredensial bocor lewat saluran yang biasa-biasa saja. Seorang kontraktor sempat punya akses selama sebuah project lalu pindah kerja. Sebuah password ditempel ke pesan chat supaya rekan tak terhambat, dan riwayat chat itu masih bisa dicari. File konfigurasi ikut tersalin ke backup, dan backup-nya mendarat di tempat yang aksesnya lebih longgar ketimbang sistem asalnya. Sebuah pesan error mencetak connection string ke log, dan log-nya disimpan setahun.
Tak satu pun dari itu serangan. Semuanya tekstur wajar dari mengoperasikan sistem, dan masing-masing meninggalkan salinan kredensial di tempat yang tak terlacak. Rotasi itulah yang membuat salinan tersebut berhenti berarti: nilai yang dikandungnya bukan lagi nilai yang bekerja.
Itu seluruh alasan mengerjakannya, dan itu pula sebabnya "kami belum pernah dibobol" bukan alasan untuk melewatinya. Pertanyaannya bukan apakah ada yang menyerang, melainkan berapa banyak salinan kredensial yang berlaku sekarang tercecer di tempat-tempat yang sudah terlupakan — dan angka itu cuma bertambah.
B. Tak semua nilai yang tampak rahasia itu password
Berikut pembedaan yang ternyata paling menentukan, sebab ia memutuskan apakah sebuah rotasi bisa menimbulkan kerusakan sungguhan.
Kredensial saling menyerupai. Hampir semuanya deretan panjang karakter yang tampak acak, duduk di file konfigurasi. Padahal ketiganya mengerjakan tugas yang sungguh berbeda, dan cuma satu di antaranya aman dirotasi dengan santai.
Sebagian disodorkan. Password database contoh yang paling jelas: service mengirimnya, database mencocokkan dengan yang tersimpan, lalu akses menyusul. Ganti di kedua tempat dan tak ada yang hilang — jenis inilah yang melatarbelakangi lahirnya rotasi.
Sebagian mendekripsi. Nilai jenis ini tak pernah ditunjukkan ke siapa pun; ia kunci yang membuat data tersimpan bisa dibaca. Menggantinya bukan mengubah siapa yang boleh masuk — ia membuat data yang dilindunginya tak terbaca, termasuk oleh Anda sendiri. Tak ada error pada saat penggantian. Kegagalannya tiba belakangan, saat ada yang mencoba membaca catatan lama.
Sebagian ditandatangani sebuah otoritas. Token jenis ini diterbitkan sistem lain yang secara kriptografis menjamin isinya. Ia duduk di konfigurasi dengan penampilan persis seperti password, tapi menggantinya dengan string acak tak melahirkan token sah yang baru — ia melahirkan nilai yang gagal diverifikasi, kerap jauh di dalam sebuah permintaan, bukan di pintu depan.
Pelajaran yang mendasarinya: format sebuah nilai tak memberi tahu apa pun tentang perannya. Cuma dengan tahu kredensial itu untuk apa, barulah ketahuan apakah menggantinya aman. Tool yang tak sanggup membedakan ketiganya adalah tool yang cepat atau lambat memperlakukan jenis kedua seperti jenis pertama.
C. Kenapa ini lebih sulit daripada mengganti password
Saat Anda mengganti password sendiri di sebuah situs, satu otoritas memegangnya dan satu klien menyodorkannya. Keduanya diperbarui pada detik yang sama, oleh tindakan yang sama.
Di sistem berisi service yang saling bekerja sama, kredensial yang sama disimpan di dua tempat yang diperbarui terpisah: di dalam service yang memvalidasinya, dan di dalam konfigurasi tiap service yang menyodorkannya. Ganti yang satu tanpa yang lain, sistem berhenti bekerja. Ganti dengan urutan yang keliru, ia berhenti bekerja selama jeda di antaranya.
Lebih repot lagi, kelompok kedua itu jamak. Satu password database bisa muncul di file konfigurasi empat service. Terlewat satu, tiga service tetap jalan sementara yang keempat gagal — dan itu lebih sulit disadari ketimbang mati total, sekaligus lebih gampang salah didiagnosis.
D. Apa yang sedang saya hadapi
Sistemnya menandatangani dokumen untuk sebuah instansi publik. Ia menjalankan kira-kira selusin service: beberapa database, dua cache, satu penyimpan objek, satu klaster pencarian, satu certificate authority, dan service aplikasi yang memakai semuanya.
Dua sifat kredensialnya membentuk seluruh cerita berikutnya.
Pertama, satu rotasi menjangkau tujuh service: tiga database, dua cache, penyimpan objek, dan klaster pencarian. Semuanya dirotasi bersama dalam satu run, jadi rotasi yang cuma menjangkau sebagian membuat sisanya gagal.
Kedua, konfigurasi yang sama juga memuat secret milik organisasi lain, misalnya yang diterbitkan penyedia identitas eksternal. Nilai milik saya dan nilai milik mereka bisa saja kebetulan string yang sama, dan tak ada apa pun di kedua sistem yang akan mencatat kenyataan itu.
E. Enam hambatan yang menghalangi
Tujuannya satu kalimat: mengganti kredensial yang dipakai tujuh service untuk mengautentikasi diri, dan sesudahnya ketujuhnya tetap bekerja. Dengan dua batasan yang ternyata menanggung sebagian besar beban. Rotasinya wajib tetap berada di dalam radius ledak yang dimaksudkan — ia tak boleh menyentuh apa pun milik sistem yang bukan saya yang mengoperasikannya. Dan ia wajib meninggalkan jalan pulang, sebab rotasi kredensial yang berhasil setengah jalan lebih buruk ketimbang yang tak pernah dimulai.
Gampang dirumuskan, canggung dibangun. Ada enam hambatan yang menghalangi, dan kesamaannya layak disebut lebih dulu: nyaris tak satu pun melahirkan error. Lima dari enam gagal justru dengan cara berhasil — tapi berhasil pada sasaran yang keliru.
Hambatan pertama: cara pelaksanaan yang paling kentara justru merusak sistem milik orang lain. Ambil nilai lama, temukan tiap tempat ia muncul, ganti — satu baris shell, tanpa daftar yang harus dirawat, dan menjangkau file yang tak seorang pun ingat menyebutkannya. Ia juga, setiap kali nilai milik saya kebetulan sama persis byte-nya dengan milik penyedia eksternal, cara diam-diam merusak integrasi yang tak diawasi siapa pun. Mengganti salinan saya atas secret milik orang lain tidak merotasi apa pun; ia cuma membuat salinan saya jadi keliru, dan autentikasi mulai gagal karena sebab yang tak akan dijelaskan log mana pun milik saya. Jadi tool-nya bekerja dari daftar eksplisit berisi key bernama di file bernama, dan menambah kredensial berarti menambahkannya ke daftar itu. Langkah tambahan itulah intinya: alternatifnya adalah tool yang radius ledaknya "tiap string yang kebetulan cocok".
Hambatan kedua: beberapa nilai tampak persis seperti password yang bisa dirotasi, padahal bukan. Key-encryption key tak memberi akses — ia mendekripsi key lain. Application encryption key melindungi kolom database. Token terbitan sebuah otoritas itu bertanda tangan, bukan secret bersama. Mengganti salah satunya tak melahirkan kredensial baru yang bekerja; ia melahirkan data yang tak terbaca selamanya, atau nilai yang gagal verifikasi tanda tangan. Dan tak satu pun gagal pada saat rotasinya. Kegagalannya tiba pada kali berikutnya sesuatu mencoba mendekripsi — bisa berhari-hari kemudian, tanpa apa pun yang menunjuk kembali ke sebabnya. Itu sebabnya daftar apa yang tak boleh dirotasi lebih lama disusun ketimbang daftar apa yang harus.
Hambatan ketiga: mengganti file konfigurasi tidak mengganti password-nya. Untuk database, object store, atau search cluster, nilai di konfigurasi cuma dibaca sekali — ketika data directory-nya masih kosong, saat inisialisasi pertama. Sesudah itu password yang sungguhan tinggal di dalam state milik service itu sendiri. Menyunting file lalu me-restart karenanya tak mencapai apa pun kecuali membuat konfigurasinya berselisih dengan kenyataan, dan client berikutnya yang memakainya gagal mengautentikasi. Urutan yang bekerja: state dulu, lalu konfigurasi, lalu restart, lalu verifikasi — dan urutan itulah seluruh isi perbaikannya.
Hambatan keempat: menaikkan container lagi tidak me-restart-nya. Runtime membandingkan state yang diinginkan dengan state yang berjalan, melihat spesifikasi container-nya tak berubah — file konfigurasinya di-mount, bukan ikut ter-build ke dalam image — lalu dengan benar membiarkan container itu apa adanya. Artinya ia terus berjalan dengan connection pool penuh koneksi yang diautentikasi memakai password lama. Gejalanya sungguh membingungkan: file di disk sudah benar, dan service melaporkan kegagalan atas kredensial yang tertulis persis di depan mata. Memaksa container dilahirkan ulang itulah yang membuat file barunya berlaku, dan tak ada apa pun pada perintah biasanya yang menyiratkan itu diperlukan.
Hambatan kelima: satu langkah verifikasi bisa lolos padahal yang ia verifikasi sudah gagal. Menjalankan perintah lalu memeriksa exit status-nya terasa seperti verifikasi dan kerap bukan, sebab banyak client menangani error koneksi di dalam dirinya sendiri lalu tetap keluar dengan status nol. Jadi tiap pemeriksaan membuka koneksi memakai kredensial baru lalu mengerjakan satu operasi sepele, dan kegagalannya me-rollback kredensial itu — nilai lamanya dipulihkan di state service, file konfigurasinya dipulihkan dari backup yang diambil beberapa saat sebelumnya. Rollback-nya sengaja per-kredensial, bukan semua-atau-tak-sama-sekali: membatalkan tujuh rotasi yang berhasil gara-gara yang kedelapan keras kepala berarti satu service yang rewel sanggup mencegah seluruh sistem dirotasi selamanya.
Hambatan keenam: pengamannya bisa merusak apa yang ia jaga. Mengambil backup penuh sebelum tiap rotasi jelas benar — sampai dua rotasi berjalan dalam satu jam, masing-masing melahirkan backup penuh nyaris kembar sebesar hampir tiga ratus megabyte. Retention menyimpan sejumlah tetap recovery point, jadi dua yang nyaris kembar mendorong keluar dua yang sungguh-sungguh lebih tua, dan operasi yang seluruh tujuannya melindungi data justru memperpendek sejauh apa data itu bisa dipulihkan. Jawabannya: biarkan tool memilih mode backup-nya dari umur backup penuh yang terakhir, bukan selalu meraih pilihan yang paling lengkap.
Keenamnya jatuh ke dalam empat pertanyaan, dan itulah urutan pengerjaannya. Dua yang pertama menentukan apa yang boleh disentuh sama sekali. Yang ketiga dan keempat menentukan apakah perubahannya benar-benar berlaku — keduanya kasus ketika sistem melaporkan keberhasilan padahal tak ada yang bergeser. Yang kelima bertanya apakah kita akan tahu seandainya tidak. Dan yang keenam bertanya apakah masih ada jalan pulang, pertanyaan yang mengatasi sisanya: tiap hambatan lain masih bisa dipulihkan selama jawaban atas yang satu itu adalah ya.
Metode
A. Kenapa rotation tool tak boleh mencari nilai lama
Inilah jawaban atas hambatan pertama: bertahan di dalam radius ledak yang dimaksudkan.
Cara paling wajar menulis tool ini: ambil kredensial lama, cari di mana saja ia muncul, ganti dengan yang baru. Satu baris shell, dan ia menangani tiap file konfigurasi tanpa perlu diberi tahu satu per satu.
Ia juga, mengingat dua sifat di atas, jalan untuk merusak integrasi dengan organisasi lain.
# yang dikerjakan tool paling terpikirkan — dan kenapa berbahaya di sini
|
# ia menemukan secret internal SEKALIGUS salinan milik penyedia eksternal,
# sebab keduanya kebetulan memegang string yang samaBila secret internal dan secret penyedia eksternal kebetulan string yang sama, cari-ganti menemukan keduanya. Yang internal memang harus berubah. Yang eksternal milik sistem yang bukan saya operasikan — mengganti salinan saya cuma membuat salinan saya jadi keliru, dan autentikasi ke penyedia itu mulai gagal karena sebab yang takkan dijelaskan oleh apa pun di log saya.
Maka tool-nya bekerja dari daftar eksplisit: kunci yang disebut namanya, di file yang disebut namanya. Ia tak bisa menyentuh apa pun yang tak diberitahukan kepadanya. Menambahkan kredensial baru ke sistem berarti menambahkannya ke daftar itu — satu langkah ekstra, disengaja, sebab alternatifnya adalah tool yang radius ledaknya "tiap string yang kebetulan cocok".
# kunci bernama, di file bernama — selain itu tak tersentuh
Keputusan rancangan yang sama memberi tiap kunci di daftar itu nilai barunya sendiri, jadi tak ada dua service yang pernah berbagi satu nilai.
B. Daftar apa yang tak boleh dirotasi, dan kenapa
Inilah jawaban atas hambatan kedua, dan inilah daftar yang paling lama disusun.
Menyusun daftar apa yang harus dirotasi itu gampang. Menyusun daftar apa yang harus dibiarkan memakan waktu lebih lama dan mengajari saya lebih banyak.
Beberapa nilai tampak persis seperti secret yang layak dirotasi, padahal bukan:
Key-encryption key bukan password — ia yang membuka kunci-kunci lain yang tersimpan di database. Menggantinya tak memberi akses baru; ia membuat bahan terenkripsinya tak terbaca. Tak ada error pada saat rotasi. Kegagalannya tiba saat berikutnya ada yang mencoba mendekripsi.
Kunci enkripsi aplikasi yang melindungi kolom database terenkripsi punya bentuk bahaya yang sama. Rotasi berarti tiap nilai yang sebelumnya terenkripsi jadi tak terbaca selamanya, kecuali framework-nya diberi tahu secara eksplisit untuk menyimpan kunci lama demi dekripsi.
Token terbitan sebuah otoritas sama sekali bukan shared secret, walau ia duduk di konfigurasi dengan penampilan yang persis sama. Ia bertanda tangan. Menggantinya dengan string acak menghasilkan nilai yang gagal diverifikasi tanda tangannya — dan gagalnya terlambat: service penerima meloloskan permintaan di gerbangnya lalu gagal jauh di dalam, dengan error yang menunjuk komponen yang sama sekali keliru.
Pola yang berlaku untuk semuanya: format sebuah nilai tak memberi tahu apa pun tentang perannya. String panjang yang tampak acak bisa jadi password, bisa kunci yang membuka kunci lain, bisa pernyataan bertanda tangan. Cuma dengan tahu ia untuk apa, barulah ketahuan apakah menggantinya aman.
C. Mengganti file konfigurasi tidak mengganti password-nya
Inilah jawaban atas hambatan ketiga — yang pertama dari dua hambatan ketika perubahan tampak berlaku padahal tidak.
Untuk database, penyimpan objek, atau klaster pencarian, password di file konfigurasi cuma dibaca saat direktori datanya masih kosong — pada inisialisasi pertama. Sesudah itu, password yang sesungguhnya hidup di dalam datanya, di tabel user milik service itu sendiri.
Jadi menyunting file konfigurasi lalu me-restart sama sekali tak menghasilkan apa-apa. Service membaca passwordnya dari datanya, yang masih memegang yang lama. Konfigurasinya kini bertentangan dengan kenyataan, dan klien berikutnya yang memakai konfigurasi itu gagal terautentikasi.
# passwordnya hidup di dalam data, bukan di file
Urutan yang benar punya empat langkah, dan justru urutannya yang jadi inti:
Ganti password di state milik service itu sendiri —
ALTER USER, atau security API yang setara.Tulis nilai baru ke file konfigurasi.
Restart service yang menyodorkannya.
Verifikasi dengan benar-benar menyambung memakai nilai baru.
State dulu, sebab di sanalah kebenarannya tinggal. Konfigurasi kedua. Restart ketiga, supaya proses yang berjalan memungutnya. Verifikasi terakhir — dan verifikasi berarti menyambung, bukan memeriksa bahwa sebuah perintah selesai dengan sukses.
D. Restart, bukan reload
Dan inilah hambatan keempat: yang kedua dari pasangan itu.
Langkah ketiga punya jebakannya sendiri. Menaikkan container dengan perintah yang biasa tak menghasilkan apa pun bila spesifikasi container-nya tak berubah — runtime membandingkan keadaan yang diinginkan dengan yang sedang berjalan, tak menemukan beda, lalu membiarkan container itu.
Lazimnya itu memang perilaku yang diinginkan. Di sini ia keliru: file konfigurasinya berubah, tapi spesifikasi container-nya tidak, sebab file itu di-mount masuk, bukan dipanggang ke dalam image. Container tetap berjalan dengan connection pool penuh sambungan yang terautentikasi memakai password lama.
Gejalanya membingungkan: file konfigurasi di disk sudah benar, dan service melaporkan kegagalan atas kredensial yang tertulis persis di depan mata Anda. Memaksa container dibuat ulang itulah yang membuat file baru berlaku.
E. Verifikasi yang sanggup menyadari kegagalan
Inilah jawaban atas hambatan kelima: mengetahui apakah semua di atas benar-benar bekerja.
Tiap langkah rotasi diakhiri sebuah pemeriksaan, dan pemeriksaannya ditulis supaya gagal ketika rotasinya gagal — yang ternyata tak sesederhana kedengarannya.
Pemeriksaan yang menjalankan perintah lalu menengok status keluarnya sering lolos terlepas dari keadaan. Banyak klien mengembalikan sukses untuk "saya tak berhasil menyambung" ketika connection error ditangani di dalam. Maka tiap verifikasi membuka sambungan memakai kredensial baru lalu mengerjakan satu operasi sepele. Kalau itu gagal, rotasi untuk kredensial tersebut dibatalkan: password lama dipulihkan di state service, dan file konfigurasi dikembalikan dari cadangan yang diambil sebelum ia ditulis.
# bukan "apakah perintahnya exit 0" — benar-benar menyambung dengan nilai baru
if ! ; then
; Pembatalannya per kredensial, bukan semua-atau-tidak-sama-sekali. Kalau satu dari delapan rotasi gagal, tujuh tetap terotasi dan satu dikembalikan ke keadaan sebelumnya. Alternatifnya — membatalkan semuanya begitu ada satu yang gagal — berarti satu service yang keras kepala menghalangi sisanya untuk selamanya dirotasi.
F. Dua detail yang cuma muncul di sistem yang berjalan
Dua hal menjegal saya, dan tak ada dokumentasi sebanyak apa pun yang akan memberitahukannya.
Pertama: password di dalam connection string itu ter-URL-encode. Password yang memuat @ muncul di konfigurasi sebagai %40, jadi pencarian biasa atas string passwordnya takkan menemukannya. Tool-nya membongkar connection string jadi bagian-bagiannya, mengganti bagian password, lalu menyusunnya kembali.
# password bermuatan @ tersimpan ter-encode, jadi pencarian biasa luput
database_url = "postgres://svc:p%40ssw0rd@db:5432/app"
# ^^^ '@' jadi '%40'Kedua: kunci enkripsi bisa tertanam di dalam job antrean yang menunggu. Di sistem ini, job yang mengantre membawa passphrase terenkripsi di dalam muatan ter-serialize-nya. Merotasi kunci yang membuka passphrase itu berarti tiap job yang sudah telanjur mengantre akan gagal saat akhirnya dijalankan — sesudah rotasinya melaporkan sukses, tanpa sambungan apa pun antara sebab dan akibat.
Maka kunci yang satu itu ditangani berbeda: tool-nya memeriksa antrean lebih dulu dan melewati rotasinya bila masih ada yang menunggu, sambil meminta operator menguras antrean lalu menjalankannya lagi khusus untuk kunci itu. Cuma kunci inilah, dari seluruh himpunan, yang punya prasyarat di luar dirinya sendiri.
# Satu-satunya prasyarat yang tinggal di luar kredensialnya sendiri.
pending=
if [; then
G. Dry run sebagai bawaan, dan backup sebelum apa pun
Dua pengaman melingkupi semua yang di atas.
Tindakan bawaan tool ini adalah mencetak apa yang akan ia kerjakan dan tidak mengubah apa pun. Menerapkan perubahan menuntut flag eksplisit. Alasannya: ongkos kedua mode itu tak setara — dry run yang tak sengaja membuang beberapa detik, sedangkan rotasi yang tak sengaja mengenai production menjatuhkan sebuah layanan.
Dan sebelum perubahan apa pun diterapkan, tool-nya mengambil backup — lalu membatalkan seluruh rotasi bila backup-nya gagal. Rotasi tanpa titik pemulihan bukan rotasi, melainkan pertaruhan.
# Aman sebagai bawaan: --apply harus diminta, dan backup gagal menghentikan semua.
apply=false
[ && apply=true
if && ; then
Yang dibutuhkan rotasi dari backup itu sempit: konfigurasi yang akan diubahnya, direkam tepat sebelum perubahan. Itulah yang memungkinkan kredensial yang gagal diperiksa dikembalikan persis seperti sesaat sebelumnya — rollback per kredensial yang dijelaskan di Pendahuluan bergantung padanya. Berapa lama backup itu disimpan sesudahnya tak penting di sini; yang penting ia sudah ada sebelum penulisan pertama.
Hasil dan Pembahasan
A. Saat pengaman bisa merusak yang dijaganya
Inilah hambatan keenam, dan ia lahir dari kehati-hatian itu sendiri.
Aturan backup-dulu itu menyimpan cacat yang gampang tak terduga, dan ia contoh kesukaan saya tentang tindakan pengamanan yang justru menimbulkan kerugian.
Misalkan tiap rotasi mengambil backup full. Kelihatannya jelas benar — titik pemulihan paling lengkap yang mungkin, sebelum operasi berisiko.
Lalu dua rotasi berjalan dalam satu jam yang sama, seperti lazimnya saat menguji. Masing-masing melahirkan backup full hampir tiga ratus megabyte, dan keduanya nyaris identik. Retensi backup menyimpan sejumlah tetap titik pemulihan, jadi dua kembar itu mendorong keluar dua titik pemulihan yang sungguh lebih tua.
Operasi yang tujuannya melindungi data justru mempersempit sejauh apa data itu bisa dipulihkan.
Karena itu tool-nya memilih sendiri mode backup dengan menengok umur full terakhir, bukan selalu meraih pilihan yang paling lengkap.
# Pengaman yang memakan retention-nya sendiri bukan pengaman.
last_full_age=
if [ || [; then
mode=full
else
mode=incremental # menjaga titik pemulihan lama tetap di dalam retention
Diukur pada data sungguhan, incremental-nya enam puluh enam megabyte berbanding dua ratus sembilan puluh empat, dan memulihkannya menelusuri rantainya dengan benar.
Yang saya ambil dari sini: tindakan pengamanan punya ongkos, dan ongkos itu dibayar dari anggaran yang sama dengan yang ia lindungi. Retensi itu terbatas. Memenuhinya dengan snapshot pertahanan yang diambil berselang menit bukan kehati-hatian — itu membelanjakan jendela pemulihan untuk titik pemulihan yang paling tak berguna yang tersedia.
B. Kenapa daftar eksplisit mengalahkan otomatisasi yang pintar
Daftar eksplisit adalah bagian paling tidak elok dari rancangan ini. Ia wajib dirawat tangan. Menambahkan kredensial ke sistem lalu lupa menambahkannya ke daftar berarti kredensial itu diam-diam tak pernah dirotasi.
Saya berdamai dengan itu, sebab kedua arah kegagalannya tak setara. Kredensial yang tak dirotasi adalah kredensial yang tetap seaman kemarin — sebuah perbaikan yang terlewat. Kredensial yang dirotasi padahal semestinya tidak bisa membuat data terenkripsi tak terbaca selamanya, atau memutus integrasi dengan organisasi yang sama sekali tak paham kenapa permintaan mereka mulai gagal.
Ketika satu arah kegagalan bisa dipulihkan dan satunya tidak, tool-nya sebaiknya gagal ke arah yang bisa dipulihkan. Di sini artinya berbuat terlalu sedikit ketimbang terlalu banyak.
C. Berapa ongkos rotasi selama ia berjalan
Rotasi me-restart service, dan me-restart service berarti gangguan singkat. Tak ada versi dari ini yang tak terlihat oleh user.
Itu membuat rotasi jadi operasi terjadwal, bukan operasi yang berjalan terus — bulanan, di jam sepi, bukan tiap saat. Artinya juga tool-nya harus cukup andal untuk berjalan tanpa ditunggui, sebab operasi yang menuntut pengawasan pukul dua pagi lambat laun akan diam-diam berhenti dikerjakan.
Inilah pertukaran yang disengaja dari merotasi kredensial di sistem yang dibangun tanpa kredensial ganda. Sistem yang memang dibangun untuk rotasi tanpa downtime mendukung dua kredensial sah sekaligus, sehingga yang lama bisa dipensiunkan sesudah tiap klien berpindah. Memasang ulang kemampuan itu ke selusin service tak bisa saya benarkan. Menerima gangguan singkat yang terjadwal, bisa.
D. Apa yang berlaku umum
Dua hal dari pekerjaan ini berlaku terlepas dari sistemnya.
Ketahui tiap kredensial itu apa sebelum merotasinya. Bukan formatnya — perannya. Apakah ia disodorkan, atau ia mendekripsi? Apakah ia shared secret, atau ditandatangani orang lain? Apakah ia juga dipegang pihak di luar sistem Anda? Pertanyaan-pertanyaan itu yang memisahkan nilai yang aman dirotasi dari yang akan memusnahkan data.
Verifikasi dengan memakai kredensialnya, bukan dengan memeriksa bahwa sebuah perintah sukses. Langkah yang menentukan adalah menyambung memakai nilai baru. Segala yang mendahuluinya cuma persiapan, dan persiapan yang tak pernah diperiksa tak bisa dibedakan dari persiapan yang gagal.
Simpulan
Rotasi kredensial di sistem yang berjalan bukan satu tindakan. Ia state, lalu konfigurasi, lalu restart, lalu verifikasi — dan tiap langkah itu punya caranya sendiri untuk tampak berhasil sambil tak mencapai apa pun.
Keputusan yang paling akan saya bela adalah daftar eksplisit itu. Ia membuat tool-nya kurang otomatis dan lebih bertele-tele, dan ia satu-satunya alasan rotasi tak pernah menjangkau secret milik organisasi lain. Otomatisasi yang bekerja dengan mencocokkan nilai adalah otomatisasi yang cepat atau lambat akan mencocoki nilai yang tak pernah dimaksudkan untuk disentuhnya.
Dan bagian yang takkan saya duga: pengamannya sendiri butuh pengaman. Mengambil backup full sebelum tiap rotasi adalah naluri yang bisa dibela, yang bisa diam-diam menghabiskan jendela pemulihan yang semestinya ia jaga. Tindakan pelindung juga mengonsumsi sumber daya, dan sumber daya yang dikonsumsinya kerap justru yang ia ada untuk melestarikannya.
Istilah
- Kredensial
- Apa pun yang disodorkan sistem untuk membuktikan ia boleh melakukan sesuatu — password, access key, token.
- Rotasi
- Mengganti kredensial dengan nilai baru, sehingga salinan yang diperoleh lebih dulu berhenti berguna.
- Key-encryption key
- Kunci yang tugasnya membuka kunci-kunci lain. Merotasinya tak mengubah akses; ia membuat kunci yang dilindunginya tak terbaca.
- Dry run
- Mode yang melaporkan apa saja yang akan dikerjakan, tanpa mengerjakannya. Menjadikannya bawaan membuat kekeliruan tak berongkos.
- Retensi
- Berapa banyak titik pemulihan disimpan sebelum yang tertua dibuang. Jumlahnya terbatas, dan itu sebabnya backup yang tak perlu punya ongkos.
- Rollback
- Mengembalikan perubahan yang gagal ke keadaan sebelumnya, yang menuntut keadaan itu sudah direkam sebelum perubahan dilakukan.
Technologies covered
- Bash
- Linux
- PostgreSQL
- Docker