Apa keuntungan menempatkan nilai-nilai rahasia situs web sebagai variabel lingkungan?

24

Pedoman devops di https://12factor.net/config menyarankan untuk memasukkan rahasia situs web (kata sandi basis data, kunci api, dll.) Ke dalam variabel lingkungan. Apa kelebihan yang dimiliki daripada menggunakan file teks (JSON, XML, YAML, INI, atau yang serupa) yang diabaikan dari kontrol versi?

Saya merasa jauh lebih mudah untuk menyalin file konfigurasi dengan rahasia daripada menangani variabel lingkungan di .bash_profile dan konfigurasi server web. Apakah saya melewatkan sesuatu?

Aidas Bendoraitis
sumber
1
Secara teori lebih mudah untuk membaca file daripada memori sehingga Anda dapat mempertimbangkan permukaan serangan yang lebih besar dan kompleksitas yang lebih kecil.
Florin Asăvoaie
Aturan praktis saya adalah bahwa menyimpan pengaturan dalam variabel lingkungan paling baik hanya dilakukan di lingkungan seperti buruh pelabuhan. Di luar VM kontainer, ia menyetujui / memilih semua poin lain dari 12factor.net dan penggunaan file konfigurasi. Tak satu pun dari kami menyukai sifat variabel lingkungan yang tidak aman pada penyebaran server biasa.
Corey Ogburn

Jawaban:

21

Penulis daftar alasan mereka, meskipun agak terpisah. Argumen utama mereka adalah bahwa mudah untuk secara tidak sengaja memeriksa file konfigurasi, dan file konfigurasi memiliki beragam format dan dapat tersebar di seluruh sistem (ketiganya merupakan argumen yang biasa-biasa saja untuk konfigurasi terkait keamanan seperti token dan kredensial auth).

Berdasarkan pengalaman saya sendiri, Anda pada dasarnya memiliki tiga opsi berikut, dengan kelebihan dan kekurangan terkait:

Simpan data dalam file konfigurasi.

Saat mengambil pendekatan ini, Anda harus mengisolasi mereka dari repositori itu sendiri, dan pastikan mereka berada di luar area tempat aplikasi menyimpan kontennya.

Keuntungan:

  • Sangat mudah untuk mengisolasi dan mengontrol akses, terutama jika Anda menggunakan hal-hal seperti SELinux atau AppArmor untuk meningkatkan keamanan sistem secara keseluruhan.
  • Umumnya mudah diubah untuk pengguna non-teknis (ini merupakan keuntungan untuk perangkat lunak yang diterbitkan, tetapi tidak harus untuk perangkat lunak khusus untuk organisasi Anda).
  • Mudah dikelola di berbagai kelompok besar server. Ada semua jenis alat untuk penyebaran konfigurasi di luar sana.
  • Sangat mudah untuk memverifikasi konfigurasi apa yang digunakan.
  • Untuk aplikasi yang ditulis dengan baik, Anda biasanya dapat mengubah konfigurasi tanpa mengganggu layanan dengan memperbarui file konfigurasi dan kemudian mengirim sinyal tertentu ke aplikasi (biasanya SIGHUP).

Kekurangan:

  • Perencanaan yang tepat diperlukan untuk menjaga keamanan data.
  • Anda mungkin harus belajar format yang berbeda (meskipun hari ini hanya ada beberapa yang perlu dikhawatirkan, dan mereka umumnya memiliki sintaks yang sama).
  • Lokasi penyimpanan yang tepat mungkin dikodekan dalam aplikasi, sehingga penyebaran berpotensi bermasalah.
  • Parsing file konfigurasi bisa bermasalah.

Simpan data dalam variabel lingkungan.

Biasanya ini dilakukan dengan sumber daftar variabel dan nilai lingkungan dari skrip startup, tetapi dalam beberapa kasus mungkin hanya menyatakannya pada baris perintah sebelum nama program.

Keuntungan:

  • Dibandingkan dengan mem-parsing file konfigurasi, menarik nilai dari variabel lingkungan adalah sepele di hampir semua bahasa pemrograman.
  • Anda tidak perlu terlalu khawatir tentang menerbitkan konfigurasi secara tidak sengaja.
  • Anda memperoleh tingkat keamanan tertentu karena ketidakjelasan karena praktik ini tidak umum, dan kebanyakan orang yang meretas aplikasi Anda tidak akan langsung berpikir untuk melihat variabel lingkungan.
  • Akses dapat dikontrol oleh aplikasi itu sendiri (ketika itu memunculkan proses anak, itu dapat dengan mudah menggosok lingkungan untuk menghapus info sensitif).

