Page cover

PostgreSQL β†’ Managing Users and Connections

Sumber: Luca Ferrari, Enrico Pirozzi - Learn PostgreSQL Use, manage, and build secure and scalable databases with PostgreSQL 16 (2023) - Chapter 3

PostgreSQL adalah sistem yang kompleks yang mencakup pengguna, basis data, dan data. Untuk dapat berinteraksi dengan basis data dalam klaster, Anda perlu memiliki setidaknya satu pengguna. Secara default, saat menginstal klaster baru, satu pengguna administrator (bernama postgres) dibuat. Meskipun memungkinkan untuk menangani semua koneksi, aplikasi, dan basis data dengan pengguna administratif tunggal ini, dari sisi keamanan dan isolasi hak akses, jauh lebih baik untuk membuat pengguna yang berbeda dengan properti dan hak akses yang berbeda, serta kredensial login, untuk setiap tugas spesifik.

PostgreSQL menyediakan struktur manajemen pengguna yang sangat kaya, dan pengguna tunggal dapat dikelompokkan ke dalam berbagai grup secara bersamaan. Selain itu, grup dapat bersarang di dalam grup lain sehingga Anda dapat memiliki representasi model akun yang sangat akurat. Berkat representasi yang akurat ini, dan karena setiap pengguna dan grup dapat diberikan properti dan hak akses yang berbeda, Anda dapat menerapkan izin yang sangat terperinci untuk setiap pengguna di basis data, tergantung pada tugas dan aktivitas spesifik yang terlibat.

Bab ini memperkenalkan Anda pada konsep di balik pengguna dan grup serta hubungan mereka. Bab ini akan fokus terutama pada properti login dari peran (baik pengguna maupun grup) dan bagaimana PostgreSQL dapat mencegah pengguna tertentu terhubung ke basis data tertentu.

Bab ini mencakup topik utama berikut:

  • Pengenalan pengguna dan grup

  • Mengelola peran

  • Mengelola koneksi masuk pada tingkat peran

Persyaratan Teknis

Contoh-contoh dalam bab ini dapat dijalankan pada image Docker standalone yang tersedia di repositori GitHub buku ini: https://github.com/PacktPublishing/Learn-PostgreSQL-Second-Edition. Untuk petunjuk instalasi dan penggunaan image Docker untuk buku ini, silakan lihat Bab 1, Pengenalan PostgreSQL.

Pengenalan Pengguna dan Grup

PostgreSQL membedakan antara pengguna dan grup pengguna: pengguna mewakili seseorang, baik itu orang atau aplikasi, yang dapat terhubung ke klaster dan melakukan aktivitas; grup mewakili kumpulan pengguna yang memiliki beberapa properti umum, paling sering izin pada objek klaster.

Untuk terhubung secara interaktif atau melalui aplikasi ke basis data PostgreSQL, Anda memerlukan kredensial login. Secara khusus, pengguna basis data, yaitu pengguna yang diizinkan untuk terhubung ke basis data tertentu, harus ada.

Pengguna basis data agak mirip dengan pengguna sistem operasi: mereka memiliki nama pengguna dan kata sandi (terenkripsi) dan dikenali oleh klaster PostgreSQL. Mirip dengan pengguna sistem operasi, pengguna basis data dapat dikelompokkan ke dalam grup pengguna untuk mempermudah pengelolaannya. Dalam SQL, dan karenanya juga dalam PostgreSQL, konsep akun pengguna tunggal dan grup akun diwakili oleh konsep peran (role).

Peran dapat berupa akun tunggal, grup akun, atau bahkan keduanya tergantung pada bagaimana Anda mendesainnya; namun, untuk mempermudah pengelolaan, sebuah peran sebaiknya hanya mewakili satu konsep pada satu waktu: yaitu, peran tersebut harus berupa pengguna tunggal atau grup tunggal, tetapi tidak keduanya.

Catatan: Meskipun peran dapat digunakan secara bersamaan sebagai grup atau pengguna tunggal, kami sangat menyarankan Anda untuk memisahkan kedua konsep pengguna dan grupβ€”ini akan menyederhanakan pengelolaan infrastruktur Anda.

Setiap peran harus memiliki nama atau pengenal unik, yang biasanya disebut nama pengguna. Peran mewakili kumpulan izin basis data dan properti koneksi. Kedua elemen ini bersifat ortogonal. Anda dapat mengatur peran hanya sebagai wadah untuk peran lain, mengkonfigurasi peran yang terkandung untuk memiliki izin yang ditetapkan, atau Anda dapat memiliki peran yang memiliki semua izin untuk peran yang terkandung, atau mencampur dan mencocokkan kedua pendekatan ini.

Penting untuk memahami bahwa peran didefinisikan pada tingkat klaster, sedangkan izin didefinisikan pada tingkat basis data. Ini berarti bahwa peran yang sama dapat memiliki hak akses dan properti yang berbeda tergantung pada basis data yang digunakan (misalnya, diizinkan untuk terhubung ke satu basis data tetapi tidak ke basis data lain).

Catatan: Karena peran didefinisikan pada tingkat klaster, peran tersebut harus memiliki nama yang unik di seluruh klaster.

