Postgres berperan dalam penerapan praktik terbaik


21

Orang-orang,

Saya dapat menggunakan bantuan Anda untuk membuat desain kontrol akses pengguna Postgres saya lebih baik dan lebih selaras dengan praktik terbaik. Saya membantu meluncurkan server Postgres produksi kecil tapi saya bukan admin DB, jadi saya tahu cukup berbahaya.

Ada satu server dengan satu instalasi Postgres v9.2. Instalasi ini meng-host beberapa database, masing-masing sepenuhnya melayani "pelanggan" yang berbeda. Dengan kata lain, customer1 tidak akan, tidak boleh menggunakan database2, dan sebagainya. Selama operasi normal, basis data masing-masing diakses oleh instance yang cocok dari CakePHP, semuanya terletak pada server yang sama dengan Postgres. Meskipun ada kemungkinan optimasi pada penyebaran ini, saya lebih tertarik pada peran Psql.

Berdasarkan apa yang saya baca, tampaknya tiga jenis peran masuk akal:

  • Postuser superuser dengan kata sandi non default
  • Peran administrator yang tidak memiliki hak superuser untuk pemeliharaan rutin, pembuatan DB, cadangan, memulihkan. Harus bisa melakukan apa saja dengan semua basis data pelanggan.
  • Peran pengguna hanya dengan kemampuan untuk CRUD di database masing-masing. Lebih banyak hak atas DB mereka sendiri dapat ditoleransi jika membersihkan implementasi.

Menerapkan desain itu adalah hal yang membuat saya kurang percaya diri. Kepemilikan DB versus tabel dan juga siapa yang harus mewarisi dari yang agak berlumpur. Di bawah ini adalah basis data dan pengguna saya. Apakah itu info yang cukup untuk mengevaluasi implementasi?

     Role name |                   Attributes                   |     Member of     
    -----------+------------------------------------------------+-------------------
     admin     | Create role, Create DB                         | {user1, user2}
     postgres  | Superuser, Create role, Create DB              | {}
     user1     |                                                | {}
     user2     |                                                | {}

    postgres=# \l
                                 List of databases
       Name    |  Owner   | Encoding | Collate | Ctype |   Access privileges   
    -----------+----------+----------+---------+-------+-----------------------
     admin     | postgres | UTF8     | en_US   | en_US | =Tc/postgres         +
               |          |          |         |       | postgres=CTc/postgres+
               |          |          |         |       | admin=CTc/postgres
     postgres  | postgres | UTF8     | en_US   | en_US | 
     template0 | postgres | UTF8     | en_US   | en_US | =c/postgres          +
               |          |          |         |       | postgres=CTc/postgres
     template1 | postgres | UTF8     | en_US   | en_US | =c/postgres          +
               |          |          |         |       | postgres=CTc/postgres
     user1     | admin    | UTF8     | en_US   | en_US | =Tc/admin            +
               |          |          |         |       | admin=CTc/admin      +
               |          |          |         |       | user1=CTc/admin
     user2     | admin    | UTF8     | en_US   | en_US | =Tc/admin            +
               |          |          |         |       | admin=CTc/admin      +
               |          |          |         |       | user2=CTc/admin

Untuk mencegah koneksi eksternal dan kata sandi di clear, pg_hba.conf adalah sebagai berikut:

local   all             all                                     md5
host    all             all             127.0.0.1/32            md5
host    all             all             ::1/128                 md5

1
Dalam pengalaman saya, pemisahan terbaik yang juga membawa sejumlah besar keuntungan lainnya adalah menjalankan cluster PostGreSQL yang terpisah (mis. Layanan) untuk setiap pelanggan. Inilah yang saat ini kami lakukan untuk lingkungan produksi besar sekarang dan saya tidak akan melakukannya secara berbeda kecuali jika jumlah DB akan sangat besar dan masing-masing akan sangat kecil. Tentu saja, aplikasi ini juga perlu tahu cara terhubung ke sumber data yang berbeda untuk setiap penyewa (pelanggan).
Florin Asăvoaie

Di sebelah @ FlorinAsăvoaie ucapannya. Tidakkah seharusnya setiap database memiliki pengguna pemiliknya sendiri dan pengguna permintaan? Ini akan membuatnya lebih mudah untuk menempatkan pengguna tertentu dalam brankas kata sandi untuk tujuan pemeliharaan.
hspaans