Kekurangan

  • Pada sebagian besar sistem UNIX, cukup mudah untuk mendapatkan akses ke variabel lingkungan proses. Beberapa sistem menyediakan cara untuk mengurangi ini ( hidepidopsi mount untuk /procdi LInux misalnya), tetapi mereka tidak diaktifkan secara default, dan tidak melindungi terhadap serangan dari pengguna yang memiliki proses.
  • Bukan hal yang sepele untuk melihat pengaturan yang tepat yang digunakan sesuatu jika Anda menangani masalah keamanan yang disebutkan di atas dengan benar.
  • Anda harus percaya aplikasi untuk menggosok lingkungan ketika memunculkan proses anak, jika tidak akan membocorkan informasi.
  • Anda tidak dapat dengan mudah mengubah konfigurasi tanpa restart aplikasi secara lengkap.

Gunakan argumen baris perintah untuk meneruskan data.

Serius, hindari ini di semua biaya, itu tidak aman dan itu adalah rasa sakit di pantat untuk mempertahankan.

Keuntungan:

  • Bahkan lebih mudah diurai daripada variabel lingkungan di sebagian besar bahasa.
  • Proses anak tidak secara otomatis mewarisi data.
  • Memberikan cara mudah untuk dengan cepat menguji konfigurasi tertentu saat mengembangkan aplikasi.

Kekurangan:

  • Sama seperti variabel lingkungan, mudah untuk membaca command-line proses lain pada kebanyakan sistem.
  • Sangat membosankan untuk memperbarui konfigurasi.
  • Menempatkan batas keras pada berapa lama konfigurasi dapat (kadang-kadang serendah 1024 karakter).
Austin Hemmelgarn
sumber
1
Satu hal yang tidak penting adalah boot tanpa pengawasan dari server, tanpa harus memberikan kata sandi secara manual, pada akhirnya mereka berada di suatu tempat di disk untuk itu
PlasmaHH
7
Pada sebagian besar sistem UNIX, Anda dapat membaca hampir semua variabel lingkungan proses tanpa memerlukan hak istimewa apa pun. - Bisakah Anda mengembangkannya? File / proc / #### / environment hanya dapat dibaca oleh pemilik, jadi Anda harus root atau memiliki sudo.
rrauenza
Saya pikir beberapa tren konfigurasi env ini juga muncul dari hal-hal seperti buruh pelabuhan di mana Anda menggunakan wadah standar dan mengkonfigurasinya dengan mengirimkan variabel env ke wadah.
rrauenza
@rrauenza Kepemilikan suatu proses bukanlah hak istimewa yang signifikan kecuali jika Anda melakukan pekerjaan yang sangat baik dalam memisahkan berbagai hal dengan akun, dan Anda sebenarnya hanya memerlukan kemampuan CAP_SYS_ADMIN (yang secara implisit dimiliki oleh root) jika Anda bukan pemiliknya. Juga, mengenai variabel lingkungan, Anda mungkin benar, tetapi ini adalah desain marjinal bahkan dengan Docker.
Austin Hemmelgarn
3
Saya setuju dengan poin yang dibuat @rrauenza. Jawabannya cukup hebat, tetapi saya ingin klarifikasi tentang bagaimana tepatnya Anda dapat membaca hampir semua variabel lingkungan proses tanpa memerlukan hak istimewa yang signifikan . Mengenai " dan Anda sebenarnya hanya perlu kapabilitas CAP_SYS_ADMIN (yang secara implisit dimiliki oleh root) ..." yah, jika agen jahat memiliki hak akses root, diskusi lebih lanjut berlebihan, dan CAP_SYS_ADMIN mungkin juga menjadi hak istimewa root (lihat man7.org/linux /man-pages/man7/capabilities.7.html , CAP_SYS_ADMIN dan Catatan untuk pengembang kernel )
Nubarke
13

Variabel lingkungan akan diwarisi oleh setiap proses anak dari server web. Itu setiap sesi yang terhubung ke server, dan setiap program memunculkannya. Rahasia akan terungkap secara otomatis ke semua proses tersebut.