Mengelola Peran

Peran dapat dikelola melalui tiga pernyataan SQL utama: CREATE ROLE untuk membuat peran dari awal, ALTER ROLEuntuk mengubah beberapa properti peran (misalnya, kata sandi login), dan DROP ROLE untuk menghapus peran yang sudah ada.

Catatan: PostgreSQL dilengkapi dengan alat sistem operasi untuk mengelola peran: createuser dan dropuser. Kedua perintah ini membuka koneksi ke klaster dan menjalankan perintah SQL yang disebutkan di atas; oleh karena itu, penggunaan alat ini tidak akan dijelaskan dalam bab ini.

Untuk menggunakan pernyataan SQL guna membuat peran baru dan kemudian mengelolanya, Anda perlu terhubung ke basis data dalam klaster. Peran superuser postgres dapat digunakan untuk tujuan ini, setidaknya pada awalnya, karena peran tersebut dibuat saat klaster basis data diinisialisasi. Menggunakan peran postgres dan basis data template adalah cara paling umum untuk membuat peran awal Anda.

Peran diidentifikasi oleh string yang mewakili nama peran, atau lebih tepatnya, nama akun dari peran tersebut. Nama ini harus unik di seluruh sistem, artinya Anda tidak dapat memiliki dua peran berbeda dengan nama yang sama. Nama harus terdiri dari huruf, angka, dan beberapa simbol, seperti garis bawah.

Membuat Peran Baru

Untuk membuat peran baru, baik itu akun pengguna tunggal atau wadah grup, Anda perlu menggunakan pernyataan CREATE ROLE. Pernyataan ini memiliki sinopsis singkat berikut dan memiliki parameter wajib, yaitu nama pengguna peran:

CREATE ROLE nama [ [ WITH ] opsi [ ... ] ]

Opsi yang dapat Anda tentukan dalam pernyataan ini berkisar dari kata sandi akun, kemampuan untuk login secara interaktif, hingga hak superuser. Ingat bahwa, tidak seperti sistem lain, di PostgreSQL, Anda dapat memiliki sebanyak mungkin superuser yang Anda inginkan, dan setiap superuser memiliki hak penuh untuk mengelola klaster.

Hampir setiap opsi dari pernyataan CREATE ROLE memiliki bentuk positif yang menambahkan kemampuan ke peran, dan bentuk negatif (dengan awalan NO) yang menghapus kemampuan dari peran. Sebagai contoh, opsi SUPERUSERmenambahkan kemampuan untuk bertindak sebagai superuser klaster, sedangkan opsi NOSUPERUSER menghapusnya dari peran.

Dalam bab ini, kami akan fokus pada kemampuan login, yang merupakan sekumpulan opsi terbatas yang memungkinkan peran untuk login ke klaster. Opsi lain akan dibahas di Bab 10, Pengguna, Peran, dan Keamanan Basis Data, karena lebih terkait dengan fitur keamanan peran.

Catatan: Bagaimana jika Anda lupa menentukan opsi saat CREATE ROLE? Atau jika Anda berubah pikiran dan ingin menghapus opsi dari peran yang sudah ada? Ada pernyataan ALTER ROLE yang memungkinkan Anda (sebagai superuser klaster) untuk memodifikasi peran yang sudah ada tanpa harus menghapus dan membuat ulang peran tersebut. Pernyataan ini akan ditunjukkan di Bab 10, Pengguna, Peran, dan Keamanan Basis Data, bersama dengan beberapa opsi menarik lainnya untuk peran.

Kata Sandi Peran, Koneksi, dan Ketersediaan

Setiap koneksi ke PostgreSQL harus dilakukan ke basis data tertentu, tidak peduli pengguna yang membuka koneksi tersebut. Menghubungkan ke basis data dalam klaster berarti peran tersebut harus mengautentikasi dirinya, dan oleh karena itu, harus ada mekanisme autentikasi, dengan nama pengguna dan kata sandi sebagai yang paling klasik.

Ketika pengguna mencoba terhubung ke basis data, PostgreSQL memeriksa kredensial login dan beberapa properti lain dari pengguna untuk memastikan bahwa pengguna tersebut diizinkan untuk login dan memiliki kredensial yang valid. Opsi utama yang memungkinkan Anda untuk memanipulasi dan mengelola upaya login adalah sebagai berikut:

  • PASSWORD atau ENCRYPTED PASSWORD adalah opsi yang setara dan memungkinkan Anda untuk mengatur kata sandi login untuk peran. Kedua opsi ini ada untuk kompatibilitas mundur dengan versi PostgreSQL yang lebih lama, tetapi saat ini, klaster selalu menyimpan kata sandi peran dalam bentuk terenkripsi, sehingga penggunaan ENCRYPTED PASSWORD tidak menambah nilai apa pun pada opsi PASSWORD.

  • PASSWORD NULL secara eksplisit memaksa kata sandi menjadi null (bukan kosong), mencegah pengguna untuk login dengan kata sandi apa pun. Opsi ini dapat digunakan untuk menolak autentikasi berbasis kata sandi.

  • CONNECTION LIMIT <n> memungkinkan pengguna untuk membuka tidak lebih dari <n> koneksi simultan ke klaster, tanpa mempedulikan basis data tertentu. Ini sering berguna untuk mencegah pengguna menghabiskan sumber daya klaster.

  • VALID UNTIL memungkinkan Anda untuk menentukan waktu (di masa depan) ketika peran akan kedaluwarsa.

