Pertama beberapa latar belakang.
Proyek LedgerSMB adalah proyek perangkat lunak akuntansi keuangan open source yang berjalan di PostgreSQL. Kami menerapkan logika bisnis dalam jumlah yang sangat besar dalam fungsi yang ditentukan pengguna, yang bertindak sebagai alat pemetaan utama antara metode objek program dan perilaku database. Saat ini kami menggunakan pengguna basis data sebagai pengguna otentikasi, sebagian karena pilihan (ini memungkinkan logika keamanan terpusat, sehingga alat lain dapat ditulis dan menggunakan kembali izin yang diberikan kepada pengguna), dan sebagian oleh kebutuhan (setelah kami bercabang dari SQL-Ledger, ada tidak banyak opsi untuk memperbaiki keamanan ke basis kode itu).
Ini memberi kita akses ke sejumlah opsi masuk tunggal yang masuk akal yang dapat diakses PostgreSQL, dari LDAP ke Kerberos 5. Kita bahkan dapat menggunakan PAM yang terkait dengan kata sandi. Itu juga memungkinkan kita untuk menggunakan kembali izin ketika berintegrasi dengan aplikasi lain, atau mengizinkan antarmuka klien lain. Untuk aplikasi akuntansi keuangan, ini seperti kemenangan bersih.
Jelas ada biaya yang harus dikeluarkan. Untuk aplikasi web, kami sangat terbatas pada jenis auth http yang dapat didukung. DIGEST misalnya sepenuhnya keluar. BASIC berfungsi, dan kami dapat mengimplementasikan KRB5 dengan cukup mudah (saya berencana untuk mendukung dan bekerja di luar kotak ini untuk 1.4). Tindakan otentikasi yang sangat kuat tidak dapat dikelola dengan baik secara langsung ini meskipun kami mungkin dapat mengacaukannya jika perlu (misalnya BASIC + sertifikat sisi klien SSL dengan cn yang cocok dengan nama pengguna dan ca root tertentu).
Pada saat yang sama, kami mendapat banyak kecaman sebagian besar dari kerumunan pengembangan dan lebih sering dari dba yang mengatakan kepada saya bahwa aplikasi harus menjadi penghalang keamanan, bukan database. Pandangan saya masih bahwa perimeter keamanan yang lebih kecil umumnya lebih baik, bahwa penggunaan kembali logika bisnis dan logika keamanan berjalan bersama, dan bahwa menurut saya berbahaya untuk menggunakan kembali logika bisnis tanpa menggunakan kembali logika keamanan pada tingkat yang sama dari program ini.
Apakah saya melewatkan pengorbanan besar di sini? Apakah ada Gotcha yang tidak saya pertimbangkan?
sumber
Jawaban:
Saya pikir Anda sedang mengkonfigurasi otentikasi dan otorisasi .
Saya sepenuhnya setuju bahwa menjaga model keamanan dalam DB adalah bijaksana, terutama karena LedgerSMB dirancang dengan akses dari banyak klien. Kecuali Anda berencana untuk pergi 3-tier dengan lapisan middleware itu membuat sempurna akal untuk memiliki pengguna sebagai peran database, terutama untuk sesuatu seperti sebuah aplikasi akuntansi.
Ini tidak berarti Anda harus mengautentikasi pengguna terhadap database menggunakan metode otentikasi yang didukung PostgreSQL. Pengguna, peran, dan hibah basis data Anda hanya dapat digunakan untuk otorisasi jika Anda mau.
Inilah cara kerjanya untuk web ui misalnya:
jane
terhubung ke server web ui dan diautentikasi menggunakan metode apa pun yang diinginkan, katakanlah HTTPS X.509 sertifikat tangan klien dan DIGEST auth. Server sekarang memiliki koneksi dari pengguna yang diterimanya benar-benarjane
.Server terhubung ke PostgreSQL menggunakan nama pengguna / kata sandi tetap (atau Kerberos atau apa pun yang Anda suka), mengautentikasi diri ke server db sebagai pengguna
webui
. Server db percayawebui
untuk mengotentikasi penggunanya sehinggawebui
telah diberikan yang sesuaiGRANT
(lihat di bawah).Pada koneksi yang digunakan server
SET ROLE jane;
untuk mengasumsikan tingkat otorisasi penggunajane
. SampaiRESET ROLE;
atau yang lainSET ROLE
dijalankan, koneksi beroperasi dengan hak akses yang sama sepertijane
danSELECT current_user()
dll akan melaporkanjane
.Server mempertahankan hubungan antara koneksi database yang memiliki
SET ROLE
kejane
dan sesi web untuk penggunajane
, tidak memungkinkan koneksi PostgreSQL untuk digunakan oleh koneksi lain dengan pengguna lain tanpa baruSET ROLE
peralihan.Anda sekarang mengautentikasi di luar server, tetapi mempertahankan otorisasi di server. Pg perlu tahu apa yang ada pengguna, tetapi tidak perlu kata sandi atau metode otentikasi untuk mereka.
Lihat:
SET SESSION AUTHORIZATION
SET ROLE
GRANT
Detail
Server webui mengontrol menjalankan kueri, dan itu tidak akan membiarkan
jane
menjalankan SQL mentah (saya harap!) Jadijane
tidak bisaRESET ROLE; SET ROLE special_admin_user;
melalui web ui. Untuk keamanan tambahan, saya akan menambahkan filter pernyataan ke server yang menolakSET ROLE
danRESET ROLE
kecuali jika koneksi itu masuk atau memasuki kumpulan koneksi yang belum ditetapkan.Anda masih bebas menggunakan otentikasi langsung ke Pg di klien lain; Anda dapat mencampur dan mencocokkan secara bebas. Anda hanya perlu
GRANT
satuwebui
pengguna hak untukSET ROLE
untuk pengguna yang dapat log in melalui web dan kemudian memberikan para pengguna setiap yang normalCONNECT
hak, password, dll yang Anda inginkan. Jika Anda ingin membuatnya hanya web, hakREVOKE
merekaCONNECT
pada database (dan daripublic
).Untuk mempermudah pemisahan otentikasi / otorisasi, saya memiliki peran khusus
assume_any_user
yang harus sayaGRANT
gunakan untuk setiap pengguna yang baru dibuat. Saya kemudianGRANT assume_any_user
menggunakan nama pengguna asli yang digunakan oleh hal-hal seperti front-end web tepercaya, memberi mereka hak untuk menjadi pengguna yang mereka sukai.Sangat penting untuk membuat
assume_any_user
sebuahNOINHERIT
peran, sehinggawebui
pengguna atau apa pun tidak memiliki privilges dengan diri dan hanya dapat bertindak pada database setelah ituSET ROLE
untuk pengguna nyata. Dalam kondisi apa pun,webui
pemilik superuser atau DB tidak boleh .Jika Anda koneksi pooling, Anda dapat menggunakan
SET LOCAL ROLE
untuk mengatur peran hanya dalam transaksi, sehingga Anda dapat mengembalikan koneksi ke pool setelahCOMMIT
atauROLLBACK
. Waspadai ituRESET ROLE
masih berfungsi, jadi masih tidak aman untuk membiarkan klien menjalankan SQL apa pun yang mereka inginkan.SET SESSION AUTHORIZATION
adalah versi terkait tetapi lebih kuat dari perintah ini. Itu tidak memerlukan peran peran, tapi itu perintah superuser saja. Anda tidak ingin ui web Anda terhubung sebagai superuser. Itu bisa dibalik denganRESET SESSION AUTHORIZATION
,SET SESSION AUTHORIZATION DEFAULT
atauSET SESSION AUTHORIZATION theusername
untuk mendapatkan kembali hak pengguna super sehingga bukan penghalang keamanan yang menjatuhkan hak istimewa juga.Perintah yang berfungsi seperti
SET SESSION AUTHORIZATION
tetapi tidak dapat dipulihkan dan akan bekerja jika Anda adalah anggota peran tetapi bukan superuser akan bagus. Pada titik ini tidak ada satu, tetapi Anda masih dapat memisahkan otentikasi dan otorisasi dengan cukup baik jika Anda berhati-hati.Contoh dan penjelasan
Sekarang terhubung sebagai
webui
. Perhatikan bahwa Anda tidak dapat melakukan apapun untuktest_table
tetapi Anda bisaSET ROLE
untukjane
dan kemudian Anda dapat mengaksestest_table
:Perhatikan itu
webui
bisaSET ROLE
tojim
, bahkan ketika sudahSET ROLE
d tojane
dan meskipunjane
belum memilikiGRANT
hak untuk mengambil peranjim
.SET ROLE
menetapkan ID pengguna efektif Anda, tetapi itu tidak menghapus kemampuan Anda untukSET ROLE
peran lain, itu adalah properti dari peran yang Anda hubungkan, bukan peran efektif Anda saat ini. Akibatnya Anda harus hati-hati mengontrol akses keSET ROLE
danRESET ROLE
perintah. Ada, AFAIK, tidak ada cara untuk secara permanenSET ROLE
untuk koneksi, benar-benar menjadi pengguna target, meskipun tentu akan menyenangkan untuk dimiliki.Membandingkan:
untuk:
Ini berarti bahwa
SET ROLE
tidak persis sama dengan masuk sebagai peran yang diberikan, sesuatu yang harus Anda ingat.webui
tidak bisaSET ROLE
untukdbowner
karena belumGRANT
ed yang tepat:jadi dengan sendirinya itu tidak berdaya, itu hanya dapat mengasumsikan hak-hak pengguna lain dan hanya ketika para pengguna memiliki akses web diaktifkan.
sumber
pgbouncer
kerjanya untuk beberapa detail.DISCARD ALL
adalah cara lain untuk hak yang akan dikembalikan ke default. Saya benar-benar berharap Pg punyaSET ROLE NORESET
atau serupa ...