Jika Anda menyimpan rahasia dalam file teks, mereka harus dapat dibaca oleh proses server, dan sangat berpotensi oleh setiap proses anak juga. Tetapi setidaknya program harus pergi dan menemukannya; mereka tidak disediakan secara otomatis. Anda mungkin juga dapat membuat beberapa proses anak berjalan di akun yang berbeda, dan membuat rahasia hanya dapat dibaca oleh akun tersebut. Sebagai contoh, suEXEC melakukan ini di Apache.

Andrew Schulman
sumber
1
"Itu setiap sesi yang terhubung ke server" adalah pernyataan yang menyesatkan. Anda tidak dapat membuka sesi http ke server dan mendapatkan akses ke variabel lingkungannya, Anda juga tidak dapat masuk ke shell di server itu dan mendapatkannya kecuali Anda memiliki akses root atau memiliki proses server web.
Segfault
Setiap proses yang dihasilkan oleh server web mewarisi lingkungannya, kecuali jika Anda mengambil langkah-langkah aktif sebaliknya. Halaman HTML tidak memiliki kemampuan untuk menggunakan informasi itu, tetapi skrip melakukannya.
Andrew Schulman
Meskipun benar, jawaban ini dapat dilakukan dengan beberapa koreksi / konsesi, terutama yang berkaitan dengan sesi istilah . Pada bacaan pertama, tampaknya melukis penggunaan variabel lingkungan dalam cahaya yang buruk hampir menyarankan kemungkinan pengungkapan informasi kepada klien eksternal. Juga, konsesi yang sebanding dengan suexec dapat dibuat untuk pengaturan terbatas env-vars misalnya pengaturan per-proses env-vars (a la MYVAR=foo /path/to/some/executable) membatasi penyebaran ke proses dan itu hanya anak-anak - dan di mana master daemon yang diperlukan dapat menggosok / mereset / memodifikasi lingkungan proses anak.
shalomb
2

Bahkan jika ada beberapa trade off terkait keamanan yang harus dibuat ketika datang ke variabel lingkungan atau file, saya tidak berpikir keamanan adalah kekuatan pendorong utama untuk rekomendasi ini. Ingat penulis 12factor.net juga (atau dulu juga?) Pengembang Heroku PaaS. Membuat semua orang menggunakan variabel lingkungan mungkin sedikit menyederhanakan pengembangan mereka. Ada begitu banyak variasi dalam berbagai format dan lokasi file konfigurasi dan akan sulit bagi mereka untuk mendukung semuanya. Variabel lingkungan mudah dibandingkan.

Tidak perlu banyak imajinasi untuk menebak beberapa percakapan yang dilakukan.

Pengembang A: "Ah UI file konfigurasi rahasia ini terlalu berantakan! Apakah kita benar-benar perlu memiliki drop down yang beralih antara json, xml, dan csv?"

Pengembang B: "Oh, hidup akan sangat megah jika hanya semua orang menggunakan variabel lingkungan untuk konfigurasi aplikasi."

Pengembang A: "Sebenarnya ada beberapa alasan terkait keamanan yang masuk akal untuk melakukan itu. Variabel lingkungan mungkin tidak akan secara tidak sengaja diperiksa ke dalam kontrol sumber."

Pengembang B: "Apakah Anda tidak mengatur variabel lingkungan dengan skrip yang meluncurkan daemon, atau file konfigurasi?"

Pengembang A: "Tidak di Heroku! Kami akan membuatnya mengetikkannya di UI."

Pengembang B: "Oh, lihat, peringatan nama domain saya untuk 12factor.net baru saja padam." 1


1 : sumber: dibuat-buat.

Segfault
sumber
1

TL; DR

Ada sejumlah alasan untuk menggunakan variabel lingkungan alih-alih file konfigurasi, tetapi dua yang paling umum untuk diabaikan adalah nilai utilitas dari konfigurasi out-of-band dan peningkatan pemisahan antara server, aplikasi, atau peran organisasi. Daripada menyajikan daftar lengkap semua alasan yang mungkin, saya hanya membahas dua topik ini dalam jawaban saya, dan menyentuh ringan pada implikasi keamanannya.

Konfigurasi Keluar-Band: Memisahkan Rahasia dari Kode Sumber

Jika Anda menyimpan semua rahasia Anda di file konfigurasi, Anda harus mendistribusikan rahasia itu ke setiap server. Itu berarti memeriksa rahasia menjadi kontrol revisi di samping kode Anda, atau memiliki repositori atau mekanisme distribusi yang sepenuhnya terpisah untuk rahasia.