Mengatur kata sandi untuk peran tertentu tidak berarti bahwa peran tersebut akan dapat terhubung ke klaster: untuk diizinkan login secara interaktif, peran juga harus memiliki opsi LOGIN. Dengan kata lain, pernyataan berikut tidak akan memungkinkan pengguna untuk login:

postgres=# CREATE ROLE luca
WITH PASSWORD 'xxx';

Opsi default adalah NOLOGIN (yang mencegah login interaktif). Oleh karena itu, untuk mendefinisikan pengguna interaktif, ingat untuk menambahkan opsi LOGIN saat membuat peran:

template1=# CREATE ROLE luca
WITH LOGIN PASSWORD 'xxx';

Beberapa opsi dapat ditulis dalam urutan apa pun, sehingga kode sebelumnya mewakili pernyataan yang sama, tetapi dalam bentuk yang kurang mudah dibaca manusia:

postgres=# CREATE ROLE luca
WITH PASSWORD 'xxx' LOGIN;

Opsi VALID UNTIL memungkinkan Anda untuk mendefinisikan tanggal atau bahkan cap waktu (timestamp, yaitu waktu tertentu) di masa depan ketika kata sandi peran akan kedaluwarsa dan tidak lagi diizinkan untuk login ke klaster. Ini dapat berguna untuk menandai sekelompok pengguna sebagai dapat dihentikan di masa depan.

Tentu saja, opsi ini hanya masuk akal untuk peran interaktif, yaitu mereka yang memiliki kemampuan LOGIN. Sebagai contoh, peran berikut akan dicegah untuk login setelah Natal 2030:

postgres=# CREATE ROLE luca
WITH LOGIN PASSWORD 'xxx'
VALID UNTIL '2030-12-25 23:59:59';

Menggunakan Peran sebagai Grup

Grup adalah peran yang berisi peran lain. Sesederhana itu!

Biasanya, ketika Anda ingin membuat grup, yang perlu Anda lakukan adalah membuat peran tanpa opsi LOGIN dan kemudian menambahkan semua anggota satu per satu ke peran yang berisi mereka. Menambahkan peran ke peran yang berisi menjadikan yang terakhir sebagai grup.

Untuk membuat peran sebagai anggota grup tertentu, opsi IN ROLE dapat digunakan. Opsi ini menerima nama grup (yang pada gilirannya adalah peran lain) yang akan menjadi anggota dari peran yang baru dibuat. Sebagai contoh, dalam blok kode berikut, Anda dapat melihat pembuatan grup book_authors dan penambahan anggota peran luca dan enrico:

postgres=# CREATE ROLE book_authors
WITH NOLOGIN;
CREATE ROLE
postgres=# CREATE ROLE luca
WITH LOGIN PASSWORD 'xxx'
IN ROLE book_authors;
CREATE ROLE
postgres=# CREATE ROLE enrico
WITH LOGIN PASSWORD 'xxx'
IN ROLE book_authors;
CREATE ROLE

Klausa IN GROUP dari CREATE ROLE adalah sinonim usang untuk klausa IN ROLE.

Dimungkinkan juga untuk menambahkan anggota ke grup menggunakan pernyataan khusus GRANT. Pernyataan GRANTadalah pernyataan SQL umum yang memungkinkan penyesuaian izin secara detail (lebih lanjut tentang ini di Bab 10, Pengguna, Peran, dan Keamanan Basis Data); PostgreSQL memperluas sintaks SQL yang memungkinkan pemberian peran ke peran lain. Ketika Anda memberikan peran ke peran lain, yang terakhir menjadi anggota dari yang pertama. Dengan kata lain, dengan asumsi semua peran sudah ada tanpa asosiasi tertentu, kode berikut menambahkan peran enrico ke grup book_authors:

postgres=# GRANT book_authors TO enrico;

Setiap grup dapat memiliki satu atau lebih anggota admin, yang diizinkan untuk menambahkan anggota baru ke grup. Opsi ADMIN memungkinkan pengguna untuk menentukan anggota yang akan diasosiasikan sebagai administrator dari grup yang baru dibuat. Sebagai contoh, dalam blok kode berikut, Anda dapat melihat pembuatan grup baru yang disebut book_reviewers dengan luca sebagai administrator; ini berarti bahwa pengguna luca, meskipun bukan superuser klaster, akan dapat menambahkan anggota baru ke grup book_reviewers:

postgres=# CREATE ROLE book_reviewers
WITH NOLOGIN
ADMIN luca;
CREATE ROLE

Jelas, opsi ADMIN hanya dapat digunakan dalam CREATE ROLE jika peran administrator sudah ada; dalam contoh tersebut, peran luca harus telah dibuat sebelum grup, karena ia akan menjadi administrator.