Jawaban:


5

Saya tahu ini adalah pertanyaan lama tetapi saya akan mencoba menjawabnya bahkan sekarang, karena saya harus melakukan penelitian terkait hal ini.

Apa yang Anda coba lakukan disebut multi-tenancy di tingkat basis data. Ini dapat dicapai dengan dua cara:

  1. Namun, dalam satu kluster basis data tunggal, bagaimana OP menjelaskan, pilihan pribadi saya adalah sebagai berikut:

    • pengguna postgres menggunakan otentikasi rekan dan tidak diizinkan koneksi kata sandi. Otentikasi MD5, menurut saya, adalah praktik yang buruk. Jika Anda mengalami masalah dengan konsistensi database atau hal-hal semacam ini, Anda masih bisa masuk jika Anda membiarkan postgres menggunakan peer auth.
    • Setiap pelanggan harus mendapatkan skema mereka sendiri dan bukan database. Ada beberapa alasan untuk ini:
      • Memiliki seluruh basis data akan memberikan banyak keistimewaan.
      • Hanya memiliki tabel spesifik akan menimbulkan masalah bagi pengembang dan akan selalu meminta admin untuk menambahkan izin dan hal-hal lain.
      • Dengan demikian, dalam pengaturan normal, masing-masing dari mereka akan mendapatkan akses untuk membuat hal-hal di dalam skema mereka, termasuk tabel, tampilan, pemicu, dll.
      • Semuanya menggunakan string koneksi yang sama kecuali nama pengguna. Di postgres, secara default, jika Anda memiliki skema dengan nama pengguna Anda, itu secara otomatis ada di search_path Anda.
    • Saya akan memilih untuk tidak memiliki pengguna admin yang dapat mengakses setiap skema, sebagai langkah pengamanan. Anda harus melakukan backup baik dengan membuang setiap skema dengan pengguna mereka sendiri atau menggunakan teknik PITR PostgreSQL. Anda masih perlu menggunakan pengguna postgres untuk membuat skema baru, saya akan menggunakan aturan sudo dan skrip untuk itu.
    • Banyak praktik keamanan yang baik merekomendasikan agar Anda membatalkan skema default - begitulah.
    • Solusi ini sangat cocok jika DB untuk setiap pelanggan kecil dan Anda mendapat banyak pelanggan.
    • Jika aplikasi Anda menangani multi-tenancy, ia dapat menggunakan kumpulan koneksi tunggal untuk semua pelanggan. Tentu saja, ini menghilangkan banyak peningkatan keamanan di atas tetapi bisa memiliki manfaat kinerja, khususnya ketika Anda memiliki sejumlah besar pelanggan (jika Anda memiliki 500-1000 sumber data terpisah dan Anda menggunakan pooling koneksi, itu akan sangat luar biasa).
  2. Setiap pelanggan mendapatkan kelompok basis data mereka sendiri. Ini adalah solusi pilihan saya terutama karena saya biasanya bekerja dengan aplikasi yang memiliki basis data besar per setiap pelanggan.

    • Yang ini membawa pemisahan data yang sangat bagus. Anda dapat menggunakan volume penyimpanan terpisah untuk setiap pelanggan, mengalokasikan batasan CPU dan Memori (menggunakan buruh pelabuhan?).
    • Fleksibilitas yang sangat baik pada apa yang dibutuhkan oleh setiap pelanggan dalam hal mereka. Mereka bisa mirip atau memiliki fitur berbeda.
    • Sangat mudah untuk mengukur pada kedua arah (atas dan ke luar).
    • Saya juga menggunakan IP virtual terpisah di mana setiap cluster mendengarkan koneksi, membuat skala-out untuk tidak memerlukan konfigurasi ulang sumber data.
    • Cadangan PITR adalah per pelanggan sehingga akan lebih mudah untuk mengembalikan satu pelanggan dibandingkan dengan multi-penyewaan per-skema.
    • Pada pengaturan yang kompleks, setiap pelanggan mungkin membutuhkan banyak basis data, skema, pengguna dan peran, dll. Jadi ini adalah solusi yang jauh lebih baik dalam kasus tersebut.

Anda juga dapat menggunakan kombinasi di atas dan menggunakan pgBouncer sebagai router.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.