Enkripsi rahasia Anda tidak benar-benar membantu menyelesaikan masalah ini. Yang perlu dilakukan hanyalah mendorong masalah ke satu penghapusan, karena sekarang Anda juga harus khawatir tentang manajemen dan distribusi utama!

Singkatnya, variabel lingkungan adalah pendekatan untuk memindahkan data per-server atau per-aplikasi dari kode sumber ketika Anda ingin memisahkan pengembangan dari operasi. Ini sangat penting jika Anda telah menerbitkan kode sumber!

Tingkatkan Pemisahan: Server, Aplikasi, dan Peran

Meskipun Anda tentu bisa memiliki file konfigurasi untuk menyimpan rahasia Anda, jika Anda menyimpan rahasia dalam kode sumber Anda memiliki masalah kekhususan. Apakah Anda memiliki cabang atau repositori terpisah untuk setiap set rahasia? Bagaimana Anda memastikan set rahasia sampai ke server yang tepat? Atau apakah Anda mengurangi keamanan dengan memiliki "rahasia" yang sama di mana-mana (atau dapat dibaca di mana-mana, jika Anda memiliki semuanya dalam satu file), dan karenanya merupakan risiko yang lebih besar jika kontrol keamanan satu sistem gagal?

Jika Anda ingin memiliki rahasia unik di setiap server, atau untuk setiap aplikasi, variabel lingkungan akan menghilangkan masalah karena harus mengelola banyak file. Jika Anda menambahkan server, aplikasi, atau peran baru, Anda tidak perlu membuat file baru atau memperbarui yang lama: Anda cukup memperbarui lingkungan sistem yang dimaksud.

Berpisah Pikiran tentang Keamanan

Walaupun eksplorasi menyeluruh terhadap keamanan kernel / memori / file berada di luar cakupan untuk jawaban ini, ada baiknya menunjukkan bahwa variabel lingkungan per-sistem yang diterapkan dengan benar tidak kalah aman daripada rahasia "terenkripsi". Dalam kedua kasus, sistem target masih harus menyimpan rahasia yang didekripsi dalam memori di beberapa titik untuk menggunakannya.

Ini juga layak menunjukkan bahwa ketika nilai disimpan dalam memori yang mudah menguap pada node yang diberikan, tidak ada file pada disk yang dapat disalin dan diserang secara offline. Ini umumnya dianggap sebagai keuntungan bagi rahasia di dalam memori, tetapi ini tentu saja tidak konklusif.

Masalah variabel lingkungan vs teknik manajemen rahasia lainnya benar-benar lebih tentang keamanan dan kegunaan pertukaran daripada tentang absolut. Jarak tempuh Anda mungkin beragam.

CodeGnome
sumber
2
Ini tidak meyakinkan, karena semua kelemahan yang Anda sebutkan untuk file konfigurasi juga berlaku untuk variabel lingkungan. Variabel lingkungan adalah data konfigurasi. Mereka secara ajaib tidak mengatur diri mereka sendiri. Mereka harus didistribusikan ke setiap sistem, dan semacam mekanisme konfigurasi harus digunakan untuk mengaturnya.
jpaugh
@ jpaugh Anda membuat argumen orang bodoh dan menyerang sesuatu yang tidak pernah saya katakan. Masalah yang saya bahas adalah konfigurasi out-of-band dan pemisahan data. Sebagaimana dijelaskan dengan jelas, Anda dapat melakukan hal-hal ini dengan cara apa pun yang Anda suka. Jika Anda mau, Anda dapat memposting rahasia Anda di samping kode Anda secara publik di GitHub, tetapi itu tampaknya tidak bijaksana dalam kasus umum. Namun, hanya Anda yang dapat menentukan pertukaran yang diperlukan agar sistem Anda beroperasi dengan baik dalam model ancaman yang diberikan.
CodeGnome
2
Semua poin Anda benar, kecuali bahwa itu berlaku untuk variabel lingkungan sebanyak data konfigurasi lainnya. Jika Anda menyimpan variabel lingkungan dalam file, maka Anda dapat mengkomitnya; dan jika Anda mengirimnya keluar-band, lebih mudah melakukannya dalam file daripada mengetiknya. Tetapi jika Anda lebih suka mengetiknya, mengapa tidak mengetikkan objek JSON saja, dan membacanya di stdin? Itu sebenarnya lebih aman daripada baris perintah.
jpaugh
1