Pernyataan GRANT dapat menyelesaikan masalah tersebutβ€”klausa WITH ADMIN OPTION memungkinkan keanggotaan peran dengan hak administratif. Sebagai contoh, potongan kode berikut menunjukkan bagaimana membuat pengguna enrico juga menjadi administrator dari grup book_reviewers. Harap dicatat bahwa Anda harus menuliskan WITH ADMIN OPTION secara lengkap, seperti yang ditunjukkan di sini:

postgres=# GRANT book_reviewers
TO enrico
WITH ADMIN OPTION;
GRANT ROLE

Apa yang terjadi jika peran grup memiliki opsi LOGIN? Grup tersebut masih akan menjadi wadah peran, tetapi juga dapat bertindak sebagai akun pengguna tunggal dengan kemampuan untuk login. Meskipun ini memungkinkan, praktik yang lebih umum adalah menolak akses login untuk peran grup guna mencegah kebingungan.

Menghapus Peran yang Ada

Untuk menghapus peran yang ada, Anda perlu menggunakan pernyataan DROP ROLE. Pernyataan ini memiliki sinopsis yang sangat sederhana:

DROP ROLE [ IF EXISTS ] nama [, ...]

Anda hanya perlu menentukan nama peran yang ingin dihapus, atau, jika Anda perlu menghapus beberapa peran, Anda dapat menentukannya sebagai daftar yang dipisahkan koma.

Agar dapat dihapus, peran tersebut harus ada; oleh karena itu, jika Anda mencoba menghapus peran yang tidak ada, Anda akan menerima kesalahan:

postgres=# DROP ROLE this_role_does_not_exist;
ERROR: role "this_role_does_not_exist" does not exist

Seperti yang Anda lihat, PostgreSQL memperingatkan Anda bahwa ia tidak dapat menghapus peran jika peran tersebut tidak ada.

Catatan: Anda tidak dapat merusak PostgreSQL! PostgreSQL akan melindungi dirinya dari kesalahan Anda dan melakukan pekerjaan yang sangat baik untuk menjaga data Anda tetap aman! Contoh di atas tentang penghapusan peran yang tidak ada adalah contoh bagaimana PostgreSQL melindungi dirinya dari kesalahan Anda untuk memastikan layanan yang selalu stabil.

Pernyataan DROP ROLE mendukung klausa IF EXISTS, yang menghentikan PostgreSQL dari mengeluh tentang penghapusan peran yang tidak ada:

postgres=# DROP ROLE IF EXISTS this_role_does_not_exist;
NOTICE: role "this_role_does_not_exist" does not exist, skipping
DROP ROLE

Seperti yang Anda lihat, kali ini PostgreSQL tidak memunculkan kesalahan; sebaliknya, ia menampilkan pemberitahuan bahwa peran tersebut tidak ada. Namun, ia menjalankan pernyataan tersebut, tidak melakukan apa-apa, tetapi melaporkan keberhasilan alih-alih kegagalan. Mengapa ini bisa berguna? Bayangkan Anda memiliki tugas otomatis yang bertugas menghapus beberapa peran: jika DROP ROLE melaporkan kegagalan, tugas Anda bisa terputus, sedangkan dengan IF EXISTS, Anda dapat yakin bahwa PostgreSQL tidak akan menyebabkan penghentian karena peran yang hilang.

Catatan: Ada beberapa pernyataan yang mendukung klausa IF EXISTS, seperti yang akan Anda lihat di bab-bab berikutnya. Idenya adalah untuk menghindari melaporkan kesalahan ketika Anda tidak tertarik untuk menangkapnya, dan Anda sebaiknya menggunakan klausa ini, kapan pun memungkinkan, dalam program otomatisasi.

Apa yang terjadi jika Anda menghapus grup? Peran anggota akan tetap ada, tetapi tentu saja, asosiasi dengan grup akan hilang (karena grup telah dihapus). Dengan kata lain, menghapus grup tidak berimbas ke anggotanya.

Memeriksa Peran yang Ada

Sekarang setelah Anda tahu cara membuat dan menghapus peran, bagaimana Anda bisa memeriksa peran yang ada, termasuk peran Anda sendiri? Ada berbagai cara untuk mendapatkan informasi tentang peran yang ada, dan semuanya bergantung pada katalog PostgreSQL, sumber introspeksi satu-satunya ke dalam klaster.

Untuk mengetahui peran yang sedang Anda jalankan, gunakan kata kunci khusus CURRENT_ROLE: Anda dapat mengkuerinya melalui pernyataan SELECT (pernyataan seperti ini akan disajikan di bab-bab berikutnya, jadi untuk saat ini, gunakan saja seperti yang ditunjukkan di sini):

postgres=# SELECT current_role;
current_role
--------------
postgres
(1 row)

Jika Anda terhubung ke basis data dengan pengguna lain, Anda akan melihat hasil yang berbeda:

$ psql -U luca postgres
psql (16.0)
Type "help" for help.
postgres=> SELECT current_role;
current_role
--------------
luca
(1 row)

Mengetahui peran Anda sendiri penting, tetapi mendapatkan informasi tentang peran yang ada dan properti mereka bisa jauh lebih mencerahkan. psql menyediakan perintah khusus \du (deskripsi pengguna) untuk mendaftar semua peran yang tersedia dalam sistem:

$ psql -U postgres
psql (16.0)
Type "help" for help.
postgres=# \du
List of roles
Role name     | Attributes
--------------+----------------------------------------------------------
book_authors  | Cannot login
enrico        |
forum         |
forum_admins  | Cannot login
forum_emails  | No inheritance, Cannot login
forum_stats   | No inheritance, Cannot login
luca          | 1 connection
postgres      | Superuser, Create role, Create DB, Replication, Bypass RLS

Kolom Attributes menunjukkan opsi dan properti peran, banyak di antaranya akan dibahas di Bab 10, Pengguna, Peran, dan Keamanan Basis Data. Mengenai properti login, jika peran dicegah untuk terhubung secara interaktif ke klaster, pesan Cannot login akan ditampilkan di baris seperti book_authors dalam contoh di atas.

Perintah khusus psql \drg akan menunjukkan semua grup yang menjadi anggota peran.

Anda bisa mendapatkan informasi tentang peran tertentu dengan langsung mengkueri katalog pg_roles, katalog yang berisi informasi tentang semua peran PostgreSQL. Misalnya, untuk mendapatkan informasi koneksi dasar untuk peran luca, Anda dapat menjalankan kueri berikut:

postgres=# SELECT rolname, rolcanlogin,
rolconnlimit, rolpassword
FROM pg_roles
WHERE rolname = 'luca';
-[ RECORD 1 ]--+---------
rolname        | luca
rolcanlogin    | t
rolconnlimit   | 1
rolpassword    | ******

Seperti yang Anda lihat, kata sandi tidak ditampilkan untuk alasan keamanan, bahkan jika superuser klaster yang memintanya. Tidak mungkin mendapatkan kata sandi dalam teks biasa: seperti yang telah kita lihat, kata sandi selalu disimpan dalam bentuk terenkripsi.

Katalog khusus pg_authid mewakili tulang punggung untuk informasi pg_roles, dan dapat dikueri dengan pernyataan yang sama, tetapi melaporkan kata sandi pengguna (sebagai teks terenkripsi). Kode berikut menunjukkan hasil dari mengkueri pg_authid untuk pengguna yang sama seperti dalam daftar keempat; perhatikan bagaimana kolom rolpassword berisi informasi yang lebih berguna kali ini:

postgres=# SELECT rolname, rolcanlogin, rolconnlimit, rolpassword
FROM pg_authid WHERE rolname = 'luca';
rolpassword | SCRAM-SHA-256$4096:EC42FTTKy6bi/hfslsa4Sw=

Kata sandi diwakili sebagai hash dan bagian awal menentukan algoritma enkripsi yang digunakan, yang saat ini default ke SCRAM-SHA-256. Perlu dicatat bahwa, sementara pg_roles dapat dikueri oleh superuser maupun pengguna normal, pg_authid hanya dapat dikueri oleh superuser.

Mengelola Koneksi Masuk pada Tingkat Peran

Ketika koneksi baru dibuat ke klaster, PostgreSQL memvalidasi permintaan masuk pada tingkat peran. Fakta bahwa peran memiliki properti LOGIN tidak cukup untuk membuka koneksi baru ke basis data apa pun dalam klaster. Ini karena PostgreSQL memeriksa permintaan koneksi masuk terhadap semacam tabel firewall, yang dikenal sebagai akses berbasis host (host-based access), yang didefinisikan dalam file pg_hba.conf.

Jika tabel menyatakan bahwa peran dapat membuka koneksi ke basis data yang ditentukan, koneksi akan diberikan (dengan asumsi memiliki properti LOGIN); jika tidak, koneksi akan ditolak.

Setiap kali Anda memodifikasi file pg_hba.conf, Anda perlu menginstruksikan klaster untuk memuat ulang aturan baru melalui sinyal HUP atau dengan perintah reload di pg_ctl. Oleh karena itu, alur kerja biasa saat menangani pg_hba.confmirip dengan berikut:

$ $EDITOR $PGDATA/pg_hba.conf
... modifikasi file sesuai keinginan ...
$ sudo -u postgres pg_ctl reload -D $PGDATA
server signaled

Catatan: Dalam contoh kode sebelumnya, $EDITOR digunakan untuk meluncurkan editor pilihan, jika telah diatur. Anda dapat mengatur variabel lingkungan EDITOR di banyak shell dengan mengetik export EDITOR=/bin/vim (atau jalur ke editor pilihan Anda).

Catatan untuk pengguna Docker: Dalam image Docker yang disediakan untuk buku ini, variabel PGDATA sudah diatur. Selain itu, shell interaktif sudah diluncurkan dengan pengguna postgres. Oleh karena itu, untuk memuat ulang konfigurasi klaster, Anda tidak perlu khawatir tentang EDITOR, PGDATA, atau sudo dan cukup menulis pg_ctl reload di prompt shell.

Perlu dicatat bahwa peran superuser dapat menginstruksikan klaster untuk memuat ulang konfigurasi melalui pernyataan SQL. Memanggil fungsi khusus pg_reload_conf() akan melakukan tindakan yang sama seperti mengeluarkan reload ke pg_ctl:

postgres=# SELECT pg_reload_conf();
pg_reload_conf
----------------
t