Secara pribadi, saya tidak akan merekomendasikan pengaturan variabel lingkungan .bashrckarena ini menjadi terlihat oleh semua proses yang dimulai oleh shell tetapi untuk mengatur mereka di tingkat daemon / pengawas (skrip init / rc, systemd config) sehingga cakupannya terbatas jika diperlukan .

Di mana tim yang terpisah mengelola operasi, variabel lingkungan menyediakan antarmuka yang mudah bagi operasi untuk mengatur lingkungan aplikasi tanpa harus mengetahui tentang file / format konfigurasi dan / atau untuk menggunakan pengelompokan konten mereka. Ini terutama benar dalam pengaturan multi-bahasa / multi-kerangka kerja di mana tim operasi dapat memilih sistem penempatan (OS, proses penyelia) berdasarkan kebutuhan operasional (kemudahan penempatan, skalabilitas, keamanan, dll).

Pertimbangan lain adalah jalur pipa CI / CD - karena kode melewati lingkungan yang berbeda(mis. dev, test / qa, staging, produksi) keterangan lingkungan (zona penempatan, keterangan koneksi basis data, kredensial, alamat IP, nama domain, dll, dll) paling baik diatur oleh alat / kerangka kerja manajemen konfigurasi khusus dan dikonsumsi oleh aplikasi proses dari lingkungan (dalam KERING, menulis sekali, jalankan di mana saja mode). Secara tradisional di mana pengembang cenderung mengelola masalah operasional ini, mereka cenderung memeriksa file konfigurasi atau template selain kode - dan akhirnya menambahkan solusi dan kompleksitas lainnya ketika persyaratan operasional berubah (misalnya lingkungan / penyebaran / situs baru ikut serta, skalabilitas / keamanan Menimbang,

  • Env-vars menyederhanakan konfigurasi / kompleksitas pada skala.
  • Env-vars menempatkan konfigurasi operasional tepat dengan tim yang bertanggung jawab atas aspek-aspek terkait non-kode aplikasi dalam cara yang tidak mengikat yang seragam (jika tidak standar).
  • Dukungan env-vars menukar proses master / supervisor (mis. Dewa, monit, supervisor, sysvinit, systemd, dll) yang mendukung aplikasi - dan tentu saja bahkan sistem penyebaran (OS, gambar kontainer, dll) atau lebih sebagai persyaratan operasional berevolusi / berubah. Sementara setiap kerangka bahasa saat ini memiliki semacam proses runtime, ini cenderung lebih rendah secara operasional, lebih cocok untuk lingkungan dev dan / atau meningkatkan kompleksitas dalam lingkungan produksi multi-bahasa / multi-kerangka.

Untuk produksi, saya lebih suka mengatur aplikasi env-vars di EnvironmentFile seperti /etc/default/myapplication.confyang digunakan oleh manajemen konfigurasi dan mengatur hanya dapat dibaca oleh rootsedemikian sehingga systemd(atau hal lain dalam hal ini) dapat menelurkan aplikasi di bawah pengguna sistem Deprivileged khusus dalam Pribadi grup . Didukung oleh grup pengguna khusus untuk opsdan sudo- file-file ini secara default tidak dapat dibaca. Ini adalah persyaratan 12faktor yang mendukung semua kebaikan Dev + Ops plus memiliki semua manfaat keamanan yang layak sambil tetap memungkinkan pengembang / penguji untuk menjatuhkan EnvironmentFiles mereka sendiri di lingkungan dev / qa / test.

shalomb
sumber
0

Dari perspektif pengembang, menyimpan data konfigurasi dalam variabel lingkungan menyederhanakan penyebaran di antara lingkungan yang berbeda - pengembangan, QA, dan produksi - dan membebaskan pengembang dari keharusan khawatir tentang penggunaan file konfigurasi yang salah.

Aplikasi web Azure menyediakan opsi untuk menggunakan pola ini dan itu bekerja dengan sangat baik.

Selain itu, menjaga data yang berpotensi sensitif di luar kendali sumber. Mengabaikan file-file dari kontrol sumber tidak benar-benar layak (setidaknya dalam. NET) karena banyak konfigurasi boilerplate yang diperlukan juga hadir dalam file-file itu.

Derek Gusoff
sumber