Sintaks pg_hba.conf

File pg_hba.conf berisi firewall untuk koneksi masuk. Setiap baris dalam file memiliki struktur berikut:

<tipe-koneksi> <basis-data> <peran> <mesin-jarak-jauh> <metode-autentikasi>

Setiap bagian dari baris memiliki arti berikut:

  • tipe-koneksi adalah jenis koneksi yang didukung oleh PostgreSQL dan bisa berupa local (artinya melalui soket sistem operasi), host (koneksi TCP/IP, baik terenkripsi maupun tidak), hostssl (koneksi TCP/IP hanya terenkripsi), atau nohostssl (koneksi TCP/IP tidak terenkripsi).

  • basis-data adalah nama basis data spesifik yang dirujuk oleh baris atau kata kunci khusus all, yang berarti setiap basis data yang tersedia. Kata kunci khusus replication digunakan untuk menangani jenis koneksi khusus yang digunakan untuk mereplikasi data ke klaster lain, dan akan dijelaskan di bab-bab berikutnya.

  • peran adalah peran spesifik (baik nama pengguna atau grup) yang dirujuk oleh baris atau kata kunci khusus all, yang berarti semua peran (dan grup) yang tersedia.

  • mesin-jarak-jauh adalah nama host, alamat IP, atau subnet dari mana koneksi diharapkan. Kata kunci khusus allcocok dengan mesin jarak jauh apa pun dari mana koneksi dibuat, sedangkan kata kunci khusus samehost dan samenet cocok dengan nama host atau subnet apa pun yang terhubung dengan klaster.

  • metode-autentikasi menentukan bagaimana koneksi harus ditangani; secara umum, ini berkaitan dengan bagaimana kredensial login harus diperiksa. Metode utama adalah scram-sha-256, md5 (metode yang digunakan di versi lama), reject untuk selalu menolak koneksi, dan trust untuk selalu menerima koneksi tanpa mempedulikan kredensial yang diberikan.

Catatan: Anda tidak dapat memberi nama basis data atau pengguna dengan salah satu kata kunci khusus, misalnya, replication.

Untuk lebih memahami cara kerja sistem, berikut adalah kutipan dari file pg_hba.conf yang mungkin:

host all luca carmensita scram-sha-256
hostssl all test 192.168.222.1/32 scram-sha-256
host digikamdb pgwatch2 192.168.222.4/32 trust
host digikamdb enrico carmensita reject

Baris pertama menunjukkan bahwa pengguna luca dapat terhubung ke setiap basis data dalam klaster (melalui klausa all) melalui koneksi TCP/IP (melalui klausa host) yang berasal dari host bernama carmensita, tetapi ia harus memberikan nama pengguna/kata sandi yang valid untuk memverifikasi metode autentikasi SCRAM.

Baris kedua menyatakan bahwa pengguna test dapat terhubung ke setiap basis data dalam sistem melalui koneksi terenkripsi SSL (lihat klausa hostssl), tetapi hanya dari mesin yang memiliki alamat IPv4 192.168.222.1; lagi-lagi, kredensial harus lulus metode autentikasi SCRAM.

Baris ketiga menyatakan bahwa akses ke basis data digikamdb hanya diberikan kepada pengguna pgwatch2 melalui koneksi tidak terenkripsi dari host 192.168.222.4; kali ini, akses diberikan (trust) tanpa memerlukan kredensial apa pun.

Terakhir, baris terakhir menolak setiap koneksi masuk dari host bernama carmensita, yang dibuka oleh pengguna enricoterhadap digikamdb; dengan kata lain, enrico tidak dapat terhubung ke digikamdb dari host carmensita.

Peringatan: Metode autentikasi trust tidak boleh digunakan; ini memungkinkan peran apa pun untuk terhubung ke basis data jika akses berbasis host (HBA) memiliki aturan yang cocok dengan koneksi masuk. Ini adalah metode yang digunakan saat klaster diinisialisasi untuk mengaktifkan superuser yang baru dibuat untuk terhubung ke klaster. Anda selalu dapat menggunakan trik ini sebagai upaya terakhir jika Anda terkunci dari klaster Anda sendiri.

Urutan Aturan di pg_hba.conf

Urutan aturan yang terdaftar dalam file pg_hba.conf sangat penting. Aturan pertama yang memenuhi logika akan diterapkan, dan yang lainnya akan dilewati. Untuk lebih memahami ini, bayangkan bahwa kita ingin mengizinkan lucauntuk terhubung ke basis data apa pun dalam klaster kecuali forumdb. Kode berikut tidak akan membuat ini terjadi:

host all luca all scram-sha-256
host forumdb luca all reject

Mengapa kode di atas tidak berhasil? Bayangkan bahwa pengguna luca mencoba membuka koneksi ke basis data forumdb: mesin dari mana koneksi dicoba dicocokkan dengan kata kunci all dengan baris yang berisi luca, dan kemudian nama basis data dicocokkan dengan kata kunci all untuk kolom basis data. Karena baik mesin jarak jauh maupun nama basis data adalah bagian dari all, koneksi diteruskan melalui metode autentikasi SCRAM-256; jika pengguna berhasil dalam autentikasi, koneksi dibuka. Baris reject karenanya dilewati karena baris pertama cocok. Di sisi lain, menukar urutan aturan seperti yang ditunjukkan dalam kode berikut berhasil:

host forumdb luca all reject
host all luca all scram-sha-256

Dengan cara ini, ketika luca mencoba terhubung ke basis data, ia akan ditolak jika basis datanya adalah forumdb; jika tidak, ia dapat terhubung (jika ia lulus metode autentikasi yang diperlukan).

Menggabungkan Beberapa Aturan menjadi Satu

Satu baris menyatakan setidaknya satu aturan, tetapi dimungkinkan untuk menggabungkan beberapa baris menjadi satu. Faktanya, kolom peran, basis data, dan mesin jarak jauh memungkinkan definisi beberapa kecocokan, masing-masing dipisahkan oleh koma (,).

Sebagai contoh, misalkan kita ingin memberikan akses ke peran luca dan enrico (dari jaringan yang sama tempat klaster berjalan) ke basis data forumdb dan learnpgdb sehingga pg_hba.conf terlihat seperti berikut:

host forumdb luca samenet scram-sha-256
host forumdb enrico samenet scram-sha-256
host learnpgdb luca samenet scram-sha-256
host learnpgdb enrico samenet scram-sha-256

Karena kolom basis data dan peran dapat mencantumkan lebih dari satu item, kode di atas dapat dipadatkan menjadi berikut:

host forumdb,learnpgdb luca samenet scram-sha-256
host forumdb,learnpgdb enrico samenet scram-sha-256

Kita dapat memadatkan aturan lebih lanjut karena mesin dari mana koneksi basis data dapat dibuat benar-benar sama untuk kedua aturan, dan oleh karena itu kode akhirnya adalah sebagai berikut:

host forumdb,learnpgdb luca,enrico samenet scram-sha-256

Sekarang seharusnya jelas bagi Anda bahwa jika lebih banyak aturan memiliki metode autentikasi dan protokol koneksi yang sama, maka dimungkinkan untuk menggabungkannya menjadi agregasi. Ini dapat membantu Anda mengelola konfigurasi akses berbasis host.

Menggunakan Grup alih-alih Peran Tunggal

Kolom peran dalam setiap aturan pg_hba.conf dapat diganti dengan nama grup (ingat bahwa grup itu sendiri adalah peran); namun, agar aturan tersebut berlaku untuk setiap anggota grup, Anda harus mengawali nama grup dengan tanda plus (+).

Untuk lebih memahami ini, pertimbangkan contoh grup book_authors, yang mencakup anggota luca. Aturan berikut tidak akan mengizinkan peran luca untuk mengakses basis data:

host forumdb book_authors all scram-sha-256

Meskipun pengguna adalah anggota peran book_authors, ia akan ditolak untuk login ke basis data; kebijakan akses berbasis host klaster mengharuskan peran book_authors benar-benar cocok dengan aturan, dan dalam perintah berikut, peran luca tidak cocok dengan aturan apa pun:

$ psql -U luca forumdb
psql: error: could not connect to server:
FATAL: no pg_hba.conf entry for host "192.168.222.1", user "luca",
database "forumdb", SSL off

Sebaliknya, jika kita dengan jelas menyatakan bahwa kita ingin menggunakan peran book_authors sebagai nama grup, dan karenanya mengizinkan semua anggotanya, koneksi dapat dibuat oleh peran apa pun yang merupakan anggota grup, termasuk luca. Oleh karena itu, kita ubah aturan menjadi berikut:

host forumdb +book_authors all scram-sha-256

Ini, dengan mempertimbangkan tanda plus, memungkinkan koneksi, seperti yang ditunjukkan di sini:

$ psql -U luca forumdb
forumdb=>

Aturan pg_hba.conf, ketika diterapkan pada nama grup (yaitu, dengan tanda + sebelum nama peran) mencakup semua anggota langsung dan tidak langsung.

Bagaimana jika kita ingin mengizinkan setiap anggota grup kecuali satu untuk mengakses basis data? Mengingat bahwa mesin aturan berhenti pada kecocokan pertama, dimungkinkan untuk menempatkan aturan reject sebelum aturan penerimaan grup. Misalnya, untuk mengizinkan setiap anggota grup book_authors mengakses basis data sambil mencegah peran tunggal luca untuk terhubung, Anda dapat menggunakan berikut:

host forumdb luca all reject
host forumdb +book_authors all scram-sha-256

Baris pertama akan mencegah peran luca untuk terhubung, meskipun baris berikutnya mengizinkan setiap anggota book_authors (termasuk luca) untuk terhubung: kecocokan pertama menang sehingga luca terkunci dari basis data.

Menggunakan File alih-alih Peran Tunggal

Kolom peran dari aturan juga dapat ditentukan sebagai file teks, baik yang dipisahkan baris maupun koma. Ini berguna ketika Anda menangani nama pengguna atau nama grup yang panjang, atau dengan daftar yang dihasilkan secara otomatis dari proses batch.

Jika Anda menentukan kolom peran dengan awalan tanda β€œat” (@), nama tersebut diinterpretasikan sebagai file teks yang dipisahkan baris (sebagai nama relatif terhadap direktori PGDATA). Misalnya, untuk menolak koneksi ke semua pengguna dan grup yang terdaftar dalam file rejected_users.txt, sambil mengizinkan koneksi ke semua nama pengguna dan grup yang ditentukan dalam file allowed_users.txt, file pg_hba.conf harus terlihat seperti potongan berikut:

host forumdb @rejected_users.txt all reject
host forumdb @allowed_users.txt all scram-sha-256

Berikut adalah isi dari file rejected_users.txt, diikuti oleh file allowed_users.txt:

$ sudo cat $PGDATA/rejected_users.txt
luca
enrico
$ sudo cat $PGDATA/allowed_users.txt
+book_authors,postgres

Seperti yang Anda lihat, dimungkinkan untuk menentukan isi file sebagai daftar yang dipisahkan baris atau daftar yang dipisahkan koma dari nama pengguna. Juga dimungkinkan untuk menentukan peran mana yang digunakan sebagai grup dengan menempatkan tanda + di depan nama peran.

Memeriksa Aturan pg_hba.conf

File pg_hba.conf berisi aturan yang diterapkan pada koneksi masuk, tetapi karena file ini dapat diubah secara manual tanpa membuat klaster memuat ulang, bagaimana Anda bisa yakin aturan mana yang diterapkan saat ini? PostgreSQL menyediakan katalog khusus bernama pg_hba_file_rules yang menunjukkan aturan mana yang telah diterapkan pada klaster.

Anda dapat mengkueri katalog sebagai tabel normal dan mendapatkan informasi tentang setiap baris dari file pg_hba.conf yang telah dipahami dan diterapkan pada klaster yang sedang berjalan. Sebagai contoh, dalam instalasi PostgreSQL baru, Anda mungkin akan melihat keluaran seperti berikut:

postgres=# SELECT line_number, type,
database, user_name,
address, auth_method
FROM pg_hba_file_rules;
line_number | type | database       | user_name | address   | auth_method
-------------+-------+---------------+-----------+-----------+------------
89          | local | {all}         | {all}     |           | trust
91          | host  | {all}         | {all}     | 127.0.0.1 | trust
93          | host  | {all}         | {all}     | ::1       | trust
96          | local | {replication} | {all}     |           | trust
97          | host  | {replication} | {all}     | 127.0.0.1 | trust
98          | host  | {replication} | {all}     | ::1       | trust
100         | host  | {all}         | {all}     | all       | scram-sha-256
(7 rows)

Seperti yang Anda lihat, pg_hba_file_rules melaporkan semua informasi yang sama yang dapat Anda temukan di pg_hba.conf, dengan indikator nomor baris yang memberi tahu Anda dari baris mana aturan tertentu telah dimuat.

Menyertakan File Lain di pg_hba.conf

Dimungkinkan untuk menyertakan file konfigurasi HBA lain ke dalam file utama pg_hba.conf. PostgreSQL menyediakan tiga direktif utama:

  • include_file menyertakan file tertentu di pg_hba.conf.

  • include_if_exists menyertakan file tertentu tetapi hanya jika file tersebut ada; jika tidak ada (atau dihapus), tidak ada kesalahan yang akan terjadi.

  • include_dir menyertakan semua file yang ditentukan dalam direktori yang diberikan.

Berkat direktif ini, dimungkinkan untuk mendefinisikan sekumpulan file konfigurasi kecil yang akan disertakan secara literal dalam konfigurasi HBA seolah-olah administrator telah mengedit file pg_hba.conf secara langsung.

Untuk memahami dari mana aturan tertentu berasal, katalog pg_hba_file_rules menyertakan kolom file_name yang melaporkan dari file mana (dan pada baris mana, berkat line_number) aturan telah diuraikan.

Ringkasan

PostgreSQL memungkinkan Anda untuk mendefinisikan pengguna tunggal dan grup pengguna, keduanya diwakili oleh konsep SQL peran. Ketika upaya koneksi basis data dilakukan, PostgreSQL memproses informasi koneksi melalui kontrol akses berbasis host sehingga dapat segera menetapkan atau menolak koneksi, tergantung pada aturan seperti firewall. Jika koneksi dapat dibuat, kredensial untuk peran diperiksa, dan akhirnya, pengguna diberikan akses.

Pengguna dan grup dapat disesuaikan secara detail dalam hal izin yang diberikan dan batasan koneksi sehingga Anda dapat menentukan berapa banyak sumber daya yang dapat dikonsumsi oleh peran tunggal.

Dalam bab ini, Anda telah melihat cara membuat dan mengelola peran, serta cara mengizinkan peran tunggal untuk terhubung ke klaster dan ke basis data tertentu. Di Bab 10, Pengguna, Peran, dan Keamanan Basis Data, Anda akan melihat cara menangani properti keamanan pengguna dan grup, tetapi sebelum Anda melangkah lebih jauh, Anda perlu tahu bagaimana objek PostgreSQL dapat dibuat dan dikelola.

Di bab berikutnya, Anda akan belajar cara berinteraksi dengan basis data PostgreSQL menggunakan pernyataan SQL.

Last updated